astro 5.4.1 → 5.4.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/components/Debug.astro +3 -2
- package/dist/actions/consts.d.ts +2 -2
- package/dist/actions/consts.js +4 -4
- package/dist/actions/integration.js +1 -5
- package/dist/actions/loadActions.d.ts +8 -0
- package/dist/actions/loadActions.js +13 -0
- package/dist/actions/plugins.d.ts +8 -0
- package/dist/actions/plugins.js +24 -5
- package/dist/actions/runtime/virtual/server.d.ts +2 -2
- package/dist/actions/runtime/virtual/server.js +1 -2
- package/dist/actions/runtime/virtual/shared.d.ts +2 -0
- package/dist/actions/runtime/virtual/shared.js +8 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/content/runtime.js +2 -1
- package/dist/core/app/types.d.ts +6 -0
- package/dist/core/base-pipeline.d.ts +9 -1
- package/dist/core/base-pipeline.js +40 -1
- package/dist/core/build/generate.js +5 -3
- package/dist/core/build/internal.d.ts +2 -1
- package/dist/core/build/internal.js +3 -1
- package/dist/core/build/plugins/index.js +2 -0
- package/dist/core/build/plugins/plugin-actions.d.ts +4 -0
- package/dist/core/build/plugins/plugin-actions.js +16 -0
- package/dist/core/build/plugins/plugin-middleware.d.ts +0 -1
- package/dist/core/build/plugins/plugin-middleware.js +0 -2
- package/dist/core/build/plugins/plugin-ssr.js +4 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/errors/errors-data.d.ts +11 -0
- package/dist/core/errors/errors-data.js +6 -0
- package/dist/core/messages.js +2 -2
- package/dist/core/render-context.d.ts +7 -5
- package/dist/core/render-context.js +28 -13
- package/dist/transitions/router.js +2 -1
- package/dist/transitions/swap-functions.d.ts +1 -0
- package/dist/transitions/swap-functions.js +15 -11
- package/dist/vite-plugin-astro-server/pipeline.d.ts +0 -1
- package/dist/vite-plugin-astro-server/pipeline.js +0 -10
- package/dist/vite-plugin-astro-server/plugin.js +1 -1
- package/dist/vite-plugin-astro-server/route.js +5 -1
- package/package.json +16 -16
- package/templates/actions.mjs +8 -4
- package/dist/actions/runtime/middleware.d.ts +0 -1
- package/dist/actions/runtime/middleware.js +0 -14
- package/dist/actions/runtime/virtual/get-action.d.ts +0 -8
- package/dist/actions/runtime/virtual/get-action.js +0 -29
package/components/Debug.astro
CHANGED
|
@@ -21,8 +21,9 @@ const value = Astro.props[key];
|
|
|
21
21
|
font-size: 14px;
|
|
22
22
|
padding: 1rem 1.5rem;
|
|
23
23
|
background: white;
|
|
24
|
-
font-family:
|
|
25
|
-
'
|
|
24
|
+
font-family:
|
|
25
|
+
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans',
|
|
26
|
+
'Helvetica Neue', sans-serif;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
.astro-debug-header,
|
package/dist/actions/consts.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export declare const VIRTUAL_MODULE_ID = "astro:actions";
|
|
2
2
|
export declare const RESOLVED_VIRTUAL_MODULE_ID: string;
|
|
3
3
|
export declare const ACTIONS_TYPES_FILE = "actions.d.ts";
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
4
|
+
export declare const ASTRO_ACTIONS_INTERNAL_MODULE_ID = "astro-internal:actions";
|
|
5
|
+
export declare const RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID: string;
|
|
6
6
|
export declare const NOOP_ACTIONS = "\0noop-actions";
|
|
7
7
|
export declare const ACTION_QUERY_PARAMS: {
|
|
8
8
|
actionName: string;
|
package/dist/actions/consts.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const VIRTUAL_MODULE_ID = "astro:actions";
|
|
2
2
|
const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
|
|
3
3
|
const ACTIONS_TYPES_FILE = "actions.d.ts";
|
|
4
|
-
const
|
|
5
|
-
const
|
|
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
6
|
const NOOP_ACTIONS = "\0noop-actions";
|
|
7
7
|
const ACTION_QUERY_PARAMS = {
|
|
8
8
|
actionName: "_action",
|
|
@@ -13,9 +13,9 @@ export {
|
|
|
13
13
|
ACTIONS_TYPES_FILE,
|
|
14
14
|
ACTION_QUERY_PARAMS,
|
|
15
15
|
ACTION_RPC_ROUTE_PATTERN,
|
|
16
|
+
ASTRO_ACTIONS_INTERNAL_MODULE_ID,
|
|
16
17
|
NOOP_ACTIONS,
|
|
17
|
-
|
|
18
|
+
RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID,
|
|
18
19
|
RESOLVED_VIRTUAL_MODULE_ID,
|
|
19
|
-
VIRTUAL_INTERNAL_MODULE_ID,
|
|
20
20
|
VIRTUAL_MODULE_ID
|
|
21
21
|
};
|
|
@@ -8,17 +8,13 @@ function astroIntegrationActionsRouteHandler({
|
|
|
8
8
|
return {
|
|
9
9
|
name: VIRTUAL_MODULE_ID,
|
|
10
10
|
hooks: {
|
|
11
|
-
async "astro:config:setup"(
|
|
11
|
+
async "astro:config:setup"() {
|
|
12
12
|
settings.injectedRoutes.push({
|
|
13
13
|
pattern: ACTION_RPC_ROUTE_PATTERN,
|
|
14
14
|
entrypoint: "astro/actions/runtime/route.js",
|
|
15
15
|
prerender: false,
|
|
16
16
|
origin: "internal"
|
|
17
17
|
});
|
|
18
|
-
params.addMiddleware({
|
|
19
|
-
entrypoint: "astro/actions/runtime/middleware.js",
|
|
20
|
-
order: "post"
|
|
21
|
-
});
|
|
22
18
|
},
|
|
23
19
|
"astro:config:done": async (params) => {
|
|
24
20
|
if (params.buildOutput === "static") {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SSRActions } from '../core/app/types.js';
|
|
2
|
+
import type { ModuleLoader } from '../core/module-loader/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* It accepts a module loader and the astro settings, and it attempts to load the middlewares defined in the configuration.
|
|
5
|
+
*
|
|
6
|
+
* If not middlewares were not set, the function returns an empty array.
|
|
7
|
+
*/
|
|
8
|
+
export declare function loadActions(moduleLoader: ModuleLoader): Promise<SSRActions>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ActionsCantBeLoaded } from "../core/errors/errors-data.js";
|
|
2
|
+
import { AstroError } from "../core/errors/index.js";
|
|
3
|
+
import { ASTRO_ACTIONS_INTERNAL_MODULE_ID } from "./consts.js";
|
|
4
|
+
async function loadActions(moduleLoader) {
|
|
5
|
+
try {
|
|
6
|
+
return await moduleLoader.import(ASTRO_ACTIONS_INTERNAL_MODULE_ID);
|
|
7
|
+
} catch (error) {
|
|
8
|
+
throw new AstroError(ActionsCantBeLoaded, { cause: error });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
loadActions
|
|
13
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type fsMod from 'node:fs';
|
|
2
2
|
import type { Plugin as VitePlugin } from 'vite';
|
|
3
|
+
import type { BuildInternals } from '../core/build/internal.js';
|
|
4
|
+
import type { StaticBuildOptions } from '../core/build/types.js';
|
|
3
5
|
import type { AstroSettings } from '../types/astro.js';
|
|
4
6
|
/**
|
|
5
7
|
* This plugin is responsible to load the known file `actions/index.js` / `actions.js`
|
|
@@ -9,6 +11,12 @@ import type { AstroSettings } from '../types/astro.js';
|
|
|
9
11
|
export declare function vitePluginUserActions({ settings }: {
|
|
10
12
|
settings: AstroSettings;
|
|
11
13
|
}): VitePlugin;
|
|
14
|
+
/**
|
|
15
|
+
* This plugin is used to retrieve the final entry point of the bundled actions.ts file
|
|
16
|
+
* @param opts
|
|
17
|
+
* @param internals
|
|
18
|
+
*/
|
|
19
|
+
export declare function vitePluginActionsBuild(opts: StaticBuildOptions, internals: BuildInternals): VitePlugin;
|
|
12
20
|
export declare function vitePluginActions({ fs, settings, }: {
|
|
13
21
|
fs: typeof fsMod;
|
|
14
22
|
settings: AstroSettings;
|
package/dist/actions/plugins.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { addRollupInput } from "../core/build/add-rollup-input.js";
|
|
1
2
|
import { shouldAppendForwardSlash } from "../core/build/util.js";
|
|
3
|
+
import { getOutputDirectory } from "../prerender/utils.js";
|
|
2
4
|
import {
|
|
5
|
+
ASTRO_ACTIONS_INTERNAL_MODULE_ID,
|
|
3
6
|
NOOP_ACTIONS,
|
|
4
|
-
|
|
7
|
+
RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID,
|
|
5
8
|
RESOLVED_VIRTUAL_MODULE_ID,
|
|
6
|
-
VIRTUAL_INTERNAL_MODULE_ID,
|
|
7
9
|
VIRTUAL_MODULE_ID
|
|
8
10
|
} from "./consts.js";
|
|
9
11
|
import { isActionsFilePresent } from "./utils.js";
|
|
@@ -15,7 +17,7 @@ function vitePluginUserActions({ settings }) {
|
|
|
15
17
|
if (id === NOOP_ACTIONS) {
|
|
16
18
|
return NOOP_ACTIONS;
|
|
17
19
|
}
|
|
18
|
-
if (id ===
|
|
20
|
+
if (id === ASTRO_ACTIONS_INTERNAL_MODULE_ID) {
|
|
19
21
|
const resolvedModule = await this.resolve(
|
|
20
22
|
`${decodeURI(new URL("actions", settings.config.srcDir).pathname)}`
|
|
21
23
|
);
|
|
@@ -23,18 +25,34 @@ function vitePluginUserActions({ settings }) {
|
|
|
23
25
|
return NOOP_ACTIONS;
|
|
24
26
|
}
|
|
25
27
|
resolvedActionsId = resolvedModule.id;
|
|
26
|
-
return
|
|
28
|
+
return RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID;
|
|
27
29
|
}
|
|
28
30
|
},
|
|
29
31
|
load(id) {
|
|
30
32
|
if (id === NOOP_ACTIONS) {
|
|
31
33
|
return "export const server = {}";
|
|
32
|
-
} else if (id ===
|
|
34
|
+
} else if (id === RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID) {
|
|
33
35
|
return `export { server } from '${resolvedActionsId}';`;
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
};
|
|
37
39
|
}
|
|
40
|
+
function vitePluginActionsBuild(opts, internals) {
|
|
41
|
+
return {
|
|
42
|
+
name: "@astro/plugin-actions-build",
|
|
43
|
+
options(options) {
|
|
44
|
+
return addRollupInput(options, [ASTRO_ACTIONS_INTERNAL_MODULE_ID]);
|
|
45
|
+
},
|
|
46
|
+
writeBundle(_, bundle) {
|
|
47
|
+
for (const [chunkName, chunk] of Object.entries(bundle)) {
|
|
48
|
+
if (chunk.type !== "asset" && chunk.facadeModuleId === RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID) {
|
|
49
|
+
const outputDirectory = getOutputDirectory(opts.settings);
|
|
50
|
+
internals.astroActionsEntryPoint = new URL(chunkName, outputDirectory);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
38
56
|
function vitePluginActions({
|
|
39
57
|
fs,
|
|
40
58
|
settings
|
|
@@ -83,5 +101,6 @@ export * from 'astro/actions/runtime/virtual/client.js';`;
|
|
|
83
101
|
}
|
|
84
102
|
export {
|
|
85
103
|
vitePluginActions,
|
|
104
|
+
vitePluginActionsBuild,
|
|
86
105
|
vitePluginUserActions
|
|
87
106
|
};
|
|
@@ -19,7 +19,7 @@ export declare function defineAction<TOutput, TAccept extends ActionAccept | und
|
|
|
19
19
|
}): ActionClient<TOutput, TAccept, TInputSchema> & string;
|
|
20
20
|
/** Transform form data to an object based on a Zod schema. */
|
|
21
21
|
export declare function formDataToObject<T extends z.AnyZodObject>(formData: FormData, schema: T): Record<string, unknown>;
|
|
22
|
-
export type
|
|
22
|
+
export type AstroActionContext = {
|
|
23
23
|
/** Information about an incoming action request. */
|
|
24
24
|
action?: {
|
|
25
25
|
/** Whether an action was called using an RPC function or by using an HTML form action. */
|
|
@@ -47,4 +47,4 @@ export type ActionMiddlewareContext = {
|
|
|
47
47
|
/**
|
|
48
48
|
* Access information about Action requests from middleware.
|
|
49
49
|
*/
|
|
50
|
-
export declare function getActionContext(context: APIContext):
|
|
50
|
+
export declare function getActionContext(context: APIContext): AstroActionContext;
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
hasContentType,
|
|
12
12
|
isActionAPIContext
|
|
13
13
|
} from "../utils.js";
|
|
14
|
-
import { getAction } from "./get-action.js";
|
|
15
14
|
import {
|
|
16
15
|
ACTION_QUERY_PARAMS,
|
|
17
16
|
ActionError,
|
|
@@ -151,7 +150,7 @@ function getActionContext(context) {
|
|
|
151
150
|
pipeline.manifest.trailingSlash,
|
|
152
151
|
pipeline.manifest.buildFormat
|
|
153
152
|
) ? removeTrailingForwardSlash(callerInfo.name) : callerInfo.name;
|
|
154
|
-
const baseAction = await getAction(callerInfoName);
|
|
153
|
+
const baseAction = await pipeline.getAction(callerInfoName);
|
|
155
154
|
let input;
|
|
156
155
|
try {
|
|
157
156
|
input = await parseRequestBody(context.request);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
|
+
import { AstroError } from '../../../core/errors/errors.js';
|
|
2
3
|
import { appendForwardSlash as _appendForwardSlash } from '../../../core/path.js';
|
|
3
4
|
import type { ErrorInferenceObject, MaybePromise, ActionAPIContext as _ActionAPIContext } from '../utils.js';
|
|
4
5
|
export type ActionAPIContext = _ActionAPIContext;
|
|
@@ -56,3 +57,4 @@ export type SerializedActionResult = {
|
|
|
56
57
|
};
|
|
57
58
|
export declare function serializeActionResult(res: SafeResult<any, any>): SerializedActionResult;
|
|
58
59
|
export declare function deserializeActionResult(res: SerializedActionResult): SafeResult<any, any>;
|
|
60
|
+
export declare function astroCalledServerError(): AstroError;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { parse as devalueParse, stringify as devalueStringify } from "devalue";
|
|
2
2
|
import { REDIRECT_STATUS_CODES } from "../../../core/constants.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ActionCalledFromServerError,
|
|
5
|
+
ActionsReturnedInvalidDataError
|
|
6
|
+
} from "../../../core/errors/errors-data.js";
|
|
4
7
|
import { AstroError } from "../../../core/errors/errors.js";
|
|
5
8
|
import { appendForwardSlash as _appendForwardSlash } from "../../../core/path.js";
|
|
6
9
|
import { ACTION_QUERY_PARAMS as _ACTION_QUERY_PARAMS } from "../../consts.js";
|
|
@@ -224,12 +227,16 @@ const actionResultErrorStack = /* @__PURE__ */ function actionResultErrorStackFn
|
|
|
224
227
|
}
|
|
225
228
|
};
|
|
226
229
|
}();
|
|
230
|
+
function astroCalledServerError() {
|
|
231
|
+
return new AstroError(ActionCalledFromServerError);
|
|
232
|
+
}
|
|
227
233
|
export {
|
|
228
234
|
ACTION_ERROR_CODES,
|
|
229
235
|
ACTION_QUERY_PARAMS,
|
|
230
236
|
ActionError,
|
|
231
237
|
ActionInputError,
|
|
232
238
|
appendForwardSlash,
|
|
239
|
+
astroCalledServerError,
|
|
233
240
|
callSafely,
|
|
234
241
|
deserializeActionResult,
|
|
235
242
|
getActionQueryString,
|
|
@@ -153,7 +153,7 @@ ${contentConfig.error.message}`);
|
|
|
153
153
|
logger.info("Content config changed");
|
|
154
154
|
shouldClear = true;
|
|
155
155
|
}
|
|
156
|
-
if (previousAstroVersion && previousAstroVersion !== "5.4.
|
|
156
|
+
if (previousAstroVersion && previousAstroVersion !== "5.4.2") {
|
|
157
157
|
logger.info("Astro version changed");
|
|
158
158
|
shouldClear = true;
|
|
159
159
|
}
|
|
@@ -161,8 +161,8 @@ ${contentConfig.error.message}`);
|
|
|
161
161
|
logger.info("Clearing content store");
|
|
162
162
|
this.#store.clearAll();
|
|
163
163
|
}
|
|
164
|
-
if ("5.4.
|
|
165
|
-
await this.#store.metaStore().set("astro-version", "5.4.
|
|
164
|
+
if ("5.4.2") {
|
|
165
|
+
await this.#store.metaStore().set("astro-version", "5.4.2");
|
|
166
166
|
}
|
|
167
167
|
if (currentConfigDigest) {
|
|
168
168
|
await this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
package/dist/content/runtime.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { escape } from "html-escaper";
|
|
1
2
|
import { Traverse } from "neotraverse/modern";
|
|
2
3
|
import pLimit from "p-limit";
|
|
3
4
|
import { ZodIssueCode, z } from "zod";
|
|
@@ -324,7 +325,7 @@ async function updateImageReferencesInBody(html, fileName) {
|
|
|
324
325
|
...attributes,
|
|
325
326
|
src: image.src,
|
|
326
327
|
srcset: image.srcSet.attribute
|
|
327
|
-
}).map(([key, value]) => value ? `${key}
|
|
328
|
+
}).map(([key, value]) => value ? `${key}="${escape(value)}"` : "").join(" ");
|
|
328
329
|
});
|
|
329
330
|
}
|
|
330
331
|
function updateImageReferencesInData(data, fileName, imageAssetMap) {
|
package/dist/core/app/types.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ZodType } from 'zod';
|
|
2
|
+
import type { ActionAccept, ActionClient } from '../../actions/runtime/virtual/server.js';
|
|
1
3
|
import type { RoutingStrategies } from '../../i18n/utils.js';
|
|
2
4
|
import type { ComponentInstance, SerializedRouteData } from '../../types/astro.js';
|
|
3
5
|
import type { AstroMiddlewareInstance } from '../../types/public/common.js';
|
|
@@ -65,6 +67,7 @@ export type SSRManifest = {
|
|
|
65
67
|
key: Promise<CryptoKey>;
|
|
66
68
|
i18n: SSRManifestI18n | undefined;
|
|
67
69
|
middleware?: () => Promise<AstroMiddlewareInstance> | AstroMiddlewareInstance;
|
|
70
|
+
actions?: SSRActions;
|
|
68
71
|
checkOrigin: boolean;
|
|
69
72
|
sessionConfig?: ResolvedSessionConfig<any>;
|
|
70
73
|
cacheDir: string | URL;
|
|
@@ -74,6 +77,9 @@ export type SSRManifest = {
|
|
|
74
77
|
buildClientDir: string | URL;
|
|
75
78
|
buildServerDir: string | URL;
|
|
76
79
|
};
|
|
80
|
+
export type SSRActions = {
|
|
81
|
+
server: Record<string, ActionClient<unknown, ActionAccept, ZodType>>;
|
|
82
|
+
};
|
|
77
83
|
export type SSRManifestI18n = {
|
|
78
84
|
fallback: Record<string, string> | undefined;
|
|
79
85
|
fallbackType: 'redirect' | 'rewrite';
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import type { ZodType } from 'zod';
|
|
2
|
+
import type { ActionAccept, ActionClient } from '../actions/runtime/virtual/server.js';
|
|
1
3
|
import type { ComponentInstance } from '../types/astro.js';
|
|
2
4
|
import type { MiddlewareHandler, RewritePayload } from '../types/public/common.js';
|
|
3
5
|
import type { RuntimeMode } from '../types/public/config.js';
|
|
4
6
|
import type { RouteData, SSRLoadedRenderer, SSRManifest, SSRResult } from '../types/public/internal.js';
|
|
7
|
+
import type { SSRActions } from './app/types.js';
|
|
5
8
|
import type { Logger } from './logger/core.js';
|
|
6
9
|
import { RouteCache } from './render/route-cache.js';
|
|
7
10
|
/**
|
|
@@ -48,8 +51,10 @@ export declare abstract class Pipeline {
|
|
|
48
51
|
route: string;
|
|
49
52
|
component: string;
|
|
50
53
|
}[];
|
|
54
|
+
readonly actions: SSRActions | undefined;
|
|
51
55
|
readonly internalMiddleware: MiddlewareHandler[];
|
|
52
56
|
resolvedMiddleware: MiddlewareHandler | undefined;
|
|
57
|
+
resolvedActions: SSRActions | undefined;
|
|
53
58
|
constructor(logger: Logger, manifest: SSRManifest,
|
|
54
59
|
/**
|
|
55
60
|
* "development" or "production" only
|
|
@@ -76,7 +81,7 @@ export declare abstract class Pipeline {
|
|
|
76
81
|
matchesComponent(filePath: URL): boolean;
|
|
77
82
|
route: string;
|
|
78
83
|
component: string;
|
|
79
|
-
}[]);
|
|
84
|
+
}[], actions?: SSRActions | undefined);
|
|
80
85
|
abstract headElements(routeData: RouteData): Promise<HeadElements> | HeadElements;
|
|
81
86
|
abstract componentMetadata(routeData: RouteData): Promise<SSRResult['componentMetadata']> | void;
|
|
82
87
|
/**
|
|
@@ -100,6 +105,9 @@ export declare abstract class Pipeline {
|
|
|
100
105
|
* it returns a no-op function
|
|
101
106
|
*/
|
|
102
107
|
getMiddleware(): Promise<MiddlewareHandler>;
|
|
108
|
+
setActions(actions: SSRActions): void;
|
|
109
|
+
getActions(): Promise<SSRActions>;
|
|
110
|
+
getAction(path: string): Promise<ActionClient<unknown, ActionAccept, ZodType>>;
|
|
103
111
|
}
|
|
104
112
|
export interface HeadElements extends Pick<SSRResult, 'scripts' | 'styles' | 'links'> {
|
|
105
113
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { createI18nMiddleware } from "../i18n/middleware.js";
|
|
2
2
|
import { createOriginCheckMiddleware } from "./app/middlewares.js";
|
|
3
|
+
import { ActionNotFoundError } from "./errors/errors-data.js";
|
|
4
|
+
import { AstroError } from "./errors/index.js";
|
|
3
5
|
import { NOOP_MIDDLEWARE_FN } from "./middleware/noop-middleware.js";
|
|
4
6
|
import { sequence } from "./middleware/sequence.js";
|
|
5
7
|
import { RouteCache } from "./render/route-cache.js";
|
|
6
8
|
import { createDefaultRoutes } from "./routing/default.js";
|
|
7
9
|
class Pipeline {
|
|
8
|
-
constructor(logger, manifest, runtimeMode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, runtimeMode), site = manifest.site ? new URL(manifest.site) : void 0, defaultRoutes = createDefaultRoutes(manifest)) {
|
|
10
|
+
constructor(logger, manifest, runtimeMode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, runtimeMode), site = manifest.site ? new URL(manifest.site) : void 0, defaultRoutes = createDefaultRoutes(manifest), actions = manifest.actions) {
|
|
9
11
|
this.logger = logger;
|
|
10
12
|
this.manifest = manifest;
|
|
11
13
|
this.runtimeMode = runtimeMode;
|
|
@@ -22,6 +24,7 @@ class Pipeline {
|
|
|
22
24
|
this.routeCache = routeCache;
|
|
23
25
|
this.site = site;
|
|
24
26
|
this.defaultRoutes = defaultRoutes;
|
|
27
|
+
this.actions = actions;
|
|
25
28
|
this.internalMiddleware = [];
|
|
26
29
|
if (i18n?.strategy !== "manual") {
|
|
27
30
|
this.internalMiddleware.push(
|
|
@@ -31,6 +34,7 @@ class Pipeline {
|
|
|
31
34
|
}
|
|
32
35
|
internalMiddleware;
|
|
33
36
|
resolvedMiddleware = void 0;
|
|
37
|
+
resolvedActions = void 0;
|
|
34
38
|
/**
|
|
35
39
|
* Resolves the middleware from the manifest, and returns the `onRequest` function. If `onRequest` isn't there,
|
|
36
40
|
* it returns a no-op function
|
|
@@ -52,6 +56,41 @@ class Pipeline {
|
|
|
52
56
|
return this.resolvedMiddleware;
|
|
53
57
|
}
|
|
54
58
|
}
|
|
59
|
+
setActions(actions) {
|
|
60
|
+
this.resolvedActions = actions;
|
|
61
|
+
}
|
|
62
|
+
async getActions() {
|
|
63
|
+
if (this.resolvedActions) {
|
|
64
|
+
return this.resolvedActions;
|
|
65
|
+
} else if (this.actions) {
|
|
66
|
+
return this.actions;
|
|
67
|
+
}
|
|
68
|
+
return { server: {} };
|
|
69
|
+
}
|
|
70
|
+
async getAction(path) {
|
|
71
|
+
const pathKeys = path.split(".").map((key) => decodeURIComponent(key));
|
|
72
|
+
let { server } = await this.getActions();
|
|
73
|
+
if (!server || !(typeof server === "object")) {
|
|
74
|
+
throw new TypeError(
|
|
75
|
+
`Expected \`server\` export in actions file to be an object. Received ${typeof server}.`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
for (const key of pathKeys) {
|
|
79
|
+
if (!(key in server)) {
|
|
80
|
+
throw new AstroError({
|
|
81
|
+
...ActionNotFoundError,
|
|
82
|
+
message: ActionNotFoundError.message(pathKeys.join("."))
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
server = server[key];
|
|
86
|
+
}
|
|
87
|
+
if (typeof server !== "function") {
|
|
88
|
+
throw new TypeError(
|
|
89
|
+
`Expected handler for action ${pathKeys.join(".")} to be a function. Received ${typeof server}.`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
return server;
|
|
93
|
+
}
|
|
55
94
|
}
|
|
56
95
|
export {
|
|
57
96
|
Pipeline
|
|
@@ -44,11 +44,13 @@ async function generatePages(options, internals) {
|
|
|
44
44
|
const renderersEntryUrl = new URL("renderers.mjs", baseDirectory);
|
|
45
45
|
const renderers = await import(renderersEntryUrl.toString());
|
|
46
46
|
const middleware = internals.middlewareEntryPoint ? await import(internals.middlewareEntryPoint.toString()).then((mod) => mod.onRequest) : NOOP_MIDDLEWARE_FN;
|
|
47
|
+
const actions = internals.astroActionsEntryPoint ? await import(internals.astroActionsEntryPoint.toString()).then((mod) => mod) : { server: {} };
|
|
47
48
|
manifest = createBuildManifest(
|
|
48
49
|
options.settings,
|
|
49
50
|
internals,
|
|
50
51
|
renderers.renderers,
|
|
51
52
|
middleware,
|
|
53
|
+
actions,
|
|
52
54
|
options.key
|
|
53
55
|
);
|
|
54
56
|
}
|
|
@@ -270,8 +272,7 @@ function getUrlForPath(pathname, base, origin, format, trailingSlash, routeType)
|
|
|
270
272
|
const buildPathRelative = removeTrailingForwardSlash(removeLeadingForwardSlash(pathname)) + ending;
|
|
271
273
|
buildPathname = joinPaths(base, buildPathRelative);
|
|
272
274
|
}
|
|
273
|
-
|
|
274
|
-
return url;
|
|
275
|
+
return new URL(buildPathname, origin);
|
|
275
276
|
}
|
|
276
277
|
async function generatePath(pathname, pipeline, gopts, route) {
|
|
277
278
|
const { mod } = gopts;
|
|
@@ -358,7 +359,7 @@ function getPrettyRouteName(route) {
|
|
|
358
359
|
}
|
|
359
360
|
return route.component;
|
|
360
361
|
}
|
|
361
|
-
function createBuildManifest(settings, internals, renderers, middleware, key) {
|
|
362
|
+
function createBuildManifest(settings, internals, renderers, middleware, actions, key) {
|
|
362
363
|
let i18nManifest = void 0;
|
|
363
364
|
if (settings.config.i18n) {
|
|
364
365
|
i18nManifest = {
|
|
@@ -399,6 +400,7 @@ function createBuildManifest(settings, internals, renderers, middleware, key) {
|
|
|
399
400
|
onRequest: middleware
|
|
400
401
|
};
|
|
401
402
|
},
|
|
403
|
+
actions,
|
|
402
404
|
checkOrigin: (settings.config.security?.checkOrigin && settings.buildOutput === "server") ?? false,
|
|
403
405
|
key
|
|
404
406
|
};
|
|
@@ -69,7 +69,8 @@ export interface BuildInternals {
|
|
|
69
69
|
manifestFileName?: string;
|
|
70
70
|
entryPoints: Map<RouteData, URL>;
|
|
71
71
|
componentMetadata: SSRResult['componentMetadata'];
|
|
72
|
-
middlewareEntryPoint
|
|
72
|
+
middlewareEntryPoint: URL | undefined;
|
|
73
|
+
astroActionsEntryPoint: URL | undefined;
|
|
73
74
|
/**
|
|
74
75
|
* Chunks in the bundle that are only used in prerendering that we can delete later
|
|
75
76
|
*/
|
|
@@ -17,7 +17,9 @@ function createBuildInternals() {
|
|
|
17
17
|
staticFiles: /* @__PURE__ */ new Set(),
|
|
18
18
|
componentMetadata: /* @__PURE__ */ new Map(),
|
|
19
19
|
entryPoints: /* @__PURE__ */ new Map(),
|
|
20
|
-
prerenderOnlyChunks: []
|
|
20
|
+
prerenderOnlyChunks: [],
|
|
21
|
+
astroActionsEntryPoint: void 0,
|
|
22
|
+
middlewareEntryPoint: void 0
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
25
|
function trackPageData(internals, _component, pageData, componentModuleId, componentURL) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { astroConfigBuildPlugin } from "../../../content/vite-plugin-content-assets.js";
|
|
2
2
|
import { astroHeadBuildPlugin } from "../../../vite-plugin-head/index.js";
|
|
3
|
+
import { pluginActions } from "./plugin-actions.js";
|
|
3
4
|
import { pluginAnalyzer } from "./plugin-analyzer.js";
|
|
4
5
|
import { pluginChunks } from "./plugin-chunks.js";
|
|
5
6
|
import { pluginComponentEntry } from "./plugin-component-entry.js";
|
|
@@ -19,6 +20,7 @@ function registerAllPlugins({ internals, options, register }) {
|
|
|
19
20
|
register(pluginManifest(options, internals));
|
|
20
21
|
register(pluginRenderers(options));
|
|
21
22
|
register(pluginMiddleware(options, internals));
|
|
23
|
+
register(pluginActions(options, internals));
|
|
22
24
|
register(pluginPages(options, internals));
|
|
23
25
|
register(pluginCSS(options, internals));
|
|
24
26
|
register(astroHeadBuildPlugin(internals));
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { BuildInternals } from '../internal.js';
|
|
2
|
+
import type { AstroBuildPlugin } from '../plugin.js';
|
|
3
|
+
import type { StaticBuildOptions } from '../types.js';
|
|
4
|
+
export declare function pluginActions(opts: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { vitePluginActionsBuild } from "../../../actions/plugins.js";
|
|
2
|
+
function pluginActions(opts, internals) {
|
|
3
|
+
return {
|
|
4
|
+
targets: ["server"],
|
|
5
|
+
hooks: {
|
|
6
|
+
"build:before": () => {
|
|
7
|
+
return {
|
|
8
|
+
vitePlugin: vitePluginActionsBuild(opts, internals)
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
pluginActions
|
|
16
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { BuildInternals } from '../internal.js';
|
|
2
2
|
import type { AstroBuildPlugin } from '../plugin.js';
|
|
3
3
|
import type { StaticBuildOptions } from '../types.js';
|
|
4
|
-
export { MIDDLEWARE_MODULE_ID } from '../../middleware/vite-plugin.js';
|
|
5
4
|
export declare function pluginMiddleware(opts: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { vitePluginMiddlewareBuild } from "../../middleware/vite-plugin.js";
|
|
2
|
-
import { MIDDLEWARE_MODULE_ID } from "../../middleware/vite-plugin.js";
|
|
3
2
|
function pluginMiddleware(opts, internals) {
|
|
4
3
|
return {
|
|
5
4
|
targets: ["server"],
|
|
@@ -13,6 +12,5 @@ function pluginMiddleware(opts, internals) {
|
|
|
13
12
|
};
|
|
14
13
|
}
|
|
15
14
|
export {
|
|
16
|
-
MIDDLEWARE_MODULE_ID,
|
|
17
15
|
pluginMiddleware
|
|
18
16
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { ASTRO_ACTIONS_INTERNAL_MODULE_ID } from "../../../actions/consts.js";
|
|
2
|
+
import { MIDDLEWARE_MODULE_ID } from "../../middleware/vite-plugin.js";
|
|
1
3
|
import { routeIsRedirect } from "../../redirects/index.js";
|
|
2
4
|
import { VIRTUAL_ISLAND_MAP_ID } from "../../server-islands/vite-plugin-server-islands.js";
|
|
3
5
|
import { addRollupInput } from "../add-rollup-input.js";
|
|
4
6
|
import { SSR_MANIFEST_VIRTUAL_MODULE_ID } from "./plugin-manifest.js";
|
|
5
|
-
import { MIDDLEWARE_MODULE_ID } from "./plugin-middleware.js";
|
|
6
7
|
import { ASTRO_PAGE_MODULE_ID } from "./plugin-pages.js";
|
|
7
8
|
import { RENDERERS_MODULE_ID } from "./plugin-renderers.js";
|
|
8
9
|
import { getVirtualModulePageName } from "./util.js";
|
|
@@ -138,6 +139,7 @@ function generateSSRCode(adapter, middlewareId) {
|
|
|
138
139
|
const edgeMiddleware = adapter?.adapterFeatures?.edgeMiddleware ?? false;
|
|
139
140
|
const imports = [
|
|
140
141
|
`import { renderers } from '${RENDERERS_MODULE_ID}';`,
|
|
142
|
+
`import * as actions from '${ASTRO_ACTIONS_INTERNAL_MODULE_ID}';`,
|
|
141
143
|
`import * as serverEntrypointModule from '${ADAPTER_VIRTUAL_MODULE_ID}';`,
|
|
142
144
|
`import { manifest as defaultManifest } from '${SSR_MANIFEST_VIRTUAL_MODULE_ID}';`,
|
|
143
145
|
`import { serverIslandMap } from '${VIRTUAL_ISLAND_MAP_ID}';`
|
|
@@ -148,6 +150,7 @@ function generateSSRCode(adapter, middlewareId) {
|
|
|
148
150
|
` pageMap,`,
|
|
149
151
|
` serverIslandMap,`,
|
|
150
152
|
` renderers,`,
|
|
153
|
+
` actions,`,
|
|
151
154
|
` middleware: ${edgeMiddleware ? "undefined" : `() => import("${middlewareId}")`}`,
|
|
152
155
|
`});`,
|
|
153
156
|
`const _args = ${adapter.args ? JSON.stringify(adapter.args, null, 4) : "undefined"};`,
|
package/dist/core/constants.js
CHANGED
package/dist/core/dev/dev.js
CHANGED
|
@@ -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.4.
|
|
25
|
+
const currentVersion = "5.4.2";
|
|
26
26
|
const isPrerelease = currentVersion.includes("-");
|
|
27
27
|
if (!isPrerelease) {
|
|
28
28
|
try {
|
|
@@ -803,6 +803,17 @@ export declare const MiddlewareCantBeLoaded: {
|
|
|
803
803
|
title: string;
|
|
804
804
|
message: string;
|
|
805
805
|
};
|
|
806
|
+
/**
|
|
807
|
+
* @docs
|
|
808
|
+
* @description
|
|
809
|
+
* Thrown in development mode when the actions file can't be loaded.
|
|
810
|
+
*
|
|
811
|
+
*/
|
|
812
|
+
export declare const ActionsCantBeLoaded: {
|
|
813
|
+
name: string;
|
|
814
|
+
title: string;
|
|
815
|
+
message: string;
|
|
816
|
+
};
|
|
806
817
|
/**
|
|
807
818
|
* @docs
|
|
808
819
|
* @see
|
|
@@ -285,6 +285,11 @@ const MiddlewareCantBeLoaded = {
|
|
|
285
285
|
title: "Can't load the middleware.",
|
|
286
286
|
message: "An unknown error was thrown while loading your middleware."
|
|
287
287
|
};
|
|
288
|
+
const ActionsCantBeLoaded = {
|
|
289
|
+
name: "ActionsCantBeLoaded",
|
|
290
|
+
title: "Can't load the Astro actions.",
|
|
291
|
+
message: "An unknown error was thrown while loading the Astro actions file."
|
|
292
|
+
};
|
|
288
293
|
const LocalImageUsedWrongly = {
|
|
289
294
|
name: "LocalImageUsedWrongly",
|
|
290
295
|
title: "Local images must be imported.",
|
|
@@ -666,6 +671,7 @@ const SessionConfigWithoutFlagError = {
|
|
|
666
671
|
export {
|
|
667
672
|
ActionCalledFromServerError,
|
|
668
673
|
ActionNotFoundError,
|
|
674
|
+
ActionsCantBeLoaded,
|
|
669
675
|
ActionsReturnedInvalidDataError,
|
|
670
676
|
ActionsWithoutServerOutputError,
|
|
671
677
|
AdapterSupportOutputMismatch,
|
package/dist/core/messages.js
CHANGED
|
@@ -38,7 +38,7 @@ function serverStart({
|
|
|
38
38
|
host,
|
|
39
39
|
base
|
|
40
40
|
}) {
|
|
41
|
-
const version = "5.4.
|
|
41
|
+
const version = "5.4.2";
|
|
42
42
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
43
43
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
44
44
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -281,7 +281,7 @@ function printHelp({
|
|
|
281
281
|
message.push(
|
|
282
282
|
linebreak(),
|
|
283
283
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
284
|
-
`v${"5.4.
|
|
284
|
+
`v${"5.4.2"}`
|
|
285
285
|
)} ${headline}`
|
|
286
286
|
);
|
|
287
287
|
}
|
|
@@ -3,6 +3,7 @@ import type { ComponentInstance } from '../types/astro.js';
|
|
|
3
3
|
import type { MiddlewareHandler, Props } from '../types/public/common.js';
|
|
4
4
|
import type { APIContext, AstroGlobal, AstroGlobalPartial } from '../types/public/context.js';
|
|
5
5
|
import type { RouteData, SSRResult } from '../types/public/internal.js';
|
|
6
|
+
import type { SSRActions } from './app/types.js';
|
|
6
7
|
import { AstroCookies } from './cookies/index.js';
|
|
7
8
|
import { type Pipeline } from './render/index.js';
|
|
8
9
|
import { AstroSession } from './session.js';
|
|
@@ -16,6 +17,7 @@ export declare class RenderContext {
|
|
|
16
17
|
readonly pipeline: Pipeline;
|
|
17
18
|
locals: App.Locals;
|
|
18
19
|
readonly middleware: MiddlewareHandler;
|
|
20
|
+
readonly actions: SSRActions;
|
|
19
21
|
pathname: string;
|
|
20
22
|
request: Request;
|
|
21
23
|
routeData: RouteData;
|
|
@@ -36,7 +38,7 @@ export declare class RenderContext {
|
|
|
36
38
|
* A safety net in case of loops
|
|
37
39
|
*/
|
|
38
40
|
counter: number;
|
|
39
|
-
static create({ locals, middleware, pathname, pipeline, request, routeData, clientAddress, status, props, partial, }: Pick<RenderContext, 'pathname' | 'pipeline' | 'request' | 'routeData' | 'clientAddress'> & Partial<Pick<RenderContext, 'locals' | 'middleware' | 'status' | 'props' | 'partial'>>): Promise<RenderContext>;
|
|
41
|
+
static create({ locals, middleware, pathname, pipeline, request, routeData, clientAddress, status, props, partial, actions, }: Pick<RenderContext, 'pathname' | 'pipeline' | 'request' | 'routeData' | 'clientAddress'> & Partial<Pick<RenderContext, 'locals' | 'middleware' | 'status' | 'props' | 'partial' | 'actions'>>): Promise<RenderContext>;
|
|
40
42
|
/**
|
|
41
43
|
* The main function of the RenderContext.
|
|
42
44
|
*
|
|
@@ -49,9 +51,9 @@ export declare class RenderContext {
|
|
|
49
51
|
* - fallback
|
|
50
52
|
*/
|
|
51
53
|
render(componentInstance: ComponentInstance | undefined, slots?: Record<string, any>): Promise<Response>;
|
|
52
|
-
createAPIContext(props: APIContext['props']): APIContext;
|
|
54
|
+
createAPIContext(props: APIContext['props'], context: ActionAPIContext): APIContext;
|
|
53
55
|
createActionAPIContext(): ActionAPIContext;
|
|
54
|
-
createResult(mod: ComponentInstance): Promise<SSRResult>;
|
|
56
|
+
createResult(mod: ComponentInstance, ctx: ActionAPIContext): Promise<SSRResult>;
|
|
55
57
|
/**
|
|
56
58
|
* The Astro global is sourced in 3 different phases:
|
|
57
59
|
* - **Static**: `.generator` and `.glob` is printed by the compiler, instantiated once per process per astro file
|
|
@@ -60,8 +62,8 @@ export declare class RenderContext {
|
|
|
60
62
|
*
|
|
61
63
|
* The page level partial is used as the prototype of the user-visible `Astro` global object, which is instantiated once per use of a component.
|
|
62
64
|
*/
|
|
63
|
-
createAstro(result: SSRResult, astroStaticPartial: AstroGlobalPartial, props: Record<string, any>, slotValues: Record<string, any> | null): AstroGlobal;
|
|
64
|
-
createAstroPagePartial(result: SSRResult, astroStaticPartial: AstroGlobalPartial): Omit<AstroGlobal, 'props' | 'self' | 'slots'>;
|
|
65
|
+
createAstro(result: SSRResult, astroStaticPartial: AstroGlobalPartial, props: Record<string, any>, slotValues: Record<string, any> | null, apiContext: ActionAPIContext): AstroGlobal;
|
|
66
|
+
createAstroPagePartial(result: SSRResult, astroStaticPartial: AstroGlobalPartial, apiContext: ActionAPIContext): Omit<AstroGlobal, 'props' | 'self' | 'slots'>;
|
|
65
67
|
getClientAddress(): string;
|
|
66
68
|
computeCurrentLocale(): string | undefined;
|
|
67
69
|
computePreferredLocale(): string | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getActionContext } from "../actions/runtime/virtual/server.js";
|
|
1
2
|
import { deserializeActionResult } from "../actions/runtime/virtual/shared.js";
|
|
2
3
|
import { createCallAction, createGetActionResult, hasActionPayload } from "../actions/utils.js";
|
|
3
4
|
import {
|
|
@@ -29,10 +30,11 @@ import { copyRequest, getOriginPathname, setOriginPathname } from "./routing/rew
|
|
|
29
30
|
import { AstroSession } from "./session.js";
|
|
30
31
|
const apiContextRoutesSymbol = Symbol.for("context.routes");
|
|
31
32
|
class RenderContext {
|
|
32
|
-
constructor(pipeline, locals, middleware, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = new URL(request.url), props = {}, partial = void 0, session = pipeline.manifest.sessionConfig ? new AstroSession(cookies, pipeline.manifest.sessionConfig) : void 0) {
|
|
33
|
+
constructor(pipeline, locals, middleware, actions, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = new URL(request.url), props = {}, partial = void 0, session = pipeline.manifest.sessionConfig ? new AstroSession(cookies, pipeline.manifest.sessionConfig) : void 0) {
|
|
33
34
|
this.pipeline = pipeline;
|
|
34
35
|
this.locals = locals;
|
|
35
36
|
this.middleware = middleware;
|
|
37
|
+
this.actions = actions;
|
|
36
38
|
this.pathname = pathname;
|
|
37
39
|
this.request = request;
|
|
38
40
|
this.routeData = routeData;
|
|
@@ -63,14 +65,17 @@ class RenderContext {
|
|
|
63
65
|
clientAddress,
|
|
64
66
|
status = 200,
|
|
65
67
|
props,
|
|
66
|
-
partial = void 0
|
|
68
|
+
partial = void 0,
|
|
69
|
+
actions
|
|
67
70
|
}) {
|
|
68
71
|
const pipelineMiddleware = await pipeline.getMiddleware();
|
|
72
|
+
const pipelineActions = actions ?? await pipeline.getActions();
|
|
69
73
|
setOriginPathname(request, pathname);
|
|
70
74
|
return new RenderContext(
|
|
71
75
|
pipeline,
|
|
72
76
|
locals,
|
|
73
77
|
sequence(...pipeline.internalMiddleware, middleware ?? pipelineMiddleware),
|
|
78
|
+
pipelineActions,
|
|
74
79
|
pathname,
|
|
75
80
|
request,
|
|
76
81
|
routeData,
|
|
@@ -106,7 +111,8 @@ class RenderContext {
|
|
|
106
111
|
serverLike,
|
|
107
112
|
base: manifest.base
|
|
108
113
|
});
|
|
109
|
-
const
|
|
114
|
+
const actionApiContext = this.createActionAPIContext();
|
|
115
|
+
const apiContext = this.createAPIContext(props, actionApiContext);
|
|
110
116
|
this.counter++;
|
|
111
117
|
if (this.counter === 4) {
|
|
112
118
|
return new Response("Loop Detected", {
|
|
@@ -153,6 +159,13 @@ class RenderContext {
|
|
|
153
159
|
this.status = 200;
|
|
154
160
|
}
|
|
155
161
|
let response2;
|
|
162
|
+
if (!ctx.isPrerendered) {
|
|
163
|
+
const { action, setActionResult, serializeActionResult } = getActionContext(ctx);
|
|
164
|
+
if (action?.calledFrom === "form") {
|
|
165
|
+
const actionResult = await action.handler();
|
|
166
|
+
setActionResult(action.name, serializeActionResult(actionResult));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
156
169
|
switch (this.routeData.type) {
|
|
157
170
|
case "endpoint": {
|
|
158
171
|
response2 = await renderEndpoint(
|
|
@@ -166,7 +179,7 @@ class RenderContext {
|
|
|
166
179
|
case "redirect":
|
|
167
180
|
return renderRedirect(this);
|
|
168
181
|
case "page": {
|
|
169
|
-
const result = await this.createResult(componentInstance);
|
|
182
|
+
const result = await this.createResult(componentInstance, actionApiContext);
|
|
170
183
|
try {
|
|
171
184
|
response2 = await renderPage(
|
|
172
185
|
result,
|
|
@@ -209,8 +222,7 @@ class RenderContext {
|
|
|
209
222
|
attachCookiesToResponse(response, cookies);
|
|
210
223
|
return response;
|
|
211
224
|
}
|
|
212
|
-
createAPIContext(props) {
|
|
213
|
-
const context = this.createActionAPIContext();
|
|
225
|
+
createAPIContext(props, context) {
|
|
214
226
|
const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } });
|
|
215
227
|
Reflect.set(context, apiContextRoutesSymbol, this.pipeline);
|
|
216
228
|
return Object.assign(context, {
|
|
@@ -295,7 +307,7 @@ class RenderContext {
|
|
|
295
307
|
session
|
|
296
308
|
};
|
|
297
309
|
}
|
|
298
|
-
async createResult(mod) {
|
|
310
|
+
async createResult(mod, ctx) {
|
|
299
311
|
const { cookies, pathname, pipeline, routeData, status } = this;
|
|
300
312
|
const { clientDirectives, inlinedScripts, compressHTML, manifest, renderers, resolve } = pipeline;
|
|
301
313
|
const { links, scripts, styles } = await pipeline.headElements(routeData);
|
|
@@ -324,7 +336,7 @@ class RenderContext {
|
|
|
324
336
|
compressHTML,
|
|
325
337
|
cookies,
|
|
326
338
|
/** This function returns the `Astro` faux-global */
|
|
327
|
-
createAstro: (astroGlobal, props, slots) => this.createAstro(result, astroGlobal, props, slots),
|
|
339
|
+
createAstro: (astroGlobal, props, slots) => this.createAstro(result, astroGlobal, props, slots, ctx),
|
|
328
340
|
links,
|
|
329
341
|
params: this.params,
|
|
330
342
|
partial,
|
|
@@ -361,17 +373,19 @@ class RenderContext {
|
|
|
361
373
|
*
|
|
362
374
|
* The page level partial is used as the prototype of the user-visible `Astro` global object, which is instantiated once per use of a component.
|
|
363
375
|
*/
|
|
364
|
-
createAstro(result, astroStaticPartial, props, slotValues) {
|
|
376
|
+
createAstro(result, astroStaticPartial, props, slotValues, apiContext) {
|
|
365
377
|
let astroPagePartial;
|
|
366
378
|
if (this.isRewriting) {
|
|
367
379
|
astroPagePartial = this.#astroPagePartial = this.createAstroPagePartial(
|
|
368
380
|
result,
|
|
369
|
-
astroStaticPartial
|
|
381
|
+
astroStaticPartial,
|
|
382
|
+
apiContext
|
|
370
383
|
);
|
|
371
384
|
} else {
|
|
372
385
|
astroPagePartial = this.#astroPagePartial ??= this.createAstroPagePartial(
|
|
373
386
|
result,
|
|
374
|
-
astroStaticPartial
|
|
387
|
+
astroStaticPartial,
|
|
388
|
+
apiContext
|
|
375
389
|
);
|
|
376
390
|
}
|
|
377
391
|
const astroComponentPartial = { props, self: null };
|
|
@@ -394,7 +408,7 @@ class RenderContext {
|
|
|
394
408
|
});
|
|
395
409
|
return Astro;
|
|
396
410
|
}
|
|
397
|
-
createAstroPagePartial(result, astroStaticPartial) {
|
|
411
|
+
createAstroPagePartial(result, astroStaticPartial, apiContext) {
|
|
398
412
|
const renderContext = this;
|
|
399
413
|
const { cookies, locals, params, pipeline, url, session } = this;
|
|
400
414
|
const { response } = result;
|
|
@@ -409,6 +423,7 @@ class RenderContext {
|
|
|
409
423
|
const rewrite = async (reroutePayload) => {
|
|
410
424
|
return await this.#executeRewrite(reroutePayload);
|
|
411
425
|
};
|
|
426
|
+
const callAction = createCallAction(apiContext);
|
|
412
427
|
return {
|
|
413
428
|
generator: astroStaticPartial.generator,
|
|
414
429
|
glob: astroStaticPartial.glob,
|
|
@@ -437,7 +452,7 @@ class RenderContext {
|
|
|
437
452
|
site: pipeline.site,
|
|
438
453
|
getActionResult: createGetActionResult(locals),
|
|
439
454
|
get callAction() {
|
|
440
|
-
return
|
|
455
|
+
return callAction;
|
|
441
456
|
},
|
|
442
457
|
url,
|
|
443
458
|
get originPathname() {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TRANSITION_AFTER_SWAP, doPreparation, doSwap } from "./events.js";
|
|
2
|
+
import { detectScriptExecuted } from "./swap-functions.js";
|
|
2
3
|
const inBrowser = import.meta.env.SSR === false;
|
|
3
4
|
const pushState = inBrowser && history.pushState.bind(history);
|
|
4
5
|
const replaceState = inBrowser && history.replaceState.bind(history);
|
|
@@ -417,7 +418,7 @@ if (inBrowser) {
|
|
|
417
418
|
}
|
|
418
419
|
}
|
|
419
420
|
for (const script of document.getElementsByTagName("script")) {
|
|
420
|
-
script
|
|
421
|
+
detectScriptExecuted(script);
|
|
421
422
|
}
|
|
422
423
|
}
|
|
423
424
|
async function prepareForClientOnlyComponents(newDocument, toLocation, signal) {
|
|
@@ -3,6 +3,7 @@ export type SavedFocus = {
|
|
|
3
3
|
start?: number | null;
|
|
4
4
|
end?: number | null;
|
|
5
5
|
};
|
|
6
|
+
export declare function detectScriptExecuted(script: HTMLScriptElement): boolean;
|
|
6
7
|
export declare function deselectScripts(doc: Document): void;
|
|
7
8
|
export declare function swapRootAttributes(doc: Document): void;
|
|
8
9
|
export declare function swapHeadElements(doc: Document): void;
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
const PERSIST_ATTR = "data-astro-transition-persist";
|
|
2
|
+
const scriptsAlreadyRan = /* @__PURE__ */ new Set();
|
|
3
|
+
function detectScriptExecuted(script) {
|
|
4
|
+
const key = script.src ? new URL(script.src, location.href).href : script.textContent;
|
|
5
|
+
if (scriptsAlreadyRan.has(key)) return true;
|
|
6
|
+
scriptsAlreadyRan.add(key);
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
2
9
|
function deselectScripts(doc) {
|
|
3
|
-
for (const
|
|
4
|
-
|
|
5
|
-
if
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
) {
|
|
11
|
-
s2.dataset.astroExec = "";
|
|
12
|
-
break;
|
|
13
|
-
}
|
|
10
|
+
for (const s2 of doc.scripts) {
|
|
11
|
+
if (
|
|
12
|
+
// Check if the script should be rerun regardless of it being the same
|
|
13
|
+
!s2.hasAttribute("data-astro-rerun") && // Check if the script has already been executed
|
|
14
|
+
detectScriptExecuted(s2)
|
|
15
|
+
) {
|
|
16
|
+
s2.dataset.astroExec = "";
|
|
14
17
|
}
|
|
15
18
|
}
|
|
16
19
|
}
|
|
@@ -106,6 +109,7 @@ const swap = (doc) => {
|
|
|
106
109
|
};
|
|
107
110
|
export {
|
|
108
111
|
deselectScripts,
|
|
112
|
+
detectScriptExecuted,
|
|
109
113
|
restoreFocus,
|
|
110
114
|
saveFocus,
|
|
111
115
|
swap,
|
|
@@ -29,5 +29,4 @@ export declare class DevPipeline extends Pipeline {
|
|
|
29
29
|
getComponentByRoute(routeData: RouteData): Promise<ComponentInstance>;
|
|
30
30
|
tryRewrite(payload: RewritePayload, request: Request): Promise<TryRewriteResult>;
|
|
31
31
|
setManifestData(manifestData: RoutesList): void;
|
|
32
|
-
rewriteKnownRoute(route: string, sourceRoute: RouteData): ComponentInstance;
|
|
33
32
|
}
|
|
@@ -154,16 +154,6 @@ class DevPipeline extends Pipeline {
|
|
|
154
154
|
setManifestData(manifestData) {
|
|
155
155
|
this.routesList = manifestData;
|
|
156
156
|
}
|
|
157
|
-
rewriteKnownRoute(route, sourceRoute) {
|
|
158
|
-
if (this.serverLike && sourceRoute.prerender) {
|
|
159
|
-
for (let def of this.defaultRoutes) {
|
|
160
|
-
if (route === def.route) {
|
|
161
|
-
return def.instance;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
throw new Error("Unknown route");
|
|
166
|
-
}
|
|
167
157
|
}
|
|
168
158
|
export {
|
|
169
159
|
DevPipeline
|
|
@@ -29,7 +29,7 @@ function createVitePluginAstroServer({
|
|
|
29
29
|
}) {
|
|
30
30
|
return {
|
|
31
31
|
name: "astro:server",
|
|
32
|
-
configureServer(viteServer) {
|
|
32
|
+
async configureServer(viteServer) {
|
|
33
33
|
const loader = createViteLoader(viteServer);
|
|
34
34
|
const pipeline = DevPipeline.create(routesList, {
|
|
35
35
|
loader,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { loadActions } from "../actions/loadActions.js";
|
|
1
2
|
import {
|
|
2
3
|
DEFAULT_404_COMPONENT,
|
|
3
4
|
NOOP_MIDDLEWARE_HEADER,
|
|
@@ -104,6 +105,8 @@ async function handleRoute({
|
|
|
104
105
|
let renderContext;
|
|
105
106
|
let mod = void 0;
|
|
106
107
|
let route;
|
|
108
|
+
const actions = await loadActions(loader);
|
|
109
|
+
pipeline.setActions(actions);
|
|
107
110
|
const middleware = (await loadMiddleware(loader)).onRequest;
|
|
108
111
|
const locals = Reflect.get(incomingRequest, clientLocalsSymbol);
|
|
109
112
|
const { preloadedComponent } = matchedRoute;
|
|
@@ -128,7 +131,8 @@ async function handleRoute({
|
|
|
128
131
|
middleware: isDefaultPrerendered404(matchedRoute.route) ? void 0 : middleware,
|
|
129
132
|
request,
|
|
130
133
|
routeData: route,
|
|
131
|
-
clientAddress: incomingRequest.socket.remoteAddress
|
|
134
|
+
clientAddress: incomingRequest.socket.remoteAddress,
|
|
135
|
+
actions
|
|
132
136
|
});
|
|
133
137
|
let response;
|
|
134
138
|
let statusCode = 200;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.2",
|
|
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",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"kleur": "^4.1.5",
|
|
134
134
|
"magic-string": "^0.30.17",
|
|
135
135
|
"magicast": "^0.3.5",
|
|
136
|
-
"mrmime": "^2.0.
|
|
136
|
+
"mrmime": "^2.0.1",
|
|
137
137
|
"neotraverse": "^0.6.18",
|
|
138
138
|
"p-limit": "^6.2.0",
|
|
139
139
|
"p-queue": "^8.1.0",
|
|
@@ -145,23 +145,23 @@
|
|
|
145
145
|
"shiki": "^1.29.2",
|
|
146
146
|
"tinyexec": "^0.3.2",
|
|
147
147
|
"tinyglobby": "^0.2.12",
|
|
148
|
-
"tsconfck": "^3.1.
|
|
148
|
+
"tsconfck": "^3.1.5",
|
|
149
149
|
"ultrahtml": "^1.5.3",
|
|
150
150
|
"unist-util-visit": "^5.0.0",
|
|
151
|
-
"unstorage": "^1.
|
|
151
|
+
"unstorage": "^1.15.0",
|
|
152
152
|
"vfile": "^6.0.3",
|
|
153
153
|
"vite": "^6.2.0",
|
|
154
|
-
"vitefu": "^1.0.
|
|
154
|
+
"vitefu": "^1.0.6",
|
|
155
155
|
"which-pm": "^3.0.1",
|
|
156
156
|
"xxhash-wasm": "^1.1.0",
|
|
157
157
|
"yargs-parser": "^21.1.1",
|
|
158
|
-
"yocto-spinner": "^0.2.
|
|
159
|
-
"zod": "^3.24.
|
|
160
|
-
"zod-to-json-schema": "^3.24.
|
|
158
|
+
"yocto-spinner": "^0.2.1",
|
|
159
|
+
"zod": "^3.24.2",
|
|
160
|
+
"zod-to-json-schema": "^3.24.3",
|
|
161
161
|
"zod-to-ts": "^1.2.0",
|
|
162
162
|
"@astrojs/internal-helpers": "0.6.0",
|
|
163
|
-
"@astrojs/
|
|
164
|
-
"@astrojs/
|
|
163
|
+
"@astrojs/markdown-remark": "6.2.0",
|
|
164
|
+
"@astrojs/telemetry": "3.2.0"
|
|
165
165
|
},
|
|
166
166
|
"optionalDependencies": {
|
|
167
167
|
"sharp": "^0.33.3"
|
|
@@ -186,8 +186,8 @@
|
|
|
186
186
|
"cheerio": "1.0.0",
|
|
187
187
|
"eol": "^0.10.0",
|
|
188
188
|
"execa": "^8.0.1",
|
|
189
|
-
"expect-type": "^1.
|
|
190
|
-
"fs-fixture": "^2.7.
|
|
189
|
+
"expect-type": "^1.2.0",
|
|
190
|
+
"fs-fixture": "^2.7.1",
|
|
191
191
|
"mdast-util-mdx": "^3.0.0",
|
|
192
192
|
"mdast-util-mdx-jsx": "^3.2.0",
|
|
193
193
|
"node-mocks-http": "^1.16.2",
|
|
@@ -196,11 +196,11 @@
|
|
|
196
196
|
"rehype-slug": "^6.0.0",
|
|
197
197
|
"rehype-toc": "^3.0.2",
|
|
198
198
|
"remark-code-titles": "^0.1.2",
|
|
199
|
-
"rollup": "^4.34.
|
|
200
|
-
"sass": "^1.
|
|
201
|
-
"undici": "^7.
|
|
199
|
+
"rollup": "^4.34.9",
|
|
200
|
+
"sass": "^1.85.1",
|
|
201
|
+
"undici": "^7.4.0",
|
|
202
202
|
"unified": "^11.0.5",
|
|
203
|
-
"vitest": "^3.0.
|
|
203
|
+
"vitest": "^3.0.7",
|
|
204
204
|
"astro-scripts": "0.0.14"
|
|
205
205
|
},
|
|
206
206
|
"engines": {
|
package/templates/actions.mjs
CHANGED
|
@@ -2,10 +2,12 @@ import {
|
|
|
2
2
|
ACTION_QUERY_PARAMS,
|
|
3
3
|
ActionError,
|
|
4
4
|
appendForwardSlash,
|
|
5
|
+
astroCalledServerError,
|
|
5
6
|
deserializeActionResult,
|
|
6
7
|
getActionQueryString,
|
|
7
8
|
} from 'astro:actions';
|
|
8
9
|
|
|
10
|
+
const apiContextRoutesSymbol = Symbol.for('context.routes');
|
|
9
11
|
const ENCODED_DOT = '%2E';
|
|
10
12
|
|
|
11
13
|
function toActionProxy(actionCallback = {}, aggregatedPath = '') {
|
|
@@ -73,11 +75,13 @@ export function getActionPath(action) {
|
|
|
73
75
|
*/
|
|
74
76
|
async function handleAction(param, path, context) {
|
|
75
77
|
// When running server-side, import the action and call it.
|
|
76
|
-
if (import.meta.env.SSR) {
|
|
77
|
-
const
|
|
78
|
-
|
|
78
|
+
if (import.meta.env.SSR && context) {
|
|
79
|
+
const pipeline = Reflect.get(context, apiContextRoutesSymbol);
|
|
80
|
+
if (!pipeline) {
|
|
81
|
+
throw astroCalledServerError();
|
|
82
|
+
}
|
|
83
|
+
const action = await pipeline.getAction(path);
|
|
79
84
|
if (!action) throw new Error(`Action not found: ${path}`);
|
|
80
|
-
|
|
81
85
|
return action.bind(context)(param);
|
|
82
86
|
}
|
|
83
87
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const onRequest: import("../../types/public/common.js").MiddlewareHandler;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { defineMiddleware } from "../../virtual-modules/middleware.js";
|
|
2
|
-
import { getActionContext } from "./virtual/server.js";
|
|
3
|
-
const onRequest = defineMiddleware(async (context, next) => {
|
|
4
|
-
if (context.isPrerendered) return next();
|
|
5
|
-
const { action, setActionResult, serializeActionResult } = getActionContext(context);
|
|
6
|
-
if (action?.calledFrom === "form") {
|
|
7
|
-
const actionResult = await action.handler();
|
|
8
|
-
setActionResult(action.name, serializeActionResult(actionResult));
|
|
9
|
-
}
|
|
10
|
-
return next();
|
|
11
|
-
});
|
|
12
|
-
export {
|
|
13
|
-
onRequest
|
|
14
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
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>>;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { ActionNotFoundError } from "../../../core/errors/errors-data.js";
|
|
2
|
-
import { AstroError } from "../../../core/errors/errors.js";
|
|
3
|
-
async function getAction(path) {
|
|
4
|
-
const pathKeys = path.split(".").map((key) => decodeURIComponent(key));
|
|
5
|
-
let { server: actionLookup } = await import("astro:internal-actions");
|
|
6
|
-
if (actionLookup == null || !(typeof actionLookup === "object")) {
|
|
7
|
-
throw new TypeError(
|
|
8
|
-
`Expected \`server\` export in actions file to be an object. Received ${typeof actionLookup}.`
|
|
9
|
-
);
|
|
10
|
-
}
|
|
11
|
-
for (const key of pathKeys) {
|
|
12
|
-
if (!(key in actionLookup)) {
|
|
13
|
-
throw new AstroError({
|
|
14
|
-
...ActionNotFoundError,
|
|
15
|
-
message: ActionNotFoundError.message(pathKeys.join("."))
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
actionLookup = actionLookup[key];
|
|
19
|
-
}
|
|
20
|
-
if (typeof actionLookup !== "function") {
|
|
21
|
-
throw new TypeError(
|
|
22
|
-
`Expected handler for action ${pathKeys.join(".")} to be a function. Received ${typeof actionLookup}.`
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
return actionLookup;
|
|
26
|
-
}
|
|
27
|
-
export {
|
|
28
|
-
getAction
|
|
29
|
-
};
|