astro 6.3.2 → 6.3.4
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/utils/metadata.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/svg.js +1 -1
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/content/runtime.js +5 -2
- package/dist/core/build/generate.js +8 -1
- package/dist/core/build/plugins/plugin-internals.js +1 -1
- package/dist/core/build/static-build.js +9 -147
- package/dist/core/build/vite-build-config.d.ts +28 -0
- package/dist/core/build/vite-build-config.js +160 -0
- package/dist/core/config/schemas/base.d.ts +3 -1
- package/dist/core/config/schemas/base.js +6 -1
- package/dist/core/config/schemas/relative.d.ts +9 -3
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/fetch/fetch-state.d.ts +7 -0
- package/dist/core/fetch/fetch-state.js +5 -0
- package/dist/core/fetch/types.d.ts +19 -0
- package/dist/core/fetch/vite-plugin.js +11 -4
- package/dist/core/hono/index.d.ts +1 -1
- package/dist/core/hono/index.js +6 -3
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/middleware/astro-middleware.js +3 -1
- package/dist/core/module-loader/vite.js +1 -2
- package/dist/core/pages/handler.js +1 -0
- package/dist/runtime/server/render/component.js +3 -3
- package/dist/types/public/config.d.ts +20 -3
- package/dist/types/public/context.d.ts +1 -1
- package/dist/types/public/extendables.d.ts +19 -0
- package/dist/types/public/index.d.ts +1 -0
- package/dist/vite-plugin-app/app.js +11 -11
- package/dist/vite-plugin-astro-server/plugin.js +8 -7
- package/package.json +4 -4
- package/templates/content/types.d.ts +1 -0
|
@@ -10,7 +10,7 @@ async function imageMetadata(data, src) {
|
|
|
10
10
|
message: AstroErrorData.NoImageMetadata.message(src)
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
|
-
if (
|
|
13
|
+
if (result.height == null || result.width == null || !result.type) {
|
|
14
14
|
throw new AstroError({
|
|
15
15
|
...AstroErrorData.NoImageMetadata,
|
|
16
16
|
message: AstroErrorData.NoImageMetadata.message(src)
|
|
@@ -77,7 +77,7 @@ const SVG = {
|
|
|
77
77
|
const root = extractorRegExps.root.exec(toUTF8String(input));
|
|
78
78
|
if (root) {
|
|
79
79
|
const attrs = parseAttributes(root[0]);
|
|
80
|
-
if (attrs.width && attrs.height) {
|
|
80
|
+
if (attrs.width != null && attrs.height != null) {
|
|
81
81
|
return calculateByDimensions(attrs);
|
|
82
82
|
}
|
|
83
83
|
if (attrs.viewbox) {
|
|
@@ -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.4") {
|
|
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.4") {
|
|
203
|
+
this.#store.metaStore().set("astro-version", "6.3.4");
|
|
204
204
|
}
|
|
205
205
|
if (currentConfigDigest) {
|
|
206
206
|
this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
package/dist/content/runtime.js
CHANGED
|
@@ -134,9 +134,10 @@ function createGetEntry({ liveCollections }) {
|
|
|
134
134
|
return;
|
|
135
135
|
}
|
|
136
136
|
const { default: imageAssetMap } = await import("astro:asset-imports");
|
|
137
|
-
|
|
137
|
+
const data = updateImageReferencesInData(entry.data, entry.filePath, imageAssetMap);
|
|
138
138
|
const result = {
|
|
139
139
|
...entry,
|
|
140
|
+
data,
|
|
140
141
|
collection
|
|
141
142
|
};
|
|
142
143
|
warnForPropertyAccess(
|
|
@@ -354,7 +355,8 @@ async function updateImageReferencesInBody(html, fileName) {
|
|
|
354
355
|
});
|
|
355
356
|
}
|
|
356
357
|
function updateImageReferencesInData(data, fileName, imageAssetMap) {
|
|
357
|
-
|
|
358
|
+
const copy = structuredClone(data);
|
|
359
|
+
new Traverse(copy).forEach(function(ctx, val) {
|
|
358
360
|
if (typeof val === "string" && val.startsWith(IMAGE_IMPORT_PREFIX)) {
|
|
359
361
|
const src = val.replace(IMAGE_IMPORT_PREFIX, "");
|
|
360
362
|
const id = imageSrcToImportId(src, fileName);
|
|
@@ -375,6 +377,7 @@ function updateImageReferencesInData(data, fileName, imageAssetMap) {
|
|
|
375
377
|
}
|
|
376
378
|
}
|
|
377
379
|
});
|
|
380
|
+
return copy;
|
|
378
381
|
}
|
|
379
382
|
async function renderEntry(entry) {
|
|
380
383
|
if (!entry) {
|
|
@@ -187,13 +187,20 @@ ${colors.bgGreen(colors.black(` ${verb} static routes `))}`);
|
|
|
187
187
|
const cpuCount = os.cpus().length;
|
|
188
188
|
const assetsCreationPipeline = await prepareAssetsGenerationEnv(options, totalCount);
|
|
189
189
|
const queue = new PQueue({ concurrency: Math.max(cpuCount, 1) });
|
|
190
|
+
const errors = [];
|
|
190
191
|
const assetsTimer = performance.now();
|
|
191
192
|
for (const [originalPath, transforms] of staticImageList) {
|
|
192
193
|
queue.add(() => generateImagesForPath(originalPath, transforms, assetsCreationPipeline)).catch((e) => {
|
|
193
|
-
|
|
194
|
+
logger.warn("build", `Unable to generate optimized image for ${originalPath}: ${e}`);
|
|
195
|
+
errors.push(new Error(`Error generating image for ${originalPath}: ${e}`, { cause: e }));
|
|
194
196
|
});
|
|
195
197
|
}
|
|
196
198
|
await queue.onIdle();
|
|
199
|
+
if (errors.length === 1) {
|
|
200
|
+
throw errors[0];
|
|
201
|
+
} else if (errors.length > 1) {
|
|
202
|
+
throw new AggregateError(errors, `${errors.length} errors occurred during asset generation`);
|
|
203
|
+
}
|
|
197
204
|
const assetsTimeEnd = performance.now();
|
|
198
205
|
logger.info(null, colors.green(`\u2713 Completed in ${getTimeStat(assetsTimer, assetsTimeEnd)}.
|
|
199
206
|
`));
|
|
@@ -10,31 +10,21 @@ import { emptyDir, removeEmptyDirs } from "../../core/fs/index.js";
|
|
|
10
10
|
import { appendForwardSlash, prependForwardSlash } from "../../core/path.js";
|
|
11
11
|
import { runHookBuildSetup } from "../../integrations/hooks.js";
|
|
12
12
|
import { SERIALIZED_MANIFEST_RESOLVED_ID } from "../../manifest/serialized.js";
|
|
13
|
-
import {
|
|
14
|
-
getClientOutputDirectory,
|
|
15
|
-
getPrerenderOutputDirectory,
|
|
16
|
-
getServerOutputDirectory
|
|
17
|
-
} from "../../prerender/utils.js";
|
|
18
|
-
import { VIRTUAL_PAGE_RESOLVED_MODULE_ID } from "../../vite-plugin-pages/const.js";
|
|
13
|
+
import { getPrerenderOutputDirectory } from "../../prerender/utils.js";
|
|
19
14
|
import { PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
|
|
20
15
|
import { routeIsRedirect } from "../routing/helpers.js";
|
|
21
16
|
import { getOutDirWithinCwd } from "./common.js";
|
|
22
|
-
import { CHUNKS_PATH } from "./consts.js";
|
|
23
17
|
import { generatePages } from "./generate.js";
|
|
24
18
|
import { trackPageData } from "./internal.js";
|
|
25
19
|
import { getAllBuildPlugins } from "./plugins/index.js";
|
|
26
20
|
import { manifestBuildPostHook } from "./plugins/plugin-manifest.js";
|
|
27
|
-
import {
|
|
28
|
-
isLegacyAdapter,
|
|
29
|
-
LEGACY_SSR_ENTRY_VIRTUAL_MODULE,
|
|
30
|
-
RESOLVED_LEGACY_SSR_ENTRY_VIRTUAL_MODULE
|
|
31
|
-
} from "./plugins/plugin-ssr.js";
|
|
32
21
|
import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from "./plugins/util.js";
|
|
33
|
-
import {
|
|
22
|
+
import { getTimeStat, viteBuildReturnToRollupOutputs } from "./util.js";
|
|
34
23
|
import { NOOP_MODULE_ID } from "./plugins/plugin-noop.js";
|
|
35
24
|
import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../constants.js";
|
|
36
25
|
import { getSSRAssets } from "./internal.js";
|
|
37
26
|
import { SERVER_ISLAND_MAP_MARKER } from "../server-islands/vite-plugin-server-islands.js";
|
|
27
|
+
import { createViteBuildConfig } from "./vite-build-config.js";
|
|
38
28
|
const PRERENDER_ENTRY_FILENAME_PREFIX = "prerender-entry";
|
|
39
29
|
function extractRelevantChunks(outputs, prerender) {
|
|
40
30
|
const extracted = [];
|
|
@@ -83,7 +73,6 @@ async function viteBuild(opts) {
|
|
|
83
73
|
async function buildEnvironments(opts, internals) {
|
|
84
74
|
const { allPages, settings, viteConfig } = opts;
|
|
85
75
|
const routes = Object.values(allPages).flatMap((pageData) => pageData.route);
|
|
86
|
-
const legacyAdapter = !settings.adapter || isLegacyAdapter(settings.adapter);
|
|
87
76
|
const buildPlugins = getAllBuildPlugins(internals, opts);
|
|
88
77
|
const flatPlugins = buildPlugins.flat().filter(Boolean);
|
|
89
78
|
const plugins = [...flatPlugins, ...viteConfig.plugins || []];
|
|
@@ -149,76 +138,10 @@ async function buildEnvironments(opts, internals) {
|
|
|
149
138
|
return Object.keys(currentRollupInput).includes(moduleName);
|
|
150
139
|
}
|
|
151
140
|
}
|
|
152
|
-
const viteBuildConfig = {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
target: "esnext",
|
|
157
|
-
// Vite defaults cssMinify to false in SSR by default, but we want to minify it
|
|
158
|
-
// as the CSS generated are used and served to the client.
|
|
159
|
-
cssMinify: viteConfig.build?.minify == null ? true : !!viteConfig.build?.minify,
|
|
160
|
-
...viteConfig.build,
|
|
161
|
-
emptyOutDir: false,
|
|
162
|
-
copyPublicDir: false,
|
|
163
|
-
manifest: false,
|
|
164
|
-
rollupOptions: {
|
|
165
|
-
...viteConfig.build?.rollupOptions,
|
|
166
|
-
// Setting as `exports-only` allows us to safely delete inputs that are only used during prerendering
|
|
167
|
-
preserveEntrySignatures: "exports-only",
|
|
168
|
-
...legacyAdapter && settings.buildOutput === "server" ? { input: LEGACY_SSR_ENTRY_VIRTUAL_MODULE } : {},
|
|
169
|
-
output: {
|
|
170
|
-
hoistTransitiveImports: false,
|
|
171
|
-
format: "esm",
|
|
172
|
-
minifyInternalExports: true,
|
|
173
|
-
// Server chunks can't go in the assets (_astro) folder
|
|
174
|
-
// We need to keep these separate
|
|
175
|
-
chunkFileNames(chunkInfo) {
|
|
176
|
-
const { name } = chunkInfo;
|
|
177
|
-
let prefix = CHUNKS_PATH;
|
|
178
|
-
let suffix = "_[hash].mjs";
|
|
179
|
-
if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
|
|
180
|
-
const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
|
|
181
|
-
return [prefix, cleanChunkName(sanitizedName), suffix].join("");
|
|
182
|
-
}
|
|
183
|
-
if (name.startsWith("pages/")) {
|
|
184
|
-
const sanitizedName = name.split(".")[0];
|
|
185
|
-
return [prefix, cleanChunkName(sanitizedName), suffix].join("");
|
|
186
|
-
}
|
|
187
|
-
return [prefix, cleanChunkName(name), suffix].join("");
|
|
188
|
-
},
|
|
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
|
-
},
|
|
197
|
-
...viteConfig.build?.rollupOptions?.output,
|
|
198
|
-
entryFileNames(chunkInfo) {
|
|
199
|
-
if (chunkInfo.facadeModuleId?.startsWith(VIRTUAL_PAGE_RESOLVED_MODULE_ID)) {
|
|
200
|
-
return makeAstroPageEntryPointFileName(
|
|
201
|
-
VIRTUAL_PAGE_RESOLVED_MODULE_ID,
|
|
202
|
-
chunkInfo.facadeModuleId,
|
|
203
|
-
routes
|
|
204
|
-
);
|
|
205
|
-
} else if (chunkInfo.facadeModuleId === RESOLVED_LEGACY_SSR_ENTRY_VIRTUAL_MODULE || // This catches the case when the adapter uses `entrypointResolution: 'auto'`. When doing so,
|
|
206
|
-
// the adapter must set rollupOptions.input or Astro sets it from `serverEntrypoint`.
|
|
207
|
-
isRollupInput(chunkInfo.name) || isRollupInput(chunkInfo.facadeModuleId)) {
|
|
208
|
-
return opts.settings.config.build.serverEntry;
|
|
209
|
-
} else {
|
|
210
|
-
return "[name].mjs";
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
ssr: true,
|
|
216
|
-
ssrEmitAssets: true,
|
|
217
|
-
// improve build performance
|
|
218
|
-
minify: false,
|
|
219
|
-
modulePreload: { polyfill: false },
|
|
220
|
-
reportCompressedSize: false
|
|
221
|
-
},
|
|
141
|
+
const viteBuildConfig = createViteBuildConfig({
|
|
142
|
+
settings,
|
|
143
|
+
viteConfig,
|
|
144
|
+
routes,
|
|
222
145
|
plugins,
|
|
223
146
|
// Top-level buildApp for framework build orchestration
|
|
224
147
|
// This takes precedence over platform plugin fallbacks (e.g., Cloudflare)
|
|
@@ -258,69 +181,8 @@ async function buildEnvironments(opts, internals) {
|
|
|
258
181
|
internals.extractedChunks = [...ssrChunks, ...prerenderChunks];
|
|
259
182
|
}
|
|
260
183
|
},
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
environments: {
|
|
264
|
-
...viteConfig.environments ?? {},
|
|
265
|
-
[ASTRO_VITE_ENVIRONMENT_NAMES.prerender]: {
|
|
266
|
-
build: {
|
|
267
|
-
emitAssets: true,
|
|
268
|
-
outDir: fileURLToPath(getPrerenderOutputDirectory(settings)),
|
|
269
|
-
rollupOptions: {
|
|
270
|
-
// Only skip the default prerender entrypoint if an adapter with `entrypointResolution: 'self'` is used
|
|
271
|
-
// AND provides a custom prerenderer. Otherwise, use the default.
|
|
272
|
-
...!legacyAdapter && settings.prerenderer ? {} : { input: "astro/entrypoints/prerender" },
|
|
273
|
-
output: {
|
|
274
|
-
entryFileNames: `${PRERENDER_ENTRY_FILENAME_PREFIX}.[hash].mjs`,
|
|
275
|
-
format: "esm",
|
|
276
|
-
...viteConfig.environments?.prerender?.build?.rollupOptions?.output
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
ssr: true
|
|
280
|
-
}
|
|
281
|
-
},
|
|
282
|
-
[ASTRO_VITE_ENVIRONMENT_NAMES.client]: {
|
|
283
|
-
build: {
|
|
284
|
-
emitAssets: true,
|
|
285
|
-
target: "esnext",
|
|
286
|
-
outDir: fileURLToPath(getClientOutputDirectory(settings)),
|
|
287
|
-
copyPublicDir: true,
|
|
288
|
-
sourcemap: viteConfig.environments?.client?.build?.sourcemap ?? false,
|
|
289
|
-
minify: true,
|
|
290
|
-
rollupOptions: {
|
|
291
|
-
preserveEntrySignatures: "exports-only",
|
|
292
|
-
output: {
|
|
293
|
-
entryFileNames(chunkInfo) {
|
|
294
|
-
return `${settings.config.build.assets}/${cleanChunkName(chunkInfo.name)}.[hash].js`;
|
|
295
|
-
},
|
|
296
|
-
chunkFileNames(chunkInfo) {
|
|
297
|
-
return `${settings.config.build.assets}/${cleanChunkName(chunkInfo.name)}.[hash].js`;
|
|
298
|
-
},
|
|
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
|
-
},
|
|
307
|
-
...viteConfig.environments?.client?.build?.rollupOptions?.output
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
},
|
|
312
|
-
[ASTRO_VITE_ENVIRONMENT_NAMES.ssr]: {
|
|
313
|
-
build: {
|
|
314
|
-
outDir: fileURLToPath(getServerOutputDirectory(settings)),
|
|
315
|
-
rollupOptions: {
|
|
316
|
-
output: {
|
|
317
|
-
...viteConfig.environments?.ssr?.build?.rollupOptions?.output
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
};
|
|
184
|
+
isRollupInput
|
|
185
|
+
});
|
|
324
186
|
const updatedViteBuildConfig = await runHookBuildSetup({
|
|
325
187
|
config: settings.config,
|
|
326
188
|
pages: internals.pagesByKeys,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type * as vite from 'vite';
|
|
2
|
+
import type { RouteData } from '../../types/public/internal.js';
|
|
3
|
+
import type { AstroSettings } from '../../types/astro.js';
|
|
4
|
+
export interface CreateViteBuildConfigOptions {
|
|
5
|
+
/** The resolved Astro settings. */
|
|
6
|
+
settings: AstroSettings;
|
|
7
|
+
/** The base Vite config produced by createVite(). */
|
|
8
|
+
viteConfig: vite.InlineConfig;
|
|
9
|
+
/** All routes to be built. */
|
|
10
|
+
routes: RouteData[];
|
|
11
|
+
/** Assembled Vite plugins (build plugins + user plugins). */
|
|
12
|
+
plugins: vite.PluginOption[];
|
|
13
|
+
/** The buildApp callback for the Vite builder. */
|
|
14
|
+
builder: vite.BuilderOptions;
|
|
15
|
+
/**
|
|
16
|
+
* A function that checks whether a given module name is a rollup input.
|
|
17
|
+
* Used by entryFileNames to determine the server entry.
|
|
18
|
+
*/
|
|
19
|
+
isRollupInput: (moduleName: string | null) => boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates the Vite InlineConfig used for the multi-environment build.
|
|
23
|
+
*
|
|
24
|
+
* This is a pure config assembly function — it does not execute the build.
|
|
25
|
+
* Extracted from `buildEnvironments()` to enable unit testing of config
|
|
26
|
+
* merging behavior (e.g. user rollup output overrides).
|
|
27
|
+
*/
|
|
28
|
+
export declare function createViteBuildConfig(opts: CreateViteBuildConfigOptions): vite.InlineConfig;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import {
|
|
3
|
+
getClientOutputDirectory,
|
|
4
|
+
getPrerenderOutputDirectory,
|
|
5
|
+
getServerOutputDirectory
|
|
6
|
+
} from "../../prerender/utils.js";
|
|
7
|
+
import { VIRTUAL_PAGE_RESOLVED_MODULE_ID } from "../../vite-plugin-pages/const.js";
|
|
8
|
+
import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../constants.js";
|
|
9
|
+
import { CHUNKS_PATH } from "./consts.js";
|
|
10
|
+
import {
|
|
11
|
+
isLegacyAdapter,
|
|
12
|
+
LEGACY_SSR_ENTRY_VIRTUAL_MODULE,
|
|
13
|
+
RESOLVED_LEGACY_SSR_ENTRY_VIRTUAL_MODULE
|
|
14
|
+
} from "./plugins/plugin-ssr.js";
|
|
15
|
+
import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from "./plugins/util.js";
|
|
16
|
+
import { cleanChunkName } from "./util.js";
|
|
17
|
+
import { makeAstroPageEntryPointFileName } from "./static-build.js";
|
|
18
|
+
const PRERENDER_ENTRY_FILENAME_PREFIX = "prerender-entry";
|
|
19
|
+
function createViteBuildConfig(opts) {
|
|
20
|
+
const { settings, viteConfig, routes, plugins, builder, isRollupInput } = opts;
|
|
21
|
+
const legacyAdapter = !settings.adapter || isLegacyAdapter(settings.adapter);
|
|
22
|
+
return {
|
|
23
|
+
...viteConfig,
|
|
24
|
+
logLevel: viteConfig.logLevel ?? "error",
|
|
25
|
+
build: {
|
|
26
|
+
target: "esnext",
|
|
27
|
+
// Vite defaults cssMinify to false in SSR by default, but we want to minify it
|
|
28
|
+
// as the CSS generated are used and served to the client.
|
|
29
|
+
cssMinify: viteConfig.build?.minify == null ? true : !!viteConfig.build?.minify,
|
|
30
|
+
...viteConfig.build,
|
|
31
|
+
emptyOutDir: false,
|
|
32
|
+
copyPublicDir: false,
|
|
33
|
+
manifest: false,
|
|
34
|
+
rollupOptions: {
|
|
35
|
+
...viteConfig.build?.rollupOptions,
|
|
36
|
+
// Setting as `exports-only` allows us to safely delete inputs that are only used during prerendering
|
|
37
|
+
preserveEntrySignatures: "exports-only",
|
|
38
|
+
...legacyAdapter && settings.buildOutput === "server" ? { input: LEGACY_SSR_ENTRY_VIRTUAL_MODULE } : {},
|
|
39
|
+
output: {
|
|
40
|
+
hoistTransitiveImports: false,
|
|
41
|
+
format: "esm",
|
|
42
|
+
minifyInternalExports: true,
|
|
43
|
+
// Server chunks can't go in the assets (_astro) folder
|
|
44
|
+
// We need to keep these separate
|
|
45
|
+
chunkFileNames(chunkInfo) {
|
|
46
|
+
const { name } = chunkInfo;
|
|
47
|
+
let prefix = CHUNKS_PATH;
|
|
48
|
+
let suffix = "_[hash].mjs";
|
|
49
|
+
if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
|
|
50
|
+
const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
|
|
51
|
+
return [prefix, cleanChunkName(sanitizedName), suffix].join("");
|
|
52
|
+
}
|
|
53
|
+
if (name.startsWith("pages/")) {
|
|
54
|
+
const sanitizedName = name.split(".")[0];
|
|
55
|
+
return [prefix, cleanChunkName(sanitizedName), suffix].join("");
|
|
56
|
+
}
|
|
57
|
+
return [prefix, cleanChunkName(name), suffix].join("");
|
|
58
|
+
},
|
|
59
|
+
assetFileNames(assetInfo) {
|
|
60
|
+
const name = assetInfo.names?.[0] ?? "";
|
|
61
|
+
if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
|
|
62
|
+
const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
|
|
63
|
+
return `${settings.config.build.assets}/${sanitizedName}.[hash][extname]`;
|
|
64
|
+
}
|
|
65
|
+
return `${settings.config.build.assets}/[name].[hash][extname]`;
|
|
66
|
+
},
|
|
67
|
+
...viteConfig.build?.rollupOptions?.output,
|
|
68
|
+
entryFileNames(chunkInfo) {
|
|
69
|
+
if (chunkInfo.facadeModuleId?.startsWith(VIRTUAL_PAGE_RESOLVED_MODULE_ID)) {
|
|
70
|
+
return makeAstroPageEntryPointFileName(
|
|
71
|
+
VIRTUAL_PAGE_RESOLVED_MODULE_ID,
|
|
72
|
+
chunkInfo.facadeModuleId,
|
|
73
|
+
routes
|
|
74
|
+
);
|
|
75
|
+
} else if (chunkInfo.facadeModuleId === RESOLVED_LEGACY_SSR_ENTRY_VIRTUAL_MODULE || // This catches the case when the adapter uses `entrypointResolution: 'auto'`. When doing so,
|
|
76
|
+
// the adapter must set rollupOptions.input or Astro sets it from `serverEntrypoint`.
|
|
77
|
+
isRollupInput(chunkInfo.name) || isRollupInput(chunkInfo.facadeModuleId)) {
|
|
78
|
+
return settings.config.build.serverEntry;
|
|
79
|
+
} else {
|
|
80
|
+
return "[name].mjs";
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
ssr: true,
|
|
86
|
+
ssrEmitAssets: true,
|
|
87
|
+
// improve build performance
|
|
88
|
+
minify: false,
|
|
89
|
+
modulePreload: { polyfill: false },
|
|
90
|
+
reportCompressedSize: false
|
|
91
|
+
},
|
|
92
|
+
plugins,
|
|
93
|
+
builder,
|
|
94
|
+
envPrefix: viteConfig.envPrefix ?? "PUBLIC_",
|
|
95
|
+
base: settings.config.base,
|
|
96
|
+
environments: {
|
|
97
|
+
...viteConfig.environments ?? {},
|
|
98
|
+
[ASTRO_VITE_ENVIRONMENT_NAMES.prerender]: {
|
|
99
|
+
build: {
|
|
100
|
+
emitAssets: true,
|
|
101
|
+
outDir: fileURLToPath(getPrerenderOutputDirectory(settings)),
|
|
102
|
+
rollupOptions: {
|
|
103
|
+
// Only skip the default prerender entrypoint if an adapter with `entrypointResolution: 'self'` is used
|
|
104
|
+
// AND provides a custom prerenderer. Otherwise, use the default.
|
|
105
|
+
...!legacyAdapter && settings.prerenderer ? {} : { input: "astro/entrypoints/prerender" },
|
|
106
|
+
output: {
|
|
107
|
+
entryFileNames: `${PRERENDER_ENTRY_FILENAME_PREFIX}.[hash].mjs`,
|
|
108
|
+
format: "esm",
|
|
109
|
+
...viteConfig.environments?.prerender?.build?.rollupOptions?.output
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
ssr: true
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
[ASTRO_VITE_ENVIRONMENT_NAMES.client]: {
|
|
116
|
+
build: {
|
|
117
|
+
emitAssets: true,
|
|
118
|
+
target: "esnext",
|
|
119
|
+
outDir: fileURLToPath(getClientOutputDirectory(settings)),
|
|
120
|
+
copyPublicDir: true,
|
|
121
|
+
sourcemap: viteConfig.environments?.client?.build?.sourcemap ?? false,
|
|
122
|
+
minify: true,
|
|
123
|
+
rollupOptions: {
|
|
124
|
+
preserveEntrySignatures: "exports-only",
|
|
125
|
+
output: {
|
|
126
|
+
entryFileNames(chunkInfo) {
|
|
127
|
+
return `${settings.config.build.assets}/${cleanChunkName(chunkInfo.name)}.[hash].js`;
|
|
128
|
+
},
|
|
129
|
+
chunkFileNames(chunkInfo) {
|
|
130
|
+
return `${settings.config.build.assets}/${cleanChunkName(chunkInfo.name)}.[hash].js`;
|
|
131
|
+
},
|
|
132
|
+
assetFileNames(assetInfo) {
|
|
133
|
+
const name = assetInfo.names?.[0] ?? "";
|
|
134
|
+
if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
|
|
135
|
+
const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
|
|
136
|
+
return `${settings.config.build.assets}/${sanitizedName}.[hash][extname]`;
|
|
137
|
+
}
|
|
138
|
+
return `${settings.config.build.assets}/[name].[hash][extname]`;
|
|
139
|
+
},
|
|
140
|
+
...viteConfig.environments?.client?.build?.rollupOptions?.output
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
[ASTRO_VITE_ENVIRONMENT_NAMES.ssr]: {
|
|
146
|
+
build: {
|
|
147
|
+
outDir: fileURLToPath(getServerOutputDirectory(settings)),
|
|
148
|
+
rollupOptions: {
|
|
149
|
+
output: {
|
|
150
|
+
...viteConfig.environments?.ssr?.build?.rollupOptions?.output
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
export {
|
|
159
|
+
createViteBuildConfig
|
|
160
|
+
};
|
|
@@ -501,7 +501,9 @@ export declare const AstroConfigSchema: z.ZodObject<{
|
|
|
501
501
|
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
502
502
|
}, z.core.$strict>>>;
|
|
503
503
|
experimental: z.ZodPrefault<z.ZodObject<{
|
|
504
|
-
advancedRouting: z.ZodDefault<z.ZodOptional<z.ZodBoolean
|
|
504
|
+
advancedRouting: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
|
|
505
|
+
fetchFile: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
506
|
+
}, z.core.$strict>]>>>;
|
|
505
507
|
clientPrerender: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
506
508
|
contentIntellisense: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
507
509
|
chromeDevtoolsWorkspace: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -310,7 +310,12 @@ const AstroConfigSchema = z.object({
|
|
|
310
310
|
prerenderConflictBehavior: z.enum(["error", "warn", "ignore"]).optional().default(ASTRO_CONFIG_DEFAULTS.prerenderConflictBehavior),
|
|
311
311
|
fonts: z.array(FontFamilySchema).optional(),
|
|
312
312
|
experimental: z.strictObject({
|
|
313
|
-
advancedRouting: z.
|
|
313
|
+
advancedRouting: z.union([
|
|
314
|
+
z.boolean(),
|
|
315
|
+
z.strictObject({
|
|
316
|
+
fetchFile: z.string().nullable().optional().default("app")
|
|
317
|
+
})
|
|
318
|
+
]).optional().default(ASTRO_CONFIG_DEFAULTS.experimental.advancedRouting),
|
|
314
319
|
clientPrerender: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.clientPrerender),
|
|
315
320
|
contentIntellisense: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.contentIntellisense),
|
|
316
321
|
chromeDevtoolsWorkspace: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.chromeDevtoolsWorkspace),
|
|
@@ -382,7 +382,9 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
382
382
|
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
383
383
|
}, z.core.$strict>>>;
|
|
384
384
|
experimental: z.ZodPrefault<z.ZodObject<{
|
|
385
|
-
advancedRouting: z.ZodDefault<z.ZodOptional<z.ZodBoolean
|
|
385
|
+
advancedRouting: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
|
|
386
|
+
fetchFile: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
387
|
+
}, z.core.$strict>]>>>;
|
|
386
388
|
clientPrerender: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
387
389
|
contentIntellisense: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
388
390
|
chromeDevtoolsWorkspace: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -576,7 +578,9 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
576
578
|
};
|
|
577
579
|
prerenderConflictBehavior: "error" | "ignore" | "warn";
|
|
578
580
|
experimental: {
|
|
579
|
-
advancedRouting: boolean
|
|
581
|
+
advancedRouting: boolean | {
|
|
582
|
+
fetchFile: string | null;
|
|
583
|
+
};
|
|
580
584
|
clientPrerender: boolean;
|
|
581
585
|
contentIntellisense: boolean;
|
|
582
586
|
chromeDevtoolsWorkspace: boolean;
|
|
@@ -826,7 +830,9 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
826
830
|
};
|
|
827
831
|
prerenderConflictBehavior: "error" | "ignore" | "warn";
|
|
828
832
|
experimental: {
|
|
829
|
-
advancedRouting: boolean
|
|
833
|
+
advancedRouting: boolean | {
|
|
834
|
+
fetchFile: string | null;
|
|
835
|
+
};
|
|
830
836
|
clientPrerender: boolean;
|
|
831
837
|
contentIntellisense: boolean;
|
|
832
838
|
chromeDevtoolsWorkspace: boolean;
|
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.4";
|
|
41
41
|
const isPrerelease = currentVersion.includes("-");
|
|
42
42
|
if (!isPrerelease) {
|
|
43
43
|
try {
|
|
@@ -44,6 +44,8 @@ export interface AstroFetchState {
|
|
|
44
44
|
readonly locals: App.Locals;
|
|
45
45
|
/** Route params derived from routeData + pathname. */
|
|
46
46
|
readonly params: Params | undefined;
|
|
47
|
+
/** The `Response` produced by handlers, if any. Set after rendering. */
|
|
48
|
+
response: Response | undefined;
|
|
47
49
|
/** Default HTTP status for the rendered response. */
|
|
48
50
|
status: number;
|
|
49
51
|
/**
|
|
@@ -119,6 +121,11 @@ export declare class FetchState implements AstroFetchState {
|
|
|
119
121
|
* allocate an empty object per request.
|
|
120
122
|
*/
|
|
121
123
|
slots: Record<string, any> | undefined;
|
|
124
|
+
/**
|
|
125
|
+
* The `Response` produced by handlers, if any. Set after page
|
|
126
|
+
* rendering or middleware completes.
|
|
127
|
+
*/
|
|
128
|
+
response: Response | undefined;
|
|
122
129
|
/**
|
|
123
130
|
* Default HTTP status for the rendered response. Callers override
|
|
124
131
|
* before rendering runs (e.g. `AstroHandler` sets this from
|
|
@@ -72,6 +72,11 @@ class FetchState {
|
|
|
72
72
|
* allocate an empty object per request.
|
|
73
73
|
*/
|
|
74
74
|
slots;
|
|
75
|
+
/**
|
|
76
|
+
* The `Response` produced by handlers, if any. Set after page
|
|
77
|
+
* rendering or middleware completes.
|
|
78
|
+
*/
|
|
79
|
+
response;
|
|
75
80
|
/**
|
|
76
81
|
* Default HTTP status for the rendered response. Callers override
|
|
77
82
|
* before rendering runs (e.g. `AstroHandler` sets this from
|
|
@@ -4,3 +4,22 @@
|
|
|
4
4
|
* lets handlers compose easily with other middleware systems later.
|
|
5
5
|
*/
|
|
6
6
|
export type FetchHandler = (request: Request) => Promise<Response>;
|
|
7
|
+
/**
|
|
8
|
+
* An object with a `fetch` method that handles incoming requests.
|
|
9
|
+
* This is the shape expected by `src/app.ts` and aligns with the
|
|
10
|
+
* convention used by Cloudflare Workers, Bun, and Hono.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import type { Fetchable } from 'astro';
|
|
15
|
+
*
|
|
16
|
+
* export default {
|
|
17
|
+
* async fetch(request) {
|
|
18
|
+
* return new Response('ok');
|
|
19
|
+
* }
|
|
20
|
+
* } satisfies Fetchable;
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export interface Fetchable {
|
|
24
|
+
fetch(request: Request): Response | Promise<Response>;
|
|
25
|
+
}
|
|
@@ -5,11 +5,14 @@ import {
|
|
|
5
5
|
import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../constants.js";
|
|
6
6
|
const FETCHABLE_MODULE_ID = "virtual:astro:fetchable";
|
|
7
7
|
const FETCHABLE_RESOLVED_MODULE_ID = "\0" + FETCHABLE_MODULE_ID;
|
|
8
|
-
const
|
|
8
|
+
const DEFAULT_FETCH_FILE = "app";
|
|
9
9
|
function vitePluginFetchable({ settings }) {
|
|
10
10
|
let resolvedUserAppId;
|
|
11
11
|
let userAppPresent = false;
|
|
12
|
-
const
|
|
12
|
+
const advancedRoutingConfig = settings.config.experimental.advancedRouting;
|
|
13
|
+
const advancedRoutingEnabled = !!advancedRoutingConfig;
|
|
14
|
+
const fetchFile = (typeof advancedRoutingConfig === "object" ? advancedRoutingConfig.fetchFile : void 0) ?? DEFAULT_FETCH_FILE;
|
|
15
|
+
const fetchFileDisabled = typeof advancedRoutingConfig === "object" && advancedRoutingConfig.fetchFile === null;
|
|
13
16
|
const normalizedSrcDir = viteNormalizePath(fileURLToPath(settings.config.srcDir));
|
|
14
17
|
return {
|
|
15
18
|
name: "@astro/plugin-fetchable",
|
|
@@ -21,7 +24,7 @@ function vitePluginFetchable({ settings }) {
|
|
|
21
24
|
const normalizedPath = viteNormalizePath(path);
|
|
22
25
|
if (!normalizedPath.startsWith(normalizedSrcDir)) return;
|
|
23
26
|
const relativePath = normalizedPath.slice(normalizedSrcDir.length);
|
|
24
|
-
if (!relativePath.startsWith(`${
|
|
27
|
+
if (!relativePath.startsWith(`${fetchFile}.`)) return;
|
|
25
28
|
for (const name of [
|
|
26
29
|
ASTRO_VITE_ENVIRONMENT_NAMES.ssr,
|
|
27
30
|
ASTRO_VITE_ENVIRONMENT_NAMES.astro
|
|
@@ -40,7 +43,11 @@ function vitePluginFetchable({ settings }) {
|
|
|
40
43
|
id: new RegExp(`^${FETCHABLE_MODULE_ID}$`)
|
|
41
44
|
},
|
|
42
45
|
async handler() {
|
|
43
|
-
|
|
46
|
+
if (fetchFileDisabled) {
|
|
47
|
+
userAppPresent = false;
|
|
48
|
+
return FETCHABLE_RESOLVED_MODULE_ID;
|
|
49
|
+
}
|
|
50
|
+
const resolved = await this.resolve(`${normalizedSrcDir}${fetchFile}`);
|
|
44
51
|
userAppPresent = advancedRoutingEnabled && !!resolved;
|
|
45
52
|
resolvedUserAppId = resolved?.id;
|
|
46
53
|
return FETCHABLE_RESOLVED_MODULE_ID;
|
|
@@ -17,5 +17,5 @@ export declare function redirects(): HonoMiddlewareHandler;
|
|
|
17
17
|
export declare function actions(): HonoMiddlewareHandler;
|
|
18
18
|
export declare function pages(): HonoMiddlewareHandler;
|
|
19
19
|
export declare function sessions(): HonoMiddlewareHandler;
|
|
20
|
-
export declare function cache(
|
|
20
|
+
export declare function cache(): HonoMiddlewareHandler;
|
|
21
21
|
export declare function i18n(): HonoMiddlewareHandler;
|
package/dist/core/hono/index.js
CHANGED
|
@@ -73,9 +73,12 @@ function sessions() {
|
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
-
function cache(
|
|
77
|
-
return async (context,
|
|
78
|
-
return fetchCache(getFetchState(context),
|
|
76
|
+
function cache() {
|
|
77
|
+
return async (context, honoNext) => {
|
|
78
|
+
return fetchCache(getFetchState(context), async () => {
|
|
79
|
+
await honoNext();
|
|
80
|
+
return context.res;
|
|
81
|
+
});
|
|
79
82
|
};
|
|
80
83
|
}
|
|
81
84
|
function i18n() {
|
|
@@ -38,7 +38,9 @@ class AstroMiddleware {
|
|
|
38
38
|
const composed = sequence(...pipeline.internalMiddleware, pipelineMiddleware);
|
|
39
39
|
response = await callMiddleware(composed, apiContext, next);
|
|
40
40
|
}
|
|
41
|
-
|
|
41
|
+
response = this.#finalize(state, response);
|
|
42
|
+
state.response = response;
|
|
43
|
+
return response;
|
|
42
44
|
}
|
|
43
45
|
#finalize(state, response) {
|
|
44
46
|
if (response.headers.get(ROUTE_TYPE_HEADER)) {
|
|
@@ -3,7 +3,6 @@ import path from "node:path";
|
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { collectErrorMetadata } from "../errors/dev/utils.js";
|
|
5
5
|
import { getViteErrorPayload } from "../errors/dev/vite.js";
|
|
6
|
-
import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../constants.js";
|
|
7
6
|
function createViteLoader(viteServer, ssrEnvironment) {
|
|
8
7
|
const events = new EventEmitter();
|
|
9
8
|
let isTsconfigUpdated = false;
|
|
@@ -90,7 +89,7 @@ function createViteLoader(viteServer, ssrEnvironment) {
|
|
|
90
89
|
return viteServer.environments.client.hot.send(msg);
|
|
91
90
|
},
|
|
92
91
|
getSSREnvironment() {
|
|
93
|
-
return
|
|
92
|
+
return ssrEnvironment;
|
|
94
93
|
},
|
|
95
94
|
isHttps() {
|
|
96
95
|
return !!ssrEnvironment.config.server.https;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { clsx } from "clsx";
|
|
2
2
|
import { AstroError, AstroErrorData } from "../../../core/errors/index.js";
|
|
3
|
-
import { markHTMLString } from "../escape.js";
|
|
3
|
+
import { escapeHTML, markHTMLString } from "../escape.js";
|
|
4
4
|
import { extractDirectives, generateHydrateScript } from "../hydration.js";
|
|
5
5
|
import { serializeProps } from "../serialize.js";
|
|
6
6
|
import { shorthash } from "../shorthash.js";
|
|
@@ -287,7 +287,7 @@ ${serializeProps(
|
|
|
287
287
|
if (Object.keys(children).length > 0) {
|
|
288
288
|
for (const key of Object.keys(children)) {
|
|
289
289
|
let tagName = renderer?.ssr?.supportsAstroStaticSlot ? !!metadata.hydrate ? "astro-slot" : "astro-static-slot" : "astro-slot";
|
|
290
|
-
let expectedHTML = key === "default" ? `<${tagName}>` : `<${tagName} name="${key}">`;
|
|
290
|
+
let expectedHTML = key === "default" ? `<${tagName}>` : `<${tagName} name="${escapeHTML(key)}">`;
|
|
291
291
|
if (!html.includes(expectedHTML)) {
|
|
292
292
|
unrenderedSlots.push(key);
|
|
293
293
|
}
|
|
@@ -297,7 +297,7 @@ ${serializeProps(
|
|
|
297
297
|
unrenderedSlots = Object.keys(children);
|
|
298
298
|
}
|
|
299
299
|
const template = unrenderedSlots.length > 0 ? unrenderedSlots.map(
|
|
300
|
-
(key) => `<template data-astro-template${key !== "default" ? `="${key}"` : ""}>${children[key]}</template>`
|
|
300
|
+
(key) => `<template data-astro-template${key !== "default" ? `="${escapeHTML(key)}"` : ""}>${children[key]}</template>`
|
|
301
301
|
).join("") : "";
|
|
302
302
|
island.children = `${html ?? ""}${template}`;
|
|
303
303
|
if (island.children) {
|
|
@@ -2647,21 +2647,38 @@ export interface AstroUserConfig<TLocales extends Locales = never, TDriver exten
|
|
|
2647
2647
|
experimental?: {
|
|
2648
2648
|
/**
|
|
2649
2649
|
* @name experimental.advancedRouting
|
|
2650
|
-
* @type {boolean}
|
|
2650
|
+
* @type {boolean | object}
|
|
2651
2651
|
* @default `false`
|
|
2652
2652
|
* @description
|
|
2653
2653
|
* Enables `src/app.ts` as an advanced routing entrypoint, allowing you to
|
|
2654
2654
|
* compose Astro's request pipeline with the Web Fetch standard or your own Hono middleware.
|
|
2655
2655
|
*
|
|
2656
|
+
* Pass `true` to enable with default settings, or an object to customize:
|
|
2657
|
+
*
|
|
2656
2658
|
* ```js
|
|
2657
2659
|
* export default defineConfig({
|
|
2658
2660
|
* experimental: {
|
|
2659
|
-
* advancedRouting:
|
|
2661
|
+
* advancedRouting: {
|
|
2662
|
+
* fetchFile: 'fetch.ts',
|
|
2663
|
+
* },
|
|
2660
2664
|
* },
|
|
2661
2665
|
* });
|
|
2662
2666
|
* ```
|
|
2663
2667
|
*/
|
|
2664
|
-
advancedRouting?: boolean
|
|
2668
|
+
advancedRouting?: boolean | {
|
|
2669
|
+
/**
|
|
2670
|
+
* @name experimental.advancedRouting.fetchFile
|
|
2671
|
+
* @type {string | null}
|
|
2672
|
+
* @default 'app'
|
|
2673
|
+
* @description
|
|
2674
|
+
*
|
|
2675
|
+
* Customizes the file used as the advanced routing entrypoint inside `srcDir`.
|
|
2676
|
+
* Defaults to `'app'`, meaning Astro looks for `src/app.ts`.
|
|
2677
|
+
*
|
|
2678
|
+
* If you already have a `src/app.ts` file in use for other purposes, define a different filename or set the value to `null` to disable the entrypoint.
|
|
2679
|
+
*/
|
|
2680
|
+
fetchFile?: string | null;
|
|
2681
|
+
};
|
|
2665
2682
|
/**
|
|
2666
2683
|
*
|
|
2667
2684
|
* @name experimental.clientPrerender
|
|
@@ -126,7 +126,7 @@ export interface AstroGlobal<Props extends Record<string, any> = Record<string,
|
|
|
126
126
|
*
|
|
127
127
|
* [Astro reference](https://docs.astro.build/en/reference/api-reference/)
|
|
128
128
|
*/
|
|
129
|
-
export interface APIContext<Props extends Record<string, any> = Record<string, any>, Params extends Record<string, string | undefined> = Record<string, string | undefined>> {
|
|
129
|
+
export interface APIContext<Props extends Record<string, any> = Record<string, any>, Params extends Record<string, string | undefined> = Record<string, string | undefined>> extends App.Providers {
|
|
130
130
|
/**
|
|
131
131
|
* The site provided in the astro config, parsed as an instance of `URL`, without base.
|
|
132
132
|
* `undefined` if the site is not provided in the config.
|
|
@@ -12,6 +12,25 @@ declare global {
|
|
|
12
12
|
*/
|
|
13
13
|
interface SessionData {
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Declare custom context providers to get typed access on `Astro` and `ctx`.
|
|
17
|
+
* Libraries and users register providers via `state.provide(key, { create, finalize? })`,
|
|
18
|
+
* and the corresponding types are declared here using module augmentation.
|
|
19
|
+
*
|
|
20
|
+
* Built-in providers like `session` are already typed by Astro and don't
|
|
21
|
+
* need to be declared here.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* declare namespace App {
|
|
26
|
+
* interface Providers {
|
|
27
|
+
* oauth: import('./lib/oauth').OAuthSession;
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
interface Providers {
|
|
33
|
+
}
|
|
15
34
|
}
|
|
16
35
|
namespace Astro {
|
|
17
36
|
interface IntegrationHooks extends BaseIntegrationHooks {
|
|
@@ -9,6 +9,7 @@ export type { AstroIntegrationLogger } from '../../core/logger/core.js';
|
|
|
9
9
|
export type { AstroSession } from '../../core/session/runtime.js';
|
|
10
10
|
export type { ToolbarServerHelpers } from '../../runtime/client/dev-toolbar/helpers.js';
|
|
11
11
|
export type { AstroEnvironmentNames } from '../../core/constants.js';
|
|
12
|
+
export type { Fetchable } from '../../core/fetch/types.js';
|
|
12
13
|
export type { SessionDriver, SessionDriverConfig } from '../../core/session/types.js';
|
|
13
14
|
export type { CacheProvider, CacheProviderConfig, CacheProviderFactory, CacheOptions, InvalidateOptions, } from '../../core/cache/types.js';
|
|
14
15
|
export type * from './common.js';
|
|
@@ -125,17 +125,6 @@ class AstroServerApp extends BaseApp {
|
|
|
125
125
|
if (url.pathname.endsWith("/") && !shouldAppendForwardSlash(this.manifest.trailingSlash, this.manifest.buildFormat)) {
|
|
126
126
|
url.pathname = url.pathname.slice(0, -1);
|
|
127
127
|
}
|
|
128
|
-
let body = void 0;
|
|
129
|
-
if (!(incomingRequest.method === "GET" || incomingRequest.method === "HEAD")) {
|
|
130
|
-
let bytes = [];
|
|
131
|
-
await new Promise((resolve) => {
|
|
132
|
-
incomingRequest.on("data", (part) => {
|
|
133
|
-
bytes.push(part);
|
|
134
|
-
});
|
|
135
|
-
incomingRequest.on("end", resolve);
|
|
136
|
-
});
|
|
137
|
-
body = Buffer.concat(bytes);
|
|
138
|
-
}
|
|
139
128
|
const self = this;
|
|
140
129
|
await self.#loadFetchHandler();
|
|
141
130
|
let handled = true;
|
|
@@ -155,6 +144,17 @@ class AstroServerApp extends BaseApp {
|
|
|
155
144
|
handled = false;
|
|
156
145
|
return;
|
|
157
146
|
}
|
|
147
|
+
let body = void 0;
|
|
148
|
+
if (!(incomingRequest.method === "GET" || incomingRequest.method === "HEAD")) {
|
|
149
|
+
let bytes = [];
|
|
150
|
+
await new Promise((resolve) => {
|
|
151
|
+
incomingRequest.on("data", (part) => {
|
|
152
|
+
bytes.push(part);
|
|
153
|
+
});
|
|
154
|
+
incomingRequest.on("end", resolve);
|
|
155
|
+
});
|
|
156
|
+
body = Buffer.concat(bytes);
|
|
157
|
+
}
|
|
158
158
|
const request = createRequest({
|
|
159
159
|
url,
|
|
160
160
|
headers: incomingRequest.headers,
|
|
@@ -107,17 +107,18 @@ function createVitePluginAstroServer({
|
|
|
107
107
|
}
|
|
108
108
|
try {
|
|
109
109
|
const pathname = decodeURI(new URL(request.url, "http://localhost").pathname);
|
|
110
|
-
const { routes } = await prerenderHandler.environment.runner.import(
|
|
111
|
-
|
|
110
|
+
const { routes } = await prerenderHandler.environment.runner.import(
|
|
111
|
+
"virtual:astro:routes"
|
|
112
|
+
);
|
|
113
|
+
const routesList = { routes: routes.map((route) => route.routeData) };
|
|
112
114
|
const matches = matchAllRoutes(pathname, routesList);
|
|
113
115
|
if (!matches.some((route) => route.prerender)) {
|
|
114
116
|
return next();
|
|
115
117
|
}
|
|
116
|
-
const handled = await
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
});
|
|
118
|
+
const handled = await localStorage.run(
|
|
119
|
+
request,
|
|
120
|
+
() => prerenderHandler.handler(request, response, { prerenderOnly: true })
|
|
121
|
+
);
|
|
121
122
|
if (!handled) {
|
|
122
123
|
return next();
|
|
123
124
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.4",
|
|
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",
|
|
@@ -198,7 +198,7 @@
|
|
|
198
198
|
"remark-code-titles": "^0.1.2",
|
|
199
199
|
"rollup": "^4.58.0",
|
|
200
200
|
"sass": "^1.98.0",
|
|
201
|
-
"typescript": "^
|
|
201
|
+
"typescript": "^6.0.3",
|
|
202
202
|
"undici": "^7.22.0",
|
|
203
203
|
"unified": "^11.0.5",
|
|
204
204
|
"vitest": "^4.1.0",
|
|
@@ -223,8 +223,8 @@
|
|
|
223
223
|
"build:ci": "pnpm run prebuild && astro-scripts build \"src/**/*.{ts,js}\" --copy-wasm",
|
|
224
224
|
"dev": "astro-scripts dev --copy-wasm --prebuild \"src/runtime/server/astro-island.ts\" --prebuild \"src/runtime/client/{idle,load,media,only,visible}.ts\" \"src/**/*.{ts,js}\"",
|
|
225
225
|
"test": "pnpm run test:unit && pnpm run test:integration && pnpm run test:types",
|
|
226
|
-
"test:match": "astro-scripts test \"test/**/*.test.
|
|
227
|
-
"test:cli": "astro-scripts test \"test/**/cli.test.
|
|
226
|
+
"test:match": "astro-scripts test \"test/**/*.test.ts\" --match",
|
|
227
|
+
"test:cli": "astro-scripts test \"test/**/cli.test.ts\"",
|
|
228
228
|
"test:e2e": "pnpm test:e2e:chrome && pnpm test:e2e:firefox",
|
|
229
229
|
"test:e2e:match": "playwright test -g",
|
|
230
230
|
"test:e2e:chrome": "playwright test",
|
|
@@ -134,6 +134,7 @@ declare module 'astro:content' {
|
|
|
134
134
|
type ExtractEntryFilterType<T> = ExtractLoaderTypes<T>['entryFilter'];
|
|
135
135
|
type ExtractCollectionFilterType<T> = ExtractLoaderTypes<T>['collectionFilter'];
|
|
136
136
|
type ExtractErrorType<T> = ExtractLoaderTypes<T>['error'];
|
|
137
|
+
type ExtractDataType<T> = ExtractLoaderTypes<T>['data'];
|
|
137
138
|
|
|
138
139
|
type LiveLoaderDataType<C extends keyof LiveContentConfig['collections']> =
|
|
139
140
|
LiveContentConfig['collections'][C]['schema'] extends undefined
|