alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
85 lines (70 loc) • 2.12 kB
text/typescript
import type { Cookie } from "../primitives/$cookie.ts";
export class CookieParser {
public parseRequestCookies(header: string): Record<string, string> {
const cookies: Record<string, string> = {};
const parts = header.split(";");
for (const part of parts) {
const eqIndex = part.indexOf("=");
if (eqIndex === -1) {
continue;
}
const key = part.slice(0, eqIndex).trim();
const value = part.slice(eqIndex + 1).trim();
if (!key || !value) {
continue;
}
cookies[key] = value;
}
return cookies;
}
public serializeResponseCookies(
cookies: Record<string, Cookie | null>,
isHttps: boolean,
): string[] {
const headers = [];
for (const [name, cookie] of Object.entries(cookies)) {
// If the cookie is null, we need to delete it
if (cookie == null) {
headers.push(`${name}=; Path=/; Max-Age=0`);
continue;
}
if (!cookie.value) {
continue;
}
headers.push(this.cookieToString(name, cookie, isHttps));
}
return headers;
}
public cookieToString(
name: string,
cookie: Cookie,
isHttps?: boolean,
): string {
const parts: string[] = [];
parts.push(`${name}=${cookie.value}`);
if (cookie.path) {
parts.push(`Path=${cookie.path}`);
}
// `!= null`, not truthy: `maxAge: 0` is the standard "delete this
// cookie now" value (used by AtomCookiePersistence.browser.ts's
// clearCookie() and BrowserCookiePrimitive.del()). A truthy check would
// silently drop `Max-Age` for exactly that value, turning a deletion
// into a plain (non-expiring-until-session-end) write.
if (cookie.maxAge != null) {
parts.push(`Max-Age=${cookie.maxAge}`);
}
if (cookie.secure !== false && isHttps) {
parts.push("Secure");
}
if (cookie.httpOnly) {
parts.push("HttpOnly");
}
if (cookie.sameSite) {
parts.push(`SameSite=${cookie.sameSite}`);
}
if (cookie.domain) {
parts.push(`Domain=${cookie.domain}`);
}
return parts.join("; ");
}
}