import {Injectable, Inject} from '../../di' import {ErrorWithContext, Safe} from '../../util' import {Request} from '../lifecycle/Request' /** * Type alias describing some inflated session data. */ export type SessionData = {[key: string]: any} /** * Error thrown when a session is requested for a key that does not exist. */ export class NoSessionKeyError extends ErrorWithContext { constructor() { super('No session ID has been set.') } } /** * Error thrown when a session operation is performed before the session has been loaded. */ export class SessionNotLoadedError extends ErrorWithContext { constructor() { super('Cannot access session data; data is not loaded.') } } /** * An abstract class representing a session driver. * Some implementation of this is injected into the request. */ @Injectable() export abstract class Session { @Inject() protected readonly request!: Request /** Get the unique key of this session. */ public abstract getKey(): string /** Set a unique key of this session. */ public abstract setKey(key: string): void /** Load the session data from the respective backend. */ public abstract load(): void | Promise /** Save the session data into the respective backend. */ public abstract persist(): void | Promise /** Get the loaded session data as an object. */ public abstract getData(): SessionData /** Bulk set an object as the session data. */ public abstract setData(data: SessionData): void /** Get a value from the session by key. */ public abstract get(key: string, fallback?: unknown): any /** Set a value in the session by key. */ public abstract set(key: string, value: unknown): void /** Remove a key from the session data. */ public abstract forget(key: string): void /** Load a key from the session as a Safe value. */ public safe(key: string): Safe { return new Safe(this.get(key)) } }