astro 4.4.12 → 4.4.14
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/@types/astro.d.ts +2 -2
- package/dist/cli/install-package.js +3 -2
- package/dist/content/runtime.d.ts +1 -1
- package/dist/content/runtime.js +1 -1
- package/dist/core/base-pipeline.d.ts +2 -2
- package/dist/core/base-pipeline.js +1 -1
- package/dist/core/build/generate.js +1 -1
- package/dist/core/compile/compile.js +2 -0
- package/dist/core/config/vite-load.js +2 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/errors/errors-data.d.ts +12 -1
- package/dist/core/errors/errors-data.js +7 -0
- package/dist/core/messages.js +2 -2
- package/dist/core/middleware/index.js +1 -6
- package/dist/core/render/index.d.ts +1 -1
- package/dist/core/render/index.js +2 -2
- package/dist/core/render/result.d.ts +7 -37
- package/dist/core/render/result.js +1 -139
- package/dist/core/render-context.d.ts +4 -2
- package/dist/core/render-context.js +106 -67
- package/dist/core/routing/manifest/create.js +9 -2
- package/dist/i18n/utils.d.ts +1 -1
- package/dist/i18n/utils.js +1 -5
- package/dist/prefetch/index.js +9 -0
- package/dist/runtime/client/dev-toolbar/apps/audit/a11y.js +31 -1
- package/dist/runtime/server/astro-global.js +2 -0
- package/dist/vite-plugin-astro-server/plugin.js +1 -1
- package/package.json +3 -3
package/dist/@types/astro.d.ts
CHANGED
|
@@ -1524,7 +1524,7 @@ export interface AstroUserConfig {
|
|
|
1524
1524
|
* @description
|
|
1525
1525
|
* Enables pre-rendering your prefetched pages on the client in supported browsers.
|
|
1526
1526
|
*
|
|
1527
|
-
* This feature uses the experimental [Speculation Rules Web API](https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API) and
|
|
1527
|
+
* This feature uses the experimental [Speculation Rules Web API](https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API) and enhances the default `prefetch` behavior globally to prerender links on the client.
|
|
1528
1528
|
* You may wish to review the [possible risks when prerendering on the client](https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API#unsafe_prefetching) before enabling this feature.
|
|
1529
1529
|
*
|
|
1530
1530
|
* Enable client side prerendering in your `astro.config.mjs` along with any desired `prefetch` configuration options:
|
|
@@ -2413,7 +2413,7 @@ export interface SSRResult {
|
|
|
2413
2413
|
componentMetadata: Map<string, SSRComponentMetadata>;
|
|
2414
2414
|
createAstro(Astro: AstroGlobalPartial, props: Record<string, any>, slots: Record<string, any> | null): AstroGlobal;
|
|
2415
2415
|
resolve: (s: string) => Promise<string>;
|
|
2416
|
-
response:
|
|
2416
|
+
response: AstroGlobal['response'];
|
|
2417
2417
|
renderers: SSRLoadedRenderer[];
|
|
2418
2418
|
/**
|
|
2419
2419
|
* Map of directive name (e.g. `load`) to the directive script code
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { sep } from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
3
4
|
import boxen from "boxen";
|
|
4
5
|
import { execa } from "execa";
|
|
5
6
|
import { bold, cyan, dim, magenta } from "kleur/colors";
|
|
@@ -15,8 +16,8 @@ async function getPackage(packageName, logger, options, otherDeps = []) {
|
|
|
15
16
|
const packageJsonLoc = require2.resolve(packageName + "/package.json", {
|
|
16
17
|
paths: [options.cwd ?? process.cwd()]
|
|
17
18
|
});
|
|
18
|
-
const packageLoc = packageJsonLoc.replace(`package.json`, "dist/index.js");
|
|
19
|
-
const packageImport2 = await import(packageLoc);
|
|
19
|
+
const packageLoc = pathToFileURL(packageJsonLoc.replace(`package.json`, "dist/index.js"));
|
|
20
|
+
const packageImport2 = await import(packageLoc.toString());
|
|
20
21
|
return packageImport2;
|
|
21
22
|
}
|
|
22
23
|
await tryResolve(packageName, options.cwd ?? process.cwd());
|
|
@@ -14,7 +14,7 @@ export declare function createGetCollection({ contentCollectionToEntryMap, dataC
|
|
|
14
14
|
contentCollectionToEntryMap: CollectionToEntryMap;
|
|
15
15
|
dataCollectionToEntryMap: CollectionToEntryMap;
|
|
16
16
|
getRenderEntryImport: GetEntryImport;
|
|
17
|
-
}): (collection: string, filter?: ((entry: any) => unknown) | undefined) => Promise<any[]
|
|
17
|
+
}): (collection: string, filter?: ((entry: any) => unknown) | undefined) => Promise<any[]>;
|
|
18
18
|
export declare function createGetEntryBySlug({ getEntryImport, getRenderEntryImport, }: {
|
|
19
19
|
getEntryImport: GetEntryImport;
|
|
20
20
|
getRenderEntryImport: GetEntryImport;
|
package/dist/content/runtime.js
CHANGED
|
@@ -49,7 +49,7 @@ function createGetCollection({
|
|
|
49
49
|
collection
|
|
50
50
|
)} does not exist or is empty. Ensure a collection directory with this name exists.`
|
|
51
51
|
);
|
|
52
|
-
return;
|
|
52
|
+
return [];
|
|
53
53
|
}
|
|
54
54
|
const lazyImports = Object.values(
|
|
55
55
|
type === "content" ? contentCollectionToEntryMap[collection] : dataCollectionToEntryMap[collection]
|
|
@@ -33,7 +33,7 @@ export declare abstract class Pipeline {
|
|
|
33
33
|
/**
|
|
34
34
|
* Used for `Astro.site`.
|
|
35
35
|
*/
|
|
36
|
-
readonly site:
|
|
36
|
+
readonly site: URL | undefined;
|
|
37
37
|
readonly internalMiddleware: MiddlewareHandler[];
|
|
38
38
|
constructor(logger: Logger, manifest: SSRManifest,
|
|
39
39
|
/**
|
|
@@ -51,7 +51,7 @@ export declare abstract class Pipeline {
|
|
|
51
51
|
/**
|
|
52
52
|
* Used for `Astro.site`.
|
|
53
53
|
*/
|
|
54
|
-
site?:
|
|
54
|
+
site?: URL | undefined);
|
|
55
55
|
abstract headElements(routeData: RouteData): Promise<HeadElements> | HeadElements;
|
|
56
56
|
abstract componentMetadata(routeData: RouteData): Promise<SSRResult['componentMetadata']> | void;
|
|
57
57
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createI18nMiddleware } from "../i18n/middleware.js";
|
|
2
2
|
import { RouteCache } from "./render/route-cache.js";
|
|
3
3
|
class Pipeline {
|
|
4
|
-
constructor(logger, manifest, mode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, mode), site = manifest.site) {
|
|
4
|
+
constructor(logger, manifest, mode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, mode), site = manifest.site ? new URL(manifest.site) : void 0) {
|
|
5
5
|
this.logger = logger;
|
|
6
6
|
this.manifest = manifest;
|
|
7
7
|
this.mode = mode;
|
|
@@ -428,7 +428,7 @@ function createBuildManifest(settings, internals, renderers, middleware) {
|
|
|
428
428
|
renderers,
|
|
429
429
|
base: settings.config.base,
|
|
430
430
|
assetsPrefix: settings.config.build.assetsPrefix,
|
|
431
|
-
site: settings.config.site
|
|
431
|
+
site: settings.config.site,
|
|
432
432
|
componentMetadata: internals.componentMetadata,
|
|
433
433
|
i18n: i18nManifest,
|
|
434
434
|
buildFormat: settings.config.build.format,
|
|
@@ -22,6 +22,8 @@ async function compile({
|
|
|
22
22
|
normalizedFilename: normalizeFilename(filename, astroConfig.root),
|
|
23
23
|
sourcemap: "both",
|
|
24
24
|
internalURL: "astro/compiler-runtime",
|
|
25
|
+
// TODO: this is no longer neccessary for `Astro.site`
|
|
26
|
+
// but it somehow allows working around caching issues in content collections for some tests
|
|
25
27
|
astroGlobalArgs: JSON.stringify(astroConfig.site),
|
|
26
28
|
scopedStyleStrategy: astroConfig.scopedStyleStrategy,
|
|
27
29
|
resultScopedSlot: true,
|
package/dist/core/constants.js
CHANGED
package/dist/core/dev/dev.js
CHANGED
|
@@ -23,7 +23,7 @@ async function dev(inlineConfig) {
|
|
|
23
23
|
base: restart.container.settings.config.base
|
|
24
24
|
})
|
|
25
25
|
);
|
|
26
|
-
const currentVersion = "4.4.
|
|
26
|
+
const currentVersion = "4.4.14";
|
|
27
27
|
if (currentVersion.includes("-")) {
|
|
28
28
|
logger.warn("SKIP_FORMAT", msg.prerelease({ currentVersion }));
|
|
29
29
|
}
|
|
@@ -701,7 +701,7 @@ export declare const MiddlewareNotAResponse: {
|
|
|
701
701
|
* @docs
|
|
702
702
|
* @description
|
|
703
703
|
*
|
|
704
|
-
* Thrown
|
|
704
|
+
* Thrown when `locals` is overwritten with something that is not an object
|
|
705
705
|
*
|
|
706
706
|
* For example:
|
|
707
707
|
* ```ts
|
|
@@ -718,6 +718,17 @@ export declare const LocalsNotAnObject: {
|
|
|
718
718
|
message: string;
|
|
719
719
|
hint: string;
|
|
720
720
|
};
|
|
721
|
+
/**
|
|
722
|
+
* @docs
|
|
723
|
+
* @description
|
|
724
|
+
* Thrown when a value is being set as the `headers` field on the `ResponseInit` object available as `Astro.response`.
|
|
725
|
+
*/
|
|
726
|
+
export declare const AstroResponseHeadersReassigned: {
|
|
727
|
+
name: string;
|
|
728
|
+
title: string;
|
|
729
|
+
message: string;
|
|
730
|
+
hint: string;
|
|
731
|
+
};
|
|
721
732
|
/**
|
|
722
733
|
* @docs
|
|
723
734
|
* @description
|
|
@@ -256,6 +256,12 @@ const LocalsNotAnObject = {
|
|
|
256
256
|
message: "`locals` can only be assigned to an object. Other values like numbers, strings, etc. are not accepted.",
|
|
257
257
|
hint: "If you tried to remove some information from the `locals` object, try to use `delete` or set the property to `undefined`."
|
|
258
258
|
};
|
|
259
|
+
const AstroResponseHeadersReassigned = {
|
|
260
|
+
name: "AstroResponseHeadersReassigned",
|
|
261
|
+
title: "`Astro.response.headers` must not be reassigned.",
|
|
262
|
+
message: "Individual headers can be added to and removed from `Astro.response.headers`, but it must not be replaced with another instance of `Headers` altogether.",
|
|
263
|
+
hint: "Consider using `Astro.response.headers.add()`, and `Astro.response.headers.delete()`."
|
|
264
|
+
};
|
|
259
265
|
const MiddlewareCantBeLoaded = {
|
|
260
266
|
name: "MiddlewareCantBeLoaded",
|
|
261
267
|
title: "Can't load the middleware.",
|
|
@@ -483,6 +489,7 @@ const UnknownError = { name: "UnknownError", title: "Unknown Error." };
|
|
|
483
489
|
export {
|
|
484
490
|
AstroGlobNoMatch,
|
|
485
491
|
AstroGlobUsedOutside,
|
|
492
|
+
AstroResponseHeadersReassigned,
|
|
486
493
|
CSSSyntaxError,
|
|
487
494
|
CantRenderPage,
|
|
488
495
|
ClientAddressNotAvailable,
|
package/dist/core/messages.js
CHANGED
|
@@ -36,7 +36,7 @@ function serverStart({
|
|
|
36
36
|
host,
|
|
37
37
|
base
|
|
38
38
|
}) {
|
|
39
|
-
const version = "4.4.
|
|
39
|
+
const version = "4.4.14";
|
|
40
40
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
41
41
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
42
42
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -261,7 +261,7 @@ function printHelp({
|
|
|
261
261
|
message.push(
|
|
262
262
|
linebreak(),
|
|
263
263
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
264
|
-
`v${"4.4.
|
|
264
|
+
`v${"4.4.14"}`
|
|
265
265
|
)} ${headline}`
|
|
266
266
|
);
|
|
267
267
|
}
|
|
@@ -44,12 +44,7 @@ function createContext({
|
|
|
44
44
|
return preferredLocaleList ??= computePreferredLocaleList(request, userDefinedLocales);
|
|
45
45
|
},
|
|
46
46
|
get currentLocale() {
|
|
47
|
-
return currentLocale ??= computeCurrentLocale(
|
|
48
|
-
route,
|
|
49
|
-
userDefinedLocales,
|
|
50
|
-
void 0,
|
|
51
|
-
void 0
|
|
52
|
-
);
|
|
47
|
+
return currentLocale ??= computeCurrentLocale(route, userDefinedLocales);
|
|
53
48
|
},
|
|
54
49
|
url,
|
|
55
50
|
get clientAddress() {
|
|
@@ -3,7 +3,7 @@ import type { Pipeline } from '../base-pipeline.js';
|
|
|
3
3
|
export { Pipeline } from '../base-pipeline.js';
|
|
4
4
|
export { getParams, getProps } from './params-and-props.js';
|
|
5
5
|
export { loadRenderer } from './renderer.js';
|
|
6
|
-
export {
|
|
6
|
+
export { Slots } from './result.js';
|
|
7
7
|
export interface SSROptions {
|
|
8
8
|
/** The pipeline instance */
|
|
9
9
|
pipeline: Pipeline;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Pipeline } from "../base-pipeline.js";
|
|
2
2
|
import { getParams, getProps } from "./params-and-props.js";
|
|
3
3
|
import { loadRenderer } from "./renderer.js";
|
|
4
|
-
import {
|
|
4
|
+
import { Slots } from "./result.js";
|
|
5
5
|
export {
|
|
6
6
|
Pipeline,
|
|
7
|
-
|
|
7
|
+
Slots,
|
|
8
8
|
getParams,
|
|
9
9
|
getProps,
|
|
10
10
|
loadRenderer
|
|
@@ -1,39 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { type
|
|
3
|
-
import { AstroCookies } from '../cookies/index.js';
|
|
1
|
+
import type { SSRResult } from '../../@types/astro.js';
|
|
2
|
+
import { type ComponentSlots } from '../../runtime/server/index.js';
|
|
4
3
|
import type { Logger } from '../logger/core.js';
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Value of Astro config's `output` option, true if "server" or "hybrid"
|
|
12
|
-
*/
|
|
13
|
-
ssr: boolean;
|
|
14
|
-
logger: Logger;
|
|
15
|
-
params: Params;
|
|
16
|
-
pathname: string;
|
|
17
|
-
renderers: SSRLoadedRenderer[];
|
|
18
|
-
clientDirectives: Map<string, string>;
|
|
19
|
-
compressHTML: boolean;
|
|
20
|
-
partial: boolean;
|
|
21
|
-
resolve: (s: string) => Promise<string>;
|
|
22
|
-
/**
|
|
23
|
-
* Used for `Astro.site`
|
|
24
|
-
*/
|
|
25
|
-
site: string | undefined;
|
|
26
|
-
links: Set<SSRElement>;
|
|
27
|
-
scripts: Set<SSRElement>;
|
|
28
|
-
styles: Set<SSRElement>;
|
|
29
|
-
componentMetadata: SSRResult['componentMetadata'];
|
|
30
|
-
request: Request;
|
|
31
|
-
status: number;
|
|
32
|
-
locals: App.Locals;
|
|
33
|
-
cookies: AstroCookies;
|
|
34
|
-
locales: Locales | undefined;
|
|
35
|
-
defaultLocale: string | undefined;
|
|
36
|
-
route: string;
|
|
37
|
-
strategy: RoutingStrategies | undefined;
|
|
4
|
+
export declare class Slots {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(result: SSRResult, slots: ComponentSlots | null, logger: Logger);
|
|
7
|
+
has(name: string): boolean;
|
|
8
|
+
render(name: string, args?: any[]): Promise<any>;
|
|
38
9
|
}
|
|
39
|
-
export declare function createResult(args: CreateResultArgs): SSRResult;
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
computeCurrentLocale,
|
|
3
|
-
computePreferredLocale,
|
|
4
|
-
computePreferredLocaleList
|
|
5
|
-
} from "../../i18n/utils.js";
|
|
6
1
|
import { renderSlotToString } from "../../runtime/server/index.js";
|
|
7
2
|
import { renderJSX } from "../../runtime/server/jsx.js";
|
|
8
3
|
import { chunkToString } from "../../runtime/server/render/index.js";
|
|
9
|
-
import { clientAddressSymbol, responseSentSymbol } from "../constants.js";
|
|
10
|
-
import { AstroCookies } from "../cookies/index.js";
|
|
11
4
|
import { AstroError, AstroErrorData } from "../errors/index.js";
|
|
12
5
|
function getFunctionExpression(slot) {
|
|
13
6
|
if (!slot)
|
|
@@ -76,137 +69,6 @@ class Slots {
|
|
|
76
69
|
return outHTML;
|
|
77
70
|
}
|
|
78
71
|
}
|
|
79
|
-
function createResult(args) {
|
|
80
|
-
const { params, request, resolve, locals } = args;
|
|
81
|
-
const url = new URL(request.url);
|
|
82
|
-
const headers = new Headers();
|
|
83
|
-
headers.set("Content-Type", "text/html");
|
|
84
|
-
const response = {
|
|
85
|
-
status: args.status,
|
|
86
|
-
statusText: "OK",
|
|
87
|
-
headers
|
|
88
|
-
};
|
|
89
|
-
Object.defineProperty(response, "headers", {
|
|
90
|
-
value: response.headers,
|
|
91
|
-
enumerable: true,
|
|
92
|
-
writable: false
|
|
93
|
-
});
|
|
94
|
-
let cookies = args.cookies;
|
|
95
|
-
let preferredLocale = void 0;
|
|
96
|
-
let preferredLocaleList = void 0;
|
|
97
|
-
let currentLocale = void 0;
|
|
98
|
-
const result = {
|
|
99
|
-
styles: args.styles ?? /* @__PURE__ */ new Set(),
|
|
100
|
-
scripts: args.scripts ?? /* @__PURE__ */ new Set(),
|
|
101
|
-
links: args.links ?? /* @__PURE__ */ new Set(),
|
|
102
|
-
componentMetadata: args.componentMetadata ?? /* @__PURE__ */ new Map(),
|
|
103
|
-
renderers: args.renderers,
|
|
104
|
-
clientDirectives: args.clientDirectives,
|
|
105
|
-
compressHTML: args.compressHTML,
|
|
106
|
-
partial: args.partial,
|
|
107
|
-
pathname: args.pathname,
|
|
108
|
-
cookies,
|
|
109
|
-
/** This function returns the `Astro` faux-global */
|
|
110
|
-
createAstro(astroGlobal, props, slots) {
|
|
111
|
-
const astroSlots = new Slots(result, slots, args.logger);
|
|
112
|
-
const Astro = {
|
|
113
|
-
// @ts-expect-error
|
|
114
|
-
__proto__: astroGlobal,
|
|
115
|
-
get clientAddress() {
|
|
116
|
-
if (!(clientAddressSymbol in request)) {
|
|
117
|
-
if (args.adapterName) {
|
|
118
|
-
throw new AstroError({
|
|
119
|
-
...AstroErrorData.ClientAddressNotAvailable,
|
|
120
|
-
message: AstroErrorData.ClientAddressNotAvailable.message(args.adapterName)
|
|
121
|
-
});
|
|
122
|
-
} else {
|
|
123
|
-
throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return Reflect.get(request, clientAddressSymbol);
|
|
127
|
-
},
|
|
128
|
-
get cookies() {
|
|
129
|
-
if (cookies) {
|
|
130
|
-
return cookies;
|
|
131
|
-
}
|
|
132
|
-
cookies = new AstroCookies(request);
|
|
133
|
-
result.cookies = cookies;
|
|
134
|
-
return cookies;
|
|
135
|
-
},
|
|
136
|
-
get preferredLocale() {
|
|
137
|
-
if (preferredLocale) {
|
|
138
|
-
return preferredLocale;
|
|
139
|
-
}
|
|
140
|
-
if (args.locales) {
|
|
141
|
-
preferredLocale = computePreferredLocale(request, args.locales);
|
|
142
|
-
return preferredLocale;
|
|
143
|
-
}
|
|
144
|
-
return void 0;
|
|
145
|
-
},
|
|
146
|
-
get preferredLocaleList() {
|
|
147
|
-
if (preferredLocaleList) {
|
|
148
|
-
return preferredLocaleList;
|
|
149
|
-
}
|
|
150
|
-
if (args.locales) {
|
|
151
|
-
preferredLocaleList = computePreferredLocaleList(request, args.locales);
|
|
152
|
-
return preferredLocaleList;
|
|
153
|
-
}
|
|
154
|
-
return void 0;
|
|
155
|
-
},
|
|
156
|
-
get currentLocale() {
|
|
157
|
-
if (currentLocale) {
|
|
158
|
-
return currentLocale;
|
|
159
|
-
}
|
|
160
|
-
if (args.locales) {
|
|
161
|
-
currentLocale = computeCurrentLocale(
|
|
162
|
-
url.pathname,
|
|
163
|
-
args.locales,
|
|
164
|
-
args.strategy,
|
|
165
|
-
args.defaultLocale
|
|
166
|
-
);
|
|
167
|
-
if (currentLocale) {
|
|
168
|
-
return currentLocale;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return void 0;
|
|
172
|
-
},
|
|
173
|
-
params,
|
|
174
|
-
props,
|
|
175
|
-
locals,
|
|
176
|
-
request,
|
|
177
|
-
url,
|
|
178
|
-
redirect(path, status) {
|
|
179
|
-
if (request[responseSentSymbol]) {
|
|
180
|
-
throw new AstroError({
|
|
181
|
-
...AstroErrorData.ResponseSentError
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
return new Response(null, {
|
|
185
|
-
status: status || 302,
|
|
186
|
-
headers: {
|
|
187
|
-
Location: path
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
},
|
|
191
|
-
response,
|
|
192
|
-
slots: astroSlots
|
|
193
|
-
};
|
|
194
|
-
return Astro;
|
|
195
|
-
},
|
|
196
|
-
resolve,
|
|
197
|
-
response,
|
|
198
|
-
_metadata: {
|
|
199
|
-
hasHydrationScript: false,
|
|
200
|
-
rendererSpecificHydrationScripts: /* @__PURE__ */ new Set(),
|
|
201
|
-
hasRenderedHead: false,
|
|
202
|
-
hasDirectives: /* @__PURE__ */ new Set(),
|
|
203
|
-
headInTree: false,
|
|
204
|
-
extraHead: [],
|
|
205
|
-
propagators: /* @__PURE__ */ new Set()
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
return result;
|
|
209
|
-
}
|
|
210
72
|
export {
|
|
211
|
-
|
|
73
|
+
Slots
|
|
212
74
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { APIContext, ComponentInstance, MiddlewareHandler, RouteData } from '../@types/astro.js';
|
|
1
|
+
import type { APIContext, AstroGlobal, AstroGlobalPartial, ComponentInstance, MiddlewareHandler, RouteData, SSRResult } from '../@types/astro.js';
|
|
2
2
|
import { AstroCookies } from './cookies/index.js';
|
|
3
3
|
import { type Pipeline } from './render/index.js';
|
|
4
4
|
export declare class RenderContext {
|
|
@@ -28,7 +28,9 @@ export declare class RenderContext {
|
|
|
28
28
|
*/
|
|
29
29
|
render(componentInstance: ComponentInstance | undefined): Promise<Response>;
|
|
30
30
|
createAPIContext(props: APIContext['props']): APIContext;
|
|
31
|
-
createResult(mod: ComponentInstance): Promise<
|
|
31
|
+
createResult(mod: ComponentInstance): Promise<SSRResult>;
|
|
32
|
+
createAstro(result: SSRResult, astroGlobalPartial: AstroGlobalPartial, props: Record<string, any>, slotValues: Record<string, any> | null): AstroGlobal;
|
|
33
|
+
clientAddress(): string;
|
|
32
34
|
computeCurrentLocale(): string | undefined;
|
|
33
35
|
computePreferredLocale(): string | undefined;
|
|
34
36
|
computePreferredLocaleList(): string[] | undefined;
|
|
@@ -10,16 +10,15 @@ import {
|
|
|
10
10
|
REROUTE_DIRECTIVE_HEADER,
|
|
11
11
|
ROUTE_TYPE_HEADER,
|
|
12
12
|
clientAddressSymbol,
|
|
13
|
-
clientLocalsSymbol
|
|
13
|
+
clientLocalsSymbol,
|
|
14
|
+
responseSentSymbol
|
|
14
15
|
} from "./constants.js";
|
|
15
|
-
import { attachCookiesToResponse } from "./cookies/index.js";
|
|
16
|
-
import { AstroCookies } from "./cookies/index.js";
|
|
16
|
+
import { AstroCookies, attachCookiesToResponse } from "./cookies/index.js";
|
|
17
17
|
import { AstroError, AstroErrorData } from "./errors/index.js";
|
|
18
18
|
import { callMiddleware } from "./middleware/callMiddleware.js";
|
|
19
19
|
import { sequence } from "./middleware/index.js";
|
|
20
20
|
import { renderRedirect } from "./redirects/render.js";
|
|
21
|
-
import {
|
|
22
|
-
import { getParams, getProps } from "./render/index.js";
|
|
21
|
+
import { Slots, getParams, getProps } from "./render/index.js";
|
|
23
22
|
class RenderContext {
|
|
24
23
|
constructor(pipeline, locals, middleware, pathname, request, routeData, status, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = new URL(request.url)) {
|
|
25
24
|
this.pipeline = pipeline;
|
|
@@ -106,38 +105,15 @@ class RenderContext {
|
|
|
106
105
|
const { cookies, params, pipeline, request, url } = this;
|
|
107
106
|
const generator = `Astro v${ASTRO_VERSION}`;
|
|
108
107
|
const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } });
|
|
109
|
-
const site = pipeline.site ? new URL(pipeline.site) : void 0;
|
|
110
108
|
return {
|
|
111
109
|
cookies,
|
|
110
|
+
get clientAddress() {
|
|
111
|
+
return renderContext.clientAddress();
|
|
112
|
+
},
|
|
112
113
|
get currentLocale() {
|
|
113
114
|
return renderContext.computeCurrentLocale();
|
|
114
115
|
},
|
|
115
116
|
generator,
|
|
116
|
-
params,
|
|
117
|
-
get preferredLocale() {
|
|
118
|
-
return renderContext.computePreferredLocale();
|
|
119
|
-
},
|
|
120
|
-
get preferredLocaleList() {
|
|
121
|
-
return renderContext.computePreferredLocaleList();
|
|
122
|
-
},
|
|
123
|
-
props,
|
|
124
|
-
redirect,
|
|
125
|
-
request,
|
|
126
|
-
site,
|
|
127
|
-
url,
|
|
128
|
-
get clientAddress() {
|
|
129
|
-
if (clientAddressSymbol in request) {
|
|
130
|
-
return Reflect.get(request, clientAddressSymbol);
|
|
131
|
-
}
|
|
132
|
-
if (pipeline.adapterName) {
|
|
133
|
-
throw new AstroError({
|
|
134
|
-
...AstroErrorData.ClientAddressNotAvailable,
|
|
135
|
-
message: AstroErrorData.ClientAddressNotAvailable.message(pipeline.adapterName)
|
|
136
|
-
});
|
|
137
|
-
} else {
|
|
138
|
-
throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
117
|
get locals() {
|
|
142
118
|
return renderContext.locals;
|
|
143
119
|
},
|
|
@@ -149,52 +125,119 @@ class RenderContext {
|
|
|
149
125
|
renderContext.locals = val;
|
|
150
126
|
Reflect.set(request, clientLocalsSymbol, val);
|
|
151
127
|
}
|
|
152
|
-
}
|
|
128
|
+
},
|
|
129
|
+
params,
|
|
130
|
+
get preferredLocale() {
|
|
131
|
+
return renderContext.computePreferredLocale();
|
|
132
|
+
},
|
|
133
|
+
get preferredLocaleList() {
|
|
134
|
+
return renderContext.computePreferredLocaleList();
|
|
135
|
+
},
|
|
136
|
+
props,
|
|
137
|
+
redirect,
|
|
138
|
+
request,
|
|
139
|
+
site: pipeline.site,
|
|
140
|
+
url
|
|
153
141
|
};
|
|
154
142
|
}
|
|
155
143
|
async createResult(mod) {
|
|
156
|
-
const { cookies,
|
|
157
|
-
const {
|
|
158
|
-
adapterName,
|
|
159
|
-
clientDirectives,
|
|
160
|
-
compressHTML,
|
|
161
|
-
i18n,
|
|
162
|
-
manifest,
|
|
163
|
-
logger,
|
|
164
|
-
renderers,
|
|
165
|
-
resolve,
|
|
166
|
-
site,
|
|
167
|
-
serverLike
|
|
168
|
-
} = pipeline;
|
|
144
|
+
const { cookies, pathname, pipeline, routeData, status } = this;
|
|
145
|
+
const { clientDirectives, compressHTML, manifest, renderers, resolve } = pipeline;
|
|
169
146
|
const { links, scripts, styles } = await pipeline.headElements(routeData);
|
|
170
147
|
const componentMetadata = await pipeline.componentMetadata(routeData) ?? manifest.componentMetadata;
|
|
171
|
-
const
|
|
148
|
+
const headers = new Headers({ "Content-Type": "text/html" });
|
|
172
149
|
const partial = Boolean(mod.partial);
|
|
173
|
-
|
|
174
|
-
|
|
150
|
+
const response = {
|
|
151
|
+
status,
|
|
152
|
+
statusText: "OK",
|
|
153
|
+
get headers() {
|
|
154
|
+
return headers;
|
|
155
|
+
},
|
|
156
|
+
// Disallow `Astro.response.headers = new Headers`
|
|
157
|
+
set headers(_) {
|
|
158
|
+
throw new AstroError(AstroErrorData.AstroResponseHeadersReassigned);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const result = {
|
|
175
162
|
clientDirectives,
|
|
176
163
|
componentMetadata,
|
|
177
164
|
compressHTML,
|
|
178
165
|
cookies,
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
locals,
|
|
182
|
-
logger,
|
|
166
|
+
/** This function returns the `Astro` faux-global */
|
|
167
|
+
createAstro: (astroGlobal, props, slots) => this.createAstro(result, astroGlobal, props, slots),
|
|
183
168
|
links,
|
|
184
|
-
params,
|
|
185
169
|
partial,
|
|
186
170
|
pathname,
|
|
187
171
|
renderers,
|
|
188
172
|
resolve,
|
|
189
|
-
|
|
190
|
-
route: routeData.route,
|
|
191
|
-
strategy,
|
|
192
|
-
site,
|
|
173
|
+
response,
|
|
193
174
|
scripts,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
175
|
+
styles,
|
|
176
|
+
_metadata: {
|
|
177
|
+
hasHydrationScript: false,
|
|
178
|
+
rendererSpecificHydrationScripts: /* @__PURE__ */ new Set(),
|
|
179
|
+
hasRenderedHead: false,
|
|
180
|
+
hasDirectives: /* @__PURE__ */ new Set(),
|
|
181
|
+
headInTree: false,
|
|
182
|
+
extraHead: [],
|
|
183
|
+
propagators: /* @__PURE__ */ new Set()
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
createAstro(result, astroGlobalPartial, props, slotValues) {
|
|
189
|
+
const renderContext = this;
|
|
190
|
+
const { cookies, locals, params, pipeline, request, url } = this;
|
|
191
|
+
const { response } = result;
|
|
192
|
+
const redirect = (path, status = 302) => {
|
|
193
|
+
if (request[responseSentSymbol]) {
|
|
194
|
+
throw new AstroError({
|
|
195
|
+
...AstroErrorData.ResponseSentError
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
return new Response(null, { status, headers: { Location: path } });
|
|
199
|
+
};
|
|
200
|
+
const slots = new Slots(result, slotValues, pipeline.logger);
|
|
201
|
+
const astroGlobalCombined = {
|
|
202
|
+
...astroGlobalPartial,
|
|
203
|
+
cookies,
|
|
204
|
+
get clientAddress() {
|
|
205
|
+
return renderContext.clientAddress();
|
|
206
|
+
},
|
|
207
|
+
get currentLocale() {
|
|
208
|
+
return renderContext.computeCurrentLocale();
|
|
209
|
+
},
|
|
210
|
+
params,
|
|
211
|
+
get preferredLocale() {
|
|
212
|
+
return renderContext.computePreferredLocale();
|
|
213
|
+
},
|
|
214
|
+
get preferredLocaleList() {
|
|
215
|
+
return renderContext.computePreferredLocaleList();
|
|
216
|
+
},
|
|
217
|
+
props,
|
|
218
|
+
locals,
|
|
219
|
+
redirect,
|
|
220
|
+
request,
|
|
221
|
+
response,
|
|
222
|
+
slots,
|
|
223
|
+
site: pipeline.site,
|
|
224
|
+
url
|
|
225
|
+
};
|
|
226
|
+
return astroGlobalCombined;
|
|
227
|
+
}
|
|
228
|
+
clientAddress() {
|
|
229
|
+
const { pipeline, request } = this;
|
|
230
|
+
if (clientAddressSymbol in request) {
|
|
231
|
+
return Reflect.get(request, clientAddressSymbol);
|
|
232
|
+
}
|
|
233
|
+
if (pipeline.adapterName) {
|
|
234
|
+
throw new AstroError({
|
|
235
|
+
...AstroErrorData.ClientAddressNotAvailable,
|
|
236
|
+
message: AstroErrorData.ClientAddressNotAvailable.message(pipeline.adapterName)
|
|
237
|
+
});
|
|
238
|
+
} else {
|
|
239
|
+
throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
|
|
240
|
+
}
|
|
198
241
|
}
|
|
199
242
|
/**
|
|
200
243
|
* API Context may be created multiple times per request, i18n data needs to be computed only once.
|
|
@@ -210,12 +253,8 @@ class RenderContext {
|
|
|
210
253
|
if (!i18n)
|
|
211
254
|
return;
|
|
212
255
|
const { defaultLocale, locales, strategy } = i18n;
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
locales,
|
|
216
|
-
strategy,
|
|
217
|
-
defaultLocale
|
|
218
|
-
);
|
|
256
|
+
const fallbackTo = strategy === "pathname-prefix-other-locales" || strategy === "domains-prefix-other-locales" ? defaultLocale : void 0;
|
|
257
|
+
return this.#currentLocale ??= computeCurrentLocale(routeData.route, locales) ?? computeCurrentLocale(url.pathname, locales) ?? fallbackTo;
|
|
219
258
|
}
|
|
220
259
|
#preferredLocale;
|
|
221
260
|
computePreferredLocale() {
|
|
@@ -20,9 +20,11 @@ function countOccurrences(needle, haystack) {
|
|
|
20
20
|
}
|
|
21
21
|
return count;
|
|
22
22
|
}
|
|
23
|
+
const ROUTE_DYNAMIC_SPLIT = /\[(.+?\(.+?\)|.+?)\]/;
|
|
24
|
+
const ROUTE_SPREAD = /^\.{3}.+$/;
|
|
23
25
|
function getParts(part, file) {
|
|
24
26
|
const result = [];
|
|
25
|
-
part.split(
|
|
27
|
+
part.split(ROUTE_DYNAMIC_SPLIT).map((str, i) => {
|
|
26
28
|
if (!str)
|
|
27
29
|
return;
|
|
28
30
|
const dynamic = i % 2 === 1;
|
|
@@ -33,7 +35,7 @@ function getParts(part, file) {
|
|
|
33
35
|
result.push({
|
|
34
36
|
content,
|
|
35
37
|
dynamic,
|
|
36
|
-
spread: dynamic &&
|
|
38
|
+
spread: dynamic && ROUTE_SPREAD.test(content)
|
|
37
39
|
});
|
|
38
40
|
});
|
|
39
41
|
return result;
|
|
@@ -116,6 +118,11 @@ function routeComparator(a, b) {
|
|
|
116
118
|
if (aIsStatic !== bIsStatic) {
|
|
117
119
|
return aIsStatic ? -1 : 1;
|
|
118
120
|
}
|
|
121
|
+
const aAllDynamic = aSegment.every((part) => part.dynamic);
|
|
122
|
+
const bAllDynamic = bSegment.every((part) => part.dynamic);
|
|
123
|
+
if (aAllDynamic !== bAllDynamic) {
|
|
124
|
+
return aAllDynamic ? 1 : -1;
|
|
125
|
+
}
|
|
119
126
|
const aHasSpread = aSegment.some((part) => part.spread);
|
|
120
127
|
const bHasSpread = bSegment.some((part) => part.spread);
|
|
121
128
|
if (aHasSpread !== bHasSpread) {
|
package/dist/i18n/utils.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare function parseLocale(header: string): BrowserLocale[];
|
|
|
20
20
|
*/
|
|
21
21
|
export declare function computePreferredLocale(request: Request, locales: Locales): string | undefined;
|
|
22
22
|
export declare function computePreferredLocaleList(request: Request, locales: Locales): string[];
|
|
23
|
-
export declare function computeCurrentLocale(pathname: string, locales: Locales
|
|
23
|
+
export declare function computeCurrentLocale(pathname: string, locales: Locales): undefined | string;
|
|
24
24
|
export type RoutingStrategies = 'pathname-prefix-always' | 'pathname-prefix-other-locales' | 'pathname-prefix-always-no-redirect' | 'domains-prefix-always' | 'domains-prefix-other-locales' | 'domains-prefix-always-no-redirect';
|
|
25
25
|
export declare function toRoutingStrategy(i18n: NonNullable<AstroConfig['i18n']>): RoutingStrategies;
|
|
26
26
|
export {};
|
package/dist/i18n/utils.js
CHANGED
|
@@ -109,7 +109,7 @@ function computePreferredLocaleList(request, locales) {
|
|
|
109
109
|
}
|
|
110
110
|
return result;
|
|
111
111
|
}
|
|
112
|
-
function computeCurrentLocale(pathname, locales
|
|
112
|
+
function computeCurrentLocale(pathname, locales) {
|
|
113
113
|
for (const segment of pathname.split("/")) {
|
|
114
114
|
for (const locale of locales) {
|
|
115
115
|
if (typeof locale === "string") {
|
|
@@ -131,10 +131,6 @@ function computeCurrentLocale(pathname, locales, routingStrategy, defaultLocale)
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
if (routingStrategy === "pathname-prefix-other-locales" || routingStrategy === "domains-prefix-other-locales") {
|
|
135
|
-
return defaultLocale;
|
|
136
|
-
}
|
|
137
|
-
return void 0;
|
|
138
134
|
}
|
|
139
135
|
function toRoutingStrategy(i18n) {
|
|
140
136
|
let { routing, domains } = i18n;
|
package/dist/prefetch/index.js
CHANGED
|
@@ -200,6 +200,15 @@ function appendSpeculationRules(url) {
|
|
|
200
200
|
source: "list",
|
|
201
201
|
urls: [url]
|
|
202
202
|
}
|
|
203
|
+
],
|
|
204
|
+
// Currently, adding `prefetch` is required to fallback if `prerender` fails.
|
|
205
|
+
// Possibly will be automatic in the future, in which case it can be removed.
|
|
206
|
+
// https://github.com/WICG/nav-speculation/issues/162#issuecomment-1977818473
|
|
207
|
+
prefetch: [
|
|
208
|
+
{
|
|
209
|
+
source: "list",
|
|
210
|
+
urls: [url]
|
|
211
|
+
}
|
|
203
212
|
]
|
|
204
213
|
});
|
|
205
214
|
document.head.append(script);
|
|
@@ -35,7 +35,24 @@ const a11y_required_attributes = {
|
|
|
35
35
|
img: ["alt"],
|
|
36
36
|
object: ["title", "aria-label", "aria-labelledby"]
|
|
37
37
|
};
|
|
38
|
-
const
|
|
38
|
+
const MAYBE_INTERACTIVE = /* @__PURE__ */ new Map([
|
|
39
|
+
["a", "href"],
|
|
40
|
+
["input", "type"],
|
|
41
|
+
["audio", "controls"],
|
|
42
|
+
["img", "usemap"],
|
|
43
|
+
["object", "usemap"],
|
|
44
|
+
["video", "controls"]
|
|
45
|
+
]);
|
|
46
|
+
const interactiveElements = [
|
|
47
|
+
"button",
|
|
48
|
+
"details",
|
|
49
|
+
"embed",
|
|
50
|
+
"iframe",
|
|
51
|
+
"label",
|
|
52
|
+
"select",
|
|
53
|
+
"textarea",
|
|
54
|
+
...MAYBE_INTERACTIVE.keys()
|
|
55
|
+
];
|
|
39
56
|
const labellableElements = ["input", "meter", "output", "progress", "select", "textarea"];
|
|
40
57
|
const aria_non_interactive_roles = [
|
|
41
58
|
"alert",
|
|
@@ -170,6 +187,13 @@ const ariaRoles = new Set(
|
|
|
170
187
|
" "
|
|
171
188
|
)
|
|
172
189
|
);
|
|
190
|
+
function isInteractive(element) {
|
|
191
|
+
const attribute = MAYBE_INTERACTIVE.get(element.localName);
|
|
192
|
+
if (attribute) {
|
|
193
|
+
return element.hasAttribute(attribute);
|
|
194
|
+
}
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
173
197
|
const a11y = [
|
|
174
198
|
{
|
|
175
199
|
code: "a11y-accesskey",
|
|
@@ -390,6 +414,8 @@ const a11y = [
|
|
|
390
414
|
message: "Interactive HTML elements like `<a>` and `<button>` cannot use non-interactive roles like `heading`, `list`, `menu`, and `toolbar`.",
|
|
391
415
|
selector: `[role]:is(${interactiveElements.join(",")})`,
|
|
392
416
|
match(element) {
|
|
417
|
+
if (!isInteractive(element))
|
|
418
|
+
return false;
|
|
393
419
|
const role = element.getAttribute("role");
|
|
394
420
|
if (!role)
|
|
395
421
|
return false;
|
|
@@ -405,6 +431,8 @@ const a11y = [
|
|
|
405
431
|
message: "Interactive roles should not be used to convert a non-interactive element to an interactive element",
|
|
406
432
|
selector: `[role]:not(${interactiveElements.join(",")})`,
|
|
407
433
|
match(element) {
|
|
434
|
+
if (!isInteractive(element))
|
|
435
|
+
return false;
|
|
408
436
|
const role = element.getAttribute("role");
|
|
409
437
|
if (!role)
|
|
410
438
|
return false;
|
|
@@ -426,6 +454,8 @@ const a11y = [
|
|
|
426
454
|
const isScrollable = element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
|
|
427
455
|
if (isScrollable)
|
|
428
456
|
return false;
|
|
457
|
+
if (!isInteractive(element))
|
|
458
|
+
return false;
|
|
429
459
|
if (!interactiveElements.includes(element.localName))
|
|
430
460
|
return true;
|
|
431
461
|
}
|
|
@@ -21,6 +21,8 @@ function createAstroGlobFn() {
|
|
|
21
21
|
}
|
|
22
22
|
function createAstro(site) {
|
|
23
23
|
return {
|
|
24
|
+
// TODO: this is no longer neccessary for `Astro.site`
|
|
25
|
+
// but it somehow allows working around caching issues in content collections for some tests
|
|
24
26
|
site: site ? new URL(site) : void 0,
|
|
25
27
|
generator: `Astro v${ASTRO_VERSION}`,
|
|
26
28
|
glob: createAstroGlobFn()
|
|
@@ -107,7 +107,7 @@ function createDevelopmentManifest(settings) {
|
|
|
107
107
|
renderers: [],
|
|
108
108
|
base: settings.config.base,
|
|
109
109
|
assetsPrefix: settings.config.build.assetsPrefix,
|
|
110
|
-
site: settings.config.site
|
|
110
|
+
site: settings.config.site,
|
|
111
111
|
componentMetadata: /* @__PURE__ */ new Map(),
|
|
112
112
|
i18n: i18nManifest,
|
|
113
113
|
middleware(_, next) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.14",
|
|
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",
|
|
@@ -163,9 +163,9 @@
|
|
|
163
163
|
"which-pm": "^2.1.1",
|
|
164
164
|
"yargs-parser": "^21.1.1",
|
|
165
165
|
"zod": "^3.22.4",
|
|
166
|
+
"@astrojs/telemetry": "3.0.4",
|
|
166
167
|
"@astrojs/internal-helpers": "0.2.1",
|
|
167
|
-
"@astrojs/markdown-remark": "4.2.1"
|
|
168
|
-
"@astrojs/telemetry": "3.0.4"
|
|
168
|
+
"@astrojs/markdown-remark": "4.2.1"
|
|
169
169
|
},
|
|
170
170
|
"optionalDependencies": {
|
|
171
171
|
"sharp": "^0.32.6"
|