/** * Provides the REST resource-specific routing functionality of an application. */ import * as squell from 'squell'; import { Model, ModelConstructor } from 'modelsafe'; import { Router, RouterContext } from './router'; import { Auth } from './auth'; /** A type of action on a REST resource. */ export declare type ResourceAction = 'read' | 'list' | 'create' | 'update' | 'delete'; /** * A REST resource version of a middleware interface. * Used for any resource middlewares. * * Note that unlike router middlewares, resource middlewares * can span across multiple milestones and it's actually * correct behaviour for a large number of resource middlewares * to be called during handling a resource action. * * This is unlikely router middlewares, where generally * only one is handled during responding a request, * unless it is doing something like parsing cookies. */ export declare type ResourceMiddleware = (this: Resource, ctx: ResourceContext, next: () => Promise) => Promise; /** * The resource-specific data associated with a resource context. */ export interface ResourceData { /** Resource name */ name: string; /** Action name */ actionName: string; /** The model constructor for the resource context. */ model: ModelConstructor; /** * The query for the resource context. This can be changed * in order to execute a custom query, e.g. to add additional * where clauses. */ query: squell.Query; /** * Whether this resource is acting on a single instance * or multiple instances. The only resource action * that acts on multiple currently is listing. */ multiple: boolean; /** * The data for the request. This is initially * populated from the body during the start milestone and then * merged onto the actual model instance during * the write step. */ data: Partial | Partial[]; /** The model instance data for the resource context (if it's been fetched). */ instance?: T | T[]; } /** * A REST resource-specific implementation of a router context. * This will be given to any middleware for a resource. */ export interface ResourceContext extends RouterContext { /** Resource-specific data for a resource context. */ resource: ResourceData; } /** Options to customize the behaviour of a REST resource. */ export interface ResourceOptions { /** Resource name */ name?: string; /** Which REST resource actions should be enabled. */ actions?: ResourceAction[]; /** List of public routes */ publicActions?: ResourceAction[]; /** Whether to include all associations on the resource. Defaults to false. */ associations?: boolean; /** Authoriser for authenticating route access */ auth?: Auth; } /** * A REST resource implementation of a router. * This has a default implementation of a REST resource. * Each action and milestone are broken up into * their own methods, allowing extending this class * with changes to the default functionality. * * This can be used on a router * at a specific path to mount the resource, e.g.: * * ``` * let resource = new Resource(db, User); * * router.use('/users', resource.routes()); * ``` */ export declare class Resource extends Router { /** Any resource options. */ protected resourceOptions: ResourceOptions; /** The Squell database connection the resource will use. */ protected db: squell.Database; /** The Squell model constructor that the resource will query. */ protected model: ModelConstructor; /** * Construct a resource router. * * @param db The Squell database. * @param model The Squell model constructor to query. * @param resOptions Any resource options to use. */ constructor(db: squell.Database, model: ModelConstructor, options?: ResourceOptions); /** * Process a single resource middleware or a chain of resource middlewares in the order given. * This normally will be called with the default chain of middlewares to run through for a specific * REST action, but you should use it if you intend to process any sub-chain of middlewares * in your own resource methods. * * Using this function ensures that every middlware (or the single middleware) will receive * a `next` function. * * This function takes a `parentNext` function which should be the `next` function given to the * the callee of this function (i.e. the middleware of the parent chain). The `next` function * then passes to the sub-chain of this process will automatically call the callee's provided * `parentNext` function if the last middleware returns/calls `next`. This ensures * that when you process a chain of middlewares, the `next` behaviour will carry across * from the chain to the parent function. * * This uses the same logic as Koa's middleware composing. * * @see https://github.com/koajs/compose/blob/master/index.js * @param ctx The resource context. * @param chain The resurce middleware[s] to process. * @param parentNext The next function of the middleware, if available. * @returns A promise processing the resource middleware[s]. */ private process(ctx, chain, parentNext?); /** * Handle starting a resource request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleStart(ctx: ResourceContext, next: () => Promise): Promise; /** * Handle authenticating a resource request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleAuth(ctx: ResourceContext, next: () => Promise): Promise; /** * Handle sending a resource request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleSend(ctx: ResourceContext, next: () => Promise): Promise; /** * Handle finishing a resource request. * * @param ctx The resource context. * @returns A promsie handling the request. */ protected handleFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before starting a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeListStart(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle starting a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleListStart(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before authenticating a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeListAuth(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle authenticating a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleListAuth(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after authenticating a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterListAuth(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after starting a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterListStart(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before fetching a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeListFetch(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle fetching a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleListFetch(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after fetching a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterListFetch(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before sending a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeListSend(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle sending a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleListSend(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after sending a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterListSend(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before finishing a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeListFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle finishing a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleListFinish(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after finishing a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterListFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle a resource list request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleList(ctx: ResourceContext): Promise; /** * Do something before starting a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeReadStart(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle starting a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleReadStart(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after starting a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterReadStart(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before authenticating a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeReadAuth(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle authenticating a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleReadAuth(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after authenticating a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterReadAuth(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before fetching a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeReadFetch(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle fetching a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleReadFetch(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after finishing a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterReadFetch(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before sending a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeReadSend(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle sending a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleReadSend(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after sending a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterReadSend(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before finishing a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeReadFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle finishing a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleReadFinish(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after finishing a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterReadFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle a resource read request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleRead(ctx: ResourceContext): Promise; /** * Do something before starting a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeCreateStart(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle starting a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleCreateStart(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after starting a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterCreateStart(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before authenticating a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeCreateAuth(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle authenticating a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleCreateAuth(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after authenticating a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterCreateAuth(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before writing a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeCreateWrite(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle writing a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleCreateWrite(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after writing a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterCreateWrite(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before sending a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeCreateSend(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle sending a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleCreateSend(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after sending a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterCreateSend(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before finishing a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeCreateFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle finishing a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleCreateFinish(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after finishing a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterCreateFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle a resource create request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleCreate(ctx: ResourceContext): Promise; /** * Do something before starting a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeUpdateStart(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle starting a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleUpdateStart(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after starting a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterUpdateStart(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before authenticating a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeUpdateAuth(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle authenticating a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleUpdateAuth(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after authenticating a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterUpdateAuth(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before fetching a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeUpdateFetch(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle fetching a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleUpdateFetch(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after fetching a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterUpdateFetch(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before writing a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeUpdateWrite(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle writing a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleUpdateWrite(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after writing a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterUpdateWrite(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before sending a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeUpdateSend(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle sending a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleUpdateSend(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after sending a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterUpdateSend(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before finishing a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeUpdateFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle finishing a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleUpdateFinish(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after finishing a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterUpdateFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle a resource update request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleUpdate(ctx: ResourceContext): Promise; /** * Do something before starting a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeDeleteStart(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle starting a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleDeleteStart(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after starting a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterDeleteStart(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before authenticating a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeDeleteAuth(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle authenticating a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleDeleteAuth(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after authenticating a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterDeleteAuth(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before fetching a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeDeleteFetch(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle fetching a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleDeleteFetch(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after fetching a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterDeleteFetch(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before writing a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeDeleteWrite(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle writing a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleDeleteWrite(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after writing a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterDeleteWrite(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before sending a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeDeleteSend(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle sending a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleDeleteSend(ctx: ResourceContext, _next: () => Promise): Promise; /** * Do something after sending a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterDeleteSend(_ctx: ResourceContext, next: () => Promise): Promise; /** * Do something before finishing a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected beforeDeleteFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle finishing a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleDeleteFinish(ctx: ResourceContext, next: () => Promise): Promise; /** * Do something after finishing a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected afterDeleteFinish(_ctx: ResourceContext, next: () => Promise): Promise; /** * Handle a resource delete request. * * @param ctx The resource context. * @returns A promise handling the request. */ protected handleDelete(ctx: ResourceContext): Promise; }