astro 4.12.2 → 4.12.3
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 +6 -4
- package/dist/actions/consts.d.ts +3 -0
- package/dist/actions/consts.js +6 -0
- package/dist/actions/index.d.ts +12 -2
- package/dist/actions/index.js +43 -7
- package/dist/actions/runtime/middleware.js +80 -23
- package/dist/actions/runtime/route.js +2 -3
- package/dist/actions/runtime/utils.d.ts +4 -2
- package/dist/actions/runtime/utils.js +1 -1
- package/dist/actions/runtime/virtual/server.d.ts +6 -5
- package/dist/actions/runtime/virtual/server.js +6 -5
- package/dist/actions/runtime/virtual/shared.d.ts +7 -0
- package/dist/actions/runtime/virtual/shared.js +11 -1
- package/dist/cli/add/index.js +1 -1
- package/dist/content/vite-plugin-content-assets.js +0 -14
- package/dist/core/build/generate.js +1 -1
- package/dist/core/build/pipeline.js +0 -1
- package/dist/core/build/plugins/plugin-content.js +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/errors/dev/utils.js +12 -3
- package/dist/core/errors/dev/vite.d.ts +13 -0
- package/dist/core/errors/dev/vite.js +18 -4
- package/dist/core/errors/errors-data.d.ts +26 -0
- package/dist/core/errors/errors-data.js +14 -0
- package/dist/core/messages.js +2 -2
- package/dist/core/render-context.js +2 -0
- package/dist/env/runtime.d.ts +2 -2
- package/dist/env/runtime.js +1 -1
- package/dist/integrations/hooks.js +1 -1
- package/dist/runtime/client/dev-toolbar/apps/audit/rules/a11y.js +0 -14
- package/dist/runtime/server/render/astro/instance.d.ts +2 -2
- package/dist/runtime/server/render/server-islands.js +2 -1
- package/dist/transitions/router.js +0 -8
- package/dist/vite-plugin-astro-server/error.js +1 -2
- package/dist/vite-plugin-astro-server/route.js +0 -1
- package/dist/vite-plugin-astro-server/vite.js +4 -0
- package/package.json +7 -7
- package/templates/actions.mjs +29 -32
- package/templates/env/module.mjs +2 -0
package/dist/@types/astro.d.ts
CHANGED
|
@@ -182,7 +182,7 @@ export interface AstroGlobal<Props extends Record<string, any> = Record<string,
|
|
|
182
182
|
* ```
|
|
183
183
|
*/
|
|
184
184
|
getActionResult: AstroSharedContext['getActionResult'];
|
|
185
|
-
/** Redirect to another page
|
|
185
|
+
/** Redirect to another page
|
|
186
186
|
*
|
|
187
187
|
* Example usage:
|
|
188
188
|
* ```typescript
|
|
@@ -191,7 +191,7 @@ export interface AstroGlobal<Props extends Record<string, any> = Record<string,
|
|
|
191
191
|
* }
|
|
192
192
|
* ```
|
|
193
193
|
*
|
|
194
|
-
* [Astro reference](https://docs.astro.build/en/
|
|
194
|
+
* [Astro reference](https://docs.astro.build/en/reference/api-reference/#astroredirect)
|
|
195
195
|
*/
|
|
196
196
|
redirect: AstroSharedContext['redirect'];
|
|
197
197
|
/**
|
|
@@ -2482,7 +2482,7 @@ export interface Page<T = any> {
|
|
|
2482
2482
|
total: number;
|
|
2483
2483
|
/** the current page number, starting from 1 */
|
|
2484
2484
|
currentPage: number;
|
|
2485
|
-
/** number of items per page (default:
|
|
2485
|
+
/** number of items per page (default: 10) */
|
|
2486
2486
|
size: number;
|
|
2487
2487
|
/** number of last page */
|
|
2488
2488
|
lastPage: number;
|
|
@@ -2593,7 +2593,7 @@ interface AstroSharedContext<Props extends Record<string, any> = Record<string,
|
|
|
2593
2593
|
/**
|
|
2594
2594
|
* Get action result on the server when using a form POST.
|
|
2595
2595
|
*/
|
|
2596
|
-
getActionResult: <TAccept extends ActionAccept, TInputSchema extends ActionInputSchema<TAccept>, TAction extends ActionClient<unknown, TAccept, TInputSchema>>(action: TAction) => Awaited<ReturnType<TAction
|
|
2596
|
+
getActionResult: <TAccept extends ActionAccept, TInputSchema extends ActionInputSchema<TAccept>, TAction extends ActionClient<unknown, TAccept, TInputSchema>>(action: TAction) => Awaited<ReturnType<TAction>> | undefined;
|
|
2597
2597
|
/**
|
|
2598
2598
|
* Route parameters for this request if this is a dynamic route.
|
|
2599
2599
|
*/
|
|
@@ -3013,6 +3013,7 @@ export interface SSRResult {
|
|
|
3013
3013
|
* Whether the page has failed with a non-recoverable error, or the client disconnected.
|
|
3014
3014
|
*/
|
|
3015
3015
|
cancelled: boolean;
|
|
3016
|
+
base: string;
|
|
3016
3017
|
styles: Set<SSRElement>;
|
|
3017
3018
|
scripts: Set<SSRElement>;
|
|
3018
3019
|
links: Set<SSRElement>;
|
|
@@ -3037,6 +3038,7 @@ export interface SSRResult {
|
|
|
3037
3038
|
pathname: string;
|
|
3038
3039
|
cookies: AstroCookies | undefined;
|
|
3039
3040
|
serverIslandNameMap: Map<string, string>;
|
|
3041
|
+
trailingSlash: AstroConfig['trailingSlash'];
|
|
3040
3042
|
_metadata: SSRMetadata;
|
|
3041
3043
|
}
|
|
3042
3044
|
/**
|
package/dist/actions/consts.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export declare const VIRTUAL_MODULE_ID = "astro:actions";
|
|
2
2
|
export declare const RESOLVED_VIRTUAL_MODULE_ID: string;
|
|
3
3
|
export declare const ACTIONS_TYPES_FILE = "actions.d.ts";
|
|
4
|
+
export declare const VIRTUAL_INTERNAL_MODULE_ID = "astro:internal-actions";
|
|
5
|
+
export declare const RESOLVED_VIRTUAL_INTERNAL_MODULE_ID = "\0astro:internal-actions";
|
|
6
|
+
export declare const NOOP_ACTIONS = "\0noop-actions";
|
package/dist/actions/consts.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
const VIRTUAL_MODULE_ID = "astro:actions";
|
|
2
2
|
const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
|
|
3
3
|
const ACTIONS_TYPES_FILE = "actions.d.ts";
|
|
4
|
+
const VIRTUAL_INTERNAL_MODULE_ID = "astro:internal-actions";
|
|
5
|
+
const RESOLVED_VIRTUAL_INTERNAL_MODULE_ID = "\0astro:internal-actions";
|
|
6
|
+
const NOOP_ACTIONS = "\0noop-actions";
|
|
4
7
|
export {
|
|
5
8
|
ACTIONS_TYPES_FILE,
|
|
9
|
+
NOOP_ACTIONS,
|
|
10
|
+
RESOLVED_VIRTUAL_INTERNAL_MODULE_ID,
|
|
6
11
|
RESOLVED_VIRTUAL_MODULE_ID,
|
|
12
|
+
VIRTUAL_INTERNAL_MODULE_ID,
|
|
7
13
|
VIRTUAL_MODULE_ID
|
|
8
14
|
};
|
package/dist/actions/index.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import fsMod from 'node:fs';
|
|
2
|
-
import type {
|
|
3
|
-
|
|
2
|
+
import type { Plugin as VitePlugin } from 'vite';
|
|
3
|
+
import type { AstroIntegration, AstroSettings } from '../@types/astro.js';
|
|
4
|
+
export default function astroActions({ fs, settings, }: {
|
|
4
5
|
fs?: typeof fsMod;
|
|
6
|
+
settings: AstroSettings;
|
|
5
7
|
}): AstroIntegration;
|
|
8
|
+
/**
|
|
9
|
+
* This plugin is responsible to load the known file `actions/index.js` / `actions.js`
|
|
10
|
+
* If the file doesn't exist, it returns an empty object.
|
|
11
|
+
* @param settings
|
|
12
|
+
*/
|
|
13
|
+
export declare function vitePluginUserActions({ settings }: {
|
|
14
|
+
settings: AstroSettings;
|
|
15
|
+
}): VitePlugin;
|
package/dist/actions/index.js
CHANGED
|
@@ -2,8 +2,18 @@ import fsMod from "node:fs";
|
|
|
2
2
|
import { ActionsWithoutServerOutputError } from "../core/errors/errors-data.js";
|
|
3
3
|
import { AstroError } from "../core/errors/errors.js";
|
|
4
4
|
import { isServerLikeOutput, viteID } from "../core/util.js";
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import {
|
|
6
|
+
ACTIONS_TYPES_FILE,
|
|
7
|
+
NOOP_ACTIONS,
|
|
8
|
+
RESOLVED_VIRTUAL_INTERNAL_MODULE_ID,
|
|
9
|
+
RESOLVED_VIRTUAL_MODULE_ID,
|
|
10
|
+
VIRTUAL_INTERNAL_MODULE_ID,
|
|
11
|
+
VIRTUAL_MODULE_ID
|
|
12
|
+
} from "./consts.js";
|
|
13
|
+
function astroActions({
|
|
14
|
+
fs = fsMod,
|
|
15
|
+
settings
|
|
16
|
+
}) {
|
|
7
17
|
return {
|
|
8
18
|
name: VIRTUAL_MODULE_ID,
|
|
9
19
|
hooks: {
|
|
@@ -18,10 +28,7 @@ function astroActions({ fs = fsMod }) {
|
|
|
18
28
|
);
|
|
19
29
|
params.updateConfig({
|
|
20
30
|
vite: {
|
|
21
|
-
|
|
22
|
-
"import.meta.env.ACTIONS_PATH": stringifiedActionsImport
|
|
23
|
-
},
|
|
24
|
-
plugins: [vitePluginActions(fs)]
|
|
31
|
+
plugins: [vitePluginUserActions({ settings }), vitePluginActions(fs)]
|
|
25
32
|
}
|
|
26
33
|
});
|
|
27
34
|
params.injectRoute({
|
|
@@ -42,6 +49,34 @@ function astroActions({ fs = fsMod }) {
|
|
|
42
49
|
}
|
|
43
50
|
};
|
|
44
51
|
}
|
|
52
|
+
function vitePluginUserActions({ settings }) {
|
|
53
|
+
let resolvedActionsId;
|
|
54
|
+
return {
|
|
55
|
+
name: "@astro/plugin-actions",
|
|
56
|
+
async resolveId(id) {
|
|
57
|
+
if (id === NOOP_ACTIONS) {
|
|
58
|
+
return NOOP_ACTIONS;
|
|
59
|
+
}
|
|
60
|
+
if (id === VIRTUAL_INTERNAL_MODULE_ID) {
|
|
61
|
+
const resolvedModule = await this.resolve(
|
|
62
|
+
`${decodeURI(new URL("actions", settings.config.srcDir).pathname)}`
|
|
63
|
+
);
|
|
64
|
+
if (!resolvedModule) {
|
|
65
|
+
return NOOP_ACTIONS;
|
|
66
|
+
}
|
|
67
|
+
resolvedActionsId = resolvedModule.id;
|
|
68
|
+
return RESOLVED_VIRTUAL_INTERNAL_MODULE_ID;
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
load(id) {
|
|
72
|
+
if (id === NOOP_ACTIONS) {
|
|
73
|
+
return "export const server = {}";
|
|
74
|
+
} else if (id === RESOLVED_VIRTUAL_INTERNAL_MODULE_ID) {
|
|
75
|
+
return `export { server } from '${resolvedActionsId}';`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
45
80
|
const vitePluginActions = (fs) => ({
|
|
46
81
|
name: VIRTUAL_MODULE_ID,
|
|
47
82
|
enforce: "pre",
|
|
@@ -81,5 +116,6 @@ async function typegen({
|
|
|
81
116
|
await fs.promises.writeFile(new URL(ACTIONS_TYPES_FILE, dotAstroDir), content);
|
|
82
117
|
}
|
|
83
118
|
export {
|
|
84
|
-
astroActions as default
|
|
119
|
+
astroActions as default,
|
|
120
|
+
vitePluginUserActions
|
|
85
121
|
};
|
|
@@ -1,49 +1,106 @@
|
|
|
1
1
|
import { yellow } from "kleur/colors";
|
|
2
|
+
import {
|
|
3
|
+
ActionQueryStringInvalidError,
|
|
4
|
+
ActionsUsedWithForGetError
|
|
5
|
+
} from "../../core/errors/errors-data.js";
|
|
6
|
+
import { AstroError } from "../../core/errors/errors.js";
|
|
2
7
|
import { defineMiddleware } from "../../core/middleware/index.js";
|
|
3
8
|
import { ApiContextStorage } from "./store.js";
|
|
4
9
|
import { formContentTypes, getAction, hasContentType } from "./utils.js";
|
|
5
|
-
import {
|
|
10
|
+
import { getActionQueryString } from "./virtual/shared.js";
|
|
6
11
|
const onRequest = defineMiddleware(async (context, next) => {
|
|
7
12
|
const locals = context.locals;
|
|
13
|
+
const { request } = context;
|
|
8
14
|
if (locals._actionsInternal) return ApiContextStorage.run(context, () => next());
|
|
9
|
-
if (
|
|
10
|
-
return nextWithLocalsStub(next, context);
|
|
11
|
-
}
|
|
12
|
-
if (context.request.method === "POST" && context.request.body === null) {
|
|
15
|
+
if (request.method === "POST" && request.body === null) {
|
|
13
16
|
return nextWithStaticStub(next, context);
|
|
14
17
|
}
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const actionName = context.url.searchParams.get("_astroAction");
|
|
19
|
+
if (context.request.method === "POST" && actionName) {
|
|
20
|
+
return handlePost({ context, next, actionName });
|
|
21
|
+
}
|
|
22
|
+
if (context.request.method === "GET" && actionName) {
|
|
23
|
+
throw new AstroError({
|
|
24
|
+
...ActionsUsedWithForGetError,
|
|
25
|
+
message: ActionsUsedWithForGetError.message(actionName)
|
|
26
|
+
});
|
|
20
27
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
if (context.request.method === "POST") {
|
|
29
|
+
return handlePostLegacy({ context, next });
|
|
30
|
+
}
|
|
31
|
+
return nextWithLocalsStub(next, context);
|
|
32
|
+
});
|
|
33
|
+
async function handlePost({
|
|
34
|
+
context,
|
|
35
|
+
next,
|
|
36
|
+
actionName
|
|
37
|
+
}) {
|
|
38
|
+
const { request } = context;
|
|
39
|
+
const action = await getAction(actionName);
|
|
40
|
+
if (!action) {
|
|
41
|
+
throw new AstroError({
|
|
42
|
+
...ActionQueryStringInvalidError,
|
|
43
|
+
message: ActionQueryStringInvalidError.message(actionName)
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const contentType = request.headers.get("content-type");
|
|
47
|
+
let formData;
|
|
48
|
+
if (contentType && hasContentType(contentType, formContentTypes)) {
|
|
49
|
+
formData = await request.clone().formData();
|
|
50
|
+
}
|
|
51
|
+
const actionResult = await ApiContextStorage.run(context, () => action(formData));
|
|
52
|
+
return handleResult({ context, next, actionName, actionResult });
|
|
53
|
+
}
|
|
54
|
+
function handleResult({
|
|
55
|
+
context,
|
|
56
|
+
next,
|
|
57
|
+
actionName,
|
|
58
|
+
actionResult
|
|
59
|
+
}) {
|
|
27
60
|
const actionsInternal = {
|
|
28
61
|
getActionResult: (actionFn) => {
|
|
29
|
-
if (actionFn.toString() !==
|
|
30
|
-
|
|
62
|
+
if (actionFn.toString() !== getActionQueryString(actionName)) {
|
|
63
|
+
return Promise.resolve(void 0);
|
|
64
|
+
}
|
|
65
|
+
return actionResult;
|
|
31
66
|
},
|
|
32
|
-
actionResult
|
|
67
|
+
actionResult
|
|
33
68
|
};
|
|
69
|
+
const locals = context.locals;
|
|
34
70
|
Object.defineProperty(locals, "_actionsInternal", { writable: false, value: actionsInternal });
|
|
35
71
|
return ApiContextStorage.run(context, async () => {
|
|
36
72
|
const response = await next();
|
|
37
|
-
if (
|
|
73
|
+
if (actionResult.error) {
|
|
38
74
|
return new Response(response.body, {
|
|
39
|
-
status:
|
|
40
|
-
statusText:
|
|
75
|
+
status: actionResult.error.status,
|
|
76
|
+
statusText: actionResult.error.type,
|
|
41
77
|
headers: response.headers
|
|
42
78
|
});
|
|
43
79
|
}
|
|
44
80
|
return response;
|
|
45
81
|
});
|
|
46
|
-
}
|
|
82
|
+
}
|
|
83
|
+
async function handlePostLegacy({ context, next }) {
|
|
84
|
+
const { request } = context;
|
|
85
|
+
if (context.url.pathname.startsWith("/_actions")) return nextWithLocalsStub(next, context);
|
|
86
|
+
const contentType = request.headers.get("content-type");
|
|
87
|
+
let formData;
|
|
88
|
+
if (contentType && hasContentType(contentType, formContentTypes)) {
|
|
89
|
+
formData = await request.clone().formData();
|
|
90
|
+
}
|
|
91
|
+
if (!formData) return nextWithLocalsStub(next, context);
|
|
92
|
+
const actionName = formData.get("_astroAction");
|
|
93
|
+
if (!actionName) return nextWithLocalsStub(next, context);
|
|
94
|
+
const action = await getAction(actionName);
|
|
95
|
+
if (!action) {
|
|
96
|
+
throw new AstroError({
|
|
97
|
+
...ActionQueryStringInvalidError,
|
|
98
|
+
message: ActionQueryStringInvalidError.message(actionName)
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
const actionResult = await ApiContextStorage.run(context, () => action(formData));
|
|
102
|
+
return handleResult({ context, next, actionName, actionResult });
|
|
103
|
+
}
|
|
47
104
|
function nextWithStaticStub(next, context) {
|
|
48
105
|
Object.defineProperty(context.locals, "_actionsInternal", {
|
|
49
106
|
writable: false,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ApiContextStorage } from "./store.js";
|
|
2
2
|
import { formContentTypes, getAction, hasContentType } from "./utils.js";
|
|
3
|
-
import { callSafely } from "./virtual/shared.js";
|
|
4
3
|
const POST = async (context) => {
|
|
5
4
|
const { request, url } = context;
|
|
6
5
|
const action = await getAction(url.pathname);
|
|
@@ -19,7 +18,7 @@ const POST = async (context) => {
|
|
|
19
18
|
} else {
|
|
20
19
|
return new Response(null, { status: 415 });
|
|
21
20
|
}
|
|
22
|
-
const result = await ApiContextStorage.run(context, () =>
|
|
21
|
+
const result = await ApiContextStorage.run(context, () => action(args));
|
|
23
22
|
if (result.error) {
|
|
24
23
|
return new Response(
|
|
25
24
|
JSON.stringify({
|
|
@@ -36,7 +35,7 @@ const POST = async (context) => {
|
|
|
36
35
|
);
|
|
37
36
|
}
|
|
38
37
|
return new Response(JSON.stringify(result.data), {
|
|
39
|
-
status: result.data ? 200 : 204,
|
|
38
|
+
status: result.data !== void 0 ? 200 : 204,
|
|
40
39
|
headers: {
|
|
41
40
|
"Content-Type": "application/json"
|
|
42
41
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import type { ZodType } from 'zod';
|
|
2
|
+
import type { ActionAccept, ActionClient } from './virtual/server.js';
|
|
1
3
|
export declare const formContentTypes: string[];
|
|
2
4
|
export declare function hasContentType(contentType: string, expected: string[]): boolean;
|
|
3
5
|
export type MaybePromise<T> = T | Promise<T>;
|
|
4
6
|
/**
|
|
5
7
|
* Get server-side action based on the route path.
|
|
6
|
-
* Imports from `
|
|
8
|
+
* Imports from the virtual module `astro:internal-actions`, which maps to
|
|
7
9
|
* the user's `src/actions/index.ts` file at build-time.
|
|
8
10
|
*/
|
|
9
|
-
export declare function getAction(path: string): Promise<
|
|
11
|
+
export declare function getAction(path: string): Promise<ActionClient<unknown, ActionAccept, ZodType> | undefined>;
|
|
10
12
|
/**
|
|
11
13
|
* Used to preserve the input schema type in the error object.
|
|
12
14
|
* This allows for type inference on the `fields` property
|
|
@@ -5,7 +5,7 @@ function hasContentType(contentType, expected) {
|
|
|
5
5
|
}
|
|
6
6
|
async function getAction(path) {
|
|
7
7
|
const pathKeys = path.replace("/_actions/", "").split(".");
|
|
8
|
-
let { server: actionLookup } = await import(
|
|
8
|
+
let { server: actionLookup } = await import("astro:internal-actions");
|
|
9
9
|
for (const key of pathKeys) {
|
|
10
10
|
if (!(key in actionLookup)) {
|
|
11
11
|
return void 0;
|
|
@@ -10,15 +10,16 @@ export type ActionAccept = 'form' | 'json';
|
|
|
10
10
|
export type ActionInputSchema<T extends ActionAccept | undefined> = T extends 'form' ? z.AnyZodObject | z.ZodType<FormData> : z.ZodType;
|
|
11
11
|
export type ActionHandler<TInputSchema, TOutput> = TInputSchema extends z.ZodType ? (input: z.infer<TInputSchema>, context: ActionAPIContext) => MaybePromise<TOutput> : (input: any, context: ActionAPIContext) => MaybePromise<TOutput>;
|
|
12
12
|
export type ActionReturnType<T extends ActionHandler<any, any>> = Awaited<ReturnType<T>>;
|
|
13
|
-
export type ActionClient<TOutput, TAccept extends ActionAccept | undefined, TInputSchema extends ActionInputSchema<TAccept> | undefined> = TInputSchema extends z.ZodType ? ((input: TAccept extends 'form' ? FormData : z.input<TInputSchema>) => Promise<Awaited<TOutput
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
export type ActionClient<TOutput, TAccept extends ActionAccept | undefined, TInputSchema extends ActionInputSchema<TAccept> | undefined> = TInputSchema extends z.ZodType ? ((input: TAccept extends 'form' ? FormData : z.input<TInputSchema>) => Promise<SafeResult<z.input<TInputSchema> extends ErrorInferenceObject ? z.input<TInputSchema> : ErrorInferenceObject, Awaited<TOutput>>>) & {
|
|
14
|
+
queryString: string;
|
|
15
|
+
orThrow: (input: TAccept extends 'form' ? FormData : z.input<TInputSchema>) => Promise<Awaited<TOutput>>;
|
|
16
|
+
} : (input?: any) => Promise<SafeResult<never, Awaited<TOutput>>> & {
|
|
17
|
+
orThrow: (input?: any) => Promise<Awaited<TOutput>>;
|
|
17
18
|
};
|
|
18
19
|
export declare function defineAction<TOutput, TAccept extends ActionAccept | undefined = undefined, TInputSchema extends ActionInputSchema<ActionAccept> | undefined = TAccept extends 'form' ? z.ZodType<FormData> : undefined>({ accept, input: inputSchema, handler, }: {
|
|
19
20
|
input?: TInputSchema;
|
|
20
21
|
accept?: TAccept;
|
|
21
22
|
handler: ActionHandler<TInputSchema, TOutput>;
|
|
22
|
-
}): ActionClient<TOutput, TAccept, TInputSchema
|
|
23
|
+
}): ActionClient<TOutput, TAccept, TInputSchema> & string;
|
|
23
24
|
/** Transform form data to an object based on a Zod schema. */
|
|
24
25
|
export declare function formDataToObject<T extends z.AnyZodObject>(formData: FormData, schema: T): Record<string, unknown>;
|
|
@@ -10,12 +10,13 @@ function defineAction({
|
|
|
10
10
|
handler
|
|
11
11
|
}) {
|
|
12
12
|
const serverHandler = accept === "form" ? getFormServerHandler(handler, inputSchema) : getJsonServerHandler(handler, inputSchema);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const safeServerHandler = async (unparsedInput) => {
|
|
14
|
+
return callSafely(() => serverHandler(unparsedInput));
|
|
15
|
+
};
|
|
16
|
+
Object.assign(safeServerHandler, {
|
|
17
|
+
orThrow: serverHandler
|
|
17
18
|
});
|
|
18
|
-
return
|
|
19
|
+
return safeServerHandler;
|
|
19
20
|
}
|
|
20
21
|
function getFormServerHandler(handler, inputSchema) {
|
|
21
22
|
return async (unparsedInput) => {
|
|
@@ -31,6 +31,13 @@ export declare class ActionInputError<T extends ErrorInferenceObject> extends Ac
|
|
|
31
31
|
constructor(issues: z.ZodIssue[]);
|
|
32
32
|
}
|
|
33
33
|
export declare function callSafely<TOutput>(handler: () => MaybePromise<TOutput>): Promise<SafeResult<z.ZodType, TOutput>>;
|
|
34
|
+
export declare function getActionQueryString(name: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* @deprecated You can now pass action functions
|
|
37
|
+
* directly to the `action` attribute on a form.
|
|
38
|
+
*
|
|
39
|
+
* Example: `<form action={actions.like} />`
|
|
40
|
+
*/
|
|
34
41
|
export declare function getActionProps<T extends (args: FormData) => MaybePromise<unknown>>(action: T): {
|
|
35
42
|
readonly type: "hidden";
|
|
36
43
|
readonly name: "_astroAction";
|
|
@@ -110,11 +110,20 @@ async function callSafely(handler) {
|
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
+
function getActionQueryString(name) {
|
|
114
|
+
const searchParams = new URLSearchParams({ _astroAction: name });
|
|
115
|
+
return `?${searchParams.toString()}`;
|
|
116
|
+
}
|
|
113
117
|
function getActionProps(action) {
|
|
118
|
+
const params = new URLSearchParams(action.toString());
|
|
119
|
+
const actionName = params.get("_astroAction");
|
|
120
|
+
if (!actionName) {
|
|
121
|
+
throw new Error("Invalid actions function was passed to getActionProps()");
|
|
122
|
+
}
|
|
114
123
|
return {
|
|
115
124
|
type: "hidden",
|
|
116
125
|
name: "_astroAction",
|
|
117
|
-
value:
|
|
126
|
+
value: actionName
|
|
118
127
|
};
|
|
119
128
|
}
|
|
120
129
|
export {
|
|
@@ -123,5 +132,6 @@ export {
|
|
|
123
132
|
ActionInputError,
|
|
124
133
|
callSafely,
|
|
125
134
|
getActionProps,
|
|
135
|
+
getActionQueryString,
|
|
126
136
|
isInputError
|
|
127
137
|
};
|
package/dist/cli/add/index.js
CHANGED
|
@@ -569,7 +569,7 @@ async function resolveRangeToInstallSpecifier(name, range) {
|
|
|
569
569
|
const versions = await fetchPackageVersions(name);
|
|
570
570
|
if (versions instanceof Error) return name;
|
|
571
571
|
const stableVersions = versions.filter((v) => !v.includes("-"));
|
|
572
|
-
const maxStable = maxSatisfying(stableVersions, range);
|
|
572
|
+
const maxStable = maxSatisfying(stableVersions.length !== 0 ? stableVersions : versions, range);
|
|
573
573
|
return `${name}@^${maxStable}`;
|
|
574
574
|
}
|
|
575
575
|
const INHERITED_FLAGS = /* @__PURE__ */ new Set([
|
|
@@ -92,22 +92,9 @@ function astroContentAssetPropagationPlugin({
|
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
94
|
function astroConfigBuildPlugin(options, internals) {
|
|
95
|
-
let ssrPluginContext = void 0;
|
|
96
95
|
return {
|
|
97
96
|
targets: ["server"],
|
|
98
97
|
hooks: {
|
|
99
|
-
"build:before": ({ target }) => {
|
|
100
|
-
return {
|
|
101
|
-
vitePlugin: {
|
|
102
|
-
name: "astro:content-build-plugin",
|
|
103
|
-
generateBundle() {
|
|
104
|
-
if (target === "server") {
|
|
105
|
-
ssrPluginContext = this;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
},
|
|
111
98
|
"build:post": ({ ssrOutputs, clientOutputs, mutate }) => {
|
|
112
99
|
const outputs = ssrOutputs.flatMap((o) => o.output);
|
|
113
100
|
const prependBase = (src) => {
|
|
@@ -187,7 +174,6 @@ function astroConfigBuildPlugin(options, internals) {
|
|
|
187
174
|
mutate(chunk, ["server"], newCode);
|
|
188
175
|
}
|
|
189
176
|
}
|
|
190
|
-
ssrPluginContext = void 0;
|
|
191
177
|
}
|
|
192
178
|
}
|
|
193
179
|
};
|
|
@@ -144,7 +144,7 @@ ${bgGreen(black(` ${verb} static routes `))}`);
|
|
|
144
144
|
await runHookBuildGenerated({ config, logger });
|
|
145
145
|
}
|
|
146
146
|
async function generatePage(pageData, ssrEntry, builtPaths, pipeline) {
|
|
147
|
-
const { config,
|
|
147
|
+
const { config, logger } = pipeline;
|
|
148
148
|
const pageModulePromise = ssrEntry.page;
|
|
149
149
|
const styles = pageData.styles.sort(cssOrder).map(({ sheet }) => sheet).reduce(mergeInlineCss, []);
|
|
150
150
|
const linkIds = [];
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { getOutputDirectory } from "../../prerender/utils.js";
|
|
2
2
|
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
|
|
3
|
-
import { DEFAULT_404_COMPONENT } from "../constants.js";
|
|
4
3
|
import { routeIsFallback, routeIsRedirect } from "../redirects/helpers.js";
|
|
5
4
|
import { RedirectSinglePageBuiltModule } from "../redirects/index.js";
|
|
6
5
|
import { Pipeline } from "../render/index.js";
|
|
@@ -278,7 +278,7 @@ async function generateContentManifest(opts, lookupMap) {
|
|
|
278
278
|
promises.push(
|
|
279
279
|
limit(async () => {
|
|
280
280
|
const data = await fsMod.promises.readFile(fileURL, { encoding: "utf8" });
|
|
281
|
-
manifest.entries.push([key, checksum(data)]);
|
|
281
|
+
manifest.entries.push([key, checksum(data, fileURL.toString())]);
|
|
282
282
|
})
|
|
283
283
|
);
|
|
284
284
|
}
|
package/dist/core/constants.js
CHANGED
package/dist/core/dev/dev.js
CHANGED
|
@@ -19,7 +19,7 @@ async function dev(inlineConfig) {
|
|
|
19
19
|
await telemetry.record([]);
|
|
20
20
|
const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
|
|
21
21
|
const logger = restart.container.logger;
|
|
22
|
-
const currentVersion = "4.12.
|
|
22
|
+
const currentVersion = "4.12.3";
|
|
23
23
|
const isPrerelease = currentVersion.includes("-");
|
|
24
24
|
if (!isPrerelease) {
|
|
25
25
|
try {
|
|
@@ -15,7 +15,10 @@ function collectErrorMetadata(e, rootFolder) {
|
|
|
15
15
|
err.forEach((error) => {
|
|
16
16
|
if (e.stack) {
|
|
17
17
|
const stackInfo = collectInfoFromStacktrace(e);
|
|
18
|
-
|
|
18
|
+
try {
|
|
19
|
+
error.stack = stripAnsi(stackInfo.stack);
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
19
22
|
error.loc = stackInfo.loc;
|
|
20
23
|
error.plugin = stackInfo.plugin;
|
|
21
24
|
error.pluginCode = stackInfo.pluginCode;
|
|
@@ -40,14 +43,20 @@ function collectErrorMetadata(e, rootFolder) {
|
|
|
40
43
|
}
|
|
41
44
|
error.hint = generateHint(e);
|
|
42
45
|
if (error.message) {
|
|
43
|
-
|
|
46
|
+
try {
|
|
47
|
+
error.message = stripAnsi(error.message);
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
44
50
|
}
|
|
45
51
|
});
|
|
46
52
|
if (!AggregateError.is(e) && Array.isArray(e.errors)) {
|
|
47
53
|
e.errors.forEach((buildError, i) => {
|
|
48
54
|
const { location, pluginName, text } = buildError;
|
|
49
55
|
if (text) {
|
|
50
|
-
|
|
56
|
+
try {
|
|
57
|
+
err[i].message = text;
|
|
58
|
+
} catch {
|
|
59
|
+
}
|
|
51
60
|
}
|
|
52
61
|
if (location) {
|
|
53
62
|
err[i].loc = { file: location.file, line: location.line, column: location.column };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ShikiTransformer } from 'shiki';
|
|
1
2
|
import type { ErrorPayload } from 'vite';
|
|
2
3
|
import type { ModuleLoader } from '../../module-loader/index.js';
|
|
3
4
|
import { type ErrorWithMetadata } from '../errors.js';
|
|
@@ -28,3 +29,15 @@ export interface AstroErrorPayload {
|
|
|
28
29
|
* Generate a payload for Vite's error overlay
|
|
29
30
|
*/
|
|
30
31
|
export declare function getViteErrorPayload(err: ErrorWithMetadata): Promise<AstroErrorPayload>;
|
|
32
|
+
/**
|
|
33
|
+
* Transformer for `shiki`'s legacy `lineOptions`, allows to add classes to specific lines
|
|
34
|
+
* FROM: https://github.com/shikijs/shiki/blob/4a58472070a9a359a4deafec23bb576a73e24c6a/packages/transformers/src/transformers/compact-line-options.ts
|
|
35
|
+
* LICENSE: https://github.com/shikijs/shiki/blob/4a58472070a9a359a4deafec23bb576a73e24c6a/LICENSE
|
|
36
|
+
*/
|
|
37
|
+
export declare function transformerCompactLineOptions(lineOptions?: {
|
|
38
|
+
/**
|
|
39
|
+
* 1-based line number.
|
|
40
|
+
*/
|
|
41
|
+
line: number;
|
|
42
|
+
classes?: string[];
|
|
43
|
+
}[]): ShikiTransformer;
|
|
@@ -86,10 +86,13 @@ async function getViteErrorPayload(err) {
|
|
|
86
86
|
highlighterLang = "md";
|
|
87
87
|
}
|
|
88
88
|
const highlightedCode = err.fullCode ? await codeToHtml(err.fullCode, {
|
|
89
|
-
|
|
90
|
-
lang: highlighterLang,
|
|
89
|
+
lang: highlighterLang ?? "text",
|
|
91
90
|
theme: cssVariablesTheme(),
|
|
92
|
-
|
|
91
|
+
transformers: [
|
|
92
|
+
transformerCompactLineOptions(
|
|
93
|
+
err.loc?.line ? [{ line: err.loc.line, classes: ["error-line"] }] : void 0
|
|
94
|
+
)
|
|
95
|
+
]
|
|
93
96
|
}) : void 0;
|
|
94
97
|
return {
|
|
95
98
|
type: "error",
|
|
@@ -113,7 +116,18 @@ async function getViteErrorPayload(err) {
|
|
|
113
116
|
}
|
|
114
117
|
};
|
|
115
118
|
}
|
|
119
|
+
function transformerCompactLineOptions(lineOptions = []) {
|
|
120
|
+
return {
|
|
121
|
+
name: "@shikijs/transformers:compact-line-options",
|
|
122
|
+
line(node, line) {
|
|
123
|
+
const lineOption = lineOptions.find((o) => o.line === line);
|
|
124
|
+
if (lineOption?.classes) this.addClassToHast(node, lineOption.classes);
|
|
125
|
+
return node;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
116
129
|
export {
|
|
117
130
|
enhanceViteSSRError,
|
|
118
|
-
getViteErrorPayload
|
|
131
|
+
getViteErrorPayload,
|
|
132
|
+
transformerCompactLineOptions
|
|
119
133
|
};
|
|
@@ -1439,6 +1439,32 @@ export declare const ActionsWithoutServerOutputError: {
|
|
|
1439
1439
|
message: string;
|
|
1440
1440
|
hint: string;
|
|
1441
1441
|
};
|
|
1442
|
+
/**
|
|
1443
|
+
* @docs
|
|
1444
|
+
* @see
|
|
1445
|
+
* - [Actions RFC](https://github.com/withastro/roadmap/blob/actions/proposals/0046-actions.md)
|
|
1446
|
+
* @description
|
|
1447
|
+
* Action was called from a form using a GET request, but only POST requests are supported. This often occurs if `method="POST"` is missing on the form.
|
|
1448
|
+
*/
|
|
1449
|
+
export declare const ActionsUsedWithForGetError: {
|
|
1450
|
+
name: string;
|
|
1451
|
+
title: string;
|
|
1452
|
+
message: (actionName: string) => string;
|
|
1453
|
+
hint: string;
|
|
1454
|
+
};
|
|
1455
|
+
/**
|
|
1456
|
+
* @docs
|
|
1457
|
+
* @see
|
|
1458
|
+
* - [Actions RFC](https://github.com/withastro/roadmap/blob/actions/proposals/0046-actions.md)
|
|
1459
|
+
* @description
|
|
1460
|
+
* The server received the query string `?_astroAction=name`, but could not find an action with that name. Use the action function's `.queryString` property to retrieve the form `action` URL.
|
|
1461
|
+
*/
|
|
1462
|
+
export declare const ActionQueryStringInvalidError: {
|
|
1463
|
+
name: string;
|
|
1464
|
+
title: string;
|
|
1465
|
+
message: (actionName: string) => string;
|
|
1466
|
+
hint: string;
|
|
1467
|
+
};
|
|
1442
1468
|
/**
|
|
1443
1469
|
* @docs
|
|
1444
1470
|
* @see
|
|
@@ -547,6 +547,18 @@ const ActionsWithoutServerOutputError = {
|
|
|
547
547
|
message: "Actions enabled without setting a server build output. A server is required to create callable backend functions. To deploy routes to a server, add a server adapter to your astro config.",
|
|
548
548
|
hint: "Learn about on-demand rendering: https://docs.astro.build/en/basics/rendering-modes/#on-demand-rendered"
|
|
549
549
|
};
|
|
550
|
+
const ActionsUsedWithForGetError = {
|
|
551
|
+
name: "ActionsUsedWithForGetError",
|
|
552
|
+
title: "An invalid Action query string was passed by a form.",
|
|
553
|
+
message: (actionName) => `Action ${actionName} was called from a form using a GET request, but only POST requests are supported. This often occurs if \`method="POST"\` is missing on the form.`,
|
|
554
|
+
hint: "Actions are experimental. Visit the RFC for usage instructions: https://github.com/withastro/roadmap/blob/actions/proposals/0046-actions.md"
|
|
555
|
+
};
|
|
556
|
+
const ActionQueryStringInvalidError = {
|
|
557
|
+
name: "ActionQueryStringInvalidError",
|
|
558
|
+
title: "An invalid Action query string was passed by a form.",
|
|
559
|
+
message: (actionName) => `The server received the query string \`?_astroAction=${actionName}\`, but could not find an action with that name. If you changed an action's name in development, remove this query param from your URL and refresh.`,
|
|
560
|
+
hint: "Actions are experimental. Visit the RFC for usage instructions: https://github.com/withastro/roadmap/blob/actions/proposals/0046-actions.md"
|
|
561
|
+
};
|
|
550
562
|
const UnsupportedConfigTransformError = {
|
|
551
563
|
name: "UnsupportedConfigTransformError",
|
|
552
564
|
title: "Unsupported transform in content config.",
|
|
@@ -556,6 +568,8 @@ Full error: ${parseError}`,
|
|
|
556
568
|
};
|
|
557
569
|
const UnknownError = { name: "UnknownError", title: "Unknown Error." };
|
|
558
570
|
export {
|
|
571
|
+
ActionQueryStringInvalidError,
|
|
572
|
+
ActionsUsedWithForGetError,
|
|
559
573
|
ActionsWithoutServerOutputError,
|
|
560
574
|
AstroGlobNoMatch,
|
|
561
575
|
AstroGlobUsedOutside,
|
package/dist/core/messages.js
CHANGED
|
@@ -38,7 +38,7 @@ function serverStart({
|
|
|
38
38
|
host,
|
|
39
39
|
base
|
|
40
40
|
}) {
|
|
41
|
-
const version = "4.12.
|
|
41
|
+
const version = "4.12.3";
|
|
42
42
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
43
43
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
44
44
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -270,7 +270,7 @@ function printHelp({
|
|
|
270
270
|
message.push(
|
|
271
271
|
linebreak(),
|
|
272
272
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
273
|
-
`v${"4.12.
|
|
273
|
+
`v${"4.12.3"}`
|
|
274
274
|
)} ${headline}`
|
|
275
275
|
);
|
|
276
276
|
}
|
|
@@ -282,6 +282,7 @@ class RenderContext {
|
|
|
282
282
|
};
|
|
283
283
|
const actionResult = hasActionsInternal(this.locals) ? this.locals._actionsInternal?.actionResult : void 0;
|
|
284
284
|
const result = {
|
|
285
|
+
base: manifest.base,
|
|
285
286
|
cancelled: false,
|
|
286
287
|
clientDirectives,
|
|
287
288
|
inlinedScripts,
|
|
@@ -302,6 +303,7 @@ class RenderContext {
|
|
|
302
303
|
styles,
|
|
303
304
|
actionResult,
|
|
304
305
|
serverIslandNameMap: manifest.serverIslandNameMap ?? /* @__PURE__ */ new Map(),
|
|
306
|
+
trailingSlash: manifest.trailingSlash,
|
|
305
307
|
_metadata: {
|
|
306
308
|
hasHydrationScript: false,
|
|
307
309
|
rendererSpecificHydrationScripts: /* @__PURE__ */ new Set(),
|
package/dist/env/runtime.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { AstroError } from '../core/errors/index.js';
|
|
|
2
2
|
import type { ValidationResultInvalid } from './validators.js';
|
|
3
3
|
export { validateEnvVariable, getEnvFieldType } from './validators.js';
|
|
4
4
|
export type GetEnv = (key: string) => string | undefined;
|
|
5
|
+
type OnSetGetEnv = (reset: boolean) => void;
|
|
5
6
|
export declare function setGetEnv(fn: GetEnv, reset?: boolean): void;
|
|
6
|
-
declare
|
|
7
|
-
export declare function setOnSetGetEnv(fn: typeof _onSetGetEnv): void;
|
|
7
|
+
export declare function setOnSetGetEnv(fn: OnSetGetEnv): void;
|
|
8
8
|
export declare function getEnv(...args: Parameters<GetEnv>): string | undefined;
|
|
9
9
|
export declare function createInvalidVariablesError(key: string, type: string, result: ValidationResultInvalid): AstroError;
|
package/dist/env/runtime.js
CHANGED
|
@@ -82,7 +82,7 @@ async function runHookConfigSetup({
|
|
|
82
82
|
}
|
|
83
83
|
if (settings.config.experimental?.actions) {
|
|
84
84
|
const { default: actionsIntegration } = await import("../actions/index.js");
|
|
85
|
-
settings.config.integrations.push(actionsIntegration({ fs }));
|
|
85
|
+
settings.config.integrations.push(actionsIntegration({ fs, settings }));
|
|
86
86
|
}
|
|
87
87
|
let updatedConfig = { ...settings.config };
|
|
88
88
|
let updatedSettings = { ...settings, config: updatedConfig };
|
|
@@ -110,10 +110,6 @@ const a11y_required_content = [
|
|
|
110
110
|
"h6"
|
|
111
111
|
];
|
|
112
112
|
const a11y_distracting_elements = ["blink", "marquee"];
|
|
113
|
-
const a11y_nested_implicit_semantics = /* @__PURE__ */ new Map([
|
|
114
|
-
["header", "banner"],
|
|
115
|
-
["footer", "contentinfo"]
|
|
116
|
-
]);
|
|
117
113
|
const a11y_implicit_semantics = /* @__PURE__ */ new Map([
|
|
118
114
|
["a", "link"],
|
|
119
115
|
["area", "link"],
|
|
@@ -525,16 +521,6 @@ const a11y = [
|
|
|
525
521
|
}
|
|
526
522
|
}
|
|
527
523
|
];
|
|
528
|
-
const a11y_labelable = [
|
|
529
|
-
"button",
|
|
530
|
-
"input",
|
|
531
|
-
"keygen",
|
|
532
|
-
"meter",
|
|
533
|
-
"output",
|
|
534
|
-
"progress",
|
|
535
|
-
"select",
|
|
536
|
-
"textarea"
|
|
537
|
-
];
|
|
538
524
|
const a11y_non_interactive_element_to_interactive_role_exceptions = {
|
|
539
525
|
ul: ["listbox", "menu", "menubar", "radiogroup", "tablist", "tree", "treegrid"],
|
|
540
526
|
ol: ["listbox", "menu", "menubar", "radiogroup", "tablist", "tree", "treegrid"],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SSRResult } from '../../../../@types/astro.js';
|
|
2
2
|
import type { ComponentSlots } from '../slot.js';
|
|
3
|
-
import type { AstroComponentFactory
|
|
3
|
+
import type { AstroComponentFactory } from './factory.js';
|
|
4
4
|
import type { RenderDestination } from '../common.js';
|
|
5
5
|
type ComponentProps = Record<string | number, any>;
|
|
6
6
|
declare const astroComponentInstanceSym: unique symbol;
|
|
@@ -12,7 +12,7 @@ export declare class AstroComponentInstance {
|
|
|
12
12
|
private readonly factory;
|
|
13
13
|
private returnValue;
|
|
14
14
|
constructor(result: SSRResult, props: ComponentProps, slots: ComponentSlots, factory: AstroComponentFactory);
|
|
15
|
-
init(result: SSRResult): Promise<AstroFactoryReturnValue>;
|
|
15
|
+
init(result: SSRResult): Promise<import("./factory.js").AstroFactoryReturnValue>;
|
|
16
16
|
render(destination: RenderDestination): Promise<void>;
|
|
17
17
|
}
|
|
18
18
|
export declare function createAstroComponentInstance(result: SSRResult, displayName: string, factory: AstroComponentFactory, props: ComponentProps, slots?: any): AstroComponentInstance;
|
|
@@ -37,6 +37,7 @@ function renderServerIsland(result, _displayName, props, slots) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
const hostId = crypto.randomUUID();
|
|
40
|
+
const serverIslandUrl = `${result.base}_server-islands/${componentId}${result.trailingSlash === "always" ? "/" : ""}`;
|
|
40
41
|
destination.write(`<script async type="module" data-island-id="${hostId}">
|
|
41
42
|
let componentId = ${safeJsonStringify(componentId)};
|
|
42
43
|
let componentExport = ${safeJsonStringify(componentExport)};
|
|
@@ -47,7 +48,7 @@ let data = {
|
|
|
47
48
|
slots: ${safeJsonStringify(renderedSlots)},
|
|
48
49
|
};
|
|
49
50
|
|
|
50
|
-
let response = await fetch('
|
|
51
|
+
let response = await fetch('${serverIslandUrl}', {
|
|
51
52
|
method: 'POST',
|
|
52
53
|
body: JSON.stringify(data),
|
|
53
54
|
});
|
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
import { TRANSITION_AFTER_SWAP, doPreparation, doSwap } from "./events.js";
|
|
2
|
-
import {
|
|
3
|
-
deselectScripts,
|
|
4
|
-
restoreFocus,
|
|
5
|
-
saveFocus,
|
|
6
|
-
swapBodyElement,
|
|
7
|
-
swapHeadElements,
|
|
8
|
-
swapRootAttributes
|
|
9
|
-
} from "./swap-functions.js";
|
|
10
2
|
const inBrowser = import.meta.env.SSR === false;
|
|
11
3
|
const pushState = inBrowser && history.pushState.bind(history);
|
|
12
4
|
const replaceState = inBrowser && history.replaceState.bind(history);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { collectErrorMetadata } from "../core/errors/dev/index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { createSafeError } from "../core/errors/index.js";
|
|
3
3
|
import { formatErrorMessage } from "../core/messages.js";
|
|
4
|
-
import { eventError, telemetry } from "../events/index.js";
|
|
5
4
|
function recordServerError(loader, config, { logger }, _err) {
|
|
6
5
|
const err = createSafeError(_err);
|
|
7
6
|
try {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import npath from "node:path";
|
|
2
2
|
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from "../core/constants.js";
|
|
3
3
|
import { unwrapId } from "../core/util.js";
|
|
4
|
+
import { hasSpecialQueries } from "../vite-plugin-utils/index.js";
|
|
4
5
|
import { isCSSRequest } from "./util.js";
|
|
5
6
|
const fileExtensionsToSSR = /* @__PURE__ */ new Set([".astro", ".mdoc", ...SUPPORTED_MARKDOWN_FILE_EXTENSIONS]);
|
|
6
7
|
const STRIP_QUERY_PARAMS_REGEX = /\?.*$/;
|
|
@@ -27,6 +28,9 @@ async function* crawlGraph(loader, _id, isRootFile, scanned = /* @__PURE__ */ ne
|
|
|
27
28
|
if (isCSSRequest(id)) {
|
|
28
29
|
continue;
|
|
29
30
|
}
|
|
31
|
+
if (hasSpecialQueries(id)) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
30
34
|
for (const importedModule of entry.importedModules) {
|
|
31
35
|
if (!importedModule.id) continue;
|
|
32
36
|
const importedModulePathname = importedModule.id.replace(STRIP_QUERY_PARAMS_REGEX, "");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "4.12.
|
|
3
|
+
"version": "4.12.3",
|
|
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",
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"vendor"
|
|
111
111
|
],
|
|
112
112
|
"dependencies": {
|
|
113
|
-
"@astrojs/compiler": "^2.9.
|
|
113
|
+
"@astrojs/compiler": "^2.9.2",
|
|
114
114
|
"@babel/core": "^7.24.9",
|
|
115
115
|
"@babel/generator": "^7.24.10",
|
|
116
116
|
"@babel/parser": "^7.24.8",
|
|
@@ -156,8 +156,8 @@
|
|
|
156
156
|
"preferred-pm": "^4.0.0",
|
|
157
157
|
"prompts": "^2.4.2",
|
|
158
158
|
"rehype": "^13.0.1",
|
|
159
|
-
"semver": "^7.6.
|
|
160
|
-
"shiki": "^1.
|
|
159
|
+
"semver": "^7.6.3",
|
|
160
|
+
"shiki": "^1.11.0",
|
|
161
161
|
"string-width": "^7.2.0",
|
|
162
162
|
"strip-ansi": "^7.1.0",
|
|
163
163
|
"tsconfck": "^3.1.1",
|
|
@@ -177,7 +177,7 @@
|
|
|
177
177
|
"sharp": "^0.33.3"
|
|
178
178
|
},
|
|
179
179
|
"devDependencies": {
|
|
180
|
-
"@astrojs/check": "^0.8.
|
|
180
|
+
"@astrojs/check": "^0.8.2",
|
|
181
181
|
"@playwright/test": "^1.45.2",
|
|
182
182
|
"@types/aria-query": "^5.0.4",
|
|
183
183
|
"@types/babel__generator": "^7.6.8",
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
"@types/debug": "^4.1.12",
|
|
189
189
|
"@types/diff": "^5.2.1",
|
|
190
190
|
"@types/dlv": "^1.1.4",
|
|
191
|
-
"@types/dom-view-transitions": "^1.0.
|
|
191
|
+
"@types/dom-view-transitions": "^1.0.5",
|
|
192
192
|
"@types/hast": "^3.0.4",
|
|
193
193
|
"@types/html-escaper": "^3.0.2",
|
|
194
194
|
"@types/http-cache-semantics": "^4.0.4",
|
|
@@ -211,7 +211,7 @@
|
|
|
211
211
|
"rehype-slug": "^6.0.0",
|
|
212
212
|
"rehype-toc": "^3.0.2",
|
|
213
213
|
"remark-code-titles": "^0.1.2",
|
|
214
|
-
"rollup": "^4.
|
|
214
|
+
"rollup": "^4.19.0",
|
|
215
215
|
"sass": "^1.77.8",
|
|
216
216
|
"srcset-parse": "^1.1.0",
|
|
217
217
|
"undici": "^6.19.2",
|
package/templates/actions.mjs
CHANGED
|
@@ -1,39 +1,36 @@
|
|
|
1
|
-
import { ActionError, callSafely } from 'astro:actions';
|
|
1
|
+
import { ActionError, callSafely, getActionQueryString } from 'astro:actions';
|
|
2
2
|
|
|
3
|
-
function toActionProxy(actionCallback = {}, aggregatedPath = '
|
|
3
|
+
function toActionProxy(actionCallback = {}, aggregatedPath = '') {
|
|
4
4
|
return new Proxy(actionCallback, {
|
|
5
5
|
get(target, objKey) {
|
|
6
|
-
if (objKey in target) {
|
|
6
|
+
if (objKey in target || typeof objKey === 'symbol') {
|
|
7
7
|
return target[objKey];
|
|
8
8
|
}
|
|
9
9
|
const path = aggregatedPath + objKey.toString();
|
|
10
|
-
const action = (param) =>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const action = (param) => callSafely(() => handleActionOrThrow(param, path));
|
|
11
|
+
|
|
12
|
+
Object.assign(action, {
|
|
13
|
+
queryString: getActionQueryString(path),
|
|
14
|
+
toString: () => action.queryString,
|
|
15
|
+
// Progressive enhancement info for React.
|
|
16
|
+
$$FORM_ACTION: function () {
|
|
17
|
+
return {
|
|
18
|
+
method: 'POST',
|
|
19
|
+
// `name` creates a hidden input.
|
|
20
|
+
// It's unused by Astro, but we can't turn this off.
|
|
21
|
+
// At least use a name that won't conflict with a user's formData.
|
|
22
|
+
name: '_astroAction',
|
|
23
|
+
action: action.toString(),
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
// Note: `orThrow` does not have progressive enhancement info.
|
|
27
|
+
// If you want to throw exceptions,
|
|
28
|
+
// you must handle those exceptions with client JS.
|
|
29
|
+
orThrow: (param) => {
|
|
30
|
+
return handleActionOrThrow(param, path);
|
|
31
|
+
},
|
|
32
|
+
});
|
|
16
33
|
|
|
17
|
-
// Add progressive enhancement info for React.
|
|
18
|
-
action.$$FORM_ACTION = function () {
|
|
19
|
-
const data = new FormData();
|
|
20
|
-
data.set('_astroAction', action.toString());
|
|
21
|
-
return {
|
|
22
|
-
method: 'POST',
|
|
23
|
-
name: action.toString(),
|
|
24
|
-
data,
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
action.safe.$$FORM_ACTION = function () {
|
|
28
|
-
const data = new FormData();
|
|
29
|
-
data.set('_astroAction', action.toString());
|
|
30
|
-
data.set('_astroActionSafe', 'true');
|
|
31
|
-
return {
|
|
32
|
-
method: 'POST',
|
|
33
|
-
name: action.toString(),
|
|
34
|
-
data,
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
34
|
// recurse to construct queries for nested object paths
|
|
38
35
|
// ex. actions.user.admins.auth()
|
|
39
36
|
return toActionProxy(action, path + '.');
|
|
@@ -46,14 +43,14 @@ function toActionProxy(actionCallback = {}, aggregatedPath = '/_actions/') {
|
|
|
46
43
|
* @param {string} path Built path to call action by path name.
|
|
47
44
|
* Usage: `actions.[name](param)`.
|
|
48
45
|
*/
|
|
49
|
-
async function
|
|
46
|
+
async function handleActionOrThrow(param, path) {
|
|
50
47
|
// When running server-side, import the action and call it.
|
|
51
48
|
if (import.meta.env.SSR) {
|
|
52
49
|
const { getAction } = await import('astro/actions/runtime/utils.js');
|
|
53
50
|
const action = await getAction(path);
|
|
54
51
|
if (!action) throw new Error(`Action not found: ${path}`);
|
|
55
52
|
|
|
56
|
-
return action(param);
|
|
53
|
+
return action.orThrow(param);
|
|
57
54
|
}
|
|
58
55
|
|
|
59
56
|
// When running client-side, make a fetch request to the action path.
|
|
@@ -72,7 +69,7 @@ async function actionHandler(param, path) {
|
|
|
72
69
|
headers.set('Content-Type', 'application/json');
|
|
73
70
|
headers.set('Content-Length', body?.length.toString() ?? '0');
|
|
74
71
|
}
|
|
75
|
-
const res = await fetch(path
|
|
72
|
+
const res = await fetch(`/_actions/${path}`, {
|
|
76
73
|
method: 'POST',
|
|
77
74
|
body,
|
|
78
75
|
headers,
|
package/templates/env/module.mjs
CHANGED
|
@@ -25,6 +25,8 @@ const _internalGetSecret = (key) => {
|
|
|
25
25
|
throw createInvalidVariablesError(key, type, result);
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
// used while generating the virtual module
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
28
30
|
setOnSetGetEnv((reset) => {
|
|
29
31
|
// @@ON_SET_GET_ENV@@
|
|
30
32
|
});
|