astro 4.13.0 → 4.13.2
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/astro-jsx.d.ts +0 -1
- package/astro.js +2 -1
- package/client.d.ts +1 -1
- package/components/Picture.astro +2 -2
- package/components/ViewTransitions.astro +1 -1
- package/config.d.ts +1 -1
- package/dist/@types/astro.d.ts +21 -2
- package/dist/actions/runtime/middleware.d.ts +3 -3
- package/dist/actions/runtime/middleware.js +39 -72
- package/dist/actions/runtime/route.js +16 -23
- package/dist/actions/runtime/utils.d.ts +2 -8
- package/dist/actions/runtime/utils.js +0 -15
- package/dist/actions/runtime/virtual/client.d.ts +0 -1
- package/dist/actions/runtime/virtual/client.js +0 -4
- package/dist/actions/runtime/virtual/get-action.d.ts +8 -0
- package/dist/actions/runtime/virtual/get-action.js +17 -0
- package/dist/actions/runtime/virtual/server.d.ts +1 -4
- package/dist/actions/runtime/virtual/server.js +20 -13
- package/dist/actions/runtime/virtual/shared.d.ts +18 -1
- package/dist/actions/runtime/virtual/shared.js +56 -8
- package/dist/actions/utils.d.ts +2 -0
- package/dist/actions/utils.js +13 -8
- package/dist/assets/build/generate.js +1 -1
- package/dist/assets/endpoint/generic.js +1 -1
- package/dist/assets/endpoint/node.js +3 -3
- package/dist/assets/services/sharp.js +1 -1
- package/dist/assets/services/vendor/squoosh/avif/avif_node_dec.js +1 -1
- package/dist/assets/services/vendor/squoosh/avif/avif_node_enc.js +1 -1
- package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_node_dec.js +1 -1
- package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_node_enc.js +1 -1
- package/dist/assets/services/vendor/squoosh/webp/webp_node_dec.js +1 -1
- package/dist/assets/services/vendor/squoosh/webp/webp_node_enc.js +1 -1
- package/dist/assets/utils/metadata.js +1 -1
- package/dist/assets/utils/node/emitAsset.js +1 -1
- package/dist/assets/utils/remoteProbe.js +1 -1
- package/dist/assets/utils/vendor/image-size/lookup.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/svg.js +4 -4
- package/dist/cli/add/index.d.ts +0 -7
- package/dist/cli/add/index.js +1 -2
- package/dist/cli/info/index.js +2 -2
- package/dist/cli/install-package.d.ts +0 -1
- package/dist/cli/install-package.js +3 -4
- package/dist/content/runtime-assets.d.ts +1 -1
- package/dist/content/utils.d.ts +2 -11
- package/dist/content/utils.js +0 -8
- package/dist/core/app/index.js +1 -1
- package/dist/core/build/css-asset-name.d.ts +3 -3
- package/dist/core/build/css-asset-name.js +15 -8
- package/dist/core/build/generate.d.ts +0 -4
- package/dist/core/build/generate.js +4 -24
- package/dist/core/build/index.js +8 -2
- package/dist/core/build/internal.d.ts +0 -18
- package/dist/core/build/internal.js +0 -17
- package/dist/core/build/page-data.d.ts +1 -1
- package/dist/core/build/page-data.js +1 -18
- package/dist/core/build/plugins/plugin-analyzer.js +0 -4
- package/dist/core/build/plugins/plugin-css.js +2 -2
- package/dist/core/build/plugins/plugin-internals.js +0 -7
- package/dist/core/build/plugins/plugin-manifest.d.ts +0 -10
- package/dist/core/build/plugins/plugin-manifest.js +0 -2
- package/dist/core/build/plugins/plugin-ssr.js +0 -1
- package/dist/core/build/types.d.ts +1 -8
- package/dist/core/compile/index.d.ts +0 -1
- package/dist/core/compile/types.d.ts +0 -7
- package/dist/core/config/schema.d.ts +55 -55
- package/dist/core/config/tsconfig.d.ts +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +2 -2
- package/dist/core/dev/restart.d.ts +0 -2
- package/dist/core/dev/restart.js +1 -3
- package/dist/core/errors/dev/vite.d.ts +0 -13
- package/dist/core/errors/dev/vite.js +5 -6
- package/dist/core/errors/errors-data.d.ts +21 -5
- package/dist/core/errors/errors-data.js +13 -6
- package/dist/core/fs/index.d.ts +0 -2
- package/dist/core/fs/index.js +0 -5
- package/dist/core/logger/core.d.ts +0 -1
- package/dist/core/logger/core.js +0 -18
- package/dist/core/messages.d.ts +0 -1
- package/dist/core/messages.js +2 -3
- package/dist/core/middleware/index.js +3 -2
- package/dist/core/render/ssr-element.d.ts +0 -1
- package/dist/core/render/ssr-element.js +0 -6
- package/dist/core/render-context.d.ts +1 -1
- package/dist/core/render-context.js +9 -4
- package/dist/core/routing/manifest/create.js +2 -2
- package/dist/core/util.d.ts +0 -2
- package/dist/core/util.js +0 -14
- package/dist/events/error.js +1 -1
- package/dist/preferences/index.d.ts +0 -1
- package/dist/preferences/index.js +0 -1
- package/dist/runtime/client/dev-toolbar/apps/audit/index.js +1 -1
- package/dist/runtime/client/dev-toolbar/apps/audit/rules/perf.js +4 -2
- package/dist/runtime/server/render/component.d.ts +0 -3
- package/dist/runtime/server/render/component.js +1 -3
- package/dist/transitions/router.js +2 -2
- package/dist/type-utils.d.ts +1 -1
- package/dist/vite-plugin-astro-server/controller.d.ts +0 -4
- package/dist/vite-plugin-astro-server/controller.js +0 -2
- package/dist/vite-plugin-astro-server/vite.js +1 -2
- package/dist/vite-plugin-env/index.js +0 -1
- package/dist/vite-plugin-load-fallback/index.js +3 -3
- package/dist/vite-plugin-scanner/index.js +1 -1
- package/dist/vite-plugin-scripts/page-ssr.js +1 -1
- package/package.json +8 -17
- package/templates/actions.mjs +25 -18
- package/templates/content/types.d.ts +12 -10
- package/types/content.d.ts +1 -1
- package/dist/actions/runtime/store.d.ts +0 -5
- package/dist/actions/runtime/store.js +0 -18
package/astro-jsx.d.ts
CHANGED
package/astro.js
CHANGED
|
@@ -52,6 +52,7 @@ async function errorNodeUnsupported() {
|
|
|
52
52
|
Node.js v${process.versions.node} is not supported by Astro!
|
|
53
53
|
Please upgrade Node.js to a supported version: "${engines}"\n`);
|
|
54
54
|
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
55
56
|
const ci = typeof require !== 'undefined' ? require('ci-info') : await import('ci-info');
|
|
56
57
|
|
|
57
58
|
// Special instructions for CI environments, which may have special steps needed.
|
|
@@ -65,7 +66,7 @@ Please upgrade Node.js to a supported version: "${engines}"\n`);
|
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
console.log(
|
|
68
|
-
`${ci.name} CI Environment Detected!\nAdditional steps may be needed to set your Node.js version
|
|
69
|
+
`${ci.name} CI Environment Detected!\nAdditional steps may be needed to set your Node.js version:`,
|
|
69
70
|
);
|
|
70
71
|
console.log(`Documentation: https://docs.astro.build/en/guides/deploy/`);
|
|
71
72
|
if (CI_INSTRUCTIONS[platform]) {
|
package/client.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ declare module 'astro:assets' {
|
|
|
50
50
|
* This is functionally equivalent to using the `<Image />` component, as the component calls this function internally.
|
|
51
51
|
*/
|
|
52
52
|
getImage: (
|
|
53
|
-
options: import('./dist/assets/types.js').UnresolvedImageTransform
|
|
53
|
+
options: import('./dist/assets/types.js').UnresolvedImageTransform,
|
|
54
54
|
) => Promise<import('./dist/assets/types.js').GetImageResult>;
|
|
55
55
|
imageConfig: import('./dist/@types/astro.js').AstroConfig['image'];
|
|
56
56
|
getConfiguredImageService: typeof import('./dist/assets/index.js').getConfiguredImageService;
|
package/components/Picture.astro
CHANGED
|
@@ -53,7 +53,7 @@ const { fallback = 'animate' } = Astro.props;
|
|
|
53
53
|
if (supportsViewTransitions || getFallback() !== 'none') {
|
|
54
54
|
if (import.meta.env.DEV && window.matchMedia('(prefers-reduced-motion)').matches) {
|
|
55
55
|
console.warn(
|
|
56
|
-
`[transitions]: all view transition animations, including fallback animation, are disabled as this device has the prefer-reduced-motion setting enabled
|
|
56
|
+
`[transitions]: all view transition animations, including fallback animation, are disabled as this device has the prefer-reduced-motion setting enabled.`,
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
59
|
document.addEventListener('click', (ev) => {
|
package/config.d.ts
CHANGED
package/dist/@types/astro.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { MarkdownHeading, MarkdownVFile, RehypePlugins, RemarkPlugins, Rema
|
|
|
4
4
|
import type * as babel from '@babel/core';
|
|
5
5
|
import type * as rollup from 'rollup';
|
|
6
6
|
import type * as vite from 'vite';
|
|
7
|
-
import type { ActionAccept, ActionClient, ActionInputSchema } from '../actions/runtime/virtual/server.js';
|
|
7
|
+
import type { ActionAccept, ActionClient, ActionInputSchema, ActionReturnType } from '../actions/runtime/virtual/server.js';
|
|
8
8
|
import type { RemotePattern } from '../assets/utils/remotePattern.js';
|
|
9
9
|
import type { AssetsPrefix, SSRManifest, SerializedSSRManifest } from '../core/app/types.js';
|
|
10
10
|
import type { PageBuildData } from '../core/build/types.js';
|
|
@@ -182,6 +182,21 @@ export interface AstroGlobal<Props extends Record<string, any> = Record<string,
|
|
|
182
182
|
* ```
|
|
183
183
|
*/
|
|
184
184
|
getActionResult: AstroSharedContext['getActionResult'];
|
|
185
|
+
/**
|
|
186
|
+
* Call an Action directly from an Astro page or API endpoint.
|
|
187
|
+
* Expects the action function as the first parameter,
|
|
188
|
+
* and the type-safe action input as the second parameter.
|
|
189
|
+
* Returns a Promise with the action result.
|
|
190
|
+
*
|
|
191
|
+
* Example usage:
|
|
192
|
+
*
|
|
193
|
+
* ```typescript
|
|
194
|
+
* import { actions } from 'astro:actions';
|
|
195
|
+
*
|
|
196
|
+
* const result = await Astro.callAction(actions.getPost, { postId: 'test' });
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
callAction: AstroSharedContext['callAction'];
|
|
185
200
|
/** Redirect to another page
|
|
186
201
|
*
|
|
187
202
|
* Example usage:
|
|
@@ -2491,7 +2506,11 @@ interface AstroSharedContext<Props extends Record<string, any> = Record<string,
|
|
|
2491
2506
|
/**
|
|
2492
2507
|
* Get action result on the server when using a form POST.
|
|
2493
2508
|
*/
|
|
2494
|
-
getActionResult: <TAccept extends ActionAccept, TInputSchema extends ActionInputSchema<TAccept>, TAction extends ActionClient<unknown, TAccept, TInputSchema>>(action: TAction) =>
|
|
2509
|
+
getActionResult: <TAccept extends ActionAccept, TInputSchema extends ActionInputSchema<TAccept>, TAction extends ActionClient<unknown, TAccept, TInputSchema>>(action: TAction) => ActionReturnType<TAction> | undefined;
|
|
2510
|
+
/**
|
|
2511
|
+
* Call action handler from the server.
|
|
2512
|
+
*/
|
|
2513
|
+
callAction: <TAccept extends ActionAccept, TInputSchema extends ActionInputSchema<TAccept>, TOutput, TAction extends ActionClient<TOutput, TAccept, TInputSchema> | ActionClient<TOutput, TAccept, TInputSchema>['orThrow']>(action: TAction, input: Parameters<TAction>[0]) => Promise<ActionReturnType<TAction>>;
|
|
2495
2514
|
/**
|
|
2496
2515
|
* Route parameters for this request if this is a dynamic route.
|
|
2497
2516
|
*/
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type SerializedActionResult } from './virtual/shared.js';
|
|
2
2
|
export type Locals = {
|
|
3
3
|
_actionsInternal: {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
actionResult: SerializedActionResult;
|
|
5
|
+
actionName: string;
|
|
6
6
|
};
|
|
7
7
|
};
|
|
8
8
|
export declare const onRequest: import("../../@types/astro.js").MiddlewareHandler;
|
|
@@ -1,34 +1,31 @@
|
|
|
1
1
|
import { yellow } from "kleur/colors";
|
|
2
|
-
import {
|
|
3
|
-
ActionQueryStringInvalidError,
|
|
4
|
-
ActionsUsedWithForGetError
|
|
5
|
-
} from "../../core/errors/errors-data.js";
|
|
2
|
+
import { ActionQueryStringInvalidError } from "../../core/errors/errors-data.js";
|
|
6
3
|
import { AstroError } from "../../core/errors/errors.js";
|
|
7
4
|
import { defineMiddleware } from "../../core/middleware/index.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
5
|
+
import { formContentTypes, hasContentType } from "./utils.js";
|
|
6
|
+
import { getAction } from "./virtual/get-action.js";
|
|
7
|
+
import {
|
|
8
|
+
serializeActionResult
|
|
9
|
+
} from "./virtual/shared.js";
|
|
11
10
|
const onRequest = defineMiddleware(async (context, next) => {
|
|
12
11
|
const locals = context.locals;
|
|
13
12
|
const { request } = context;
|
|
14
|
-
if (locals._actionsInternal) return
|
|
15
|
-
if (request.method === "POST" && request.body === null) {
|
|
16
|
-
|
|
13
|
+
if (locals._actionsInternal) return next();
|
|
14
|
+
if (import.meta.env.DEV && request.method === "POST" && request.body === null) {
|
|
15
|
+
console.warn(
|
|
16
|
+
yellow("[astro:actions]"),
|
|
17
|
+
'POST requests should not be sent to prerendered pages. If you\'re using Actions, disable prerendering with `export const prerender = "false".'
|
|
18
|
+
);
|
|
19
|
+
return next();
|
|
17
20
|
}
|
|
18
21
|
const actionName = context.url.searchParams.get("_astroAction");
|
|
19
22
|
if (context.request.method === "POST" && actionName) {
|
|
20
23
|
return handlePost({ context, next, actionName });
|
|
21
24
|
}
|
|
22
|
-
if (context.request.method === "GET" && actionName) {
|
|
23
|
-
throw new AstroError({
|
|
24
|
-
...ActionsUsedWithForGetError,
|
|
25
|
-
message: ActionsUsedWithForGetError.message(actionName)
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
25
|
if (context.request.method === "POST") {
|
|
29
26
|
return handlePostLegacy({ context, next });
|
|
30
27
|
}
|
|
31
|
-
return
|
|
28
|
+
return next();
|
|
32
29
|
});
|
|
33
30
|
async function handlePost({
|
|
34
31
|
context,
|
|
@@ -36,8 +33,8 @@ async function handlePost({
|
|
|
36
33
|
actionName
|
|
37
34
|
}) {
|
|
38
35
|
const { request } = context;
|
|
39
|
-
const
|
|
40
|
-
if (!
|
|
36
|
+
const baseAction = await getAction(actionName);
|
|
37
|
+
if (!baseAction) {
|
|
41
38
|
throw new AstroError({
|
|
42
39
|
...ActionQueryStringInvalidError,
|
|
43
40
|
message: ActionQueryStringInvalidError.message(actionName)
|
|
@@ -48,83 +45,53 @@ async function handlePost({
|
|
|
48
45
|
if (contentType && hasContentType(contentType, formContentTypes)) {
|
|
49
46
|
formData = await request.clone().formData();
|
|
50
47
|
}
|
|
51
|
-
const
|
|
48
|
+
const action = baseAction.bind(context);
|
|
49
|
+
const actionResult = await action(formData);
|
|
52
50
|
return handleResult({ context, next, actionName, actionResult });
|
|
53
51
|
}
|
|
54
|
-
function handleResult({
|
|
52
|
+
async function handleResult({
|
|
55
53
|
context,
|
|
56
54
|
next,
|
|
57
55
|
actionName,
|
|
58
56
|
actionResult
|
|
59
57
|
}) {
|
|
60
|
-
const actionsInternal = {
|
|
61
|
-
getActionResult: (actionFn) => {
|
|
62
|
-
if (actionFn.toString() !== getActionQueryString(actionName)) {
|
|
63
|
-
return Promise.resolve(void 0);
|
|
64
|
-
}
|
|
65
|
-
return actionResult;
|
|
66
|
-
},
|
|
67
|
-
actionResult
|
|
68
|
-
};
|
|
69
58
|
const locals = context.locals;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
59
|
+
locals._actionsInternal = {
|
|
60
|
+
actionName,
|
|
61
|
+
actionResult: serializeActionResult(actionResult)
|
|
62
|
+
};
|
|
63
|
+
const response = await next();
|
|
64
|
+
if (actionResult.error) {
|
|
65
|
+
return new Response(response.body, {
|
|
66
|
+
status: actionResult.error.status,
|
|
67
|
+
statusText: actionResult.error.type,
|
|
68
|
+
headers: response.headers
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return response;
|
|
82
72
|
}
|
|
83
73
|
async function handlePostLegacy({ context, next }) {
|
|
84
74
|
const { request } = context;
|
|
85
|
-
if (context.url.pathname.startsWith("/_actions")) return
|
|
75
|
+
if (context.url.pathname.startsWith("/_actions")) return next();
|
|
86
76
|
const contentType = request.headers.get("content-type");
|
|
87
77
|
let formData;
|
|
88
78
|
if (contentType && hasContentType(contentType, formContentTypes)) {
|
|
89
79
|
formData = await request.clone().formData();
|
|
90
80
|
}
|
|
91
|
-
if (!formData) return
|
|
81
|
+
if (!formData) return next();
|
|
92
82
|
const actionName = formData.get("_astroAction");
|
|
93
|
-
if (!actionName) return
|
|
94
|
-
const
|
|
95
|
-
if (!
|
|
83
|
+
if (!actionName) return next();
|
|
84
|
+
const baseAction = await getAction(actionName);
|
|
85
|
+
if (!baseAction) {
|
|
96
86
|
throw new AstroError({
|
|
97
87
|
...ActionQueryStringInvalidError,
|
|
98
88
|
message: ActionQueryStringInvalidError.message(actionName)
|
|
99
89
|
});
|
|
100
90
|
}
|
|
101
|
-
const
|
|
91
|
+
const action = baseAction.bind(context);
|
|
92
|
+
const actionResult = await action(formData);
|
|
102
93
|
return handleResult({ context, next, actionName, actionResult });
|
|
103
94
|
}
|
|
104
|
-
function nextWithStaticStub(next, context) {
|
|
105
|
-
Object.defineProperty(context.locals, "_actionsInternal", {
|
|
106
|
-
writable: false,
|
|
107
|
-
value: {
|
|
108
|
-
getActionResult: () => {
|
|
109
|
-
console.warn(
|
|
110
|
-
yellow("[astro:actions]"),
|
|
111
|
-
"`getActionResult()` should not be called on prerendered pages. Astro can only handle actions for pages rendered on-demand."
|
|
112
|
-
);
|
|
113
|
-
return void 0;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
return ApiContextStorage.run(context, () => next());
|
|
118
|
-
}
|
|
119
|
-
function nextWithLocalsStub(next, context) {
|
|
120
|
-
Object.defineProperty(context.locals, "_actionsInternal", {
|
|
121
|
-
writable: false,
|
|
122
|
-
value: {
|
|
123
|
-
getActionResult: () => void 0
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
return ApiContextStorage.run(context, () => next());
|
|
127
|
-
}
|
|
128
95
|
export {
|
|
129
96
|
onRequest
|
|
130
97
|
};
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { formContentTypes, hasContentType } from "./utils.js";
|
|
2
|
+
import { getAction } from "./virtual/get-action.js";
|
|
3
|
+
import { serializeActionResult } from "./virtual/shared.js";
|
|
3
4
|
const POST = async (context) => {
|
|
4
5
|
const { request, url } = context;
|
|
5
|
-
const
|
|
6
|
-
if (!
|
|
6
|
+
const baseAction = await getAction(url.pathname);
|
|
7
|
+
if (!baseAction) {
|
|
7
8
|
return new Response(null, { status: 404 });
|
|
8
9
|
}
|
|
9
10
|
const contentType = request.headers.get("Content-Type");
|
|
10
11
|
const contentLength = request.headers.get("Content-Length");
|
|
11
12
|
let args;
|
|
12
|
-
if (contentLength === "0") {
|
|
13
|
+
if (!contentType || contentLength === "0") {
|
|
13
14
|
args = void 0;
|
|
14
15
|
} else if (contentType && hasContentType(contentType, formContentTypes)) {
|
|
15
16
|
args = await request.clone().formData();
|
|
@@ -18,26 +19,18 @@ const POST = async (context) => {
|
|
|
18
19
|
} else {
|
|
19
20
|
return new Response(null, { status: 415 });
|
|
20
21
|
}
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}),
|
|
29
|
-
{
|
|
30
|
-
status: result.error.status,
|
|
31
|
-
headers: {
|
|
32
|
-
"Content-Type": "application/json"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
);
|
|
22
|
+
const action = baseAction.bind(context);
|
|
23
|
+
const result = await action(args);
|
|
24
|
+
const serialized = serializeActionResult(result);
|
|
25
|
+
if (serialized.type === "empty") {
|
|
26
|
+
return new Response(null, {
|
|
27
|
+
status: serialized.status
|
|
28
|
+
});
|
|
36
29
|
}
|
|
37
|
-
return new Response(
|
|
38
|
-
status:
|
|
30
|
+
return new Response(serialized.body, {
|
|
31
|
+
status: serialized.status,
|
|
39
32
|
headers: {
|
|
40
|
-
"Content-Type":
|
|
33
|
+
"Content-Type": serialized.contentType
|
|
41
34
|
}
|
|
42
35
|
});
|
|
43
36
|
};
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ActionAccept, ActionClient } from './virtual/server.js';
|
|
1
|
+
import type { APIContext } from '../../@types/astro.js';
|
|
3
2
|
export declare const formContentTypes: string[];
|
|
4
3
|
export declare function hasContentType(contentType: string, expected: string[]): boolean;
|
|
4
|
+
export type ActionAPIContext = Omit<APIContext, 'getActionResult' | 'callAction' | 'props'>;
|
|
5
5
|
export type MaybePromise<T> = T | Promise<T>;
|
|
6
|
-
/**
|
|
7
|
-
* Get server-side action based on the route path.
|
|
8
|
-
* Imports from the virtual module `astro:internal-actions`, which maps to
|
|
9
|
-
* the user's `src/actions/index.ts` file at build-time.
|
|
10
|
-
*/
|
|
11
|
-
export declare function getAction(path: string): Promise<ActionClient<unknown, ActionAccept, ZodType> | undefined>;
|
|
12
6
|
/**
|
|
13
7
|
* Used to preserve the input schema type in the error object.
|
|
14
8
|
* This allows for type inference on the `fields` property
|
|
@@ -3,22 +3,7 @@ function hasContentType(contentType, expected) {
|
|
|
3
3
|
const type = contentType.split(";")[0].toLowerCase();
|
|
4
4
|
return expected.some((t) => type === t);
|
|
5
5
|
}
|
|
6
|
-
async function getAction(path) {
|
|
7
|
-
const pathKeys = path.replace("/_actions/", "").split(".");
|
|
8
|
-
let { server: actionLookup } = await import("astro:internal-actions");
|
|
9
|
-
for (const key of pathKeys) {
|
|
10
|
-
if (!(key in actionLookup)) {
|
|
11
|
-
return void 0;
|
|
12
|
-
}
|
|
13
|
-
actionLookup = actionLookup[key];
|
|
14
|
-
}
|
|
15
|
-
if (typeof actionLookup !== "function") {
|
|
16
|
-
return void 0;
|
|
17
|
-
}
|
|
18
|
-
return actionLookup;
|
|
19
|
-
}
|
|
20
6
|
export {
|
|
21
7
|
formContentTypes,
|
|
22
|
-
getAction,
|
|
23
8
|
hasContentType
|
|
24
9
|
};
|
|
@@ -2,9 +2,6 @@ export * from "./shared.js";
|
|
|
2
2
|
function defineAction() {
|
|
3
3
|
throw new Error("[astro:action] `defineAction()` unexpectedly used on the client.");
|
|
4
4
|
}
|
|
5
|
-
function getApiContext() {
|
|
6
|
-
throw new Error("[astro:action] `getApiContext()` unexpectedly used on the client.");
|
|
7
|
-
}
|
|
8
5
|
const z = new Proxy(
|
|
9
6
|
{},
|
|
10
7
|
{
|
|
@@ -15,6 +12,5 @@ const z = new Proxy(
|
|
|
15
12
|
);
|
|
16
13
|
export {
|
|
17
14
|
defineAction,
|
|
18
|
-
getApiContext,
|
|
19
15
|
z
|
|
20
16
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ZodType } from 'zod';
|
|
2
|
+
import type { ActionAccept, ActionClient } from './server.js';
|
|
3
|
+
/**
|
|
4
|
+
* Get server-side action based on the route path.
|
|
5
|
+
* Imports from the virtual module `astro:internal-actions`, which maps to
|
|
6
|
+
* the user's `src/actions/index.ts` file at build-time.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getAction(path: string): Promise<ActionClient<unknown, ActionAccept, ZodType> | undefined>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
async function getAction(path) {
|
|
2
|
+
const pathKeys = path.replace("/_actions/", "").split(".");
|
|
3
|
+
let { server: actionLookup } = await import("astro:internal-actions");
|
|
4
|
+
for (const key of pathKeys) {
|
|
5
|
+
if (!(key in actionLookup)) {
|
|
6
|
+
return void 0;
|
|
7
|
+
}
|
|
8
|
+
actionLookup = actionLookup[key];
|
|
9
|
+
}
|
|
10
|
+
if (typeof actionLookup !== "function") {
|
|
11
|
+
return void 0;
|
|
12
|
+
}
|
|
13
|
+
return actionLookup;
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
getAction
|
|
17
|
+
};
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
import type { ErrorInferenceObject, MaybePromise } from '../utils.js';
|
|
2
|
+
import type { ActionAPIContext, ErrorInferenceObject, MaybePromise } from '../utils.js';
|
|
4
3
|
import { type SafeResult } from './shared.js';
|
|
5
4
|
export * from './shared.js';
|
|
6
5
|
export { z } from 'zod';
|
|
7
|
-
/** @deprecated Access context from the second `handler()` parameter. */
|
|
8
|
-
export declare const getApiContext: typeof _getApiContext;
|
|
9
6
|
export type ActionAccept = 'form' | 'json';
|
|
10
7
|
export type ActionInputSchema<T extends ActionAccept | undefined> = T extends 'form' ? z.AnyZodObject | z.ZodType<FormData> : z.ZodType;
|
|
11
8
|
export type ActionHandler<TInputSchema, TOutput> = TInputSchema extends z.ZodType ? (input: z.infer<TInputSchema>, context: ActionAPIContext) => MaybePromise<TOutput> : (input: any, context: ActionAPIContext) => MaybePromise<TOutput>;
|
|
@@ -1,53 +1,61 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import { ActionCalledFromServerError } from "../../../core/errors/errors-data.js";
|
|
3
|
+
import { AstroError } from "../../../core/errors/errors.js";
|
|
3
4
|
import { ActionError, ActionInputError, callSafely } from "./shared.js";
|
|
4
5
|
export * from "./shared.js";
|
|
5
6
|
import { z as z2 } from "zod";
|
|
6
|
-
const getApiContext = _getApiContext;
|
|
7
7
|
function defineAction({
|
|
8
8
|
accept,
|
|
9
9
|
input: inputSchema,
|
|
10
10
|
handler
|
|
11
11
|
}) {
|
|
12
12
|
const serverHandler = accept === "form" ? getFormServerHandler(handler, inputSchema) : getJsonServerHandler(handler, inputSchema);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
async function safeServerHandler(unparsedInput) {
|
|
14
|
+
if (typeof this === "function") {
|
|
15
|
+
throw new AstroError(ActionCalledFromServerError);
|
|
16
|
+
}
|
|
17
|
+
return callSafely(() => serverHandler(unparsedInput, this));
|
|
18
|
+
}
|
|
16
19
|
Object.assign(safeServerHandler, {
|
|
17
|
-
orThrow
|
|
20
|
+
orThrow(unparsedInput) {
|
|
21
|
+
if (typeof this === "function") {
|
|
22
|
+
throw new AstroError(ActionCalledFromServerError);
|
|
23
|
+
}
|
|
24
|
+
return serverHandler(unparsedInput, this);
|
|
25
|
+
}
|
|
18
26
|
});
|
|
19
27
|
return safeServerHandler;
|
|
20
28
|
}
|
|
21
29
|
function getFormServerHandler(handler, inputSchema) {
|
|
22
|
-
return async (unparsedInput) => {
|
|
30
|
+
return async (unparsedInput, context) => {
|
|
23
31
|
if (!(unparsedInput instanceof FormData)) {
|
|
24
32
|
throw new ActionError({
|
|
25
33
|
code: "UNSUPPORTED_MEDIA_TYPE",
|
|
26
34
|
message: "This action only accepts FormData."
|
|
27
35
|
});
|
|
28
36
|
}
|
|
29
|
-
if (!(inputSchema instanceof z.ZodObject)) return await handler(unparsedInput,
|
|
37
|
+
if (!(inputSchema instanceof z.ZodObject)) return await handler(unparsedInput, context);
|
|
30
38
|
const parsed = await inputSchema.safeParseAsync(formDataToObject(unparsedInput, inputSchema));
|
|
31
39
|
if (!parsed.success) {
|
|
32
40
|
throw new ActionInputError(parsed.error.issues);
|
|
33
41
|
}
|
|
34
|
-
return await handler(parsed.data,
|
|
42
|
+
return await handler(parsed.data, context);
|
|
35
43
|
};
|
|
36
44
|
}
|
|
37
45
|
function getJsonServerHandler(handler, inputSchema) {
|
|
38
|
-
return async (unparsedInput) => {
|
|
46
|
+
return async (unparsedInput, context) => {
|
|
39
47
|
if (unparsedInput instanceof FormData) {
|
|
40
48
|
throw new ActionError({
|
|
41
49
|
code: "UNSUPPORTED_MEDIA_TYPE",
|
|
42
50
|
message: "This action only accepts JSON."
|
|
43
51
|
});
|
|
44
52
|
}
|
|
45
|
-
if (!inputSchema) return await handler(unparsedInput,
|
|
53
|
+
if (!inputSchema) return await handler(unparsedInput, context);
|
|
46
54
|
const parsed = await inputSchema.safeParseAsync(unparsedInput);
|
|
47
55
|
if (!parsed.success) {
|
|
48
56
|
throw new ActionInputError(parsed.error.issues);
|
|
49
57
|
}
|
|
50
|
-
return await handler(parsed.data,
|
|
58
|
+
return await handler(parsed.data, context);
|
|
51
59
|
};
|
|
52
60
|
}
|
|
53
61
|
function formDataToObject(formData, schema) {
|
|
@@ -87,6 +95,5 @@ function handleFormDataGet(key, formData, validator, baseValidator) {
|
|
|
87
95
|
export {
|
|
88
96
|
defineAction,
|
|
89
97
|
formDataToObject,
|
|
90
|
-
getApiContext,
|
|
91
98
|
z2 as z
|
|
92
99
|
};
|
|
@@ -13,8 +13,9 @@ export declare class ActionError<T extends ErrorInferenceObject = ErrorInference
|
|
|
13
13
|
});
|
|
14
14
|
static codeToStatus(code: ActionErrorCode): number;
|
|
15
15
|
static statusToCode(status: number): ActionErrorCode;
|
|
16
|
-
static
|
|
16
|
+
static fromJson(body: any): ActionError<ErrorInferenceObject>;
|
|
17
17
|
}
|
|
18
|
+
export declare function isActionError(error?: unknown): error is ActionError;
|
|
18
19
|
export declare function isInputError<T extends ErrorInferenceObject>(error?: ActionError<T>): error is ActionInputError<T>;
|
|
19
20
|
export declare function isInputError(error?: unknown): error is ActionInputError<ErrorInferenceObject>;
|
|
20
21
|
export type SafeResult<TInput extends ErrorInferenceObject, TOutput> = {
|
|
@@ -43,3 +44,19 @@ export declare function getActionProps<T extends (args: FormData) => MaybePromis
|
|
|
43
44
|
readonly name: "_astroAction";
|
|
44
45
|
readonly value: string;
|
|
45
46
|
};
|
|
47
|
+
export type SerializedActionResult = {
|
|
48
|
+
type: 'data';
|
|
49
|
+
contentType: 'application/json+devalue';
|
|
50
|
+
status: 200;
|
|
51
|
+
body: string;
|
|
52
|
+
} | {
|
|
53
|
+
type: 'error';
|
|
54
|
+
contentType: 'application/json';
|
|
55
|
+
status: number;
|
|
56
|
+
body: string;
|
|
57
|
+
} | {
|
|
58
|
+
type: 'empty';
|
|
59
|
+
status: 204;
|
|
60
|
+
};
|
|
61
|
+
export declare function serializeActionResult(res: SafeResult<any, any>): SerializedActionResult;
|
|
62
|
+
export declare function deserializeActionResult(res: SerializedActionResult): SafeResult<any, any>;
|