astro 6.1.3 → 6.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/consts.d.ts +2 -0
- package/dist/assets/consts.js +4 -0
- package/dist/assets/utils/index.d.ts +1 -1
- package/dist/assets/utils/index.js +1 -9
- package/dist/assets/utils/vendor/image-size/utils/bit-reader.d.ts +2 -2
- package/dist/assets/utils/vendor/image-size/utils/bit-reader.js +5 -3
- package/dist/assets/vite-plugin-assets.js +33 -3
- package/dist/cli/add/index.js +38 -55
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/cli/preferences/index.js +1 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/content/loaders/errors.d.ts +2 -2
- package/dist/content/loaders/errors.js +3 -0
- package/dist/content/runtime.js +1 -1
- package/dist/core/app/base.js +1 -1
- package/dist/core/base-pipeline.d.ts +22 -35
- package/dist/core/base-pipeline.js +41 -8
- package/dist/core/build/generate.js +9 -1
- package/dist/core/build/pipeline.d.ts +3 -7
- package/dist/core/build/pipeline.js +30 -28
- package/dist/core/config/schemas/refined-validators.d.ts +44 -0
- package/dist/core/config/schemas/refined-validators.js +168 -0
- package/dist/core/config/schemas/refined.js +28 -141
- package/dist/core/constants.js +1 -1
- package/dist/core/cookies/cookies.js +1 -0
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/dev/restart.js +63 -68
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/render-context.d.ts +2 -2
- package/dist/core/render-context.js +20 -0
- package/dist/core/routing/create-manifest.js +12 -4
- package/dist/core/routing/default.d.ts +2 -3
- package/dist/env/validators.d.ts +1 -1
- package/dist/integrations/features-validation.d.ts +3 -1
- package/dist/integrations/features-validation.js +2 -0
- package/dist/preferences/dlv.d.ts +1 -0
- package/dist/preferences/dlv.js +9 -0
- package/dist/preferences/index.js +1 -1
- package/dist/preferences/store.js +3 -2
- package/dist/runtime/server/render/component.js +6 -6
- package/dist/runtime/server/transition.d.ts +2 -2
- package/dist/runtime/server/transition.js +4 -2
- package/dist/transitions/swap-functions.js +1 -1
- package/dist/vite-plugin-app/pipeline.d.ts +4 -13
- package/dist/vite-plugin-app/pipeline.js +27 -12
- package/dist/vite-plugin-astro-server/base.d.ts +52 -0
- package/dist/vite-plugin-astro-server/base.js +66 -36
- package/dist/vite-plugin-astro-server/trailing-slash.d.ts +34 -0
- package/dist/vite-plugin-astro-server/trailing-slash.js +24 -11
- package/package.json +3 -5
|
@@ -4,13 +4,31 @@ import { appendForwardSlash, prependForwardSlash } from "@astrojs/internal-helpe
|
|
|
4
4
|
import colors from "piccolore";
|
|
5
5
|
import { notFoundTemplate, subpathNotUsedTemplate } from "../template/4xx.js";
|
|
6
6
|
import { writeHtmlResponse } from "./response.js";
|
|
7
|
+
function resolveDevRoot(base, site) {
|
|
8
|
+
const effectiveBase = base || "/";
|
|
9
|
+
const siteUrl = site ? new URL(effectiveBase, site) : void 0;
|
|
10
|
+
const devRootURL = new URL(effectiveBase, "http://localhost");
|
|
11
|
+
const devRoot = siteUrl ? siteUrl.pathname : devRootURL.pathname;
|
|
12
|
+
const devRootReplacement = devRoot.endsWith("/") ? "/" : "";
|
|
13
|
+
return { devRoot, devRootReplacement };
|
|
14
|
+
}
|
|
15
|
+
function evaluateBaseRewrite(url, pathname, acceptHeader, devRoot, devRootReplacement) {
|
|
16
|
+
if (pathname.startsWith(devRoot)) {
|
|
17
|
+
let newUrl = url.replace(devRoot, devRootReplacement);
|
|
18
|
+
if (!newUrl.startsWith("/")) newUrl = prependForwardSlash(newUrl);
|
|
19
|
+
return { action: "rewrite", newUrl };
|
|
20
|
+
}
|
|
21
|
+
if (pathname === "/" || pathname === "/index.html") {
|
|
22
|
+
return { action: "not-found-subpath", pathname, devRoot };
|
|
23
|
+
}
|
|
24
|
+
if (acceptHeader?.includes("text/html")) {
|
|
25
|
+
return { action: "not-found", pathname };
|
|
26
|
+
}
|
|
27
|
+
return { action: "check-public" };
|
|
28
|
+
}
|
|
7
29
|
function baseMiddleware(settings, logger) {
|
|
8
30
|
const { config } = settings;
|
|
9
|
-
const
|
|
10
|
-
const site = config.site ? new URL(base, config.site) : void 0;
|
|
11
|
-
const devRootURL = new URL(base, "http://localhost");
|
|
12
|
-
const devRoot = site ? site.pathname : devRootURL.pathname;
|
|
13
|
-
const devRootReplacement = devRoot.endsWith("/") ? "/" : "";
|
|
31
|
+
const { devRoot, devRootReplacement } = resolveDevRoot(config.base, config.site);
|
|
14
32
|
return function devBaseMiddleware(req, res, next) {
|
|
15
33
|
const url = req.url;
|
|
16
34
|
let pathname;
|
|
@@ -19,40 +37,52 @@ function baseMiddleware(settings, logger) {
|
|
|
19
37
|
} catch (e) {
|
|
20
38
|
return next(e);
|
|
21
39
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
path.posix.relative(config.root.pathname, config.publicDir.pathname)
|
|
40
|
-
);
|
|
41
|
-
const expectedLocation = new URL(devRootURL.pathname + url, devRootURL).pathname;
|
|
42
|
-
logger.error(
|
|
43
|
-
"router",
|
|
44
|
-
`Request URLs for ${colors.bold(
|
|
45
|
-
publicDir
|
|
46
|
-
)} assets must also include your base. "${expectedLocation}" expected, but received "${url}".`
|
|
47
|
-
);
|
|
48
|
-
const html = subpathNotUsedTemplate(devRoot, pathname);
|
|
40
|
+
const decision = evaluateBaseRewrite(
|
|
41
|
+
url,
|
|
42
|
+
pathname,
|
|
43
|
+
req.headers.accept,
|
|
44
|
+
devRoot,
|
|
45
|
+
devRootReplacement
|
|
46
|
+
);
|
|
47
|
+
switch (decision.action) {
|
|
48
|
+
case "rewrite":
|
|
49
|
+
req.url = decision.newUrl;
|
|
50
|
+
return next();
|
|
51
|
+
case "not-found-subpath": {
|
|
52
|
+
const html = subpathNotUsedTemplate(decision.devRoot, decision.pathname);
|
|
53
|
+
return writeHtmlResponse(res, 404, html);
|
|
54
|
+
}
|
|
55
|
+
case "not-found": {
|
|
56
|
+
const html = notFoundTemplate(decision.pathname);
|
|
49
57
|
return writeHtmlResponse(res, 404, html);
|
|
50
|
-
} else {
|
|
51
|
-
next();
|
|
52
58
|
}
|
|
53
|
-
|
|
59
|
+
case "check-public": {
|
|
60
|
+
const publicPath = new URL("." + req.url, config.publicDir);
|
|
61
|
+
fs.stat(publicPath, (_err, stats) => {
|
|
62
|
+
if (stats) {
|
|
63
|
+
const publicDir = appendForwardSlash(
|
|
64
|
+
path.posix.relative(config.root.pathname, config.publicDir.pathname)
|
|
65
|
+
);
|
|
66
|
+
const devRootURL = new URL(devRoot, "http://localhost");
|
|
67
|
+
const expectedLocation = new URL(devRootURL.pathname + url, devRootURL).pathname;
|
|
68
|
+
logger.error(
|
|
69
|
+
"router",
|
|
70
|
+
`Request URLs for ${colors.bold(
|
|
71
|
+
publicDir
|
|
72
|
+
)} assets must also include your base. "${expectedLocation}" expected, but received "${url}".`
|
|
73
|
+
);
|
|
74
|
+
const html = subpathNotUsedTemplate(devRoot, pathname);
|
|
75
|
+
return writeHtmlResponse(res, 404, html);
|
|
76
|
+
} else {
|
|
77
|
+
next();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
54
82
|
};
|
|
55
83
|
}
|
|
56
84
|
export {
|
|
57
|
-
baseMiddleware
|
|
85
|
+
baseMiddleware,
|
|
86
|
+
evaluateBaseRewrite,
|
|
87
|
+
resolveDevRoot
|
|
58
88
|
};
|
|
@@ -1,3 +1,37 @@
|
|
|
1
1
|
import type * as vite from 'vite';
|
|
2
2
|
import type { AstroSettings } from '../types/astro.js';
|
|
3
|
+
/**
|
|
4
|
+
* Outcome of the trailing-slash evaluation for a dev-server request.
|
|
5
|
+
*
|
|
6
|
+
* - **`next`** — The URL is acceptable. Pass the request through to the next
|
|
7
|
+
* middleware / route handler unchanged.
|
|
8
|
+
* - **`redirect`** — The URL contains duplicate trailing slashes (e.g.
|
|
9
|
+
* `/about//`). The client should be permanently redirected (301) to the
|
|
10
|
+
* collapsed form (`/about/`) so crawlers and browsers update their links.
|
|
11
|
+
* - **`reject`** — The URL's trailing-slash style conflicts with the project's
|
|
12
|
+
* `trailingSlash` config (`'always'` or `'never'`). The dev server responds
|
|
13
|
+
* with a 404 and a human-readable error page explaining the mismatch, giving
|
|
14
|
+
* the developer immediate feedback that their link is wrong before it reaches
|
|
15
|
+
* production.
|
|
16
|
+
*/
|
|
17
|
+
export type TrailingSlashDecision = {
|
|
18
|
+
action: 'next';
|
|
19
|
+
} | {
|
|
20
|
+
action: 'redirect';
|
|
21
|
+
status: 301;
|
|
22
|
+
location: string;
|
|
23
|
+
} | {
|
|
24
|
+
action: 'reject';
|
|
25
|
+
status: 404;
|
|
26
|
+
pathname: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Pure decision function for trailing-slash dev-server behavior.
|
|
30
|
+
*
|
|
31
|
+
* Evaluates a decoded `pathname`, the query-string portion (including leading
|
|
32
|
+
* `?`), and the project's `trailingSlash` config and returns the action the
|
|
33
|
+
* middleware should take. The middleware is responsible for translating the
|
|
34
|
+
* decision into an HTTP response.
|
|
35
|
+
*/
|
|
36
|
+
export declare function evaluateTrailingSlash(pathname: string, search: string, trailingSlash: 'always' | 'never' | 'ignore'): TrailingSlashDecision;
|
|
3
37
|
export declare function trailingSlashMiddleware(settings: AstroSettings): vite.Connect.NextHandleFunction;
|
|
@@ -5,6 +5,19 @@ import {
|
|
|
5
5
|
} from "@astrojs/internal-helpers/path";
|
|
6
6
|
import { trailingSlashMismatchTemplate } from "../template/4xx.js";
|
|
7
7
|
import { writeHtmlResponse, writeRedirectResponse } from "./response.js";
|
|
8
|
+
function evaluateTrailingSlash(pathname, search, trailingSlash) {
|
|
9
|
+
if (isInternalPath(pathname)) {
|
|
10
|
+
return { action: "next" };
|
|
11
|
+
}
|
|
12
|
+
const collapsed = collapseDuplicateTrailingSlashes(pathname, true);
|
|
13
|
+
if (pathname && collapsed !== pathname) {
|
|
14
|
+
return { action: "redirect", status: 301, location: `${collapsed}${search}` };
|
|
15
|
+
}
|
|
16
|
+
if (trailingSlash === "never" && pathname.endsWith("/") && pathname !== "/" || trailingSlash === "always" && !pathname.endsWith("/") && !hasFileExtension(pathname)) {
|
|
17
|
+
return { action: "reject", status: 404, pathname };
|
|
18
|
+
}
|
|
19
|
+
return { action: "next" };
|
|
20
|
+
}
|
|
8
21
|
function trailingSlashMiddleware(settings) {
|
|
9
22
|
const { trailingSlash } = settings.config;
|
|
10
23
|
return function devTrailingSlash(req, res, next) {
|
|
@@ -15,20 +28,20 @@ function trailingSlashMiddleware(settings) {
|
|
|
15
28
|
} catch (e) {
|
|
16
29
|
return next(e);
|
|
17
30
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
const decision = evaluateTrailingSlash(pathname, url.search, trailingSlash);
|
|
32
|
+
switch (decision.action) {
|
|
33
|
+
case "redirect":
|
|
34
|
+
return writeRedirectResponse(res, decision.status, decision.location);
|
|
35
|
+
case "reject": {
|
|
36
|
+
const html = trailingSlashMismatchTemplate(decision.pathname, trailingSlash);
|
|
37
|
+
return writeHtmlResponse(res, decision.status, html);
|
|
38
|
+
}
|
|
39
|
+
case "next":
|
|
40
|
+
return next();
|
|
28
41
|
}
|
|
29
|
-
return next();
|
|
30
42
|
};
|
|
31
43
|
}
|
|
32
44
|
export {
|
|
45
|
+
evaluateTrailingSlash,
|
|
33
46
|
trailingSlashMiddleware
|
|
34
47
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.5",
|
|
4
4
|
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "withastro",
|
|
@@ -114,7 +114,6 @@
|
|
|
114
114
|
"cookie": "^1.1.1",
|
|
115
115
|
"devalue": "^5.6.3",
|
|
116
116
|
"diff": "^8.0.3",
|
|
117
|
-
"dlv": "^1.1.3",
|
|
118
117
|
"dset": "^3.1.4",
|
|
119
118
|
"es-module-lexer": "^2.0.0",
|
|
120
119
|
"esbuild": "^0.27.3",
|
|
@@ -153,9 +152,9 @@
|
|
|
153
152
|
"xxhash-wasm": "^1.1.0",
|
|
154
153
|
"yargs-parser": "^22.0.0",
|
|
155
154
|
"zod": "^4.3.6",
|
|
156
|
-
"@astrojs/internal-helpers": "0.8.0",
|
|
157
155
|
"@astrojs/markdown-remark": "7.1.0",
|
|
158
|
-
"@astrojs/telemetry": "3.3.0"
|
|
156
|
+
"@astrojs/telemetry": "3.3.0",
|
|
157
|
+
"@astrojs/internal-helpers": "0.8.0"
|
|
159
158
|
},
|
|
160
159
|
"optionalDependencies": {
|
|
161
160
|
"sharp": "^0.34.0"
|
|
@@ -164,7 +163,6 @@
|
|
|
164
163
|
"@astrojs/compiler-rs": "^0.1.6",
|
|
165
164
|
"@playwright/test": "1.58.2",
|
|
166
165
|
"@types/aria-query": "^5.0.4",
|
|
167
|
-
"@types/dlv": "^1.1.5",
|
|
168
166
|
"@types/hast": "^3.0.4",
|
|
169
167
|
"@types/html-escaper": "3.0.4",
|
|
170
168
|
"@types/http-cache-semantics": "^4.2.0",
|