remix-utils
Version:
This package contains simple utility functions to use with [React Router](https://reactrouter.com/).
90 lines • 3.01 kB
JavaScript
import { isSession, } from "react-router";
import { z } from "zod";
export function createTypedSessionStorage({ sessionStorage, schema, }) {
return {
async getSession(cookieHeader, options) {
let session = await sessionStorage.getSession(cookieHeader, options);
return await createTypedSession({ session, schema });
},
async commitSession(session, options) {
// check if session.data is valid
await schema.parseAsync(session.data);
return await sessionStorage.commitSession(session, options);
},
async destroySession(session) {
// check if session.data is valid
await schema.parseAsync(session.data);
return await sessionStorage.destroySession(session);
},
};
}
async function createTypedSession({ session, schema, }) {
// get a raw shape version of the schema but converting all the keys to their
// flash versions.
let flashSchema = {};
for (let key in schema.shape) {
flashSchema[flash(key)] = schema.shape[key].optional();
}
// parse session.data to add default values and remove invalid ones
// we use strict mode here so we can throw an error if the session data
// contains any invalid key, which is a sign that the session data is
// corrupted.
let data = await schema.extend(flashSchema).strict().parseAsync(session.data);
return {
get isTyped() {
return true;
},
get id() {
return session.id;
},
get data() {
return data;
},
has(name) {
let key = String(safeKey(schema, name));
return key in data || flash(key) in data;
},
get(name) {
let key = String(safeKey(schema, name));
if (key in data)
return data[key];
let flashKey = flash(key);
if (flashKey in data) {
let value = data[flashKey];
delete data[flashKey];
return value;
}
return;
},
set(name, value) {
let key = String(safeKey(schema, name));
data[key] = value;
},
flash(name, value) {
let key = String(safeKey(schema, name));
let flashKey = flash(key);
data[flashKey] = value;
},
unset(name) {
let key = String(safeKey(schema, name));
delete data[key];
},
};
}
/**
* ReReturns true if an object is a Remix Utils typed session.
*
* @see https://github.com/sergiodxa/remix-utils#typed-session
*/
export function isTypedSession(value) {
return (isSession(value) &&
value.isTyped === true);
}
function flash(name) {
return `__flash_${name}__`;
}
// checks that the key is a valid key of the schema
function safeKey(schema, key) {
return schema.keyof().parse(key);
}
//# sourceMappingURL=typed-session.js.map