Skip to content

Commit

Permalink
refactor: move actionHandler to helper fn
Browse files Browse the repository at this point in the history
  • Loading branch information
bholmesdev committed May 7, 2024
1 parent 454cf34 commit d61c4d7
Showing 1 changed file with 41 additions and 36 deletions.
77 changes: 41 additions & 36 deletions packages/astro/templates/actions.mjs
Expand Up @@ -3,45 +3,11 @@ import { ActionError, callSafely } from 'astro:actions';
function toActionProxy(actionCallback = {}, aggregatedPath = '/_actions/') {
return new Proxy(actionCallback, {
get(target, objKey) {
const path = aggregatedPath + objKey.toString();
if (objKey in target) {
return target[objKey];
}
// `callerParam` is the argument passed to the action when used on the client.
// Usage: `actions.[name](callerParam)`.
async function action(callerParam) {
if (import.meta.env.SSR) {
throw new ActionError({
code: 'BAD_REQUEST',
message:
'Action unexpectedly called on the server. If this error is unexpected, share your feedback on our RFC discussion: https://github.com/withastro/roadmap/pull/912',
});
}
const headers = new Headers();
headers.set('Accept', 'application/json');
let body = callerParam;
if (!(body instanceof FormData)) {
try {
body = callerParam ? JSON.stringify(callerParam) : undefined;
} catch (e) {
throw new ActionError({
code: 'BAD_REQUEST',
message: `Failed to serialize request body to JSON. Full error: ${e.message}`,
});
}
headers.set('Content-Type', 'application/json');
}
const res = await fetch(path, {
method: 'POST',
body,
headers,
});
if (!res.ok) {
throw await ActionError.fromResponse(res);
}
const json = await res.json();
return json;
}
const path = aggregatedPath + objKey.toString();
const action = (clientParam) => actionHandler(clientParam, path);
action.toString = () => path;
action.safe = (input) => {
return callSafely(() => action(input));
Expand All @@ -53,4 +19,43 @@ function toActionProxy(actionCallback = {}, aggregatedPath = '/_actions/') {
});
}

/**
* @param {*} clientParam argument passed to the action when used on the client.
* @param {string} path Built path to call action on the server.
* Usage: `actions.[name](clientParam)`.
*/
async function actionHandler(clientParam, path) {
if (import.meta.env.SSR) {
throw new ActionError({
code: 'BAD_REQUEST',
message:
'Action unexpectedly called on the server. If this error is unexpected, share your feedback on our RFC discussion: https://github.com/withastro/roadmap/pull/912',
});
}
const headers = new Headers();
headers.set('Accept', 'application/json');
let body = clientParam;
if (!(body instanceof FormData)) {
try {
body = clientParam ? JSON.stringify(clientParam) : undefined;
} catch (e) {
throw new ActionError({
code: 'BAD_REQUEST',
message: `Failed to serialize request body to JSON. Full error: ${e.message}`,
});
}
headers.set('Content-Type', 'application/json');
}
const res = await fetch(path, {
method: 'POST',
body,
headers,
});
if (!res.ok) {
throw await ActionError.fromResponse(res);
}
const json = await res.json();
return json;
}

export const actions = toActionProxy();

0 comments on commit d61c4d7

Please sign in to comment.