@astro-utils/forms
Version:
Server component for Astro (call server functions from client side with validation and state management)
70 lines (69 loc) • 2.82 kB
JavaScript
import { DEFAULT_SETTINGS as DEFAULT_SETTINGS_CSRF, ensureValidationSecret } from './form-tools/csrf.js';
import { JWTSession } from './jwt-session.js';
import { FORM_OPTIONS } from './settings.js';
import { v4 as uuid } from 'uuid';
import objectAssignDeep from 'object-assign-deep';
import FormsReact from './form-tools/forms-react.js';
import ThrowOverrideResponse from './throw-action/throwOverrideResponse.js';
import { DEFAULT_BIG_FILE_UPLOAD_OPTIONS_SERVER } from './components/form/UploadBigFile/uploadBigFileServer.js';
const DEFAULT_FORM_OPTIONS = {
csrf: DEFAULT_SETTINGS_CSRF,
forms: {
viewStateFormFiled: '__view-state',
bigFilesUpload: {
bigFileServerOptions: DEFAULT_BIG_FILE_UPLOAD_OPTIONS_SERVER
}
},
session: {
cookieName: 'session',
cookieOptions: {
httpOnly: true,
sameSite: "lax",
maxAge: 1000 * 60 * 60 * 24 * 7,
path: '/'
}
},
secret: uuid(),
logs: (type, message) => {
console[type](message);
},
};
export default function astroForms(settings = {}) {
objectAssignDeep(FORM_OPTIONS, DEFAULT_FORM_OPTIONS, settings);
return async function onRequest({ locals, request, cookies }, next) {
const likeAstro = { locals, request, cookies };
const session = new JWTSession(cookies);
locals.session = session.sessionData;
locals.forms = new FormsReact(likeAstro);
locals.__formsInternalUtils = {
FORM_OPTIONS: FORM_OPTIONS,
bindFormCounter: 0
};
await ensureValidationSecret(likeAstro);
try {
const response = await next();
const isHTML = response.headers.get('Content-Type')?.includes('text/html');
if (locals.webFormOff || !isHTML) {
return response;
}
const content = await response.text();
const newResponse = locals.forms.overrideResponse || new Response(content, response);
if (!(newResponse instanceof Response)) {
throw new Error('Astro.locals.forms.overrideResponse must be a Response instance');
}
session.setCookieHeader(newResponse.headers);
return newResponse;
}
catch (error) {
if (!(error instanceof ThrowOverrideResponse)) {
throw error;
}
const newResponse = error.response ?? locals.forms.overrideResponse ?? new Response(error.message, { status: 500 });
if (!(newResponse instanceof Response)) {
throw new Error('ThrowOverrideResponse.response must be a Response instance');
}
session.setCookieHeader(newResponse.headers);
return newResponse;
}
};
}