UNPKG

remix-toast

Version:

Utility functions for server-side toast notifications

172 lines (167 loc) 6.83 kB
// src/index.ts import { createCookieSessionStorage as createCookieSessionStorage2, data as dataFn, redirect, replace } from "react-router"; // src/schema.ts import { z } from "zod"; var toastMessageSchema = z.looseObject({ message: z.string(), description: z.string().optional(), duration: z.number().int().nonnegative().optional(), type: z.custom() }); var toastMessageWithoutTypeSchema = z.looseObject({ message: z.string(), description: z.string().optional(), duration: z.number().int().nonnegative().optional() }); var flashSessionValuesSchema = z.object({ toast: toastMessageSchema.optional() }); var FLASH_SESSION = "flash"; // src/session.ts import { createCookieSessionStorage } from "react-router"; var toastCookieOptions = { name: "toast-session", sameSite: "lax", path: "/", httpOnly: true, secrets: ["s3Cr3t"] }; var sessionStorage = createCookieSessionStorage({ cookie: toastCookieOptions }); // src/index.ts function setToastCookieOptions(options) { Object.assign(toastCookieOptions, options); Object.assign( sessionStorage, createCookieSessionStorage2({ cookie: toastCookieOptions }) ); } async function flashMessage(flash, headers, customSession) { const sessionToUse = customSession ? customSession : sessionStorage; const session = await sessionToUse.getSession(); session.flash(FLASH_SESSION, flash); const cookie = await sessionToUse.commitSession(session); const newHeaders = new Headers(headers); newHeaders.append("Set-Cookie", cookie); return newHeaders; } async function redirectWithFlash(url, flash, init, customSession) { return redirect(url, { ...init, headers: await flashMessage(flash, init == null ? void 0 : init.headers, customSession) }); } async function replaceWithFlash(url, flash, init, customSession) { return replace(url, { ...init, headers: await flashMessage(flash, init == null ? void 0 : init.headers, customSession) }); } async function dataWithFlash(data, flash, init, customSession) { return dataFn(data, { ...init, headers: await flashMessage(flash, init == null ? void 0 : init.headers, customSession) }); } var dataWithToastFactory = ({ type, session }) => { return (data, messageOrToast, init, customSession) => { const finalInfo = typeof messageOrToast === "string" ? { message: messageOrToast } : messageOrToast; return dataWithFlash(data, { toast: { ...finalInfo, type } }, init, customSession != null ? customSession : session); }; }; var redirectWithToastFactory = ({ type, session }) => { return (redirectUrl, messageOrToast, init, customSession) => { const finalInfo = typeof messageOrToast === "string" ? { message: messageOrToast } : messageOrToast; return redirectWithFlash(redirectUrl, { toast: { ...finalInfo, type } }, init, customSession != null ? customSession : session); }; }; var replaceWithToastFactory = ({ type, session }) => { return (replaceUrl, messageOrToast, init, customSession) => { const finalInfo = typeof messageOrToast === "string" ? { message: messageOrToast } : messageOrToast; return replaceWithFlash(replaceUrl, { toast: { ...finalInfo, type } }, init, customSession != null ? customSession : session); }; }; async function getToast(request, customSession) { const sessionToUse = customSession ? customSession : sessionStorage; const cookie = request.headers.get("Cookie"); const session = await sessionToUse.getSession(cookie); const result = flashSessionValuesSchema.safeParse(session.get(FLASH_SESSION)); const flash = result.success ? result.data : void 0; const headers = new Headers({ "Set-Cookie": await sessionToUse.commitSession(session) }); const toast = flash == null ? void 0 : flash.toast; return { toast, headers }; } var createToastUtilsWithCustomSession = (session) => { return { dataWithToast: (data, toast, init) => { return dataWithFlash(data, { toast }, init, session); }, dataWithSuccess: dataWithToastFactory({ type: "success", session }), dataWithError: dataWithToastFactory({ type: "error", session }), dataWithInfo: dataWithToastFactory({ type: "info", session }), dataWithWarning: dataWithToastFactory({ type: "warning", session }), redirectWithToast: (redirectUrl, toast, init) => { return redirectWithFlash(redirectUrl, { toast }, init, session); }, replaceWithToast: (replaceUrl, toast, init) => { return replaceWithFlash(replaceUrl, { toast }, init, session); }, redirectWithSuccess: redirectWithToastFactory({ type: "success", session }), redirectWithError: redirectWithToastFactory({ type: "error", session }), redirectWithInfo: redirectWithToastFactory({ type: "info", session }), redirectWithWarning: redirectWithToastFactory({ type: "warning", session }), replaceWithSuccess: replaceWithToastFactory({ type: "success", session }), replaceWithError: replaceWithToastFactory({ type: "error", session }), replaceWithInfo: replaceWithToastFactory({ type: "info", session }), replaceWithWarning: replaceWithToastFactory({ type: "warning", session }), getToast: (request) => getToast(request, session) }; }; var dataWithToast = (data, toast, init, customSession) => { return dataWithFlash(data, { toast }, init, customSession); }; var dataWithSuccess = dataWithToastFactory({ type: "success" }); var dataWithError = dataWithToastFactory({ type: "error" }); var dataWithInfo = dataWithToastFactory({ type: "info" }); var dataWithWarning = dataWithToastFactory({ type: "warning" }); var redirectWithToast = (redirectUrl, toast, init, customSession) => { return redirectWithFlash(redirectUrl, { toast }, init, customSession); }; var replaceWithToast = (replaceUrl, toast, init, customSession) => { return replaceWithFlash(replaceUrl, { toast }, init, customSession); }; var redirectWithError = redirectWithToastFactory({ type: "error" }); var replaceWithError = replaceWithToastFactory({ type: "error" }); var redirectWithSuccess = redirectWithToastFactory({ type: "success" }); var replaceWithSuccess = replaceWithToastFactory({ type: "success" }); var redirectWithWarning = redirectWithToastFactory({ type: "warning" }); var replaceWithWarning = replaceWithToastFactory({ type: "warning" }); var redirectWithInfo = redirectWithToastFactory({ type: "info" }); var replaceWithInfo = replaceWithToastFactory({ type: "info" }); export { FLASH_SESSION, sessionStorage, setToastCookieOptions, getToast, createToastUtilsWithCustomSession, dataWithToast, dataWithSuccess, dataWithError, dataWithInfo, dataWithWarning, redirectWithToast, replaceWithToast, redirectWithError, replaceWithError, redirectWithSuccess, replaceWithSuccess, redirectWithWarning, replaceWithWarning, redirectWithInfo, replaceWithInfo };