import { Injectable } from '../../../di/src/decorator/Injection.ts' import { getCookies, setCookie, delCookie, ServerRequest } from '../external/http.ts' import { InMemCache } from '../support/InMemCache.ts' import { HTTPRequest } from './type/HTTPRequest.ts' export interface Cookie { key: string, original_value: string, value: any, } export type MaybeCookie = Cookie | undefined // TODO cookie options (http only, expires, &c.) @Injectable() export class CookieJar { protected _parsed: { [key: string]: string } = {} protected _cache = new InMemCache() constructor( protected request: HTTPRequest, ) { this._parsed = getCookies(this.request.to_native) } public async get(key: string): Promise { // Try the cache if ( await this._cache.has(key) ) return this._cache.fetch(key) // If the cache missed, try to parse it and load in cache if ( key in this._parsed ) { let value = this._parsed[key] try { value = JSON.parse(atob(this._parsed[key])) } catch(e) {} const cookie = { key, value, original_value: this._parsed[key], } await this._cache.put(key, cookie) return cookie } } public async set(key: string, value: any): Promise { const original_value = btoa(JSON.stringify(value)) const cookie = { key, value, original_value, } await this._cache.put(key, value) setCookie(this.request.response, { name: key, value: original_value }) } public async has(key: string): Promise { return (await this._cache.has(key)) || key in this._parsed } public async delete(key: string): Promise { await this._cache.drop(key) delCookie(this.request.response, key) } }