astro 5.1.6 → 5.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/integration.js +1 -1
- package/dist/assets/layout.js +4 -0
- package/dist/cli/add/index.js +2 -0
- package/dist/content/content-layer.js +11 -4
- package/dist/content/loaders/file.js +1 -0
- package/dist/content/loaders/glob.js +1 -0
- package/dist/content/runtime.js +1 -13
- package/dist/content/server-listeners.js +4 -12
- package/dist/content/types-generator.js +7 -1
- package/dist/content/watcher.d.ts +5 -0
- package/dist/content/watcher.js +38 -0
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/container.js +4 -3
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/dev/restart.js +2 -0
- package/dist/core/messages.js +2 -2
- package/dist/core/routing/3xx.d.ts +1 -1
- package/dist/core/routing/3xx.js +1 -1
- package/dist/core/routing/manifest/create.js +2 -0
- package/dist/core/routing/match.d.ts +2 -0
- package/dist/core/routing/match.js +11 -1
- package/dist/core/sync/index.d.ts +3 -1
- package/dist/core/sync/index.js +7 -2
- package/dist/env/vite-plugin-import-meta-env.js +3 -1
- package/dist/i18n/index.js +3 -1
- package/dist/i18n/middleware.js +1 -0
- package/dist/jsx/rehype.js +3 -0
- package/dist/runtime/client/dev-toolbar/apps/audit/rules/perf.js +12 -2
- package/dist/runtime/server/hydration.js +2 -0
- package/dist/types/public/common.d.ts +1 -1
- package/dist/vite-plugin-astro-server/base.js +6 -1
- package/dist/vite-plugin-astro-server/response.d.ts +1 -0
- package/dist/vite-plugin-astro-server/response.js +12 -0
- package/dist/vite-plugin-astro-server/route.js +6 -5
- package/package.json +24 -24
|
@@ -27,7 +27,7 @@ function astroIntegrationActionsRouteHandler({
|
|
|
27
27
|
throw error;
|
|
28
28
|
}
|
|
29
29
|
const stringifiedActionsImport = JSON.stringify(
|
|
30
|
-
viteID(new URL("./actions
|
|
30
|
+
viteID(new URL("./actions", params.config.srcDir))
|
|
31
31
|
);
|
|
32
32
|
settings.injectedTypes.push({
|
|
33
33
|
filename: ACTIONS_TYPES_FILE,
|
package/dist/assets/layout.js
CHANGED
|
@@ -84,10 +84,14 @@ const getSizesAttribute = ({
|
|
|
84
84
|
return void 0;
|
|
85
85
|
}
|
|
86
86
|
switch (layout) {
|
|
87
|
+
// If screen is wider than the max size then image width is the max size,
|
|
88
|
+
// otherwise it's the width of the screen
|
|
87
89
|
case `responsive`:
|
|
88
90
|
return `(min-width: ${width}px) ${width}px, 100vw`;
|
|
91
|
+
// Image is always the same width, whatever the size of the screen
|
|
89
92
|
case `fixed`:
|
|
90
93
|
return `${width}px`;
|
|
94
|
+
// Image is always the width of the screen
|
|
91
95
|
case `full-width`:
|
|
92
96
|
return `100vw`;
|
|
93
97
|
case "none":
|
package/dist/cli/add/index.js
CHANGED
|
@@ -307,6 +307,8 @@ async function add(names, { flags }) {
|
|
|
307
307
|
logger.info("SKIP_FORMAT", msg.success(`Configuration up-to-date.`));
|
|
308
308
|
break;
|
|
309
309
|
}
|
|
310
|
+
// NOTE: failure shouldn't happen in practice because `updateAstroConfig` doesn't return that.
|
|
311
|
+
// Pipe this to the same handling as `UpdateResult.updated` for now.
|
|
310
312
|
case 3 /* failure */:
|
|
311
313
|
case 1 /* updated */:
|
|
312
314
|
case void 0: {
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
globalContentConfigObserver,
|
|
16
16
|
safeStringify
|
|
17
17
|
} from "./utils.js";
|
|
18
|
+
import { createWatcherWrapper } from "./watcher.js";
|
|
18
19
|
class ContentLayer {
|
|
19
20
|
#logger;
|
|
20
21
|
#store;
|
|
@@ -29,7 +30,9 @@ class ContentLayer {
|
|
|
29
30
|
this.#logger = logger;
|
|
30
31
|
this.#store = store;
|
|
31
32
|
this.#settings = settings;
|
|
32
|
-
|
|
33
|
+
if (watcher) {
|
|
34
|
+
this.#watcher = createWatcherWrapper(watcher);
|
|
35
|
+
}
|
|
33
36
|
this.#queue = new PQueue({ concurrency: 1 });
|
|
34
37
|
}
|
|
35
38
|
/**
|
|
@@ -55,6 +58,7 @@ class ContentLayer {
|
|
|
55
58
|
dispose() {
|
|
56
59
|
this.#queue.clear();
|
|
57
60
|
this.#unsubscribe?.();
|
|
61
|
+
this.#watcher?.removeAllTrackedListeners();
|
|
58
62
|
}
|
|
59
63
|
async #getGenerateDigest() {
|
|
60
64
|
if (this.#generateDigest) {
|
|
@@ -148,7 +152,7 @@ ${contentConfig.error.message}`);
|
|
|
148
152
|
logger.info("Content config changed");
|
|
149
153
|
shouldClear = true;
|
|
150
154
|
}
|
|
151
|
-
if (previousAstroVersion && previousAstroVersion !== "5.1.
|
|
155
|
+
if (previousAstroVersion && previousAstroVersion !== "5.1.8") {
|
|
152
156
|
logger.info("Astro version changed");
|
|
153
157
|
shouldClear = true;
|
|
154
158
|
}
|
|
@@ -156,8 +160,8 @@ ${contentConfig.error.message}`);
|
|
|
156
160
|
logger.info("Clearing content store");
|
|
157
161
|
this.#store.clearAll();
|
|
158
162
|
}
|
|
159
|
-
if ("5.1.
|
|
160
|
-
await this.#store.metaStore().set("astro-version", "5.1.
|
|
163
|
+
if ("5.1.8") {
|
|
164
|
+
await this.#store.metaStore().set("astro-version", "5.1.8");
|
|
161
165
|
}
|
|
162
166
|
if (currentConfigDigest) {
|
|
163
167
|
await this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
|
@@ -165,6 +169,9 @@ ${contentConfig.error.message}`);
|
|
|
165
169
|
if (astroConfigDigest) {
|
|
166
170
|
await this.#store.metaStore().set("astro-config-digest", astroConfigDigest);
|
|
167
171
|
}
|
|
172
|
+
if (!options?.loaders?.length) {
|
|
173
|
+
this.#watcher?.removeAllTrackedListeners();
|
|
174
|
+
}
|
|
168
175
|
await Promise.all(
|
|
169
176
|
Object.entries(contentConfig.config.collections).map(async ([name, collection]) => {
|
|
170
177
|
if (collection.type !== CONTENT_LAYER_TYPE) {
|
|
@@ -71,6 +71,7 @@ function file(fileName, options) {
|
|
|
71
71
|
}
|
|
72
72
|
const filePath = fileURLToPath(url);
|
|
73
73
|
await syncData(filePath, context);
|
|
74
|
+
watcher?.add(filePath);
|
|
74
75
|
watcher?.on("change", async (changedPath) => {
|
|
75
76
|
if (changedPath === filePath) {
|
|
76
77
|
logger.info(`Reloading data from ${fileName}`);
|
|
@@ -219,6 +219,7 @@ function glob(globOptions) {
|
|
|
219
219
|
if (!watcher) {
|
|
220
220
|
return;
|
|
221
221
|
}
|
|
222
|
+
watcher.add(filePath);
|
|
222
223
|
const matchesGlob = (entry) => !entry.startsWith("../") && micromatch.isMatch(entry, globOptions.pattern);
|
|
223
224
|
const basePath = fileURLToPath(baseDir);
|
|
224
225
|
async function onChange(changedPath) {
|
package/dist/content/runtime.js
CHANGED
|
@@ -468,7 +468,6 @@ This is an Astro bug, so please file an issue at https://github.com/withastro/as
|
|
|
468
468
|
return;
|
|
469
469
|
}
|
|
470
470
|
const flattenedErrorPath = ctx.path.join(".");
|
|
471
|
-
const collectionIsInStore = store.hasCollection(collection);
|
|
472
471
|
if (typeof lookup === "object") {
|
|
473
472
|
if (lookup.collection !== collection) {
|
|
474
473
|
ctx.addIssue({
|
|
@@ -479,18 +478,7 @@ This is an Astro bug, so please file an issue at https://github.com/withastro/as
|
|
|
479
478
|
}
|
|
480
479
|
return lookup;
|
|
481
480
|
}
|
|
482
|
-
if (
|
|
483
|
-
const entry2 = store.get(collection, lookup);
|
|
484
|
-
if (!entry2) {
|
|
485
|
-
ctx.addIssue({
|
|
486
|
-
code: ZodIssueCode.custom,
|
|
487
|
-
message: `**${flattenedErrorPath}**: Reference to ${collection} invalid. Entry ${lookup} does not exist.`
|
|
488
|
-
});
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
return { id: lookup, collection };
|
|
492
|
-
}
|
|
493
|
-
if (!lookupMap[collection] && store.collections().size <= 1) {
|
|
481
|
+
if (!lookupMap[collection]) {
|
|
494
482
|
return { id: lookup, collection };
|
|
495
483
|
}
|
|
496
484
|
const { type, entries } = lookupMap[collection];
|
|
@@ -13,14 +13,7 @@ async function attachContentServerListeners({
|
|
|
13
13
|
}) {
|
|
14
14
|
const contentPaths = getContentPaths(settings.config, fs);
|
|
15
15
|
if (!settings.config.legacy?.collections) {
|
|
16
|
-
|
|
17
|
-
fs,
|
|
18
|
-
settings,
|
|
19
|
-
logger,
|
|
20
|
-
viteServer,
|
|
21
|
-
contentConfigObserver: globalContentConfigObserver
|
|
22
|
-
});
|
|
23
|
-
await contentGenerator.init();
|
|
16
|
+
await attachListeners();
|
|
24
17
|
} else if (fs.existsSync(contentPaths.contentDir)) {
|
|
25
18
|
logger.debug(
|
|
26
19
|
"content",
|
|
@@ -58,10 +51,9 @@ async function attachContentServerListeners({
|
|
|
58
51
|
"addDir",
|
|
59
52
|
(entry) => contentGenerator.queueEvent({ name: "addDir", entry })
|
|
60
53
|
);
|
|
61
|
-
viteServer.watcher.on(
|
|
62
|
-
"change",
|
|
63
|
-
|
|
64
|
-
);
|
|
54
|
+
viteServer.watcher.on("change", (entry) => {
|
|
55
|
+
contentGenerator.queueEvent({ name: "change", entry });
|
|
56
|
+
});
|
|
65
57
|
viteServer.watcher.on("unlink", (entry) => {
|
|
66
58
|
contentGenerator.queueEvent({ name: "unlink", entry });
|
|
67
59
|
});
|
|
@@ -226,7 +226,13 @@ async function createContentTypesGenerator({
|
|
|
226
226
|
entry: pathToFileURL(rawEvent.entry),
|
|
227
227
|
name: rawEvent.name
|
|
228
228
|
};
|
|
229
|
-
if (
|
|
229
|
+
if (settings.config.legacy.collections) {
|
|
230
|
+
if (!event.entry.pathname.startsWith(contentPaths.contentDir.pathname)) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
} else if (contentPaths.config.url.pathname !== event.entry.pathname) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
230
236
|
events.push(event);
|
|
231
237
|
debounceTimeout && clearTimeout(debounceTimeout);
|
|
232
238
|
const runEventsSafe = async () => {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
function createWatcherWrapper(watcher) {
|
|
2
|
+
const listeners = /* @__PURE__ */ new Map();
|
|
3
|
+
const handler = {
|
|
4
|
+
get(target, prop, receiver) {
|
|
5
|
+
if (prop === "on") {
|
|
6
|
+
return function(event, callback) {
|
|
7
|
+
if (!listeners.has(event)) {
|
|
8
|
+
listeners.set(event, /* @__PURE__ */ new Set());
|
|
9
|
+
}
|
|
10
|
+
listeners.get(event).add(callback);
|
|
11
|
+
return Reflect.get(target, prop, receiver).call(target, event, callback);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
if (prop === "off") {
|
|
15
|
+
return function(event, callback) {
|
|
16
|
+
listeners.get(event)?.delete(callback);
|
|
17
|
+
return Reflect.get(target, prop, receiver).call(target, event, callback);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (prop === "removeAllTrackedListeners") {
|
|
21
|
+
return function() {
|
|
22
|
+
for (const [event, callbacks] of listeners.entries()) {
|
|
23
|
+
for (const callback of callbacks) {
|
|
24
|
+
target.off(event, callback);
|
|
25
|
+
}
|
|
26
|
+
callbacks.clear();
|
|
27
|
+
}
|
|
28
|
+
listeners.clear();
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return Reflect.get(target, prop, receiver);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
return new Proxy(watcher, handler);
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
createWatcherWrapper
|
|
38
|
+
};
|
package/dist/core/constants.js
CHANGED
|
@@ -57,19 +57,20 @@ async function createContainer({
|
|
|
57
57
|
ssrManifest: devSSRManifest
|
|
58
58
|
}
|
|
59
59
|
);
|
|
60
|
+
const viteServer = await vite.createServer(viteConfig);
|
|
60
61
|
await syncInternal({
|
|
61
62
|
settings,
|
|
62
63
|
mode,
|
|
63
64
|
logger,
|
|
64
65
|
skip: {
|
|
65
|
-
content:
|
|
66
|
+
content: !isRestart,
|
|
66
67
|
cleanup: true
|
|
67
68
|
},
|
|
68
69
|
force: inlineConfig?.force,
|
|
69
70
|
manifest,
|
|
70
|
-
command: "dev"
|
|
71
|
+
command: "dev",
|
|
72
|
+
watcher: viteServer.watcher
|
|
71
73
|
});
|
|
72
|
-
const viteServer = await vite.createServer(viteConfig);
|
|
73
74
|
const container = {
|
|
74
75
|
inlineConfig: inlineConfig ?? {},
|
|
75
76
|
fs,
|
package/dist/core/dev/dev.js
CHANGED
|
@@ -22,7 +22,7 @@ async function dev(inlineConfig) {
|
|
|
22
22
|
await telemetry.record([]);
|
|
23
23
|
const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
|
|
24
24
|
const logger = restart.container.logger;
|
|
25
|
-
const currentVersion = "5.1.
|
|
25
|
+
const currentVersion = "5.1.8";
|
|
26
26
|
const isPrerelease = currentVersion.includes("-");
|
|
27
27
|
if (!isPrerelease) {
|
|
28
28
|
try {
|
package/dist/core/dev/restart.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { fileURLToPath } from "node:url";
|
|
2
2
|
import * as vite from "vite";
|
|
3
3
|
import { globalContentLayer } from "../../content/content-layer.js";
|
|
4
|
+
import { attachContentServerListeners } from "../../content/server-listeners.js";
|
|
4
5
|
import { eventCliSession, telemetry } from "../../events/index.js";
|
|
5
6
|
import { SETTINGS_FILE } from "../../preferences/constants.js";
|
|
6
7
|
import { createNodeLogger, createSettings, resolveConfig } from "../config/index.js";
|
|
@@ -101,6 +102,7 @@ async function createContainerWithAutomaticRestart({
|
|
|
101
102
|
} else {
|
|
102
103
|
restart.container = result;
|
|
103
104
|
setupContainer();
|
|
105
|
+
await attachContentServerListeners(restart.container);
|
|
104
106
|
if (server) {
|
|
105
107
|
server.resolvedUrls = result.viteServer.resolvedUrls;
|
|
106
108
|
}
|
package/dist/core/messages.js
CHANGED
|
@@ -38,7 +38,7 @@ function serverStart({
|
|
|
38
38
|
host,
|
|
39
39
|
base
|
|
40
40
|
}) {
|
|
41
|
-
const version = "5.1.
|
|
41
|
+
const version = "5.1.8";
|
|
42
42
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
43
43
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
44
44
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -276,7 +276,7 @@ function printHelp({
|
|
|
276
276
|
message.push(
|
|
277
277
|
linebreak(),
|
|
278
278
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
279
|
-
`v${"5.1.
|
|
279
|
+
`v${"5.1.8"}`
|
|
280
280
|
)} ${headline}`
|
|
281
281
|
);
|
|
282
282
|
}
|
package/dist/core/routing/3xx.js
CHANGED
|
@@ -6,7 +6,7 @@ function redirectTemplate({ status, location, from }) {
|
|
|
6
6
|
<meta name="robots" content="noindex">
|
|
7
7
|
<link rel="canonical" href="${location}">
|
|
8
8
|
<body>
|
|
9
|
-
<a href="${location}">Redirecting from <code>${from}</code> to <code>${location}</code></a>
|
|
9
|
+
<a href="${location}">Redirecting ${from ? `from <code>${from}</code> ` : ""}to <code>${location}</code></a>
|
|
10
10
|
</body>`;
|
|
11
11
|
}
|
|
12
12
|
export {
|
|
@@ -483,6 +483,8 @@ async function createRouteManifest(params, logger, { dev = false } = {}) {
|
|
|
483
483
|
}
|
|
484
484
|
if (dev || settings.buildOutput === "server") {
|
|
485
485
|
injectImageEndpoint(settings, { routes }, dev ? "dev" : "build");
|
|
486
|
+
}
|
|
487
|
+
if (dev || settings.config.adapter) {
|
|
486
488
|
injectServerIslandRoute(settings.config, { routes });
|
|
487
489
|
}
|
|
488
490
|
await runHookRoutesResolved({ routes, settings, logger });
|
|
@@ -4,6 +4,8 @@ import type { RouteData } from '../../types/public/internal.js';
|
|
|
4
4
|
export declare function matchRoute(pathname: string, manifest: ManifestData): RouteData | undefined;
|
|
5
5
|
/** Finds all matching routes from pathname */
|
|
6
6
|
export declare function matchAllRoutes(pathname: string, manifest: ManifestData): RouteData[];
|
|
7
|
+
export declare function isRoute404(route: string): boolean;
|
|
8
|
+
export declare function isRoute500(route: string): boolean;
|
|
7
9
|
/**
|
|
8
10
|
* Determines if the given route matches a 404 or 500 error page.
|
|
9
11
|
*
|
|
@@ -7,11 +7,21 @@ function matchRoute(pathname, manifest) {
|
|
|
7
7
|
function matchAllRoutes(pathname, manifest) {
|
|
8
8
|
return manifest.routes.filter((route) => route.pattern.test(decodeURI(pathname)));
|
|
9
9
|
}
|
|
10
|
+
const ROUTE404_RE = /^\/404\/?$/;
|
|
11
|
+
const ROUTE500_RE = /^\/500\/?$/;
|
|
12
|
+
function isRoute404(route) {
|
|
13
|
+
return ROUTE404_RE.test(route);
|
|
14
|
+
}
|
|
15
|
+
function isRoute500(route) {
|
|
16
|
+
return ROUTE500_RE.test(route);
|
|
17
|
+
}
|
|
10
18
|
function isRoute404or500(route) {
|
|
11
|
-
return route.
|
|
19
|
+
return isRoute404(route.route) || isRoute500(route.route);
|
|
12
20
|
}
|
|
13
21
|
export {
|
|
22
|
+
isRoute404,
|
|
14
23
|
isRoute404or500,
|
|
24
|
+
isRoute500,
|
|
15
25
|
matchAllRoutes,
|
|
16
26
|
matchRoute
|
|
17
27
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fsMod from 'node:fs';
|
|
2
|
+
import { type FSWatcher } from 'vite';
|
|
2
3
|
import type { AstroSettings, ManifestData } from '../../types/astro.js';
|
|
3
4
|
import type { AstroInlineConfig } from '../../types/public/config.js';
|
|
4
5
|
import type { Logger } from '../logger/core.js';
|
|
@@ -13,6 +14,7 @@ export type SyncOptions = {
|
|
|
13
14
|
};
|
|
14
15
|
manifest: ManifestData;
|
|
15
16
|
command: 'build' | 'dev' | 'sync';
|
|
17
|
+
watcher?: FSWatcher;
|
|
16
18
|
};
|
|
17
19
|
export default function sync(inlineConfig: AstroInlineConfig, { fs, telemetry: _telemetry }?: {
|
|
18
20
|
fs?: typeof fsMod;
|
|
@@ -33,4 +35,4 @@ export declare function clearContentLayerCache({ settings, logger, fs, isDev, }:
|
|
|
33
35
|
*
|
|
34
36
|
* @experimental The JavaScript API is experimental
|
|
35
37
|
*/
|
|
36
|
-
export declare function syncInternal({ mode, logger, fs, settings, skip, force, manifest, command, }: SyncOptions): Promise<void>;
|
|
38
|
+
export declare function syncInternal({ mode, logger, fs, settings, skip, force, manifest, command, watcher, }: SyncOptions): Promise<void>;
|
package/dist/core/sync/index.js
CHANGED
|
@@ -74,7 +74,8 @@ async function syncInternal({
|
|
|
74
74
|
skip,
|
|
75
75
|
force,
|
|
76
76
|
manifest,
|
|
77
|
-
command
|
|
77
|
+
command,
|
|
78
|
+
watcher
|
|
78
79
|
}) {
|
|
79
80
|
const isDev = command === "dev";
|
|
80
81
|
if (force) {
|
|
@@ -98,8 +99,12 @@ async function syncInternal({
|
|
|
98
99
|
const contentLayer = globalContentLayer.init({
|
|
99
100
|
settings,
|
|
100
101
|
logger,
|
|
101
|
-
store
|
|
102
|
+
store,
|
|
103
|
+
watcher
|
|
102
104
|
});
|
|
105
|
+
if (watcher) {
|
|
106
|
+
contentLayer.watchContentConfig();
|
|
107
|
+
}
|
|
103
108
|
await contentLayer.sync();
|
|
104
109
|
if (!skip?.cleanup) {
|
|
105
110
|
contentLayer.dispose();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { transform } from "esbuild";
|
|
2
2
|
import MagicString from "magic-string";
|
|
3
|
+
import { createFilter, isCSSRequest } from "vite";
|
|
3
4
|
const importMetaEnvOnlyRe = /\bimport\.meta\.env\b(?!\.)/;
|
|
4
5
|
function getReferencedPrivateKeys(source, privateEnv) {
|
|
5
6
|
const references = /* @__PURE__ */ new Set();
|
|
@@ -43,6 +44,7 @@ function importMetaEnv({ envLoader }) {
|
|
|
43
44
|
let isDev;
|
|
44
45
|
let devImportMetaEnvPrepend;
|
|
45
46
|
let viteConfig;
|
|
47
|
+
const filter = createFilter(null, ["**/*.html", "**/*.htm", "**/*.json"]);
|
|
46
48
|
return {
|
|
47
49
|
name: "astro:vite-plugin-env",
|
|
48
50
|
config(_, { command }) {
|
|
@@ -65,7 +67,7 @@ function importMetaEnv({ envLoader }) {
|
|
|
65
67
|
}
|
|
66
68
|
},
|
|
67
69
|
transform(source, id, options) {
|
|
68
|
-
if (!options?.ssr || !source.includes("import.meta.env")) {
|
|
70
|
+
if (!options?.ssr || !source.includes("import.meta.env") || !filter(id) || isCSSRequest(id) || viteConfig.assetsInclude(id)) {
|
|
69
71
|
return;
|
|
70
72
|
}
|
|
71
73
|
privateEnv ??= envLoader.getPrivateEnv();
|
package/dist/i18n/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { shouldAppendForwardSlash } from "../core/build/util.js";
|
|
|
3
3
|
import { REROUTE_DIRECTIVE_HEADER } from "../core/constants.js";
|
|
4
4
|
import { MissingLocale, i18nNoLocaleFoundInPath } from "../core/errors/errors-data.js";
|
|
5
5
|
import { AstroError } from "../core/errors/index.js";
|
|
6
|
+
import { isRoute404, isRoute500 } from "../core/routing/match.js";
|
|
6
7
|
import { createI18nMiddleware } from "./middleware.js";
|
|
7
8
|
function requestHasLocale(locales) {
|
|
8
9
|
return function(context) {
|
|
@@ -11,7 +12,8 @@ function requestHasLocale(locales) {
|
|
|
11
12
|
}
|
|
12
13
|
function requestIs404Or500(request, base = "") {
|
|
13
14
|
const url = new URL(request.url);
|
|
14
|
-
|
|
15
|
+
const pathname = url.pathname.slice(base.length);
|
|
16
|
+
return isRoute404(pathname) || isRoute500(pathname);
|
|
15
17
|
}
|
|
16
18
|
function pathHasLocale(path, locales) {
|
|
17
19
|
const segments = path.split("/");
|
package/dist/i18n/middleware.js
CHANGED
package/dist/jsx/rehype.js
CHANGED
|
@@ -111,14 +111,17 @@ function findMatchingImport(tagName, imports) {
|
|
|
111
111
|
if (local === tagSpecifier) {
|
|
112
112
|
if (tagSpecifier !== tagName) {
|
|
113
113
|
switch (imported) {
|
|
114
|
+
// Namespace import: "<buttons.Foo.Bar />" => name: "Foo.Bar"
|
|
114
115
|
case "*": {
|
|
115
116
|
const accessPath = tagName.slice(tagSpecifier.length + 1);
|
|
116
117
|
return { name: accessPath, path: source };
|
|
117
118
|
}
|
|
119
|
+
// Default import: "<buttons.Foo.Bar />" => name: "default.Foo.Bar"
|
|
118
120
|
case "default": {
|
|
119
121
|
const accessPath = tagName.slice(tagSpecifier.length + 1);
|
|
120
122
|
return { name: `default.${accessPath}`, path: source };
|
|
121
123
|
}
|
|
124
|
+
// Named import: "<buttons.Foo.Bar />" => name: "buttons.Foo.Bar"
|
|
122
125
|
default: {
|
|
123
126
|
return { name: tagName, path: source };
|
|
124
127
|
}
|
|
@@ -23,7 +23,12 @@ const perf = [
|
|
|
23
23
|
selector: 'img:not([loading]), img[loading="eager"], iframe:not([loading]), iframe[loading="eager"]',
|
|
24
24
|
match(element) {
|
|
25
25
|
const htmlElement = element;
|
|
26
|
-
|
|
26
|
+
let currentElement = element;
|
|
27
|
+
let elementYPosition = 0;
|
|
28
|
+
while (currentElement) {
|
|
29
|
+
elementYPosition += currentElement.offsetTop;
|
|
30
|
+
currentElement = currentElement.offsetParent;
|
|
31
|
+
}
|
|
27
32
|
if (elementYPosition < window.innerHeight) return false;
|
|
28
33
|
if (htmlElement.src.startsWith("data:")) return false;
|
|
29
34
|
return true;
|
|
@@ -36,7 +41,12 @@ const perf = [
|
|
|
36
41
|
selector: 'img[loading="lazy"], iframe[loading="lazy"]',
|
|
37
42
|
match(element) {
|
|
38
43
|
const htmlElement = element;
|
|
39
|
-
|
|
44
|
+
let currentElement = element;
|
|
45
|
+
let elementYPosition = 0;
|
|
46
|
+
while (currentElement) {
|
|
47
|
+
elementYPosition += currentElement.offsetTop;
|
|
48
|
+
currentElement = currentElement.offsetParent;
|
|
49
|
+
}
|
|
40
50
|
if (elementYPosition > window.innerHeight) return false;
|
|
41
51
|
if (htmlElement.src.startsWith("data:")) return false;
|
|
42
52
|
return true;
|
|
@@ -37,6 +37,8 @@ function extractDirectives(inputProps, clientDirectives) {
|
|
|
37
37
|
extracted.hydration.componentExport.value = value;
|
|
38
38
|
break;
|
|
39
39
|
}
|
|
40
|
+
// This is a special prop added to prove that the client hydration method
|
|
41
|
+
// was added statically.
|
|
40
42
|
case "client:component-hydration": {
|
|
41
43
|
break;
|
|
42
44
|
}
|
|
@@ -79,7 +79,7 @@ export type PaginateFunction = <PaginateData, AdditionalPaginateProps extends Pr
|
|
|
79
79
|
page: Page<PaginateData>;
|
|
80
80
|
} & OmitIndexSignature<AdditionalPaginateProps>>;
|
|
81
81
|
}[];
|
|
82
|
-
export type APIRoute<
|
|
82
|
+
export type APIRoute<APIProps extends Record<string, any> = Record<string, any>, APIParams extends Record<string, string | undefined> = Record<string, string | undefined>> = (context: APIContext<APIProps, APIParams>) => Response | Promise<Response>;
|
|
83
83
|
export type RewritePayload = string | URL | Request;
|
|
84
84
|
export type MiddlewareNext = (rewritePayload?: RewritePayload) => Promise<Response>;
|
|
85
85
|
export type MiddlewareHandler = (context: APIContext, next: MiddlewareNext) => Promise<Response> | Response | Promise<void> | void;
|
|
@@ -3,7 +3,8 @@ import path from "node:path";
|
|
|
3
3
|
import { appendForwardSlash } from "@astrojs/internal-helpers/path";
|
|
4
4
|
import { bold } from "kleur/colors";
|
|
5
5
|
import notFoundTemplate, { subpathNotUsedTemplate } from "../template/4xx.js";
|
|
6
|
-
import { writeHtmlResponse } from "./response.js";
|
|
6
|
+
import { writeHtmlResponse, writeRedirectResponse } from "./response.js";
|
|
7
|
+
const manySlashes = /\/{2,}$/;
|
|
7
8
|
function baseMiddleware(settings, logger) {
|
|
8
9
|
const { config } = settings;
|
|
9
10
|
const site = config.site ? new URL(config.base, config.site) : void 0;
|
|
@@ -12,6 +13,10 @@ function baseMiddleware(settings, logger) {
|
|
|
12
13
|
const devRootReplacement = devRoot.endsWith("/") ? "/" : "";
|
|
13
14
|
return function devBaseMiddleware(req, res, next) {
|
|
14
15
|
const url = req.url;
|
|
16
|
+
if (manySlashes.test(url)) {
|
|
17
|
+
const destination = url.replace(manySlashes, "/");
|
|
18
|
+
return writeRedirectResponse(res, 301, destination);
|
|
19
|
+
}
|
|
15
20
|
let pathname;
|
|
16
21
|
try {
|
|
17
22
|
pathname = decodeURI(new URL(url, "http://localhost").pathname);
|
|
@@ -4,5 +4,6 @@ import type { ModuleLoader } from '../core/module-loader/index.js';
|
|
|
4
4
|
export declare function handle404Response(origin: string, req: http.IncomingMessage, res: http.ServerResponse): Promise<void>;
|
|
5
5
|
export declare function handle500Response(loader: ModuleLoader, res: http.ServerResponse, err: ErrorWithMetadata): Promise<void>;
|
|
6
6
|
export declare function writeHtmlResponse(res: http.ServerResponse, statusCode: number, html: string): void;
|
|
7
|
+
export declare function writeRedirectResponse(res: http.ServerResponse, statusCode: number, location: string): void;
|
|
7
8
|
export declare function writeWebResponse(res: http.ServerResponse, webResponse: Response): Promise<void>;
|
|
8
9
|
export declare function writeSSRResult(webRequest: Request, webResponse: Response, res: http.ServerResponse): Promise<void>;
|
|
@@ -2,6 +2,7 @@ import { Http2ServerResponse } from "node:http2";
|
|
|
2
2
|
import { Readable } from "node:stream";
|
|
3
3
|
import { getSetCookiesFromResponse } from "../core/cookies/index.js";
|
|
4
4
|
import { getViteErrorPayload } from "../core/errors/dev/index.js";
|
|
5
|
+
import { redirectTemplate } from "../core/routing/3xx.js";
|
|
5
6
|
import notFoundTemplate from "../template/4xx.js";
|
|
6
7
|
async function handle404Response(origin, req, res) {
|
|
7
8
|
const pathname = decodeURI(new URL(origin + req.url).pathname);
|
|
@@ -37,6 +38,16 @@ function writeHtmlResponse(res, statusCode, html) {
|
|
|
37
38
|
res.write(html);
|
|
38
39
|
res.end();
|
|
39
40
|
}
|
|
41
|
+
function writeRedirectResponse(res, statusCode, location) {
|
|
42
|
+
const html = redirectTemplate({ status: statusCode, location });
|
|
43
|
+
res.writeHead(statusCode, {
|
|
44
|
+
Location: location,
|
|
45
|
+
"Content-Type": "text/html",
|
|
46
|
+
"Content-Length": Buffer.byteLength(html, "utf-8")
|
|
47
|
+
});
|
|
48
|
+
res.write(html);
|
|
49
|
+
res.end();
|
|
50
|
+
}
|
|
40
51
|
async function writeWebResponse(res, webResponse) {
|
|
41
52
|
const { status, headers, body, statusText } = webResponse;
|
|
42
53
|
const setCookieHeaders = Array.from(getSetCookiesFromResponse(webResponse));
|
|
@@ -87,6 +98,7 @@ export {
|
|
|
87
98
|
handle404Response,
|
|
88
99
|
handle500Response,
|
|
89
100
|
writeHtmlResponse,
|
|
101
|
+
writeRedirectResponse,
|
|
90
102
|
writeSSRResult,
|
|
91
103
|
writeWebResponse
|
|
92
104
|
};
|
|
@@ -14,6 +14,7 @@ import { getProps } from "../core/render/index.js";
|
|
|
14
14
|
import { createRequest } from "../core/request.js";
|
|
15
15
|
import { redirectTemplate } from "../core/routing/3xx.js";
|
|
16
16
|
import { matchAllRoutes } from "../core/routing/index.js";
|
|
17
|
+
import { isRoute404, isRoute500 } from "../core/routing/match.js";
|
|
17
18
|
import { PERSIST_SYMBOL } from "../core/session.js";
|
|
18
19
|
import { getSortedPreloadedMatches } from "../prerender/routing.js";
|
|
19
20
|
import { writeSSRResult, writeWebResponse } from "./response.js";
|
|
@@ -21,12 +22,10 @@ function isLoggedRequest(url) {
|
|
|
21
22
|
return url !== "/favicon.ico";
|
|
22
23
|
}
|
|
23
24
|
function getCustom404Route(manifestData) {
|
|
24
|
-
|
|
25
|
-
return manifestData.routes.find((r) => route404.test(r.route));
|
|
25
|
+
return manifestData.routes.find((r) => isRoute404(r.route));
|
|
26
26
|
}
|
|
27
27
|
function getCustom500Route(manifestData) {
|
|
28
|
-
|
|
29
|
-
return manifestData.routes.find((r) => route500.test(r.route));
|
|
28
|
+
return manifestData.routes.find((r) => isRoute500(r.route));
|
|
30
29
|
}
|
|
31
30
|
async function matchRoute(pathname, manifestData, pipeline) {
|
|
32
31
|
const { config, logger, routeCache, serverLike, settings } = pipeline;
|
|
@@ -175,7 +174,9 @@ async function handleRoute({
|
|
|
175
174
|
})
|
|
176
175
|
);
|
|
177
176
|
}
|
|
178
|
-
if (statusCode === 404 &&
|
|
177
|
+
if (statusCode === 404 && // If the body isn't null, that means the user sets the 404 status
|
|
178
|
+
// but uses the current route to handle the 404
|
|
179
|
+
response.body === null && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") {
|
|
179
180
|
const fourOhFourRoute = await matchRoute("/404", manifestData, pipeline);
|
|
180
181
|
if (fourOhFourRoute) {
|
|
181
182
|
renderContext = await RenderContext.create({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.8",
|
|
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",
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"dependencies": {
|
|
106
106
|
"@astrojs/compiler": "^2.10.3",
|
|
107
107
|
"@oslojs/encoding": "^1.1.0",
|
|
108
|
-
"@rollup/pluginutils": "^5.1.
|
|
108
|
+
"@rollup/pluginutils": "^5.1.4",
|
|
109
109
|
"@types/cookie": "^0.6.0",
|
|
110
110
|
"acorn": "^8.14.0",
|
|
111
111
|
"aria-query": "^5.3.2",
|
|
@@ -116,51 +116,51 @@
|
|
|
116
116
|
"common-ancestor-path": "^1.0.1",
|
|
117
117
|
"cookie": "^0.7.2",
|
|
118
118
|
"cssesc": "^3.0.0",
|
|
119
|
-
"debug": "^4.
|
|
119
|
+
"debug": "^4.4.0",
|
|
120
120
|
"deterministic-object-hash": "^2.0.2",
|
|
121
121
|
"devalue": "^5.1.1",
|
|
122
122
|
"diff": "^5.2.0",
|
|
123
123
|
"dlv": "^1.1.3",
|
|
124
124
|
"dset": "^3.1.4",
|
|
125
|
-
"es-module-lexer": "^1.
|
|
126
|
-
"esbuild": "^0.
|
|
125
|
+
"es-module-lexer": "^1.6.0",
|
|
126
|
+
"esbuild": "^0.24.2",
|
|
127
127
|
"estree-walker": "^3.0.3",
|
|
128
|
-
"fast-glob": "^3.3.
|
|
128
|
+
"fast-glob": "^3.3.3",
|
|
129
129
|
"flattie": "^1.1.1",
|
|
130
130
|
"github-slugger": "^2.0.0",
|
|
131
131
|
"html-escaper": "^3.0.3",
|
|
132
132
|
"http-cache-semantics": "^4.1.1",
|
|
133
133
|
"js-yaml": "^4.1.0",
|
|
134
134
|
"kleur": "^4.1.5",
|
|
135
|
-
"magic-string": "^0.30.
|
|
135
|
+
"magic-string": "^0.30.17",
|
|
136
136
|
"magicast": "^0.3.5",
|
|
137
137
|
"micromatch": "^4.0.8",
|
|
138
138
|
"mrmime": "^2.0.0",
|
|
139
139
|
"neotraverse": "^0.6.18",
|
|
140
|
-
"p-limit": "^6.
|
|
140
|
+
"p-limit": "^6.2.0",
|
|
141
141
|
"p-queue": "^8.0.1",
|
|
142
142
|
"preferred-pm": "^4.0.0",
|
|
143
143
|
"prompts": "^2.4.2",
|
|
144
144
|
"rehype": "^13.0.2",
|
|
145
145
|
"semver": "^7.6.3",
|
|
146
|
-
"shiki": "^1.
|
|
147
|
-
"tinyexec": "^0.3.
|
|
146
|
+
"shiki": "^1.29.1",
|
|
147
|
+
"tinyexec": "^0.3.2",
|
|
148
148
|
"tsconfck": "^3.1.4",
|
|
149
149
|
"ultrahtml": "^1.5.3",
|
|
150
150
|
"unist-util-visit": "^5.0.0",
|
|
151
|
-
"unstorage": "^1.14.
|
|
151
|
+
"unstorage": "^1.14.4",
|
|
152
152
|
"vfile": "^6.0.3",
|
|
153
|
-
"vite": "^6.0.
|
|
154
|
-
"vitefu": "^1.0.
|
|
153
|
+
"vite": "^6.0.9",
|
|
154
|
+
"vitefu": "^1.0.5",
|
|
155
155
|
"which-pm": "^3.0.0",
|
|
156
156
|
"xxhash-wasm": "^1.1.0",
|
|
157
157
|
"yargs-parser": "^21.1.1",
|
|
158
|
-
"yocto-spinner": "^0.1.
|
|
159
|
-
"zod": "^3.
|
|
160
|
-
"zod-to-json-schema": "^3.
|
|
158
|
+
"yocto-spinner": "^0.1.2",
|
|
159
|
+
"zod": "^3.24.1",
|
|
160
|
+
"zod-to-json-schema": "^3.24.1",
|
|
161
161
|
"zod-to-ts": "^1.2.0",
|
|
162
162
|
"@astrojs/internal-helpers": "0.4.2",
|
|
163
|
-
"@astrojs/markdown-remark": "6.0.
|
|
163
|
+
"@astrojs/markdown-remark": "6.0.2",
|
|
164
164
|
"@astrojs/telemetry": "3.2.0"
|
|
165
165
|
},
|
|
166
166
|
"optionalDependencies": {
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
},
|
|
169
169
|
"devDependencies": {
|
|
170
170
|
"@astrojs/check": "^0.9.4",
|
|
171
|
-
"@playwright/test": "^1.49.
|
|
171
|
+
"@playwright/test": "^1.49.1",
|
|
172
172
|
"@types/aria-query": "^5.0.4",
|
|
173
173
|
"@types/common-ancestor-path": "^1.0.2",
|
|
174
174
|
"@types/cssesc": "^3.0.2",
|
|
@@ -189,18 +189,18 @@
|
|
|
189
189
|
"expect-type": "^1.1.0",
|
|
190
190
|
"fs-fixture": "^2.6.0",
|
|
191
191
|
"mdast-util-mdx": "^3.0.0",
|
|
192
|
-
"mdast-util-mdx-jsx": "^3.
|
|
193
|
-
"node-mocks-http": "^1.16.
|
|
192
|
+
"mdast-util-mdx-jsx": "^3.2.0",
|
|
193
|
+
"node-mocks-http": "^1.16.2",
|
|
194
194
|
"parse-srcset": "^1.0.2",
|
|
195
195
|
"rehype-autolink-headings": "^7.1.0",
|
|
196
196
|
"rehype-slug": "^6.0.0",
|
|
197
197
|
"rehype-toc": "^3.0.2",
|
|
198
198
|
"remark-code-titles": "^0.1.2",
|
|
199
|
-
"rollup": "^4.
|
|
200
|
-
"sass": "^1.
|
|
201
|
-
"undici": "^7.2.
|
|
199
|
+
"rollup": "^4.31.0",
|
|
200
|
+
"sass": "^1.83.4",
|
|
201
|
+
"undici": "^7.2.3",
|
|
202
202
|
"unified": "^11.0.5",
|
|
203
|
-
"vitest": "^3.0.
|
|
203
|
+
"vitest": "^3.0.2",
|
|
204
204
|
"astro-scripts": "0.0.14"
|
|
205
205
|
},
|
|
206
206
|
"engines": {
|