TypeDoc all the thngs
This commit is contained in:
@@ -12,8 +12,14 @@ export interface HTTPCookie {
|
||||
options?: HTTPCookieOptions,
|
||||
}
|
||||
|
||||
/**
|
||||
* Type alias for something that is either an HTTP cookie, or undefined.
|
||||
*/
|
||||
export type MaybeHTTPCookie = HTTPCookie | undefined;
|
||||
|
||||
/**
|
||||
* Interface describing the available cookie options.
|
||||
*/
|
||||
export interface HTTPCookieOptions {
|
||||
domain?: string,
|
||||
expires?: Date, // encodeURIComponent
|
||||
@@ -25,21 +31,36 @@ export interface HTTPCookieOptions {
|
||||
sameSite?: 'strict' | 'lax' | 'none-secure',
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for accessing and managing cookies in the associated request.
|
||||
*/
|
||||
export class HTTPCookieJar {
|
||||
/** The cookies parsed from the request. */
|
||||
protected parsed: {[key: string]: HTTPCookie} = {}
|
||||
|
||||
constructor(
|
||||
/** The request whose cookies should be loaded. */
|
||||
protected request: Request,
|
||||
) {
|
||||
this.parseCookies()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTPCookie by name, if it exists.
|
||||
* @param name
|
||||
*/
|
||||
get(name: string): MaybeHTTPCookie {
|
||||
if ( name in this.parsed ) {
|
||||
return this.parsed[name]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new cookie using the specified options.
|
||||
* @param name
|
||||
* @param value
|
||||
* @param options
|
||||
*/
|
||||
set(name: string, value: any, options?: HTTPCookieOptions) {
|
||||
this.parsed[name] = {
|
||||
key: name,
|
||||
@@ -50,10 +71,23 @@ export class HTTPCookieJar {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a cookie exists with the given name.
|
||||
* @param name
|
||||
*/
|
||||
has(name: string) {
|
||||
return !!this.parsed[name]
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the given cookie.
|
||||
*
|
||||
* Important: if the cookie was set with any `options`, the SAME options
|
||||
* must be provided here in order for the cookie to be cleared on the client.
|
||||
*
|
||||
* @param name
|
||||
* @param options
|
||||
*/
|
||||
clear(name: string, options?: HTTPCookieOptions) {
|
||||
if ( !options ) options = {}
|
||||
options.expires = new Date(0)
|
||||
@@ -67,6 +101,9 @@ export class HTTPCookieJar {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of `Set-Cookie` headers to include in the response.
|
||||
*/
|
||||
getSetCookieHeaders(): string[] {
|
||||
const headers: string[] = []
|
||||
|
||||
@@ -119,6 +156,7 @@ export class HTTPCookieJar {
|
||||
return headers
|
||||
}
|
||||
|
||||
/** Parse the cookies from the request. */
|
||||
private parseCookies() {
|
||||
const cookies = String(this.request.getHeader('cookie'))
|
||||
cookies.split(';').forEach(cookie => {
|
||||
|
||||
@@ -10,10 +10,27 @@ import {error} from "../response/ErrorResponseFactory";
|
||||
* Interface for fluently registering kernel modules into the kernel.
|
||||
*/
|
||||
export interface ModuleRegistrationFluency {
|
||||
/**
|
||||
* If no argument is provided, the module will be registered before the core module.
|
||||
* If an argument is provided, the module will be registered before the other specified module.
|
||||
* @param other
|
||||
*/
|
||||
before: (other?: Instantiable<HTTPKernelModule>) => HTTPKernel,
|
||||
|
||||
/**
|
||||
* If no argument is provided, the module will be registered after the core module.
|
||||
* If an argument is provided, the module will be registered after the other specified module.
|
||||
* @param other
|
||||
*/
|
||||
after: (other?: Instantiable<HTTPKernelModule>) => HTTPKernel,
|
||||
|
||||
/** The module will be registered as the first module in the preflight. */
|
||||
first: () => HTTPKernel,
|
||||
|
||||
/** The module will be registered as the last module in the postflight. */
|
||||
last: () => HTTPKernel,
|
||||
|
||||
/** The module will be registered as the core handler for the request. */
|
||||
core: () => HTTPKernel,
|
||||
}
|
||||
|
||||
@@ -27,6 +44,9 @@ export class KernelModuleNotFoundError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A singleton class that handles requests, applying logic in modular layers.
|
||||
*/
|
||||
@Singleton()
|
||||
export class HTTPKernel extends AppClass {
|
||||
@Inject()
|
||||
|
||||
@@ -3,8 +3,19 @@ import {AppClass} from "../../lifecycle/AppClass";
|
||||
import {HTTPKernel} from "./HTTPKernel";
|
||||
import {Request} from "../lifecycle/Request";
|
||||
|
||||
/**
|
||||
* Base class for modules that define logic that is applied to requests
|
||||
* handled by the HTTP kernel.
|
||||
*/
|
||||
@Injectable()
|
||||
export class HTTPKernelModule extends AppClass {
|
||||
/**
|
||||
* By default, if a kernel module interrupts the request flow to send a response
|
||||
* (for example, if an error occurs), subsequent modules are skipped.
|
||||
*
|
||||
* However, a module can override this property to be true and its logic will still
|
||||
* be applied, even after a module has interrupted the request flow.
|
||||
*/
|
||||
public readonly executeWithBlockingWriteback: boolean = false
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,16 @@ import {plaintext} from "../../response/StringResponseFactory";
|
||||
import {ResponseFactory} from "../../response/ResponseFactory";
|
||||
import {json} from "../../response/JSONResponseFactory";
|
||||
|
||||
/**
|
||||
* Base class for HTTP kernel modules that apply some response from a route handler to the request.
|
||||
*/
|
||||
export abstract class AbstractResolvedRouteHandlerHTTPModule extends HTTPKernelModule {
|
||||
/**
|
||||
* Given a response object, write the response to the request in the appropriate format.
|
||||
* @param object
|
||||
* @param request
|
||||
* @protected
|
||||
*/
|
||||
protected async applyResponseObject(object: ResponseObject, request: Request) {
|
||||
if ( (typeof object === 'string') || (typeof object === 'number') ) {
|
||||
object = plaintext(String(object))
|
||||
|
||||
@@ -6,6 +6,11 @@ import {http} from "../../response/HTTPErrorResponseFactory";
|
||||
import {HTTPStatus} from "@extollo/util";
|
||||
import {AbstractResolvedRouteHandlerHTTPModule} from "./AbstractResolvedRouteHandlerHTTPModule";
|
||||
|
||||
/**
|
||||
* HTTP kernel module that runs the handler for the request's route.
|
||||
*
|
||||
* In most cases, this is the controller method defined by the route.
|
||||
*/
|
||||
export class ExecuteResolvedRouteHandlerHTTPModule extends AbstractResolvedRouteHandlerHTTPModule {
|
||||
public static register(kernel: HTTPKernel) {
|
||||
kernel.register(this).core()
|
||||
|
||||
@@ -5,6 +5,11 @@ import {ResponseObject} from "../../routing/Route";
|
||||
import {AbstractResolvedRouteHandlerHTTPModule} from "./AbstractResolvedRouteHandlerHTTPModule";
|
||||
import {PersistSessionHTTPModule} from "./PersistSessionHTTPModule";
|
||||
|
||||
/**
|
||||
* HTTP kernel module that executes the postflight handlers for the route.
|
||||
*
|
||||
* Usually, this is post middleware.
|
||||
*/
|
||||
export class ExecuteResolvedRoutePostflightHTTPModule extends AbstractResolvedRouteHandlerHTTPModule {
|
||||
public static register(kernel: HTTPKernel) {
|
||||
kernel.register(this).before(PersistSessionHTTPModule)
|
||||
|
||||
@@ -5,6 +5,11 @@ import {ActivatedRoute} from "../../routing/ActivatedRoute";
|
||||
import {ResponseObject} from "../../routing/Route";
|
||||
import {AbstractResolvedRouteHandlerHTTPModule} from "./AbstractResolvedRouteHandlerHTTPModule";
|
||||
|
||||
/**
|
||||
* HTTP Kernel module that executes the preflight handlers for the route.
|
||||
*
|
||||
* Usually, this is the pre middleware.
|
||||
*/
|
||||
export class ExecuteResolvedRoutePreflightHTTPModule extends AbstractResolvedRouteHandlerHTTPModule {
|
||||
public static register(kernel: HTTPKernel) {
|
||||
kernel.register(this).after(MountActivatedRouteHTTPModule)
|
||||
|
||||
@@ -7,6 +7,10 @@ import {SetSessionCookieHTTPModule} from "./SetSessionCookieHTTPModule";
|
||||
import {SessionFactory} from "../../session/SessionFactory";
|
||||
import {Session} from "../../session/Session";
|
||||
|
||||
/**
|
||||
* HTTP kernel middleware that creates the session using the configured driver
|
||||
* and loads its data using the request's session cookie.
|
||||
*/
|
||||
@Injectable()
|
||||
export class InjectSessionHTTPModule extends HTTPKernelModule {
|
||||
public readonly executeWithBlockingWriteback = true
|
||||
|
||||
@@ -6,6 +6,10 @@ import {Routing} from "../../../service/Routing";
|
||||
import {ActivatedRoute} from "../../routing/ActivatedRoute";
|
||||
import {Logging} from "../../../service/Logging";
|
||||
|
||||
/**
|
||||
* HTTP kernel middleware that tries to find a registered route matching the request's
|
||||
* path and creates an ActivatedRoute instance from it.
|
||||
*/
|
||||
@Injectable()
|
||||
export class MountActivatedRouteHTTPModule extends HTTPKernelModule {
|
||||
public readonly executeWithBlockingWriteback = true
|
||||
|
||||
@@ -4,6 +4,10 @@ import {HTTPKernel} from "../HTTPKernel";
|
||||
import {Request} from "../../lifecycle/Request";
|
||||
import {Session} from "../../session/Session";
|
||||
|
||||
/**
|
||||
* HTTP kernel module that runs after the main logic in the request to persist
|
||||
* the session data to the driver's backend.
|
||||
*/
|
||||
@Injectable()
|
||||
export class PersistSessionHTTPModule extends HTTPKernelModule {
|
||||
public readonly executeWithBlockingWriteback = true
|
||||
|
||||
@@ -4,6 +4,9 @@ import {Injectable, Inject} from "@extollo/di"
|
||||
import {HTTPKernel} from "../HTTPKernel";
|
||||
import {Config} from "../../../service/Config";
|
||||
|
||||
/**
|
||||
* HTTP kernel middleware that sets the `X-Powered-By` header.
|
||||
*/
|
||||
@Injectable()
|
||||
export class PoweredByHeaderInjectionHTTPModule extends HTTPKernelModule {
|
||||
public readonly executeWithBlockingWriteback = true
|
||||
|
||||
@@ -5,6 +5,10 @@ import {HTTPKernel} from "../HTTPKernel";
|
||||
import {Request} from "../../lifecycle/Request";
|
||||
import {Logging} from "../../../service/Logging";
|
||||
|
||||
/**
|
||||
* HTTP kernel middleware that tries to look up the session ID from the request.
|
||||
* If none exists, generates a new one and sets the cookie.
|
||||
*/
|
||||
@Injectable()
|
||||
export class SetSessionCookieHTTPModule extends HTTPKernelModule {
|
||||
public readonly executeWithBlockingWriteback = true
|
||||
|
||||
Reference in New Issue
Block a user