0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-02-10 22:38:53 -05:00

refactor: clean up cookie -> action payload

This commit is contained in:
bholmesdev 2024-08-08 11:19:33 -04:00
parent d3ba81a8a6
commit ffe80acb2e
2 changed files with 28 additions and 9 deletions

View file

@ -4,3 +4,8 @@ export const ACTIONS_TYPES_FILE = 'actions.d.ts';
export const VIRTUAL_INTERNAL_MODULE_ID = 'astro:internal-actions'; export const VIRTUAL_INTERNAL_MODULE_ID = 'astro:internal-actions';
export const RESOLVED_VIRTUAL_INTERNAL_MODULE_ID = '\0astro:internal-actions'; export const RESOLVED_VIRTUAL_INTERNAL_MODULE_ID = '\0astro:internal-actions';
export const NOOP_ACTIONS = '\0noop-actions'; export const NOOP_ACTIONS = '\0noop-actions';
export const ACTION_QUERY_PARAMS = {
actionName: '_astroAction',
actionPayload: '_astroActionPayload',
};

View file

@ -10,12 +10,15 @@ import {
type SerializedActionResult, type SerializedActionResult,
serializeActionResult, serializeActionResult,
} from './virtual/shared.js'; } from './virtual/shared.js';
import { ACTION_QUERY_PARAMS } from '../consts.js';
type ActionPayload = {
actionResult: SerializedActionResult;
actionName: string;
};
export type Locals = { export type Locals = {
_actionsInternal: { _actionsInternal: ActionPayload;
actionResult: SerializedActionResult;
actionName: string;
};
}; };
export const onRequest = defineMiddleware(async (context, next) => { export const onRequest = defineMiddleware(async (context, next) => {
@ -27,9 +30,12 @@ export const onRequest = defineMiddleware(async (context, next) => {
// so short circuit if already defined. // so short circuit if already defined.
if (locals._actionsInternal) return next(); if (locals._actionsInternal) return next();
const actionResultCookie = context.cookies.get('_actionResult'); const actionPayload = context.cookies.get(ACTION_QUERY_PARAMS.actionPayload)?.json();
if (actionResultCookie) { if (actionPayload) {
return renderResult({ context, next, ...actionResultCookie.json() }); if (!isActionPayload(actionPayload)) {
throw new Error('Internal: Invalid action payload in cookie.');
}
return renderResult({ context, next, ...actionPayload });
} }
// Heuristic: If body is null, Astro might've reset this for prerendering. // Heuristic: If body is null, Astro might've reset this for prerendering.
@ -70,7 +76,7 @@ async function renderResult({
locals._actionsInternal = { actionResult, actionName }; locals._actionsInternal = { actionResult, actionName };
const response = await next(); const response = await next();
context.cookies.delete('_actionResult'); context.cookies.delete(ACTION_QUERY_PARAMS.actionPayload);
if (locals._actionsInternal.actionResult.type === 'error') { if (locals._actionsInternal.actionResult.type === 'error') {
return new Response(response.body, { return new Response(response.body, {
@ -126,7 +132,7 @@ async function redirectWithResult({
actionName: string; actionName: string;
actionResult: SafeResult<any, any>; actionResult: SafeResult<any, any>;
}) { }) {
context.cookies.set('_actionResult', { context.cookies.set(ACTION_QUERY_PARAMS.actionPayload, {
actionName, actionName,
actionResult: serializeActionResult(actionResult), actionResult: serializeActionResult(actionResult),
}); });
@ -174,3 +180,11 @@ async function handlePostLegacy({ context, next }: { context: APIContext; next:
const actionResult = await action(formData); const actionResult = await action(formData);
return redirectWithResult({ context, actionName, actionResult }); return redirectWithResult({ context, actionName, actionResult });
} }
function isActionPayload(json: unknown): json is ActionPayload {
if (typeof json !== 'object' || json == null) return false;
if (!('actionResult' in json) || typeof json.actionResult !== 'object') return false;
if (!('actionName' in json) || typeof json.actionName !== 'string') return false;
return true;
}