///
import { IncomingMessage, ServerResponse } from 'http';
import Route from './route';
import Request from './request';
import DenaliObject from '../metal/object';
import ConfigService from './config';
export interface RoutesCache {
GET: Route[];
POST: Route[];
PUT: Route[];
PATCH: Route[];
DELETE: Route[];
HEAD: Route[];
OPTIONS: Route[];
[method: string]: Route[];
}
export interface MiddlewareFn {
(req: IncomingMessage, res: ServerResponse, next: Function): void;
}
export interface ResourceOptions {
/**
* Should routes for related resources be generated? If true, routes will be
* generated following the JSON-API recommendations for relationship URLs.
*
* @see {@link http://jsonapi.org/recommendations/#urls-relationships|JSON-API URL
* Recommendatiosn}
*/
related?: boolean;
/**
* A list of action types to _not_ generate.
*/
except?: string[];
/**
* A list of action types that should be the _only_ ones generated.
*/
only?: string[];
}
export interface RouterDSL {
get(pattern: string, action: string, params?: {}): void;
post(pattern: string, action: string, params?: {}): void;
put(pattern: string, action: string, params?: {}): void;
patch(pattern: string, action: string, params?: {}): void;
delete(pattern: string, action: string, params?: {}): void;
head(pattern: string, action: string, params?: {}): void;
options(pattern: string, action: string, params?: {}): void;
resource(resourceName: string, options?: ResourceOptions): void;
}
/**
* The Router handles incoming requests, sending them to the appropriate
* action. It's also responsible for defining routes in the first place - it's
* passed into the `config/routes.js` file's exported function as the first
* argument.
*
* @package runtime
* @since 0.1.0
*/
export default class Router extends DenaliObject implements RouterDSL {
/**
* The cache of available routes.
*/
routes: RoutesCache;
/**
* The internal generic middleware handler, responsible for building and
* executing the middleware chain.
*/
protected middleware: any;
readonly config: ConfigService;
/**
* Helper method to invoke the function exported by `config/routes.js` in the
* context of the current router instance.
*
* @since 0.1.0
*/
map(fn: (router: Router) => void): void;
/**
* Takes an incoming request and it's response from an HTTP server, prepares
* them, runs the generic middleware first, hands them off to the appropriate
* action given the incoming URL, and finally renders the response.
*/
handle(req: IncomingMessage, res: ServerResponse): Promise;
/**
* Takes a request, response, and an error and hands off to the generic
* application level error action.
*/
protected handleError(request: Request, res: ServerResponse, error: Error): Promise;
/**
* Add the supplied middleware function to the generic middleware stack that
* runs prior to action handling.
*
* @since 0.1.0
*/
use(middleware: MiddlewareFn): void;
/**
* Add a route to the application. Maps a method and URL pattern to an
* action, with optional additional parameters.
*
* URL patterns can use:
*
* * Dynamic segments, i.e. `'foo/:bar'` * Wildcard segments, i.e.
* `'foo/*bar'`, captures the rest of the URL up to the querystring
* * Optional groups, i.e. `'foo(/:bar)'`
*
* @since 0.1.0
*/
route(method: string, rawPattern: string, actionPath: string, params?: any): void;
/**
* Returns the URL for a given action. You can supply a params object which
* will be used to fill in the dynamic segements of the action's route (if
* any).
*/
urlFor(actionPath: string, data: any): string | boolean;
/**
* Shorthand for `this.route('get', ...arguments)`
*
* @since 0.1.0
*/
get(rawPattern: string, actionPath: string, params?: any): void;
/**
* Shorthand for `this.route('post', ...arguments)`
*
* @since 0.1.0
*/
post(rawPattern: string, actionPath: string, params?: any): void;
/**
* Shorthand for `this.route('put', ...arguments)`
*
* @since 0.1.0
*/
put(rawPattern: string, actionPath: string, params?: any): void;
/**
* Shorthand for `this.route('patch', ...arguments)`
*
* @since 0.1.0
*/
patch(rawPattern: string, actionPath: string, params?: any): void;
/**
* Shorthand for `this.route('delete', ...arguments)`
*
* @since 0.1.0
*/
delete(rawPattern: string, actionPath: string, params?: any): void;
/**
* Shorthand for `this.route('head', ...arguments)`
*
* @since 0.1.0
*/
head(rawPattern: string, actionPath: string, params?: any): void;
/**
* Shorthand for `this.route('options', ...arguments)`
*
* @since 0.1.0
*/
options(rawPattern: string, actionPath: string, params?: any): void;
/**
* Create all the CRUD routes for a given resource and it's relationships.
* Based on the JSON-API recommendations for URL design.
*
* The `options` argument lets you pass in `only` or `except` arrays to
* define exceptions. Action names included in `only` will be the only ones
* generated, while names included in `except` will be omitted.
*
* Set `options.related = false` to disable relationship routes.
*
* If no options are supplied, the following routes are generated (assuming a
* 'books' resource as an example):
*
* * `GET /books`
* * `POST /books`
* * `GET /books/:id`
* * `PATCH /books/:id`
* * `DELETE /books/:id`
* * `GET /books/:id/:relation`
* * `GET /books/:id/relationships/:relation`
* * `PATCH /books/:id/relationships/:relation`
* * `POST /books/:id/relationships/:relation`
* * `DELETE /books/:id/relationships/:relation`
*
* See http://jsonapi.org/recommendations/#urls for details.
*
* @since 0.1.0
*/
resource(resourceName: string, options?: ResourceOptions): void;
[methodName: string]: any;
/**
* Enables easy route namespacing. You can supply a method which takes a
* single argument that works just like the `router` argument in your
* `config/routes.js`, or you can use the return value just like the router.
*
* router.namespace('users', (namespace) => {
* namespace.get('sign-in');
* });
* // or ...
* let namespace = router.namespace('users');
* namespace.get('sign-in');
*/
namespace(namespace: string, fn: (wrapper: RouterDSL) => void): void;
}