astro 5.14.5 → 5.14.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/actions/consts.d.ts +10 -5
  2. package/dist/actions/consts.js +15 -9
  3. package/dist/actions/loadActions.js +2 -2
  4. package/dist/actions/runtime/route.js +1 -1
  5. package/dist/actions/runtime/{virtual/server.d.ts → server.d.ts} +2 -2
  6. package/dist/actions/runtime/{virtual/server.js → server.js} +12 -12
  7. package/dist/actions/runtime/{virtual/shared.d.ts → shared.d.ts} +3 -3
  8. package/dist/actions/runtime/{virtual/shared.js → shared.js} +5 -5
  9. package/dist/actions/runtime/utils.d.ts +1 -1
  10. package/dist/actions/utils.js +1 -1
  11. package/dist/actions/{plugins.d.ts → vite-plugin-actions.d.ts} +0 -8
  12. package/dist/actions/{plugins.js → vite-plugin-actions.js} +48 -56
  13. package/dist/assets/fonts/constants.d.ts +1 -0
  14. package/dist/content/content-layer.js +3 -3
  15. package/dist/content/runtime.js +1 -11
  16. package/dist/core/app/types.d.ts +1 -1
  17. package/dist/core/base-pipeline.d.ts +1 -1
  18. package/dist/core/build/plugins/plugin-actions.js +1 -1
  19. package/dist/core/build/plugins/plugin-ssr.js +2 -2
  20. package/dist/core/constants.js +1 -1
  21. package/dist/core/create-vite.js +1 -2
  22. package/dist/core/dev/dev.js +1 -1
  23. package/dist/core/messages.js +2 -2
  24. package/dist/core/render-context.js +2 -2
  25. package/dist/env/constants.d.ts +7 -6
  26. package/dist/env/constants.js +12 -8
  27. package/dist/env/vite-plugin-env.js +18 -11
  28. package/dist/runtime/server/render/util.js +1 -1
  29. package/dist/types/public/content.d.ts +4 -2
  30. package/dist/types/public/context.d.ts +1 -1
  31. package/dist/virtual-modules/actions.d.ts +4 -0
  32. package/dist/virtual-modules/actions.js +123 -0
  33. package/package.json +3 -3
  34. package/types/actions.d.ts +2 -2
  35. package/templates/actions.mjs +0 -133
  36. /package/dist/actions/runtime/{virtual/client.d.ts → client.d.ts} +0 -0
  37. /package/dist/actions/runtime/{virtual/client.js → client.js} +0 -0
@@ -1,9 +1,14 @@
1
- export declare const VIRTUAL_MODULE_ID = "astro:actions";
2
- export declare const RESOLVED_VIRTUAL_MODULE_ID: string;
3
1
  export declare const ACTIONS_TYPES_FILE = "actions.d.ts";
4
- export declare const ASTRO_ACTIONS_INTERNAL_MODULE_ID = "astro-internal:actions";
5
- export declare const RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID: string;
6
- export declare const NOOP_ACTIONS = "\0noop-actions";
2
+ export declare const VIRTUAL_MODULE_ID = "astro:actions";
3
+ /** Used to expose shared utilities, with server or client specific implementations */
4
+ export declare const RUNTIME_VIRTUAL_MODULE_ID = "virtual:astro:actions/runtime";
5
+ export declare const RESOLVED_RUNTIME_VIRTUAL_MODULE_ID: string;
6
+ export declare const ENTRYPOINT_VIRTUAL_MODULE_ID = "virtual:astro:actions/entrypoint";
7
+ export declare const RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID: string;
8
+ /** Used to pass data from the config to the main virtual module */
9
+ export declare const OPTIONS_VIRTUAL_MODULE_ID = "virtual:astro:actions/options";
10
+ export declare const RESOLVED_OPTIONS_VIRTUAL_MODULE_ID: string;
11
+ export declare const RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID = "\0virtual:astro:actions/noop-entrypoint";
7
12
  export declare const ACTION_QUERY_PARAMS: {
8
13
  actionName: string;
9
14
  actionPayload: string;
@@ -1,9 +1,12 @@
1
- const VIRTUAL_MODULE_ID = "astro:actions";
2
- const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
3
1
  const ACTIONS_TYPES_FILE = "actions.d.ts";
4
- const ASTRO_ACTIONS_INTERNAL_MODULE_ID = "astro-internal:actions";
5
- const RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID = "\0" + ASTRO_ACTIONS_INTERNAL_MODULE_ID;
6
- const NOOP_ACTIONS = "\0noop-actions";
2
+ const VIRTUAL_MODULE_ID = "astro:actions";
3
+ const RUNTIME_VIRTUAL_MODULE_ID = "virtual:astro:actions/runtime";
4
+ const RESOLVED_RUNTIME_VIRTUAL_MODULE_ID = "\0" + RUNTIME_VIRTUAL_MODULE_ID;
5
+ const ENTRYPOINT_VIRTUAL_MODULE_ID = "virtual:astro:actions/entrypoint";
6
+ const RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID = "\0" + ENTRYPOINT_VIRTUAL_MODULE_ID;
7
+ const OPTIONS_VIRTUAL_MODULE_ID = "virtual:astro:actions/options";
8
+ const RESOLVED_OPTIONS_VIRTUAL_MODULE_ID = "\0" + OPTIONS_VIRTUAL_MODULE_ID;
9
+ const RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID = "\0virtual:astro:actions/noop-entrypoint";
7
10
  const ACTION_QUERY_PARAMS = {
8
11
  actionName: "_action",
9
12
  actionPayload: "_astroActionPayload"
@@ -13,9 +16,12 @@ export {
13
16
  ACTIONS_TYPES_FILE,
14
17
  ACTION_QUERY_PARAMS,
15
18
  ACTION_RPC_ROUTE_PATTERN,
16
- ASTRO_ACTIONS_INTERNAL_MODULE_ID,
17
- NOOP_ACTIONS,
18
- RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID,
19
- RESOLVED_VIRTUAL_MODULE_ID,
19
+ ENTRYPOINT_VIRTUAL_MODULE_ID,
20
+ OPTIONS_VIRTUAL_MODULE_ID,
21
+ RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID,
22
+ RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID,
23
+ RESOLVED_OPTIONS_VIRTUAL_MODULE_ID,
24
+ RESOLVED_RUNTIME_VIRTUAL_MODULE_ID,
25
+ RUNTIME_VIRTUAL_MODULE_ID,
20
26
  VIRTUAL_MODULE_ID
21
27
  };
@@ -1,9 +1,9 @@
1
1
  import { ActionsCantBeLoaded } from "../core/errors/errors-data.js";
2
2
  import { AstroError } from "../core/errors/index.js";
3
- import { ASTRO_ACTIONS_INTERNAL_MODULE_ID } from "./consts.js";
3
+ import { ENTRYPOINT_VIRTUAL_MODULE_ID } from "./consts.js";
4
4
  async function loadActions(moduleLoader) {
5
5
  try {
6
- return await moduleLoader.import(ASTRO_ACTIONS_INTERNAL_MODULE_ID);
6
+ return await moduleLoader.import(ENTRYPOINT_VIRTUAL_MODULE_ID);
7
7
  } catch (error) {
8
8
  throw new AstroError(ActionsCantBeLoaded, { cause: error });
9
9
  }
@@ -1,4 +1,4 @@
1
- import { getActionContext } from "./virtual/server.js";
1
+ import { getActionContext } from "./server.js";
2
2
  const POST = async (context) => {
3
3
  const { action, serializeActionResult } = getActionContext(context);
4
4
  if (action?.calledFrom !== "rpc") {
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
- import type { APIContext } from '../../../types/public/index.js';
3
- import { type ActionAPIContext, type ErrorInferenceObject, type MaybePromise } from '../utils.js';
2
+ import type { APIContext } from '../../types/public/index.js';
4
3
  import { deserializeActionResult, type SafeResult, type SerializedActionResult, serializeActionResult } from './shared.js';
4
+ import { type ActionAPIContext, type ErrorInferenceObject, type MaybePromise } from './utils.js';
5
5
  export * from './shared.js';
6
6
  export type ActionAccept = 'form' | 'json';
7
7
  export type ActionHandler<TInputSchema, TOutput> = TInputSchema extends z.ZodType ? (input: z.infer<TInputSchema>, context: ActionAPIContext) => MaybePromise<TOutput> : (input: any, context: ActionAPIContext) => MaybePromise<TOutput>;
@@ -1,16 +1,10 @@
1
1
  import { z } from "zod";
2
- import { shouldAppendForwardSlash } from "../../../core/build/util.js";
3
- import { AstroError } from "../../../core/errors/errors.js";
4
- import { ActionCalledFromServerError } from "../../../core/errors/errors-data.js";
5
- import { removeTrailingForwardSlash } from "../../../core/path.js";
6
- import { apiContextRoutesSymbol } from "../../../core/render-context.js";
7
- import { ACTION_RPC_ROUTE_PATTERN } from "../../consts.js";
8
- import {
9
- ACTION_API_CONTEXT_SYMBOL,
10
- formContentTypes,
11
- hasContentType,
12
- isActionAPIContext
13
- } from "../utils.js";
2
+ import { shouldAppendForwardSlash } from "../../core/build/util.js";
3
+ import { AstroError } from "../../core/errors/errors.js";
4
+ import { ActionCalledFromServerError } from "../../core/errors/errors-data.js";
5
+ import { removeTrailingForwardSlash } from "../../core/path.js";
6
+ import { apiContextRoutesSymbol } from "../../core/render-context.js";
7
+ import { ACTION_RPC_ROUTE_PATTERN } from "../consts.js";
14
8
  import {
15
9
  ACTION_QUERY_PARAMS,
16
10
  ActionError,
@@ -19,6 +13,12 @@ import {
19
13
  deserializeActionResult,
20
14
  serializeActionResult
21
15
  } from "./shared.js";
16
+ import {
17
+ ACTION_API_CONTEXT_SYMBOL,
18
+ formContentTypes,
19
+ hasContentType,
20
+ isActionAPIContext
21
+ } from "./utils.js";
22
22
  export * from "./shared.js";
23
23
  function defineAction({
24
24
  accept,
@@ -1,7 +1,7 @@
1
1
  import type { z } from 'zod';
2
- import { AstroError } from '../../../core/errors/errors.js';
3
- import { appendForwardSlash as _appendForwardSlash } from '../../../core/path.js';
4
- import type { ActionAPIContext as _ActionAPIContext, ErrorInferenceObject, MaybePromise } from '../utils.js';
2
+ import { AstroError } from '../../core/errors/errors.js';
3
+ import { appendForwardSlash as _appendForwardSlash } from '../../core/path.js';
4
+ import type { ActionAPIContext as _ActionAPIContext, ErrorInferenceObject, MaybePromise } from './utils.js';
5
5
  export type ActionAPIContext = _ActionAPIContext;
6
6
  export declare const ACTION_QUERY_PARAMS: {
7
7
  actionName: string;
@@ -1,12 +1,12 @@
1
1
  import { parse as devalueParse, stringify as devalueStringify } from "devalue";
2
- import { REDIRECT_STATUS_CODES } from "../../../core/constants.js";
3
- import { AstroError } from "../../../core/errors/errors.js";
2
+ import { REDIRECT_STATUS_CODES } from "../../core/constants.js";
3
+ import { AstroError } from "../../core/errors/errors.js";
4
4
  import {
5
5
  ActionCalledFromServerError,
6
6
  ActionsReturnedInvalidDataError
7
- } from "../../../core/errors/errors-data.js";
8
- import { appendForwardSlash as _appendForwardSlash } from "../../../core/path.js";
9
- import { ACTION_QUERY_PARAMS as _ACTION_QUERY_PARAMS } from "../../consts.js";
7
+ } from "../../core/errors/errors-data.js";
8
+ import { appendForwardSlash as _appendForwardSlash } from "../../core/path.js";
9
+ import { ACTION_QUERY_PARAMS as _ACTION_QUERY_PARAMS } from "../consts.js";
10
10
  const ACTION_QUERY_PARAMS = _ACTION_QUERY_PARAMS;
11
11
  const appendForwardSlash = _appendForwardSlash;
12
12
  const ACTION_ERROR_CODES = [
@@ -1,5 +1,5 @@
1
1
  import type { APIContext, AstroSharedContext } from '../../types/public/context.js';
2
- import type { SerializedActionResult } from './virtual/shared.js';
2
+ import type { SerializedActionResult } from './shared.js';
3
3
  export type ActionPayload = {
4
4
  actionResult: SerializedActionResult;
5
5
  actionName: string;
@@ -1,6 +1,6 @@
1
1
  import * as eslexer from "es-module-lexer";
2
+ import { deserializeActionResult, getActionQueryString } from "./runtime/shared.js";
2
3
  import { ACTION_API_CONTEXT_SYMBOL } from "./runtime/utils.js";
3
- import { deserializeActionResult, getActionQueryString } from "./runtime/virtual/shared.js";
4
4
  function hasActionPayload(locals) {
5
5
  return "_actionPayload" in locals;
6
6
  }
@@ -3,14 +3,6 @@ import type { Plugin as VitePlugin } from 'vite';
3
3
  import type { BuildInternals } from '../core/build/internal.js';
4
4
  import type { StaticBuildOptions } from '../core/build/types.js';
5
5
  import type { AstroSettings } from '../types/astro.js';
6
- /**
7
- * This plugin is responsible to load the known file `actions/index.js` / `actions.js`
8
- * If the file doesn't exist, it returns an empty object.
9
- * @param settings
10
- */
11
- export declare function vitePluginUserActions({ settings }: {
12
- settings: AstroSettings;
13
- }): VitePlugin;
14
6
  /**
15
7
  * This plugin is used to retrieve the final entry point of the bundled actions.ts file
16
8
  * @param opts
@@ -2,50 +2,25 @@ import { addRollupInput } from "../core/build/add-rollup-input.js";
2
2
  import { shouldAppendForwardSlash } from "../core/build/util.js";
3
3
  import { getServerOutputDirectory } from "../prerender/utils.js";
4
4
  import {
5
- ASTRO_ACTIONS_INTERNAL_MODULE_ID,
6
- NOOP_ACTIONS,
7
- RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID,
8
- RESOLVED_VIRTUAL_MODULE_ID,
5
+ ENTRYPOINT_VIRTUAL_MODULE_ID,
6
+ OPTIONS_VIRTUAL_MODULE_ID,
7
+ RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID,
8
+ RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID,
9
+ RESOLVED_OPTIONS_VIRTUAL_MODULE_ID,
10
+ RESOLVED_RUNTIME_VIRTUAL_MODULE_ID,
11
+ RUNTIME_VIRTUAL_MODULE_ID,
9
12
  VIRTUAL_MODULE_ID
10
13
  } from "./consts.js";
11
14
  import { isActionsFilePresent } from "./utils.js";
12
- function vitePluginUserActions({ settings }) {
13
- let resolvedActionsId;
14
- return {
15
- name: "@astro/plugin-actions",
16
- async resolveId(id) {
17
- if (id === NOOP_ACTIONS) {
18
- return NOOP_ACTIONS;
19
- }
20
- if (id === ASTRO_ACTIONS_INTERNAL_MODULE_ID) {
21
- const resolvedModule = await this.resolve(
22
- `${decodeURI(new URL("actions", settings.config.srcDir).pathname)}`
23
- );
24
- if (!resolvedModule) {
25
- return NOOP_ACTIONS;
26
- }
27
- resolvedActionsId = resolvedModule.id;
28
- return RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID;
29
- }
30
- },
31
- load(id) {
32
- if (id === NOOP_ACTIONS) {
33
- return "export const server = {}";
34
- } else if (id === RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID) {
35
- return `export { server } from '${resolvedActionsId}';`;
36
- }
37
- }
38
- };
39
- }
40
15
  function vitePluginActionsBuild(opts, internals) {
41
16
  return {
42
17
  name: "@astro/plugin-actions-build",
43
18
  options(options) {
44
- return addRollupInput(options, [ASTRO_ACTIONS_INTERNAL_MODULE_ID]);
19
+ return addRollupInput(options, [ENTRYPOINT_VIRTUAL_MODULE_ID]);
45
20
  },
46
21
  writeBundle(_, bundle) {
47
22
  for (const [chunkName, chunk] of Object.entries(bundle)) {
48
- if (chunk.type !== "asset" && chunk.facadeModuleId === RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID) {
23
+ if (chunk.type !== "asset" && chunk.facadeModuleId === RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID) {
49
24
  const outputDirectory = getServerOutputDirectory(opts.settings);
50
25
  internals.astroActionsEntryPoint = new URL(chunkName, outputDirectory);
51
26
  }
@@ -57,12 +32,29 @@ function vitePluginActions({
57
32
  fs,
58
33
  settings
59
34
  }) {
35
+ let resolvedActionsId;
60
36
  return {
61
37
  name: VIRTUAL_MODULE_ID,
62
38
  enforce: "pre",
63
- resolveId(id) {
39
+ async resolveId(id) {
64
40
  if (id === VIRTUAL_MODULE_ID) {
65
- return RESOLVED_VIRTUAL_MODULE_ID;
41
+ return this.resolve("astro/virtual-modules/actions.js");
42
+ }
43
+ if (id === RUNTIME_VIRTUAL_MODULE_ID) {
44
+ return RESOLVED_RUNTIME_VIRTUAL_MODULE_ID;
45
+ }
46
+ if (id === OPTIONS_VIRTUAL_MODULE_ID) {
47
+ return RESOLVED_OPTIONS_VIRTUAL_MODULE_ID;
48
+ }
49
+ if (id === ENTRYPOINT_VIRTUAL_MODULE_ID) {
50
+ const resolvedModule = await this.resolve(
51
+ `${decodeURI(new URL("actions", settings.config.srcDir).pathname)}`
52
+ );
53
+ if (!resolvedModule) {
54
+ return RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID;
55
+ }
56
+ resolvedActionsId = resolvedModule.id;
57
+ return RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID;
66
58
  }
67
59
  },
68
60
  async configureServer(server) {
@@ -77,30 +69,30 @@ function vitePluginActions({
77
69
  server.watcher.on("change", watcherCallback);
78
70
  },
79
71
  async load(id, opts) {
80
- if (id !== RESOLVED_VIRTUAL_MODULE_ID) return;
81
- let code = await fs.promises.readFile(
82
- new URL("../../templates/actions.mjs", import.meta.url),
83
- "utf-8"
84
- );
85
- if (opts?.ssr) {
86
- code += `
87
- export * from 'astro/actions/runtime/virtual/server.js';`;
88
- } else {
89
- code += `
90
- export * from 'astro/actions/runtime/virtual/client.js';`;
72
+ if (id === RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID) {
73
+ return { code: "export const server = {}" };
74
+ }
75
+ if (id === RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID) {
76
+ return { code: `export { server } from ${JSON.stringify(resolvedActionsId)};` };
77
+ }
78
+ if (id === RESOLVED_RUNTIME_VIRTUAL_MODULE_ID) {
79
+ return {
80
+ code: `export * from 'astro/actions/runtime/${opts?.ssr ? "server" : "client"}.js';`
81
+ };
82
+ }
83
+ if (id === RESOLVED_OPTIONS_VIRTUAL_MODULE_ID) {
84
+ return {
85
+ code: `
86
+ export const shouldAppendTrailingSlash = ${JSON.stringify(
87
+ shouldAppendForwardSlash(settings.config.trailingSlash, settings.config.build.format)
88
+ )};
89
+ `
90
+ };
91
91
  }
92
- code = code.replace(
93
- "'/** @TRAILING_SLASH@ **/'",
94
- JSON.stringify(
95
- shouldAppendForwardSlash(settings.config.trailingSlash, settings.config.build.format)
96
- )
97
- );
98
- return { code };
99
92
  }
100
93
  };
101
94
  }
102
95
  export {
103
96
  vitePluginActions,
104
- vitePluginActionsBuild,
105
- vitePluginUserActions
97
+ vitePluginActionsBuild
106
98
  };
@@ -1,6 +1,7 @@
1
1
  import type { Defaults, FontType } from './types.js';
2
2
  export declare const LOCAL_PROVIDER_NAME = "local";
3
3
  export declare const DEFAULTS: Defaults;
4
+ /** Used to serialize data, to be used by public APIs */
4
5
  export declare const VIRTUAL_MODULE_ID = "virtual:astro:assets/fonts/internal";
5
6
  export declare const RESOLVED_VIRTUAL_MODULE_ID: string;
6
7
  export declare const ASSETS_DIR = "fonts";
@@ -164,7 +164,7 @@ ${contentConfig.error.message}`);
164
164
  logger.info("Content config changed");
165
165
  shouldClear = true;
166
166
  }
167
- if (previousAstroVersion && previousAstroVersion !== "5.14.5") {
167
+ if (previousAstroVersion && previousAstroVersion !== "5.14.6") {
168
168
  logger.info("Astro version changed");
169
169
  shouldClear = true;
170
170
  }
@@ -172,8 +172,8 @@ ${contentConfig.error.message}`);
172
172
  logger.info("Clearing content store");
173
173
  this.#store.clearAll();
174
174
  }
175
- if ("5.14.5") {
176
- await this.#store.metaStore().set("astro-version", "5.14.5");
175
+ if ("5.14.6") {
176
+ await this.#store.metaStore().set("astro-version", "5.14.6");
177
177
  }
178
178
  if (currentConfigDigest) {
179
179
  await this.#store.metaStore().set("content-config-digest", currentConfigDigest);
@@ -41,7 +41,6 @@ function createCollectionToGlobResultMap({
41
41
  }
42
42
  const cacheHintSchema = z.object({
43
43
  tags: z.array(z.string()).optional(),
44
- maxAge: z.number().optional(),
45
44
  lastModified: z.date().optional()
46
45
  });
47
46
  async function parseLiveEntry(entry, schema, collection) {
@@ -381,18 +380,12 @@ function createGetLiveCollection({
381
380
  }
382
381
  if (processedEntries.length > 0) {
383
382
  const entryTags = /* @__PURE__ */ new Set();
384
- let minMaxAge;
385
383
  let latestModified;
386
384
  for (const entry of processedEntries) {
387
385
  if (entry.cacheHint) {
388
386
  if (entry.cacheHint.tags) {
389
387
  entry.cacheHint.tags.forEach((tag) => entryTags.add(tag));
390
388
  }
391
- if (typeof entry.cacheHint.maxAge === "number") {
392
- if (minMaxAge === void 0 || entry.cacheHint.maxAge < minMaxAge) {
393
- minMaxAge = entry.cacheHint.maxAge;
394
- }
395
- }
396
389
  if (entry.cacheHint.lastModified instanceof Date) {
397
390
  if (latestModified === void 0 || entry.cacheHint.lastModified > latestModified) {
398
391
  latestModified = entry.cacheHint.lastModified;
@@ -400,14 +393,11 @@ function createGetLiveCollection({
400
393
  }
401
394
  }
402
395
  }
403
- if (entryTags.size > 0 || minMaxAge !== void 0 || latestModified || cacheHint) {
396
+ if (entryTags.size > 0 || latestModified || cacheHint) {
404
397
  const mergedCacheHint = {};
405
398
  if (cacheHint?.tags || entryTags.size > 0) {
406
399
  mergedCacheHint.tags = [.../* @__PURE__ */ new Set([...cacheHint?.tags || [], ...entryTags])];
407
400
  }
408
- if (cacheHint?.maxAge !== void 0 || minMaxAge !== void 0) {
409
- mergedCacheHint.maxAge = cacheHint?.maxAge !== void 0 && minMaxAge !== void 0 ? Math.min(cacheHint.maxAge, minMaxAge) : cacheHint?.maxAge ?? minMaxAge;
410
- }
411
401
  if (cacheHint?.lastModified && latestModified) {
412
402
  mergedCacheHint.lastModified = cacheHint.lastModified > latestModified ? cacheHint.lastModified : latestModified;
413
403
  } else if (cacheHint?.lastModified || latestModified) {
@@ -1,5 +1,5 @@
1
1
  import type { ZodType } from 'zod';
2
- import type { ActionAccept, ActionClient } from '../../actions/runtime/virtual/server.js';
2
+ import type { ActionAccept, ActionClient } from '../../actions/runtime/server.js';
3
3
  import type { RoutingStrategies } from '../../i18n/utils.js';
4
4
  import type { ComponentInstance, SerializedRouteData } from '../../types/astro.js';
5
5
  import type { AstroMiddlewareInstance } from '../../types/public/common.js';
@@ -1,5 +1,5 @@
1
1
  import type { ZodType } from 'zod';
2
- import type { ActionAccept, ActionClient } from '../actions/runtime/virtual/server.js';
2
+ import type { ActionAccept, ActionClient } from '../actions/runtime/server.js';
3
3
  import type { ComponentInstance } from '../types/astro.js';
4
4
  import type { MiddlewareHandler, RewritePayload } from '../types/public/common.js';
5
5
  import type { RuntimeMode } from '../types/public/config.js';
@@ -1,4 +1,4 @@
1
- import { vitePluginActionsBuild } from "../../../actions/plugins.js";
1
+ import { vitePluginActionsBuild } from "../../../actions/vite-plugin-actions.js";
2
2
  function pluginActions(opts, internals) {
3
3
  return {
4
4
  targets: ["server"],
@@ -1,4 +1,4 @@
1
- import { ASTRO_ACTIONS_INTERNAL_MODULE_ID } from "../../../actions/consts.js";
1
+ import { ENTRYPOINT_VIRTUAL_MODULE_ID } from "../../../actions/consts.js";
2
2
  import { MIDDLEWARE_MODULE_ID } from "../../middleware/vite-plugin.js";
3
3
  import { routeIsRedirect } from "../../redirects/index.js";
4
4
  import { VIRTUAL_ISLAND_MAP_ID } from "../../server-islands/vite-plugin-server-islands.js";
@@ -149,7 +149,7 @@ function generateSSRCode(adapter, middlewareId) {
149
149
  ` pageMap,`,
150
150
  ` serverIslandMap,`,
151
151
  ` renderers,`,
152
- ` actions: () => import("${ASTRO_ACTIONS_INTERNAL_MODULE_ID}"),`,
152
+ ` actions: () => import("${ENTRYPOINT_VIRTUAL_MODULE_ID}"),`,
153
153
  ` middleware: ${edgeMiddleware ? "undefined" : `() => import("${middlewareId}")`}`,
154
154
  `});`,
155
155
  `const _args = ${adapter.args ? JSON.stringify(adapter.args, null, 4) : "undefined"};`,
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "5.14.5";
1
+ const ASTRO_VERSION = "5.14.6";
2
2
  const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
3
3
  const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite";
4
4
  const REWRITE_DIRECTIVE_HEADER_VALUE = "yes";
@@ -3,7 +3,7 @@ import { fileURLToPath } from "node:url";
3
3
  import { convertPathToPattern } from "tinyglobby";
4
4
  import * as vite from "vite";
5
5
  import { crawlFrameworkPkgs } from "vitefu";
6
- import { vitePluginActions, vitePluginUserActions } from "../actions/plugins.js";
6
+ import { vitePluginActions } from "../actions/vite-plugin-actions.js";
7
7
  import { getAssetsPrefix } from "../assets/utils/getAssetsPrefix.js";
8
8
  import astroAssetsPlugin from "../assets/vite-plugin-assets.js";
9
9
  import astroContainer from "../container/vite-plugin-container.js";
@@ -136,7 +136,6 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
136
136
  vitePluginFileURL(),
137
137
  astroInternationalization({ settings }),
138
138
  vitePluginActions({ fs, settings }),
139
- vitePluginUserActions({ settings }),
140
139
  vitePluginServerIslands({ settings, logger }),
141
140
  astroContainer(),
142
141
  astroHmrReloadPlugin()
@@ -22,7 +22,7 @@ async function dev(inlineConfig) {
22
22
  await telemetry.record([]);
23
23
  const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
24
24
  const logger = restart.container.logger;
25
- const currentVersion = "5.14.5";
25
+ const currentVersion = "5.14.6";
26
26
  const isPrerelease = currentVersion.includes("-");
27
27
  if (!isPrerelease) {
28
28
  try {
@@ -37,7 +37,7 @@ function serverStart({
37
37
  host,
38
38
  base
39
39
  }) {
40
- const version = "5.14.5";
40
+ const version = "5.14.6";
41
41
  const localPrefix = `${dim("\u2503")} Local `;
42
42
  const networkPrefix = `${dim("\u2503")} Network `;
43
43
  const emptyPrefix = " ".repeat(11);
@@ -274,7 +274,7 @@ function printHelp({
274
274
  message.push(
275
275
  linebreak(),
276
276
  ` ${bgGreen(black(` ${commandName} `))} ${green(
277
- `v${"5.14.5"}`
277
+ `v${"5.14.6"}`
278
278
  )} ${headline}`
279
279
  );
280
280
  }
@@ -1,6 +1,6 @@
1
1
  import { green } from "kleur/colors";
2
- import { getActionContext } from "../actions/runtime/virtual/server.js";
3
- import { deserializeActionResult } from "../actions/runtime/virtual/shared.js";
2
+ import { getActionContext } from "../actions/runtime/server.js";
3
+ import { deserializeActionResult } from "../actions/runtime/shared.js";
4
4
  import { createCallAction, createGetActionResult, hasActionPayload } from "../actions/utils.js";
5
5
  import {
6
6
  computeCurrentLocale,
@@ -1,8 +1,9 @@
1
- export declare const VIRTUAL_MODULES_IDS: {
2
- client: string;
3
- server: string;
4
- internal: string;
5
- };
6
- export declare const VIRTUAL_MODULES_IDS_VALUES: Set<string>;
1
+ export declare const CLIENT_VIRTUAL_MODULE_ID = "astro:env/client";
2
+ export declare const RESOLVED_CLIENT_VIRTUAL_MODULE_ID: string;
3
+ export declare const SERVER_VIRTUAL_MODULE_ID = "astro:env/server";
4
+ export declare const RESOLVED_SERVER_VIRTUAL_MODULE_ID: string;
5
+ /** Used to serialize the schema */
6
+ export declare const INTERNAL_VIRTUAL_MODULE_ID = "virtual:astro:env/internal";
7
+ export declare const RESOLVED_INTERNAL_VIRTUAL_MODULE_ID: string;
7
8
  export declare const ENV_TYPES_FILE = "env.d.ts";
8
9
  export declare const MODULE_TEMPLATE_URL: URL;
@@ -1,15 +1,19 @@
1
- const VIRTUAL_MODULES_IDS = {
2
- client: "astro:env/client",
3
- server: "astro:env/server",
4
- internal: "virtual:astro:env/internal"
5
- };
6
- const VIRTUAL_MODULES_IDS_VALUES = new Set(Object.values(VIRTUAL_MODULES_IDS));
1
+ const CLIENT_VIRTUAL_MODULE_ID = "astro:env/client";
2
+ const RESOLVED_CLIENT_VIRTUAL_MODULE_ID = "\0" + CLIENT_VIRTUAL_MODULE_ID;
3
+ const SERVER_VIRTUAL_MODULE_ID = "astro:env/server";
4
+ const RESOLVED_SERVER_VIRTUAL_MODULE_ID = "\0" + SERVER_VIRTUAL_MODULE_ID;
5
+ const INTERNAL_VIRTUAL_MODULE_ID = "virtual:astro:env/internal";
6
+ const RESOLVED_INTERNAL_VIRTUAL_MODULE_ID = "\0" + INTERNAL_VIRTUAL_MODULE_ID;
7
7
  const ENV_TYPES_FILE = "env.d.ts";
8
8
  const PKG_BASE = new URL("../../", import.meta.url);
9
9
  const MODULE_TEMPLATE_URL = new URL("templates/env.mjs", PKG_BASE);
10
10
  export {
11
+ CLIENT_VIRTUAL_MODULE_ID,
11
12
  ENV_TYPES_FILE,
13
+ INTERNAL_VIRTUAL_MODULE_ID,
12
14
  MODULE_TEMPLATE_URL,
13
- VIRTUAL_MODULES_IDS,
14
- VIRTUAL_MODULES_IDS_VALUES
15
+ RESOLVED_CLIENT_VIRTUAL_MODULE_ID,
16
+ RESOLVED_INTERNAL_VIRTUAL_MODULE_ID,
17
+ RESOLVED_SERVER_VIRTUAL_MODULE_ID,
18
+ SERVER_VIRTUAL_MODULE_ID
15
19
  };
@@ -1,9 +1,13 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
3
3
  import {
4
+ CLIENT_VIRTUAL_MODULE_ID,
5
+ INTERNAL_VIRTUAL_MODULE_ID,
4
6
  MODULE_TEMPLATE_URL,
5
- VIRTUAL_MODULES_IDS,
6
- VIRTUAL_MODULES_IDS_VALUES
7
+ RESOLVED_CLIENT_VIRTUAL_MODULE_ID,
8
+ RESOLVED_INTERNAL_VIRTUAL_MODULE_ID,
9
+ RESOLVED_SERVER_VIRTUAL_MODULE_ID,
10
+ SERVER_VIRTUAL_MODULE_ID
7
11
  } from "./constants.js";
8
12
  import { invalidVariablesToError } from "./errors.js";
9
13
  import { getEnvFieldType, validateEnvVariable } from "./validators.js";
@@ -47,35 +51,38 @@ function astroEnv({ settings, sync, envLoader }) {
47
51
  templates = null;
48
52
  },
49
53
  resolveId(id) {
50
- if (VIRTUAL_MODULES_IDS_VALUES.has(id)) {
51
- return resolveVirtualModuleId(id);
54
+ if (id === CLIENT_VIRTUAL_MODULE_ID) {
55
+ return RESOLVED_CLIENT_VIRTUAL_MODULE_ID;
56
+ }
57
+ if (id === SERVER_VIRTUAL_MODULE_ID) {
58
+ return RESOLVED_SERVER_VIRTUAL_MODULE_ID;
59
+ }
60
+ if (id === INTERNAL_VIRTUAL_MODULE_ID) {
61
+ return RESOLVED_INTERNAL_VIRTUAL_MODULE_ID;
52
62
  }
53
63
  },
54
64
  load(id, options) {
55
- if (id === resolveVirtualModuleId(VIRTUAL_MODULES_IDS.client)) {
65
+ if (id === RESOLVED_CLIENT_VIRTUAL_MODULE_ID) {
56
66
  ensureTemplateAreLoaded();
57
67
  return { code: templates.client };
58
68
  }
59
- if (id === resolveVirtualModuleId(VIRTUAL_MODULES_IDS.server)) {
69
+ if (id === RESOLVED_SERVER_VIRTUAL_MODULE_ID) {
60
70
  if (options?.ssr) {
61
71
  ensureTemplateAreLoaded();
62
72
  return { code: templates.server };
63
73
  }
64
74
  throw new AstroError({
65
75
  ...AstroErrorData.ServerOnlyModule,
66
- message: AstroErrorData.ServerOnlyModule.message(VIRTUAL_MODULES_IDS.server)
76
+ message: AstroErrorData.ServerOnlyModule.message(SERVER_VIRTUAL_MODULE_ID)
67
77
  });
68
78
  }
69
- if (id === resolveVirtualModuleId(VIRTUAL_MODULES_IDS.internal)) {
79
+ if (id === RESOLVED_INTERNAL_VIRTUAL_MODULE_ID) {
70
80
  ensureTemplateAreLoaded();
71
81
  return { code: templates.internal };
72
82
  }
73
83
  }
74
84
  };
75
85
  }
76
- function resolveVirtualModuleId(id) {
77
- return `\0${id}`;
78
- }
79
86
  function validatePublicVariables({
80
87
  schema,
81
88
  loadedEnv,
@@ -2,7 +2,7 @@ import { clsx } from "clsx";
2
2
  import { HTMLString, markHTMLString } from "../escape.js";
3
3
  import { isPromise } from "../util.js";
4
4
  const voidElementNames = /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i;
5
- const htmlBooleanAttributes = /^(?:allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|inert|loop|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|selected|itemscope)$/i;
5
+ const htmlBooleanAttributes = /^(?:allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|inert|loop|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|selected|itemscope)$/i;
6
6
  const AMPERSAND_REGEX = /&/g;
7
7
  const DOUBLE_QUOTE_REGEX = /"/g;
8
8
  const STATIC_DIRECTIVES = /* @__PURE__ */ new Set(["set:html", "set:text"]);
@@ -112,8 +112,6 @@ export type GetDataEntryInfoReturnType = {
112
112
  export interface CacheHint {
113
113
  /** Cache tags */
114
114
  tags?: Array<string>;
115
- /** Maximum age of the response in seconds */
116
- maxAge?: number;
117
115
  /** Last modified time of the content */
118
116
  lastModified?: Date;
119
117
  }
@@ -122,6 +120,10 @@ export interface LiveDataEntry<TData extends Record<string, any> = Record<string
122
120
  id: string;
123
121
  /** The parsed entry data */
124
122
  data: TData;
123
+ /** Optional rendered content */
124
+ rendered?: {
125
+ html: string;
126
+ };
125
127
  /** A hint for how to cache this entry */
126
128
  cacheHint?: CacheHint;
127
129
  }
@@ -1,5 +1,5 @@
1
1
  import type { z } from 'zod';
2
- import type { ActionAccept, ActionClient, ActionReturnType } from '../../actions/runtime/virtual/server.js';
2
+ import type { ActionAccept, ActionClient, ActionReturnType } from '../../actions/runtime/server.js';
3
3
  import type { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from '../../core/constants.js';
4
4
  import type { AstroCookies } from '../../core/cookies/cookies.js';
5
5
  import type { CspDirective, CspHash } from '../../core/csp/config.js';
@@ -0,0 +1,4 @@
1
+ import type { ActionClient } from '../actions/runtime/server.js';
2
+ export * from 'virtual:astro:actions/runtime';
3
+ export declare function getActionPath(action: ActionClient<any, any, any>): string;
4
+ export declare const actions: Record<string | symbol, any>;
@@ -0,0 +1,123 @@
1
+ import { shouldAppendTrailingSlash } from "virtual:astro:actions/options";
2
+ import {
3
+ ACTION_QUERY_PARAMS,
4
+ ActionError,
5
+ appendForwardSlash,
6
+ astroCalledServerError,
7
+ deserializeActionResult,
8
+ getActionQueryString
9
+ } from "../actions/runtime/shared.js";
10
+ export * from "virtual:astro:actions/runtime";
11
+ const apiContextRoutesSymbol = Symbol.for("context.routes");
12
+ const ENCODED_DOT = "%2E";
13
+ function toActionProxy(actionCallback = {}, aggregatedPath = "") {
14
+ return new Proxy(actionCallback, {
15
+ get(target, objKey) {
16
+ if (target.hasOwnProperty(objKey) || typeof objKey === "symbol") {
17
+ return target[objKey];
18
+ }
19
+ const path = aggregatedPath + encodeURIComponent(objKey.toString()).replaceAll(".", ENCODED_DOT);
20
+ function action(param) {
21
+ return handleAction(param, path, this);
22
+ }
23
+ Object.assign(action, {
24
+ queryString: getActionQueryString(path),
25
+ toString: () => action.queryString,
26
+ // redefine prototype methods as the object's own property, not the prototype's
27
+ bind: action.bind,
28
+ valueOf: () => action.valueOf,
29
+ // Progressive enhancement info for React.
30
+ $$FORM_ACTION: function() {
31
+ const searchParams = new URLSearchParams(action.toString());
32
+ return {
33
+ method: "POST",
34
+ // `name` creates a hidden input.
35
+ // It's unused by Astro, but we can't turn this off.
36
+ // At least use a name that won't conflict with a user's formData.
37
+ name: "_astroAction",
38
+ action: "?" + searchParams.toString()
39
+ };
40
+ },
41
+ // Note: `orThrow` does not have progressive enhancement info.
42
+ // If you want to throw exceptions,
43
+ // you must handle those exceptions with client JS.
44
+ async orThrow(param) {
45
+ const { data, error } = await handleAction(param, path, this);
46
+ if (error) throw error;
47
+ return data;
48
+ }
49
+ });
50
+ return toActionProxy(action, path + ".");
51
+ }
52
+ });
53
+ }
54
+ function _getActionPath(toString) {
55
+ let path = `${import.meta.env.BASE_URL.replace(/\/$/, "")}/_actions/${new URLSearchParams(toString()).get(ACTION_QUERY_PARAMS.actionName)}`;
56
+ if (shouldAppendTrailingSlash) {
57
+ path = appendForwardSlash(path);
58
+ }
59
+ return path;
60
+ }
61
+ function getActionPath(action) {
62
+ return _getActionPath(action.toString);
63
+ }
64
+ async function handleAction(param, path, context) {
65
+ if (import.meta.env.SSR && context) {
66
+ const pipeline = Reflect.get(context, apiContextRoutesSymbol);
67
+ if (!pipeline) {
68
+ throw astroCalledServerError();
69
+ }
70
+ const action = await pipeline.getAction(path);
71
+ if (!action) throw new Error(`Action not found: ${path}`);
72
+ return action.bind(context)(param);
73
+ }
74
+ const headers = new Headers();
75
+ headers.set("Accept", "application/json");
76
+ let body = param;
77
+ if (!(body instanceof FormData)) {
78
+ try {
79
+ body = JSON.stringify(param);
80
+ } catch (e) {
81
+ throw new ActionError({
82
+ code: "BAD_REQUEST",
83
+ message: `Failed to serialize request body to JSON. Full error: ${e.message}`
84
+ });
85
+ }
86
+ if (body) {
87
+ headers.set("Content-Type", "application/json");
88
+ } else {
89
+ headers.set("Content-Length", "0");
90
+ }
91
+ }
92
+ const rawResult = await fetch(
93
+ _getActionPath(() => getActionQueryString(path)),
94
+ {
95
+ method: "POST",
96
+ body,
97
+ headers
98
+ }
99
+ );
100
+ if (rawResult.status === 204) {
101
+ return deserializeActionResult({ type: "empty", status: 204 });
102
+ }
103
+ const bodyText = await rawResult.text();
104
+ if (rawResult.ok) {
105
+ return deserializeActionResult({
106
+ type: "data",
107
+ body: bodyText,
108
+ status: 200,
109
+ contentType: "application/json+devalue"
110
+ });
111
+ }
112
+ return deserializeActionResult({
113
+ type: "error",
114
+ body: bodyText,
115
+ status: rawResult.status,
116
+ contentType: "application/json"
117
+ });
118
+ }
119
+ const actions = toActionProxy();
120
+ export {
121
+ actions,
122
+ getActionPath
123
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "5.14.5",
3
+ "version": "5.14.6",
4
4
  "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
5
5
  "type": "module",
6
6
  "author": "withastro",
@@ -149,9 +149,9 @@
149
149
  "zod": "^3.25.76",
150
150
  "zod-to-json-schema": "^3.24.6",
151
151
  "zod-to-ts": "^1.2.0",
152
- "@astrojs/internal-helpers": "0.7.4",
153
152
  "@astrojs/markdown-remark": "6.3.8",
154
- "@astrojs/telemetry": "3.3.0"
153
+ "@astrojs/telemetry": "3.3.0",
154
+ "@astrojs/internal-helpers": "0.7.4"
155
155
  },
156
156
  "optionalDependencies": {
157
157
  "sharp": "^0.34.0"
@@ -1,7 +1,7 @@
1
1
  declare module 'astro:actions' {
2
- export * from 'astro/actions/runtime/virtual/server.js';
2
+ export * from 'astro/actions/runtime/server.js';
3
3
 
4
4
  export function getActionPath(
5
- action: import('astro/actions/runtime/virtual/server.js').ActionClient<any, any, any>,
5
+ action: import('astro/actions/runtime/server.js').ActionClient<any, any, any>,
6
6
  ): string;
7
7
  }
@@ -1,133 +0,0 @@
1
- import {
2
- ACTION_QUERY_PARAMS,
3
- ActionError,
4
- appendForwardSlash,
5
- astroCalledServerError,
6
- deserializeActionResult,
7
- getActionQueryString,
8
- } from 'astro:actions';
9
-
10
- const apiContextRoutesSymbol = Symbol.for('context.routes');
11
- const ENCODED_DOT = '%2E';
12
-
13
- function toActionProxy(actionCallback = {}, aggregatedPath = '') {
14
- return new Proxy(actionCallback, {
15
- get(target, objKey) {
16
- if (target.hasOwnProperty(objKey) || typeof objKey === 'symbol') {
17
- return target[objKey];
18
- }
19
- // Add the key, encoding dots so they're not interpreted as nested properties.
20
- const path =
21
- aggregatedPath + encodeURIComponent(objKey.toString()).replaceAll('.', ENCODED_DOT);
22
- function action(param) {
23
- return handleAction(param, path, this);
24
- }
25
-
26
- Object.assign(action, {
27
- queryString: getActionQueryString(path),
28
- toString: () => action.queryString,
29
- // redefine prototype methods as the object's own property, not the prototype's
30
- bind: action.bind,
31
- valueOf: () => action.valueOf,
32
- // Progressive enhancement info for React.
33
- $$FORM_ACTION: function () {
34
- const searchParams = new URLSearchParams(action.toString());
35
- return {
36
- method: 'POST',
37
- // `name` creates a hidden input.
38
- // It's unused by Astro, but we can't turn this off.
39
- // At least use a name that won't conflict with a user's formData.
40
- name: '_astroAction',
41
- action: '?' + searchParams.toString(),
42
- };
43
- },
44
- // Note: `orThrow` does not have progressive enhancement info.
45
- // If you want to throw exceptions,
46
- // you must handle those exceptions with client JS.
47
- async orThrow(param) {
48
- const { data, error } = await handleAction(param, path, this);
49
- if (error) throw error;
50
- return data;
51
- },
52
- });
53
-
54
- // recurse to construct queries for nested object paths
55
- // ex. actions.user.admins.auth()
56
- return toActionProxy(action, path + '.');
57
- },
58
- });
59
- }
60
-
61
- const SHOULD_APPEND_TRAILING_SLASH = '/** @TRAILING_SLASH@ **/';
62
-
63
- /** @param {import('astro:actions').ActionClient<any, any, any>} */
64
- export function getActionPath(action) {
65
- let path = `${import.meta.env.BASE_URL.replace(/\/$/, '')}/_actions/${new URLSearchParams(action.toString()).get(ACTION_QUERY_PARAMS.actionName)}`;
66
- if (SHOULD_APPEND_TRAILING_SLASH) {
67
- path = appendForwardSlash(path);
68
- }
69
- return path;
70
- }
71
-
72
- /**
73
- * @param {*} param argument passed to the action when called server or client-side.
74
- * @param {string} path Built path to call action by path name.
75
- * @param {import('../dist/types/public/context.js').APIContext | undefined} context Injected API context when calling actions from the server.
76
- * Usage: `actions.[name](param)`.
77
- * @returns {Promise<import('../dist/actions/runtime/virtual/shared.js').SafeResult<any, any>>}
78
- */
79
- async function handleAction(param, path, context) {
80
- // When running server-side, import the action and call it.
81
- if (import.meta.env.SSR && context) {
82
- const pipeline = Reflect.get(context, apiContextRoutesSymbol);
83
- if (!pipeline) {
84
- throw astroCalledServerError();
85
- }
86
- const action = await pipeline.getAction(path);
87
- if (!action) throw new Error(`Action not found: ${path}`);
88
- return action.bind(context)(param);
89
- }
90
-
91
- // When running client-side, make a fetch request to the action path.
92
- const headers = new Headers();
93
- headers.set('Accept', 'application/json');
94
- let body = param;
95
- if (!(body instanceof FormData)) {
96
- try {
97
- body = JSON.stringify(param);
98
- } catch (e) {
99
- throw new ActionError({
100
- code: 'BAD_REQUEST',
101
- message: `Failed to serialize request body to JSON. Full error: ${e.message}`,
102
- });
103
- }
104
- if (body) {
105
- headers.set('Content-Type', 'application/json');
106
- } else {
107
- headers.set('Content-Length', '0');
108
- }
109
- }
110
- const rawResult = await fetch(
111
- getActionPath({
112
- toString() {
113
- return getActionQueryString(path);
114
- },
115
- }),
116
- {
117
- method: 'POST',
118
- body,
119
- headers,
120
- },
121
- );
122
-
123
- if (rawResult.status === 204) {
124
- return deserializeActionResult({ type: 'empty', status: 204 });
125
- }
126
-
127
- return deserializeActionResult({
128
- type: rawResult.ok ? 'data' : 'error',
129
- body: await rawResult.text(),
130
- });
131
- }
132
-
133
- export const actions = toActionProxy();