@tdb/util
Version:
Shared helpers and utilities.
87 lines (76 loc) • 2.04 kB
text/typescript
import { R } from '../../libs';
import { IS_BROWSER } from '../../constants';
import {
ICookieAttributes,
CookieValue,
ICookieServerContext,
CookieProperty,
} from './types';
import { prop } from './prop';
const SERVER_COOKIE_KEY = '__TDB_TEMP__';
export interface IServerCookie {
key: string;
value: CookieValue;
options?: ICookieAttributes;
}
/**
* A cookie builder for writing on the server.
* Adds a set of values that is then passed to the client
* in a `Set-Cookie` header.
*
* For example usage of cookies on the server see:
* Module: @tdb/web
* Path: /example/components/Home
* Method: getInitialProps
*
*/
export class ServerCookie {
public cookies: IServerCookie[] = [];
/**
* Chaining method to add cookies.
*/
public add(prop: CookieProperty<any>, value?: CookieValue) {
if (value) {
const { key } = prop;
const options = R.isEmpty(prop.options) ? undefined : prop.options;
this.cookies = [...this.cookies, { key, value, options }];
}
return this;
}
public get header() {
const obj: any = {};
this.cookies.forEach(cookie => (obj[cookie.key] = cookie));
const json = JSON.stringify(obj);
return `${SERVER_COOKIE_KEY}=${encodeURIComponent(json)}`;
}
/**
* Writes and flushes the server cookie cache.
*/
public write(ctx: ICookieServerContext) {
if (!IS_BROWSER && this.cookies.length > 0) {
const header = this.header;
ctx.res.setHeader('Set-Cookie', header);
}
}
/**
* Removes all cookies values that have been added.
*/
public clear() {
this.cookies = [];
}
}
/**
* Write any cookies sent from the server.
*/
if (IS_BROWSER) {
const serverCookies = prop(SERVER_COOKIE_KEY, { path: '/' });
// Read the value from the server
const cookies = serverCookies();
if (cookies) {
Object.keys(cookies)
.map(key => cookies[key])
.forEach(cookie => prop(cookie.key, cookie.options)(cookie.value));
}
// Clear temporary cookie.
serverCookies(null);
}