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.
Files changed (110) hide show
  1. package/astro-jsx.d.ts +0 -1
  2. package/astro.js +2 -1
  3. package/client.d.ts +1 -1
  4. package/components/Picture.astro +2 -2
  5. package/components/ViewTransitions.astro +1 -1
  6. package/config.d.ts +1 -1
  7. package/dist/@types/astro.d.ts +21 -2
  8. package/dist/actions/runtime/middleware.d.ts +3 -3
  9. package/dist/actions/runtime/middleware.js +39 -72
  10. package/dist/actions/runtime/route.js +16 -23
  11. package/dist/actions/runtime/utils.d.ts +2 -8
  12. package/dist/actions/runtime/utils.js +0 -15
  13. package/dist/actions/runtime/virtual/client.d.ts +0 -1
  14. package/dist/actions/runtime/virtual/client.js +0 -4
  15. package/dist/actions/runtime/virtual/get-action.d.ts +8 -0
  16. package/dist/actions/runtime/virtual/get-action.js +17 -0
  17. package/dist/actions/runtime/virtual/server.d.ts +1 -4
  18. package/dist/actions/runtime/virtual/server.js +20 -13
  19. package/dist/actions/runtime/virtual/shared.d.ts +18 -1
  20. package/dist/actions/runtime/virtual/shared.js +56 -8
  21. package/dist/actions/utils.d.ts +2 -0
  22. package/dist/actions/utils.js +13 -8
  23. package/dist/assets/build/generate.js +1 -1
  24. package/dist/assets/endpoint/generic.js +1 -1
  25. package/dist/assets/endpoint/node.js +3 -3
  26. package/dist/assets/services/sharp.js +1 -1
  27. package/dist/assets/services/vendor/squoosh/avif/avif_node_dec.js +1 -1
  28. package/dist/assets/services/vendor/squoosh/avif/avif_node_enc.js +1 -1
  29. package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_node_dec.js +1 -1
  30. package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_node_enc.js +1 -1
  31. package/dist/assets/services/vendor/squoosh/webp/webp_node_dec.js +1 -1
  32. package/dist/assets/services/vendor/squoosh/webp/webp_node_enc.js +1 -1
  33. package/dist/assets/utils/metadata.js +1 -1
  34. package/dist/assets/utils/node/emitAsset.js +1 -1
  35. package/dist/assets/utils/remoteProbe.js +1 -1
  36. package/dist/assets/utils/vendor/image-size/lookup.js +1 -1
  37. package/dist/assets/utils/vendor/image-size/types/svg.js +4 -4
  38. package/dist/cli/add/index.d.ts +0 -7
  39. package/dist/cli/add/index.js +1 -2
  40. package/dist/cli/info/index.js +2 -2
  41. package/dist/cli/install-package.d.ts +0 -1
  42. package/dist/cli/install-package.js +3 -4
  43. package/dist/content/runtime-assets.d.ts +1 -1
  44. package/dist/content/utils.d.ts +2 -11
  45. package/dist/content/utils.js +0 -8
  46. package/dist/core/app/index.js +1 -1
  47. package/dist/core/build/css-asset-name.d.ts +3 -3
  48. package/dist/core/build/css-asset-name.js +15 -8
  49. package/dist/core/build/generate.d.ts +0 -4
  50. package/dist/core/build/generate.js +4 -24
  51. package/dist/core/build/index.js +8 -2
  52. package/dist/core/build/internal.d.ts +0 -18
  53. package/dist/core/build/internal.js +0 -17
  54. package/dist/core/build/page-data.d.ts +1 -1
  55. package/dist/core/build/page-data.js +1 -18
  56. package/dist/core/build/plugins/plugin-analyzer.js +0 -4
  57. package/dist/core/build/plugins/plugin-css.js +2 -2
  58. package/dist/core/build/plugins/plugin-internals.js +0 -7
  59. package/dist/core/build/plugins/plugin-manifest.d.ts +0 -10
  60. package/dist/core/build/plugins/plugin-manifest.js +0 -2
  61. package/dist/core/build/plugins/plugin-ssr.js +0 -1
  62. package/dist/core/build/types.d.ts +1 -8
  63. package/dist/core/compile/index.d.ts +0 -1
  64. package/dist/core/compile/types.d.ts +0 -7
  65. package/dist/core/config/schema.d.ts +55 -55
  66. package/dist/core/config/tsconfig.d.ts +1 -1
  67. package/dist/core/constants.js +1 -1
  68. package/dist/core/dev/dev.js +2 -2
  69. package/dist/core/dev/restart.d.ts +0 -2
  70. package/dist/core/dev/restart.js +1 -3
  71. package/dist/core/errors/dev/vite.d.ts +0 -13
  72. package/dist/core/errors/dev/vite.js +5 -6
  73. package/dist/core/errors/errors-data.d.ts +21 -5
  74. package/dist/core/errors/errors-data.js +13 -6
  75. package/dist/core/fs/index.d.ts +0 -2
  76. package/dist/core/fs/index.js +0 -5
  77. package/dist/core/logger/core.d.ts +0 -1
  78. package/dist/core/logger/core.js +0 -18
  79. package/dist/core/messages.d.ts +0 -1
  80. package/dist/core/messages.js +2 -3
  81. package/dist/core/middleware/index.js +3 -2
  82. package/dist/core/render/ssr-element.d.ts +0 -1
  83. package/dist/core/render/ssr-element.js +0 -6
  84. package/dist/core/render-context.d.ts +1 -1
  85. package/dist/core/render-context.js +9 -4
  86. package/dist/core/routing/manifest/create.js +2 -2
  87. package/dist/core/util.d.ts +0 -2
  88. package/dist/core/util.js +0 -14
  89. package/dist/events/error.js +1 -1
  90. package/dist/preferences/index.d.ts +0 -1
  91. package/dist/preferences/index.js +0 -1
  92. package/dist/runtime/client/dev-toolbar/apps/audit/index.js +1 -1
  93. package/dist/runtime/client/dev-toolbar/apps/audit/rules/perf.js +4 -2
  94. package/dist/runtime/server/render/component.d.ts +0 -3
  95. package/dist/runtime/server/render/component.js +1 -3
  96. package/dist/transitions/router.js +2 -2
  97. package/dist/type-utils.d.ts +1 -1
  98. package/dist/vite-plugin-astro-server/controller.d.ts +0 -4
  99. package/dist/vite-plugin-astro-server/controller.js +0 -2
  100. package/dist/vite-plugin-astro-server/vite.js +1 -2
  101. package/dist/vite-plugin-env/index.js +0 -1
  102. package/dist/vite-plugin-load-fallback/index.js +3 -3
  103. package/dist/vite-plugin-scanner/index.js +1 -1
  104. package/dist/vite-plugin-scripts/page-ssr.js +1 -1
  105. package/package.json +8 -17
  106. package/templates/actions.mjs +25 -18
  107. package/templates/content/types.d.ts +12 -10
  108. package/types/content.d.ts +1 -1
  109. package/dist/actions/runtime/store.d.ts +0 -5
  110. package/dist/actions/runtime/store.js +0 -18
package/astro-jsx.d.ts CHANGED
@@ -14,7 +14,6 @@ declare namespace astroHTML.JSX {
14
14
  export type Children = Child | Child[];
15
15
 
16
16
  interface ElementChildrenAttribute {
17
- // eslint-disable-next-line @typescript-eslint/ban-types
18
17
  children: {};
19
18
  }
20
19
 
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;
@@ -53,8 +53,8 @@ const optimizedImages: GetImageResult[] = await Promise.all(
53
53
  format: format,
54
54
  widths: props.widths,
55
55
  densities: props.densities,
56
- })
57
- )
56
+ }),
57
+ ),
58
58
  );
59
59
 
60
60
  let resultFallbackFormat = fallbackFormat ?? defaultFallbackFormat;
@@ -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
@@ -17,7 +17,7 @@ export function defineConfig(config: AstroUserConfig): AstroUserConfig;
17
17
  */
18
18
  export function getViteConfig(
19
19
  config: ViteUserConfig,
20
- inlineAstroConfig?: AstroInlineConfig
20
+ inlineAstroConfig?: AstroInlineConfig,
21
21
  ): ViteUserConfigFn;
22
22
 
23
23
  /**
@@ -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) => Awaited<ReturnType<TAction>> | undefined;
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 { APIContext } from '../../@types/astro.js';
1
+ import { type SerializedActionResult } from './virtual/shared.js';
2
2
  export type Locals = {
3
3
  _actionsInternal: {
4
- getActionResult: APIContext['getActionResult'];
5
- actionResult?: ReturnType<APIContext['getActionResult']>;
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 { ApiContextStorage } from "./store.js";
9
- import { formContentTypes, getAction, hasContentType } from "./utils.js";
10
- import { getActionQueryString } from "./virtual/shared.js";
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 ApiContextStorage.run(context, () => next());
15
- if (request.method === "POST" && request.body === null) {
16
- return nextWithStaticStub(next, context);
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 nextWithLocalsStub(next, context);
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 action = await getAction(actionName);
40
- if (!action) {
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 actionResult = await ApiContextStorage.run(context, () => action(formData));
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
- Object.defineProperty(locals, "_actionsInternal", { writable: false, value: actionsInternal });
71
- return ApiContextStorage.run(context, async () => {
72
- const response = await next();
73
- if (actionResult.error) {
74
- return new Response(response.body, {
75
- status: actionResult.error.status,
76
- statusText: actionResult.error.type,
77
- headers: response.headers
78
- });
79
- }
80
- return response;
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 nextWithLocalsStub(next, context);
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 nextWithLocalsStub(next, context);
81
+ if (!formData) return next();
92
82
  const actionName = formData.get("_astroAction");
93
- if (!actionName) return nextWithLocalsStub(next, context);
94
- const action = await getAction(actionName);
95
- if (!action) {
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 actionResult = await ApiContextStorage.run(context, () => action(formData));
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 { ApiContextStorage } from "./store.js";
2
- import { formContentTypes, getAction, hasContentType } from "./utils.js";
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 action = await getAction(url.pathname);
6
- if (!action) {
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 result = await ApiContextStorage.run(context, () => action(args));
22
- if (result.error) {
23
- return new Response(
24
- JSON.stringify({
25
- ...result.error,
26
- message: result.error.message,
27
- stack: import.meta.env.PROD ? void 0 : result.error.stack
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(JSON.stringify(result.data), {
38
- status: result.data !== void 0 ? 200 : 204,
30
+ return new Response(serialized.body, {
31
+ status: serialized.status,
39
32
  headers: {
40
- "Content-Type": "application/json"
33
+ "Content-Type": serialized.contentType
41
34
  }
42
35
  });
43
36
  };
@@ -1,14 +1,8 @@
1
- import type { ZodType } from 'zod';
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
  };
@@ -1,4 +1,3 @@
1
1
  export * from './shared.js';
2
2
  export declare function defineAction(): void;
3
- export declare function getApiContext(): void;
4
3
  export declare const z: {};
@@ -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 { type ActionAPIContext, getApiContext as _getApiContext } from '../store.js';
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 { getApiContext as _getApiContext } from "../store.js";
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
- const safeServerHandler = async (unparsedInput) => {
14
- return callSafely(() => serverHandler(unparsedInput));
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: serverHandler
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, getApiContext());
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, getApiContext());
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, getApiContext());
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, getApiContext());
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 fromResponse(res: Response): Promise<ActionError<ErrorInferenceObject>>;
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>;