astro 4.5.4 → 4.5.6
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 +4 -0
- package/dist/cli/install-package.d.ts +1 -0
- package/dist/cli/install-package.js +2 -0
- package/dist/content/types-generator.js +2 -2
- package/dist/core/build/index.js +2 -2
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/errors/dev/utils.js +4 -4
- package/dist/core/errors/errors-data.d.ts +22 -0
- package/dist/core/errors/errors-data.js +6 -0
- package/dist/core/messages.js +2 -2
- package/dist/core/render-context.js +32 -17
- package/dist/core/routing/manifest/create.js +9 -3
- package/dist/core/sync/index.js +19 -5
- package/dist/runtime/client/dev-toolbar/apps/audit/index.js +13 -3
- package/dist/runtime/client/dev-toolbar/apps/audit/ui/audit-list-item.js +7 -0
- package/dist/runtime/client/dev-toolbar/apps/audit/ui/audit-ui.js +8 -2
- package/dist/runtime/server/endpoint.js +5 -0
- package/dist/runtime/server/render/astro/render.js +5 -3
- package/dist/runtime/server/render/component.js +12 -4
- package/dist/transitions/router.js +1 -1
- package/package.json +3 -3
package/dist/@types/astro.d.ts
CHANGED
|
@@ -2478,6 +2478,10 @@ export type SSRComponentMetadata = {
|
|
|
2478
2478
|
containsHead: boolean;
|
|
2479
2479
|
};
|
|
2480
2480
|
export interface SSRResult {
|
|
2481
|
+
/**
|
|
2482
|
+
* Whether the page has failed with a non-recoverable error, or the client disconnected.
|
|
2483
|
+
*/
|
|
2484
|
+
cancelled: boolean;
|
|
2481
2485
|
styles: Set<SSRElement>;
|
|
2482
2486
|
scripts: Set<SSRElement>;
|
|
2483
2487
|
links: Set<SSRElement>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Logger } from '../core/logger/core.js';
|
|
2
2
|
type GetPackageOptions = {
|
|
3
3
|
skipAsk?: boolean;
|
|
4
|
+
optional?: boolean;
|
|
4
5
|
cwd?: string;
|
|
5
6
|
};
|
|
6
7
|
export declare function getPackage<T>(packageName: string, logger: Logger, options: GetPackageOptions, otherDeps?: string[]): Promise<T | undefined>;
|
|
@@ -24,6 +24,8 @@ async function getPackage(packageName, logger, options, otherDeps = []) {
|
|
|
24
24
|
const packageImport = await import(packageName);
|
|
25
25
|
return packageImport;
|
|
26
26
|
} catch (e) {
|
|
27
|
+
if (options.optional)
|
|
28
|
+
return void 0;
|
|
27
29
|
logger.info(
|
|
28
30
|
"SKIP_FORMAT",
|
|
29
31
|
`To continue, Astro requires the following dependency to be installed: ${bold(packageName)}.`
|
|
@@ -360,7 +360,7 @@ async function writeContentFiles({
|
|
|
360
360
|
};
|
|
361
361
|
`;
|
|
362
362
|
if (settings.config.experimental.contentCollectionJsonSchema && collectionConfig?.schema) {
|
|
363
|
-
let zodSchemaForJson = collectionConfig.schema;
|
|
363
|
+
let zodSchemaForJson = typeof collectionConfig.schema === "function" ? collectionConfig.schema({ image: () => z.string() }) : collectionConfig.schema;
|
|
364
364
|
if (zodSchemaForJson instanceof z.ZodObject) {
|
|
365
365
|
zodSchemaForJson = zodSchemaForJson.extend({
|
|
366
366
|
$schema: z.string().optional()
|
|
@@ -382,7 +382,7 @@ async function writeContentFiles({
|
|
|
382
382
|
} catch (err) {
|
|
383
383
|
logger.warn(
|
|
384
384
|
"content",
|
|
385
|
-
`An error was encountered while creating the JSON schema. Proceeding without it. Error: ${err}`
|
|
385
|
+
`An error was encountered while creating the JSON schema for the ${entryKey} entry in ${collectionKey} collection. Proceeding without it. Error: ${err}`
|
|
386
386
|
);
|
|
387
387
|
}
|
|
388
388
|
}
|
package/dist/core/build/index.js
CHANGED
|
@@ -89,8 +89,8 @@ class AstroBuilder {
|
|
|
89
89
|
{ settings: this.settings, logger: this.logger, mode: "build", command: "build" }
|
|
90
90
|
);
|
|
91
91
|
await runHookConfigDone({ settings: this.settings, logger });
|
|
92
|
-
const {
|
|
93
|
-
const syncRet = await
|
|
92
|
+
const { syncContentCollections } = await import("../sync/index.js");
|
|
93
|
+
const syncRet = await syncContentCollections(this.settings, { logger, fs });
|
|
94
94
|
if (syncRet !== 0) {
|
|
95
95
|
return process.exit(syncRet);
|
|
96
96
|
}
|
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.5.
|
|
26
|
+
const currentVersion = "4.5.6";
|
|
27
27
|
if (currentVersion.includes("-")) {
|
|
28
28
|
logger.warn("SKIP_FORMAT", msg.prerelease({ currentVersion }));
|
|
29
29
|
}
|
|
@@ -141,11 +141,11 @@ function getDocsForError(err) {
|
|
|
141
141
|
return errorName.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
+
const linkRegex = /\[([^[]+)\]\((.*)\)/g;
|
|
145
|
+
const boldRegex = /\*\*(.+)\*\*/g;
|
|
146
|
+
const urlRegex = / ((?:https?|ftp):\/\/[-\w+&@#\\/%?=~|!:,.;]*[-\w+&@#\\/%=~|])/gi;
|
|
147
|
+
const codeRegex = /`([^`]+)`/g;
|
|
144
148
|
function renderErrorMarkdown(markdown, target) {
|
|
145
|
-
const linkRegex = /\[([^[]+)\]\((.*)\)/g;
|
|
146
|
-
const boldRegex = /\*\*(.+)\*\*/g;
|
|
147
|
-
const urlRegex = / ((?:https?|ftp):\/\/[-\w+&@#\\/%?=~|!:,.;]*[-\w+&@#\\/%=~|])/gi;
|
|
148
|
-
const codeRegex = /`([^`]+)`/g;
|
|
149
149
|
if (target === "html") {
|
|
150
150
|
return escape(markdown).replace(linkRegex, `<a href="$2" target="_blank">$1</a>`).replace(boldRegex, "<b>$1</b>").replace(urlRegex, ' <a href="$1" target="_blank">$1</a>').replace(codeRegex, "<code>$1</code>");
|
|
151
151
|
} else {
|
|
@@ -697,6 +697,28 @@ export declare const MiddlewareNotAResponse: {
|
|
|
697
697
|
title: string;
|
|
698
698
|
message: string;
|
|
699
699
|
};
|
|
700
|
+
/**
|
|
701
|
+
* @docs
|
|
702
|
+
* @description
|
|
703
|
+
* Thrown when an endpoint does not return anything or returns an object that is not a `Response` object.
|
|
704
|
+
*
|
|
705
|
+
* An endpoint must return either a `Response`, or a `Promise` that resolves with a `Response`. For example:
|
|
706
|
+
* ```ts
|
|
707
|
+
* import type { APIContext } from 'astro';
|
|
708
|
+
*
|
|
709
|
+
* export async function GET({ request, url, cookies }: APIContext): Promise<Response> {
|
|
710
|
+
* return Response.json({
|
|
711
|
+
* success: true,
|
|
712
|
+
* result: 'Data from Astro Endpoint!'
|
|
713
|
+
* })
|
|
714
|
+
* }
|
|
715
|
+
* ```
|
|
716
|
+
*/
|
|
717
|
+
export declare const EndpointDidNotReturnAResponse: {
|
|
718
|
+
name: string;
|
|
719
|
+
title: string;
|
|
720
|
+
message: string;
|
|
721
|
+
};
|
|
700
722
|
/**
|
|
701
723
|
* @docs
|
|
702
724
|
* @description
|
|
@@ -250,6 +250,11 @@ const MiddlewareNotAResponse = {
|
|
|
250
250
|
title: "The middleware returned something that is not a `Response` object.",
|
|
251
251
|
message: "Any data returned from middleware must be a valid `Response` object."
|
|
252
252
|
};
|
|
253
|
+
const EndpointDidNotReturnAResponse = {
|
|
254
|
+
name: "EndpointDidNotReturnAResponse",
|
|
255
|
+
title: "The endpoint did not return a `Response`.",
|
|
256
|
+
message: "An endpoint must return either a `Response`, or a `Promise` that resolves with a `Response`."
|
|
257
|
+
};
|
|
253
258
|
const LocalsNotAnObject = {
|
|
254
259
|
name: "LocalsNotAnObject",
|
|
255
260
|
title: "Value assigned to `locals` is not accepted.",
|
|
@@ -501,6 +506,7 @@ export {
|
|
|
501
506
|
CouldNotTransformImage,
|
|
502
507
|
DataCollectionEntryParseError,
|
|
503
508
|
DuplicateContentEntrySlugError,
|
|
509
|
+
EndpointDidNotReturnAResponse,
|
|
504
510
|
ExpectedImage,
|
|
505
511
|
ExpectedImageOptions,
|
|
506
512
|
FailedToFetchRemoteImageDimensions,
|
package/dist/core/messages.js
CHANGED
|
@@ -36,7 +36,7 @@ function serverStart({
|
|
|
36
36
|
host,
|
|
37
37
|
base
|
|
38
38
|
}) {
|
|
39
|
-
const version = "4.5.
|
|
39
|
+
const version = "4.5.6";
|
|
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.5.
|
|
264
|
+
`v${"4.5.6"}`
|
|
265
265
|
)} ${headline}`
|
|
266
266
|
);
|
|
267
267
|
}
|
|
@@ -74,24 +74,38 @@ class RenderContext {
|
|
|
74
74
|
serverLike
|
|
75
75
|
});
|
|
76
76
|
const apiContext = this.createAPIContext(props);
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
77
|
+
const lastNext = async () => {
|
|
78
|
+
switch (routeData.type) {
|
|
79
|
+
case "endpoint":
|
|
80
|
+
return renderEndpoint(componentInstance, apiContext, serverLike, logger);
|
|
81
|
+
case "redirect":
|
|
82
|
+
return renderRedirect(this);
|
|
83
|
+
case "page": {
|
|
84
|
+
const result = await this.createResult(componentInstance);
|
|
85
|
+
let response2;
|
|
86
|
+
try {
|
|
87
|
+
response2 = await renderPage(
|
|
88
|
+
result,
|
|
89
|
+
componentInstance?.default,
|
|
90
|
+
props,
|
|
91
|
+
{},
|
|
92
|
+
streaming,
|
|
93
|
+
routeData
|
|
94
|
+
);
|
|
95
|
+
} catch (e) {
|
|
96
|
+
result.cancelled = true;
|
|
97
|
+
throw e;
|
|
98
|
+
}
|
|
99
|
+
response2.headers.set(ROUTE_TYPE_HEADER, "page");
|
|
100
|
+
if (routeData.route === "/404" || routeData.route === "/500") {
|
|
101
|
+
response2.headers.set(REROUTE_DIRECTIVE_HEADER, "no");
|
|
102
|
+
}
|
|
103
|
+
return response2;
|
|
104
|
+
}
|
|
105
|
+
case "fallback": {
|
|
106
|
+
return new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: "fallback" } });
|
|
107
|
+
}
|
|
91
108
|
}
|
|
92
|
-
return response2;
|
|
93
|
-
} : type === "fallback" ? () => new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: "fallback" } }) : () => {
|
|
94
|
-
throw new Error("Unknown type of route: " + type);
|
|
95
109
|
};
|
|
96
110
|
const response = await callMiddleware(middleware, apiContext, lastNext);
|
|
97
111
|
if (response.headers.get(ROUTE_TYPE_HEADER)) {
|
|
@@ -159,6 +173,7 @@ class RenderContext {
|
|
|
159
173
|
}
|
|
160
174
|
};
|
|
161
175
|
const result = {
|
|
176
|
+
cancelled: false,
|
|
162
177
|
clientDirectives,
|
|
163
178
|
inlinedScripts,
|
|
164
179
|
componentMetadata,
|
|
@@ -240,7 +240,7 @@ function createFileBasedRoutes({ settings, cwd, fsMod }, logger) {
|
|
|
240
240
|
const pattern = getPattern(segments, settings.config, trailingSlash);
|
|
241
241
|
const generate = getRouteGenerator(segments, trailingSlash);
|
|
242
242
|
const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) ? `/${segments.map((segment) => segment[0].content).join("/")}` : null;
|
|
243
|
-
const route =
|
|
243
|
+
const route = joinSegments(segments);
|
|
244
244
|
routes.push({
|
|
245
245
|
route,
|
|
246
246
|
isIndex: item.isIndex,
|
|
@@ -295,7 +295,7 @@ function createInjectedRoutes({ settings, cwd }) {
|
|
|
295
295
|
const generate = getRouteGenerator(segments, trailingSlash);
|
|
296
296
|
const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) ? `/${segments.map((segment) => segment[0].content).join("/")}` : null;
|
|
297
297
|
const params = segments.flat().filter((p) => p.dynamic).map((p) => p.content);
|
|
298
|
-
const route =
|
|
298
|
+
const route = joinSegments(segments);
|
|
299
299
|
routes[priority].push({
|
|
300
300
|
type,
|
|
301
301
|
// For backwards compatibility, an injected route is never considered an index route.
|
|
@@ -330,7 +330,7 @@ function createRedirectRoutes({ settings }, routeMap, logger) {
|
|
|
330
330
|
const generate = getRouteGenerator(segments, trailingSlash);
|
|
331
331
|
const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) ? `/${segments.map((segment) => segment[0].content).join("/")}` : null;
|
|
332
332
|
const params = segments.flat().filter((p) => p.dynamic).map((p) => p.content);
|
|
333
|
-
const route =
|
|
333
|
+
const route = joinSegments(segments);
|
|
334
334
|
let destination;
|
|
335
335
|
if (typeof to === "string") {
|
|
336
336
|
destination = to;
|
|
@@ -577,6 +577,12 @@ function computeRoutePriority(config) {
|
|
|
577
577
|
}
|
|
578
578
|
return "legacy";
|
|
579
579
|
}
|
|
580
|
+
function joinSegments(segments) {
|
|
581
|
+
const arr = segments.map((segment) => {
|
|
582
|
+
return segment.map((rp) => rp.dynamic ? `[${rp.content}]` : rp.content).join("");
|
|
583
|
+
});
|
|
584
|
+
return `/${arr.join("/")}`.toLowerCase();
|
|
585
|
+
}
|
|
580
586
|
export {
|
|
581
587
|
createRouteManifest
|
|
582
588
|
};
|
package/dist/core/sync/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { performance } from "node:perf_hooks";
|
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { dim } from "kleur/colors";
|
|
5
5
|
import { createServer } from "vite";
|
|
6
|
+
import { getPackage } from "../../cli/install-package.js";
|
|
6
7
|
import { createContentTypesGenerator } from "../../content/index.js";
|
|
7
8
|
import { globalContentConfigObserver } from "../../content/utils.js";
|
|
8
9
|
import { telemetry } from "../../events/index.js";
|
|
@@ -29,8 +30,23 @@ async function sync(inlineConfig, options) {
|
|
|
29
30
|
logger,
|
|
30
31
|
command: "build"
|
|
31
32
|
});
|
|
33
|
+
const timerStart = performance.now();
|
|
34
|
+
const dbPackage = await getPackage(
|
|
35
|
+
"@astrojs/db",
|
|
36
|
+
logger,
|
|
37
|
+
{
|
|
38
|
+
optional: true,
|
|
39
|
+
cwd: inlineConfig.root
|
|
40
|
+
},
|
|
41
|
+
[]
|
|
42
|
+
);
|
|
32
43
|
try {
|
|
33
|
-
|
|
44
|
+
await dbPackage?.typegen?.(astroConfig);
|
|
45
|
+
const exitCode = await syncContentCollections(settings, { ...options, logger });
|
|
46
|
+
if (exitCode !== 0)
|
|
47
|
+
return exitCode;
|
|
48
|
+
logger.info(null, `Types generated ${dim(getTimeStat(timerStart, performance.now()))}`);
|
|
49
|
+
return 0;
|
|
34
50
|
} catch (err) {
|
|
35
51
|
const error = createSafeError(err);
|
|
36
52
|
logger.error(
|
|
@@ -40,8 +56,7 @@ async function sync(inlineConfig, options) {
|
|
|
40
56
|
return 1;
|
|
41
57
|
}
|
|
42
58
|
}
|
|
43
|
-
async function
|
|
44
|
-
const timerStart = performance.now();
|
|
59
|
+
async function syncContentCollections(settings, { logger, fs }) {
|
|
45
60
|
const tempViteServer = await createServer(
|
|
46
61
|
await createVite(
|
|
47
62
|
{
|
|
@@ -96,11 +111,10 @@ async function syncInternal(settings, { logger, fs }) {
|
|
|
96
111
|
} finally {
|
|
97
112
|
await tempViteServer.close();
|
|
98
113
|
}
|
|
99
|
-
logger.info(null, `Types generated ${dim(getTimeStat(timerStart, performance.now()))}`);
|
|
100
114
|
await setUpEnvTs({ settings, logger, fs: fs ?? fsMod });
|
|
101
115
|
return 0;
|
|
102
116
|
}
|
|
103
117
|
export {
|
|
104
118
|
sync as default,
|
|
105
|
-
|
|
119
|
+
syncContentCollections
|
|
106
120
|
};
|
|
@@ -11,6 +11,7 @@ try {
|
|
|
11
11
|
customElements.define("astro-dev-toolbar-audit-list-item", DevToolbarAuditListItem);
|
|
12
12
|
} catch (e) {
|
|
13
13
|
}
|
|
14
|
+
let showState = false;
|
|
14
15
|
var audit_default = {
|
|
15
16
|
id: "astro:audit",
|
|
16
17
|
name: "Audit",
|
|
@@ -33,13 +34,19 @@ var audit_default = {
|
|
|
33
34
|
if ("requestIdleCallback" in window) {
|
|
34
35
|
window.requestIdleCallback(
|
|
35
36
|
async () => {
|
|
36
|
-
lint()
|
|
37
|
+
lint().then(() => {
|
|
38
|
+
if (showState)
|
|
39
|
+
createAuditsUI();
|
|
40
|
+
});
|
|
37
41
|
},
|
|
38
42
|
{ timeout: 300 }
|
|
39
43
|
);
|
|
40
44
|
} else {
|
|
41
|
-
setTimeout(() => {
|
|
42
|
-
lint()
|
|
45
|
+
setTimeout(async () => {
|
|
46
|
+
lint().then(() => {
|
|
47
|
+
if (showState)
|
|
48
|
+
createAuditsUI();
|
|
49
|
+
});
|
|
43
50
|
}, 150);
|
|
44
51
|
}
|
|
45
52
|
}, 250);
|
|
@@ -59,7 +66,10 @@ var audit_default = {
|
|
|
59
66
|
});
|
|
60
67
|
eventTarget.addEventListener("app-toggled", (event) => {
|
|
61
68
|
if (event.detail.state === true) {
|
|
69
|
+
showState = true;
|
|
62
70
|
createAuditsUI();
|
|
71
|
+
} else {
|
|
72
|
+
showState = false;
|
|
63
73
|
}
|
|
64
74
|
});
|
|
65
75
|
closeOnOutsideClick(eventTarget, () => {
|
|
@@ -68,6 +68,7 @@ class DevToolbarAuditListItem extends HTMLElement {
|
|
|
68
68
|
border: none;
|
|
69
69
|
z-index: 1000000000;
|
|
70
70
|
flex-direction: column;
|
|
71
|
+
line-height: 1.25rem;
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
:host([active])>button#astro-overlay-card {
|
|
@@ -104,6 +105,12 @@ class DevToolbarAuditListItem extends HTMLElement {
|
|
|
104
105
|
color: rgba(191, 193, 201, 1);
|
|
105
106
|
}
|
|
106
107
|
|
|
108
|
+
.extended-info code {
|
|
109
|
+
padding: 1px 3px;
|
|
110
|
+
border-radius: 3px;
|
|
111
|
+
background: #1F2433;
|
|
112
|
+
}
|
|
113
|
+
|
|
107
114
|
.reset-button {
|
|
108
115
|
text-align: left;
|
|
109
116
|
border: none;
|
|
@@ -109,18 +109,24 @@ function buildAuditCard(rule, highlightElement, auditedElement, audits) {
|
|
|
109
109
|
extendedInfo.append(document.createElement("hr"));
|
|
110
110
|
const message = document.createElement("p");
|
|
111
111
|
message.classList.add("audit-message");
|
|
112
|
-
message.innerHTML = rule.message;
|
|
112
|
+
message.innerHTML = simpleRenderMarkdown(rule.message);
|
|
113
113
|
extendedInfo.appendChild(message);
|
|
114
114
|
const description = rule.description;
|
|
115
115
|
if (description) {
|
|
116
116
|
const descriptionElement = document.createElement("p");
|
|
117
117
|
descriptionElement.classList.add("audit-description");
|
|
118
|
-
descriptionElement.innerHTML = description;
|
|
118
|
+
descriptionElement.innerHTML = simpleRenderMarkdown(description);
|
|
119
119
|
extendedInfo.appendChild(descriptionElement);
|
|
120
120
|
}
|
|
121
121
|
card.shadowRoot.appendChild(extendedInfo);
|
|
122
122
|
return card;
|
|
123
123
|
}
|
|
124
|
+
const linkRegex = /\[([^[]+)\]\((.*)\)/g;
|
|
125
|
+
const boldRegex = /\*\*(.+)\*\*/g;
|
|
126
|
+
const codeRegex = /`([^`]+)`/g;
|
|
127
|
+
function simpleRenderMarkdown(markdown) {
|
|
128
|
+
return escapeHTML(markdown).replace(linkRegex, `<a href="$2" target="_blank">$1</a>`).replace(boldRegex, "<b>$1</b>").replace(codeRegex, "<code>$1</code>");
|
|
129
|
+
}
|
|
124
130
|
export {
|
|
125
131
|
createAuditUI
|
|
126
132
|
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { bold } from "kleur/colors";
|
|
2
2
|
import { REROUTABLE_STATUS_CODES, REROUTE_DIRECTIVE_HEADER } from "../../core/constants.js";
|
|
3
|
+
import { EndpointDidNotReturnAResponse } from "../../core/errors/errors-data.js";
|
|
4
|
+
import { AstroError } from "../../core/errors/errors.js";
|
|
3
5
|
async function renderEndpoint(mod, context, ssr, logger) {
|
|
4
6
|
const { request, url } = context;
|
|
5
7
|
const method = request.method.toUpperCase();
|
|
@@ -30,6 +32,9 @@ Found handlers: ${Object.keys(mod).map((exp) => JSON.stringify(exp)).join(", ")}
|
|
|
30
32
|
return new Response(null, { status: 500 });
|
|
31
33
|
}
|
|
32
34
|
const response = await handler.call(mod, context);
|
|
35
|
+
if (!response || response instanceof Response === false) {
|
|
36
|
+
throw new AstroError(EndpointDidNotReturnAResponse);
|
|
37
|
+
}
|
|
33
38
|
if (REROUTABLE_STATUS_CODES.includes(response.status)) {
|
|
34
39
|
response.headers.set(REROUTE_DIRECTIVE_HEADER, "no");
|
|
35
40
|
}
|
|
@@ -80,6 +80,9 @@ async function renderToReadableStream(result, componentFactory, props, children,
|
|
|
80
80
|
setTimeout(() => controller.error(e), 0);
|
|
81
81
|
}
|
|
82
82
|
})();
|
|
83
|
+
},
|
|
84
|
+
cancel() {
|
|
85
|
+
result.cancelled = true;
|
|
83
86
|
}
|
|
84
87
|
});
|
|
85
88
|
}
|
|
@@ -127,11 +130,10 @@ async function renderToAsyncIterable(result, componentFactory, props, children,
|
|
|
127
130
|
}
|
|
128
131
|
let error = null;
|
|
129
132
|
let next = promiseWithResolvers();
|
|
130
|
-
let cancelled = false;
|
|
131
133
|
const buffer = [];
|
|
132
134
|
const iterator = {
|
|
133
135
|
async next() {
|
|
134
|
-
if (cancelled)
|
|
136
|
+
if (result.cancelled)
|
|
135
137
|
return { done: true, value: void 0 };
|
|
136
138
|
await next.promise;
|
|
137
139
|
if (error) {
|
|
@@ -157,7 +159,7 @@ async function renderToAsyncIterable(result, componentFactory, props, children,
|
|
|
157
159
|
return returnValue;
|
|
158
160
|
},
|
|
159
161
|
async return() {
|
|
160
|
-
cancelled = true;
|
|
162
|
+
result.cancelled = true;
|
|
161
163
|
return { done: true, value: void 0 };
|
|
162
164
|
}
|
|
163
165
|
};
|
|
@@ -345,19 +345,27 @@ function renderAstroComponent(result, displayName, Component, props, slots = {})
|
|
|
345
345
|
}
|
|
346
346
|
async function renderComponent(result, displayName, Component, props, slots = {}) {
|
|
347
347
|
if (isPromise(Component)) {
|
|
348
|
-
Component = await Component;
|
|
348
|
+
Component = await Component.catch(handleCancellation);
|
|
349
349
|
}
|
|
350
350
|
if (isFragmentComponent(Component)) {
|
|
351
|
-
return await renderFragmentComponent(result, slots);
|
|
351
|
+
return await renderFragmentComponent(result, slots).catch(handleCancellation);
|
|
352
352
|
}
|
|
353
353
|
props = normalizeProps(props);
|
|
354
354
|
if (isHTMLComponent(Component)) {
|
|
355
|
-
return await renderHTMLComponent(result, Component, props, slots);
|
|
355
|
+
return await renderHTMLComponent(result, Component, props, slots).catch(handleCancellation);
|
|
356
356
|
}
|
|
357
357
|
if (isAstroComponentFactory(Component)) {
|
|
358
358
|
return renderAstroComponent(result, displayName, Component, props, slots);
|
|
359
359
|
}
|
|
360
|
-
return await renderFrameworkComponent(result, displayName, Component, props, slots)
|
|
360
|
+
return await renderFrameworkComponent(result, displayName, Component, props, slots).catch(
|
|
361
|
+
handleCancellation
|
|
362
|
+
);
|
|
363
|
+
function handleCancellation(e) {
|
|
364
|
+
if (result.cancelled)
|
|
365
|
+
return { render() {
|
|
366
|
+
} };
|
|
367
|
+
throw e;
|
|
368
|
+
}
|
|
361
369
|
}
|
|
362
370
|
function normalizeProps(props) {
|
|
363
371
|
if (props["class:list"] !== void 0) {
|
|
@@ -405,7 +405,7 @@ function onPopState(ev) {
|
|
|
405
405
|
transition(direction, originalLocation, new URL(location.href), {}, state);
|
|
406
406
|
}
|
|
407
407
|
const onScrollEnd = () => {
|
|
408
|
-
if (scrollX !== history.state.scrollX || scrollY !== history.state.scrollY) {
|
|
408
|
+
if (history.state && (scrollX !== history.state.scrollX || scrollY !== history.state.scrollY)) {
|
|
409
409
|
updateScrollPosition({ scrollX, scrollY });
|
|
410
410
|
}
|
|
411
411
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "4.5.
|
|
3
|
+
"version": "4.5.6",
|
|
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",
|
|
@@ -162,8 +162,8 @@
|
|
|
162
162
|
"zod": "^3.22.4",
|
|
163
163
|
"zod-to-json-schema": "^3.22.4",
|
|
164
164
|
"@astrojs/internal-helpers": "0.3.0",
|
|
165
|
-
"@astrojs/
|
|
166
|
-
"@astrojs/
|
|
165
|
+
"@astrojs/telemetry": "3.0.4",
|
|
166
|
+
"@astrojs/markdown-remark": "4.3.0"
|
|
167
167
|
},
|
|
168
168
|
"optionalDependencies": {
|
|
169
169
|
"sharp": "^0.32.6"
|