/// import http = require("http"); import https = require("https"); import Logger = require("bunyan"); import url = require("url"); import spdy = require("spdy"); import stream = require("stream"); import zlib = require("zlib"); import { File } from "formidable"; export interface ServerOptions { ca?: string | Buffer | ReadonlyArray | undefined; certificate?: string | Buffer | ReadonlyArray | undefined; cert?: string | Buffer | ReadonlyArray | undefined; key?: string | Buffer | ReadonlyArray | undefined; passphrase?: string | undefined; requestCert?: boolean | undefined; ciphers?: string | undefined; formatters?: Formatters | undefined; log?: Logger | undefined; name?: string | undefined; spdy?: spdy.ServerOptions | undefined; version?: string | undefined; versions?: string[] | undefined; handleUpgrades?: boolean | undefined; httpsServerOptions?: https.ServerOptions | undefined; handleUncaughtExceptions?: boolean | undefined; router?: Router | undefined; socketio?: boolean | undefined; noWriteContinue?: boolean | undefined; rejectUnauthorized?: boolean | undefined; secureOptions?: number | undefined; http2?: any; dtrace?: boolean | undefined; onceNext?: boolean | undefined; strictNext?: boolean | undefined; ignoreTrailingSlash?: boolean | undefined; maxParamLength?: number | undefined; strictFormatters?: boolean | undefined; } export interface AddressInterface { port: number; family: string; address: string; } export interface Server extends http.Server { /** * Returns the server address. Wraps node's address(). */ address(): AddressInterface; /** * Gets the server up and listening. Wraps node's listen(). * * You can call like: * server.listen(80) * server.listen(80, '127.0.0.1') * server.listen('/tmp/server.sock') * * @throws {TypeError} * @param callback optionally get notified when listening. */ listen(...args: any[]): any; /** * Shuts down this server, and invokes callback (optionally) when done. * Wraps node's close(). * @param callback optional callback to invoke when done. */ close(callback?: () => any): any; /** * Returns the number of currently inflight requests. */ inflightRequests(): number; /** * Mounts a chain on the given path against this HTTP verb * * @param opts if string, the URL to handle. * if options, the URL to handle, at minimum. * @returns the newly created route. */ del(opts: string | RegExp | RouteOptions, ...handlers: RequestHandlerType[]): Route | boolean; /** * Mounts a chain on the given path against this HTTP verb * * @param opts if string, the URL to handle. * if options, the URL to handle, at minimum. * @returns the newly created route. */ get(opts: string | RegExp | RouteOptions, ...handlers: RequestHandlerType[]): Route | boolean; /** * Mounts a chain on the given path against this HTTP verb * * @param opts if string, the URL to handle. * if options, the URL to handle, at minimum. * @returns the newly created route. */ head(opts: string | RegExp | RouteOptions, ...handlers: RequestHandlerType[]): Route | boolean; /** * Mounts a chain on the given path against this HTTP verb * * @param opts if string, the URL to handle. * if options, the URL to handle, at minimum. * @returns the newly created route. */ opts(opts: string | RegExp | RouteOptions, ...handlers: RequestHandlerType[]): Route | boolean; /** * Mounts a chain on the given path against this HTTP verb * * @param opts if string, the URL to handle. * if options, the URL to handle, at minimum. * @returns the newly created route. */ post(opts: string | RegExp | RouteOptions, ...handlers: RequestHandlerType[]): Route | boolean; /** * Mounts a chain on the given path against this HTTP verb * * @param opts if string, the URL to handle. * if options, the URL to handle, at minimum. * @returns the newly created route. */ put(opts: string | RegExp | RouteOptions, ...handlers: RequestHandlerType[]): Route | boolean; /** * Mounts a chain on the given path against this HTTP verb * * @param opts if string, the URL to handle. * if options, the URL to handle, at minimum. * @returns the newly created route. */ patch(opts: string | RegExp | RouteOptions, ...handlers: RequestHandlerType[]): Route | boolean; /** * Minimal port of the functionality offered by Express.js Route Param * Pre-conditions * @link http://expressjs.com/guide.html#route-param%20pre-conditions * * This basically piggy-backs on the `server.use` method. It attaches a * new middleware function that only fires if the specified parameter exists * in req.params * * Exposes an API: * server.param("user", function (req, res, next) { * // load the user's information here, always making sure to call next() * }); * * @param name The name of the URL param to respond to * @param fn The middleware function to execute * @returns returns self */ param(name: string, fn: RequestHandler): Server; /** * Removes a route from the server. * You pass in the route 'blob' you got from a mount call. * @throws {TypeError} on bad input. * @param route the route name. * @returns true if route was removed, false if not. */ rm(route: string): boolean; /** * Installs a list of handlers to run _before_ the "normal" handlers of all * routes. * * You can pass in any combination of functions or array of functions. * @returns returns self */ use(...handlers: RequestHandlerType[]): Server; /** * Gives you hooks to run _before_ any routes are located. This gives you * a chance to intercept the request and change headers, etc., that routing * depends on. Note that req.params will _not_ be set yet. * @returns returns self */ pre(...pre: RequestHandlerType[]): Server; /** * toString() the server for easy reading/output. */ toString(): string; /** * Return debug information about the server. */ getDebugInfo(): any; /** Name of the server. */ name: string; /** Default version(s) to use in all routes. */ versions: string[]; /** bunyan instance. */ log: Logger; /** List of content-types this server can respond with. */ acceptable: string[]; /** Once listen() is called, this will be filled in with where the server is running. */ url: string; /** Node server instance */ server: http.Server | https.Server | spdy.Server; /** Router instance */ router: Router; /** Handle uncaught exceptions */ handleUncaughtExceptions: boolean; /** enable DTrace support */ dtrace: boolean; /** Custom response formatters */ formatters: Formatters; /** Prevents calling next multiple times */ onceNext: boolean; /** Throws error when next() is called more than once, enabled onceNext option */ strictNext: boolean; /** Pre handlers */ preChain: Chain; useChain: Chain; spdy?: boolean | undefined; http2?: boolean | undefined; ca: ServerOptions["ca"]; certificate: ServerOptions["certificate"]; key: ServerOptions["key"]; passphrase: ServerOptions["passphrase"] | null; secure?: boolean | undefined; } export interface ChainOptions { onceNext?: boolean | undefined; strictNext?: boolean | undefined; } export interface Chain { /** Get handlers of a chain instance */ getHandlers(): RequestHandler[]; /** Utilize the given middleware `handler` */ add(handler: RequestHandler): void; /** Returns the number of handlers */ count(): number; /** Handle server requests, punting them down the middleware stack. */ run(req: Request, res: Response, done: () => any): void; /** Prevents calling next multiple times */ onceNext: boolean; /** Throws error when next() is called more than once, enables onceNext option */ strictNext: boolean; } export interface RouterRegistryRadix { /** * Adds a route. */ add(route: Route): boolean; /** * Removes a route. */ remove(name: string): Route | undefined; /** * Registry for route. */ lookup(method: string, pathname: string): Chain | undefined; /** * Get registry. */ get(): Route[]; /** * toString() serialization. */ toString(): string; } export interface RouterOptions { log?: Logger | undefined; onceNext?: boolean | undefined; strictNext?: boolean | undefined; ignoreTrailingSlash?: boolean | undefined; registry?: RouterRegistryRadix | undefined; } export class Router { constructor(options: RouterOptions); /** * Lookup for route */ lookup(req: Request, res: Response): Chain | undefined; /** * Lookup by name */ lookupByName(name: string, req: Request, res: Response): Chain | undefined; /** * adds a route. * @param options an options object * @returns returns the route name if creation is successful. */ mount(options: MountOptions, ...handlers: RequestHandlerType[]): string; /** * unmounts a route. * @param name the route name * @returns the name of the deleted route. */ unmount(name: string): string; /** * Return mounted routes. */ getRoutes(): Route[]; /** * Default route, when no route found */ defaultRoute(req: Request, res: Response, next: Next): void; /** * takes an object of route params and query params, and 'renders' a URL. * @param routeName the route name * @param params an object of route params * @param query an object of query params */ render(routeName: string, params: object, query?: object): string; /** * toString() serialization. */ toString(): string; /** * Return information about the routes registered in the router. * @returns The routes in the router. */ getDebugInfo(): any; name: string; log?: Logger | undefined; onceNext: boolean; strictNext: boolean; } export interface RequestAuthorization { scheme: string; credentials: string; basic?: { username: string; password: string; } | undefined; } export interface Request extends http.IncomingMessage { /** * Builds an absolute URI for the request. */ absoluteUri(path: string): string; /** * checks if the accept header is present and has the value requested. * e.g., req.accepts('html'); * @param types an array of accept type headers */ accepts(types: string | string[]): boolean; /** * checks if the request accepts the encoding types. * @param types an array of accept type headers */ acceptsEncoding(types: string | string[]): boolean; /** * gets the content-length header off the request. */ getContentLength(): number; /** * pass through to getContentLength. */ contentLength(): number; /** * gets the content-type header. */ getContentType(): string; /** * pass through to getContentType. */ contentType(): string; /** * retrieves the complete URI requested by the client. */ getHref(): string; /** * pass through to getHref. */ href(): string; /** * retrieves the request uuid. was created when the request was setup. */ getId(): string; /** * pass through to getId. */ id(): string; /** * retrieves the cleaned up url path. * e.g., /foo?a=1 => /foo */ getPath(): string; /** * pass through to getPath. */ path(): string; /** * returns the raw query string */ getQuery(): string; // /** // * pass through to getQuery. // * @public // * @function query // * @returns {String} // */ // query(): string; /** * returns ms since epoch when request was setup. */ time(): number; /** * returns a parsed URL object. */ getUrl(): url.Url; /** * returns the accept-version header. */ getVersion(): string; /** * pass through to getVersion. */ version(): string; /** * returns the version of the route that matched. */ matchedVersion(): string; /** * Get the case-insensitive request header key, * and optionally provide a default value (express-compliant). * Returns any header off the request. also, 'correct' any * correctly spelled 'referrer' header to the actual spelling used. * @param key - the key of the header * @param defaultValue - default value if header isn't found on the req */ header(key: string, defaultValue?: string): string; /** * returns any trailer header off the request. also, 'correct' any * correctly spelled 'referrer' header to the actual spelling used. * @param name the name of the header * @param defaultValue default value if header isn't found on the req */ trailer(name: string, defaultValue?: string): string; /** * Check if the incoming request contains the Content-Type header field, and * if it contains the given mime type. * @param type a content-type header value */ is(type: string): boolean; /** * Check if the incoming request is chunked. */ isChunked(): boolean; /** * Check if the incoming request is kept alive. */ isKeepAlive(): boolean; /** * Check if the incoming request is encrypted. */ isSecure(): boolean; /** * Check if the incoming request has been upgraded. */ isUpgradeRequest(): boolean; /** * Check if the incoming request is an upload verb. */ isUpload(): boolean; /** * toString serialization */ toString(): string; /** * retrieves the user-agent header. */ userAgent(): string; /** * Start the timer for a request handler function. You must explicitly invoke * endHandlerTimer() after invoking this function. Otherwise timing information * will be inaccurate. * @param handlerName The name of the handler. */ startHandlerTimer(handlerName: string): void; /** * Stop the timer for a request handler function. * @param handlerName The name of the handler. */ endHandlerTimer(handlerName: string): void; /** * returns the connection state of the request. current valid values are * 'close' and 'aborted'. */ connectionState(): string; /** * returns the route object to which the current request was matched to. * Route info object structure: * { * path: '/ping/:name', * method: 'GET', * versions: [], * name: 'getpingname' * } */ getRoute(): Route; /** bunyan logger you can piggyback on. */ log: Logger; /** available when queryParser plugin is used. */ query?: any; /** available when bodyParser plugin is used. */ body?: any; /** available when bodyParser plugin is used. */ rawBody?: any; /** available when queryParser or bodyParser plugin is used with mapParams enabled. */ params?: any; /** available when multipartBodyParser plugin is used. */ files?: { [name: string]: File | undefined } | undefined; /** available when authorizationParser plugin is used */ username?: string | undefined; /** available when authorizationParser plugin is used */ authorization?: RequestAuthorization | undefined; } export interface CacheOptions { maxAge: number; } export interface Response extends http.ServerResponse { /** * sets the cache-control header. `type` defaults to _public_, * and options currently only takes maxAge. * @param type value of the header * @param [options] an options object * @returns the value set to the header */ cache(type: string, options?: CacheOptions): string; /** * sets the cache-control header. `type` defaults to _public_, * and options currently only takes maxAge. * @param [options] an options object * @returns the value set to the header */ cache(options?: CacheOptions): string; /** * turns off all cache related headers. * @returns self, the response object */ noCache(): Response; /** * Appends the provided character set to the response's Content-Type. * e.g., res.charSet('utf-8'); * @param type char-set value * @returns self, the response object */ charSet(type: string): Response; /** * retrieves a header off the response. * @param name the header name */ get(name: string): string; /** * retrieves all headers off the response. */ getHeaders(): any; /** * pass through to getHeaders. */ headers(): any; /** * sets headers on the response. * @param key the name of the header * @param value the value of the header */ header(key: string, value?: any): any; /** * short hand method for: * res.contentType = 'json'; * res.send({hello: 'world'}); * @param code http status code * @param body value to json.stringify * @param [headers] headers to set on the response */ json(code: number, body: any, headers?: { [header: string]: string }): any; /** * short hand method for: * res.contentType = 'json'; * res.send({hello: 'world'}); * @param body value to json.stringify * @param [headers] headers to set on the response */ json(body: any, headers?: { [header: string]: string }): any; /** * sets the link heaader. * @param key the link key * @param value the link value * @returns the header value set to res */ link(key: string, value: string): string; /** * sends the response object. pass through to internal __send that uses a * formatter based on the content-type header. * @param [code] http status code * @param [body] the content to send * @param [headers] any add'l headers to set * @returns the response object */ send(code?: number, body?: any, headers?: { [header: string]: string }): any; /** * sends the response object. pass through to internal __send that uses a * formatter based on the content-type header. * @param [body] the content to send * @param [headers] any add'l headers to set * @returns the response object */ send(body?: any, headers?: { [header: string]: string }): any; /** * sends the response object. pass through to internal __send that skips * formatters entirely and sends the content as is. * @param [code] http status code * @param [body] the content to send * @param [headers] any add'l headers to set * @returns the response object */ sendRaw(code?: number, body?: any, headers?: { [header: string]: string }): any; /** * sends the response object. pass through to internal __send that skips * formatters entirely and sends the content as is. * @param [body] the content to send * @param [headers] any add'l headers to set * @returns the response object */ sendRaw(body?: any, headers?: { [header: string]: string }): any; /** * sets a header on the response. * @param name name of the header * @param val value of the header * @returns self, the response object */ set(name: string, val: string): Response; /** * sets a header on the response. * @param val object of headers * @returns self, the response object */ set(headers?: { [header: string]: string }): Response; /** * sets the http status code on the response. * @param code http status code * @returns the status code passed in */ status(code: number): number; /** * toString() serialization. */ toString(): string; /** * redirect is sugar method for redirecting. * res.redirect(301, 'www.foo.com', next); * `next` is mandatory, to complete the response and trigger audit logger. * @param code the status code * @param url to redirect to * @param next - mandatory, to complete the response and trigger audit logger * @fires redirect */ redirect(code: number, url: string, next: Next): void; /** * redirect is sugar method for redirecting. * res.redirect({...}, next); * `next` is mandatory, to complete the response and trigger audit logger. * @param url to redirect to or options object to configure a redirect or * @param next - mandatory, to complete the response and trigger audit logger * @fires redirect */ redirect(opts: string | RedirectOptions, next: Next): void; /** HTTP status code. */ code: number; /** short hand for the header content-length. */ contentLength: number; /** short hand for the header content-type. */ contentType: string; /** A unique request id (x-request-id). */ id: string; } export interface RedirectOptions { /** * whether to redirect to http or https */ secure?: boolean | undefined; /** * redirect location's hostname */ hostname?: string | undefined; /** * redirect location's pathname */ pathname?: string | undefined; /** * redirect location's port number */ port?: string | undefined; /** * redirect location's query string parameters */ query?: string | object | undefined; /** * if true, `options.query` * stomps over any existing query * parameters on current URL. * by default, will merge the two. */ overrideQuery?: boolean | undefined; /** * if true, sets 301. defaults to 302. */ permanent?: boolean | undefined; } export interface Next { (err?: any): void; } export interface RouteSpec { method: string; name?: string | undefined; path: string | RegExp; versions?: string[] | undefined; } export interface Route { name: string; method: string; path: string | RegExp; spec: RouteSpec; chain: Chain; } export interface RouteOptions { name?: string | undefined; path?: string | RegExp | undefined; url?: string | RegExp | undefined; urlParamPattern?: RegExp | undefined; contentType?: string | string[] | undefined; version?: string | undefined; versions?: string[] | undefined; } export interface MountOptions { name: string; method: string; path?: string | RegExp | undefined; url?: string | RegExp | undefined; urlParamPattern?: RegExp | undefined; contentType?: string | string[] | undefined; version?: string | undefined; versions?: string[] | undefined; } export type FindRouteCallback = (err: Error, route?: Route, params?: any) => void; export type RequestHandler = (req: Request, res: Response, next: Next) => any; export type RequestHandlerType = RequestHandler | RequestHandler[]; export interface ServerUpgradeResponse { /** * Set the status code of the response. * @param code - the http status code */ status(code: number): number; /** * Sends the response. * @param code - the http status code * @param body - the response to send out */ send(code: number, body: any): any; /** * Sends the response. * @param body - the response to send out */ send(body: any): boolean; /** * Ends the response */ end(): boolean; /** * Write to the response. */ write(): boolean; /** * Write to the head of the response. * @param statusCode - the http status code * @param reason - a message */ writeHead(statusCode: number, reason?: string): void; /** * Attempt to upgrade. */ claimUpgrade(): any; } export namespace bunyan { interface RequestCaptureOptions { /** The stream to which to write when dumping captured records. */ stream?: Logger.Stream | undefined; /** The streams to which to write when dumping captured records. */ streams?: readonly Logger.Stream[] | undefined; /** * The level at which to trigger dumping captured records. Defaults to * bunyan.WARN. */ level?: Logger.LogLevel | undefined; /** Number of records to capture. Default 100. */ maxRecords?: number | undefined; /** * Number of simultaneous request id capturing buckets to maintain. * Default 1000. */ maxRequestIds?: number | undefined; /** * If true, then dump captured records on the *default* request id when * dumping. I.e. dump records logged without "req_id" field. Default * false. */ dumpDefault?: boolean | undefined; } /** * A Bunyan stream to capture records in a ring buffer and only pass through * on a higher-level record. E.g. buffer up all records but only dump when * getting a WARN or above. */ class RequestCaptureStream extends stream.Stream { constructor(opts: RequestCaptureOptions); /** write to the stream */ write(record: any): void; } const serializers: Logger.Serializers & { err: Logger.Serializer; req: Logger.Serializer; res: Logger.Serializer; client_req: Logger.Serializer; client_res: Logger.Serializer; }; /** create a bunyan logger */ function createLogger(name: string): Logger; } export function createServer(options?: ServerOptions): Server; export type Formatter = (req: Request, res: Response, body: any) => string | Buffer | null; export interface Formatters { [contentType: string]: Formatter; } export const formatters: Formatters; export namespace plugins { namespace pre { /** * Provide req.set(key, val) and req.get(key) methods for setting and retrieving context to a specific request. */ function context(): RequestHandler; function dedupeSlashes(): RequestHandler; /** * This pre handler fixes issues with node hanging when an asyncHandler is used prior to bodyParser. */ function pause(): RequestHandler; /** * Cleans up duplicate or trailing / on the URL */ function sanitizePath(): RequestHandler; /** * Automatically reuse incoming request header as the request id. */ function reqIdHeaders(options: { headers: string[] }): RequestHandler; /** * Checks req.urls query params with strict key/val format and rejects non-strict requests with status code 400. */ function strictQueryParams(options?: { message: string }): RequestHandler; /** * Regexp to capture curl user-agents */ function userAgentConnection(options?: { userAgentRegExp: any; }): RequestHandler; } // *************** This module includes the following header parser plugins: /** * Check the client's Accept header can be handled by this server. */ function acceptParser(accepts: string[]): RequestHandler; type AuditLoggerContext = ( req: Request, res: Response, route: any, error: any, ) => any; interface AuditLoggerOptions { /** * Bunyan logger */ log: Logger; /** * The event from the server which initiates the * log, one of 'pre', 'routed', or 'after' */ event: "pre" | "routed" | "after"; /** * Restify server. If passed in, causes server to emit 'auditlog' event after audit logs are flushed */ server?: Server | undefined; /** * The optional context function of signature * f(req, res, route, err). Invoked each time an audit log is generated. This * function can return an object that customizes the format of anything off the * req, res, route, and err objects. The output of this function will be * available on the `context` key in the audit object. */ context?: AuditLoggerContext | undefined; /** * Ringbuffer which is written to if passed in */ logBuffer?: any; /** * When true, prints audit logs. default true. */ printLog?: boolean | undefined; body?: boolean | undefined; } /** * An audit logger for recording all handled requests */ function auditLogger(options: AuditLoggerOptions): (...args: any[]) => void; /** * Authorization header */ function authorizationParser(options?: any): RequestHandler; interface HandlerCandidate { handler: RequestHandler | RequestHandler[]; version?: string | string[] | undefined; contentType?: string | string[] | undefined; } /** * Runs first handler that matches to the condition */ function conditionalHandler( candidates: HandlerCandidate | HandlerCandidate[], ): RequestHandler; /** * Conditional headers (If-*) */ function conditionalRequest(): RequestHandler[]; interface CpuUsageThrottleOptions { limit?: number | undefined; max?: number | undefined; interval?: number | undefined; halfLife?: number | undefined; } /** * Cpu Throttle middleware */ function cpuUsageThrottle(opts?: CpuUsageThrottleOptions): RequestHandler; /** * Handles disappeared CORS headers */ function fullResponse(): RequestHandler; // ************ This module includes the following data parsing plugins: interface BodyParserOptions { /** * The maximum size in bytes allowed in the HTTP body. Useful for limiting clients from hogging server memory. */ maxBodySize?: number | undefined; /** * If req.params should be filled with parsed parameters from HTTP body. */ mapParams?: boolean | undefined; /** * If req.params should be filled with the contents of files sent through a multipart request. * Formidable is used internally for parsing, and a file is denoted as a multipart part with the filename option set in its Content-Disposition. * This will only be performed if mapParams is true. */ mapFiles?: boolean | undefined; /** * If an entry in req.params should be overwritten by the value in the body if the names are the same. * For instance, if you have the route /:someval, and someone posts an x-www-form-urlencoded Content-Type with the body someval=happy to /sad, * the value will be happy if overrideParams is true, sad otherwise. */ overrideParams?: boolean | undefined; /** * A callback to handle any multipart part which is not a file. * If this is omitted, the default handler is invoked which may or may not map the parts into req.params, depending on the mapParams-option. */ multipartHandler?(): void; /** * A callback to handle any multipart file. * It will be a file if the part have a Content-Disposition with the filename parameter set. * This typically happens when a browser sends a form and there is a parameter similar to . * If this is not provided, the default behaviour is to map the contents into req.params. */ multipartFileHandler?(): void; /** * If you want the uploaded files to include the extensions of the original files (multipart uploads only). Does nothing if multipartFileHandler is defined. */ keepExtensions?: boolean | undefined; /** * Where uploaded files are intermediately stored during transfer before the contents is mapped into req.params. Does nothing if multipartFileHandler is defined. */ uploadDir?: string | undefined; /** * If you want to support html5 multiple attribute in upload fields. */ multiples?: boolean | undefined; /** * If you want checksums calculated for incoming files, set this to either sha1 or md5. */ hash?: string | undefined; /** * Set to true if you want to end the request with a UnsupportedMediaTypeError when none of the supported content types was given. */ rejectUnknown?: boolean | undefined; requestBodyOnGet?: boolean | undefined; reviver?: any; maxFieldsSize?: number | undefined; maxFileSize?: number | undefined; } /** * Parses POST bodies to req.body. automatically uses one of the following parsers based on content type. */ function bodyParser(options?: BodyParserOptions): RequestHandler[]; /** * Reads the body of the request. */ function bodyReader(options?: { maxBodySize?: number | undefined }): RequestHandler; interface UrlEncodedBodyParserOptions { mapParams?: boolean | undefined; overrideParams?: boolean | undefined; bodyReader?: boolean | undefined; } /** * Parse the HTTP request body IFF the contentType is application/x-www-form-urlencoded. * * If req.params already contains a given key, that key is skipped and an * error is logged. */ function urlEncodedBodyParser( options?: UrlEncodedBodyParserOptions, ): RequestHandler[]; interface JsonBodyParserOptions { mapParams?: boolean | undefined; overrideParams?: boolean | undefined; reviver?(key: any, value: any): any; bodyReader?: boolean | undefined; } /** * Parses JSON POST bodies */ function jsonBodyParser(options?: JsonBodyParserOptions): RequestHandler[]; /** * Parses JSONP callback */ function jsonp(): RequestHandler; interface MultipartBodyParser { overrideParams?: boolean | undefined; multiples?: boolean | undefined; keepExtensions?: boolean | undefined; uploadDir?: string | undefined; maxFieldsSize?: number | undefined; hash?: string | undefined; multipartFileHandler?: any; multipartHandler?: any; mapParams?: boolean | undefined; mapFiles?: boolean | undefined; maxFileSize?: number | undefined; } /** * Parses JSONP callback */ function multipartBodyParser(options?: MultipartBodyParser): RequestHandler; interface QueryParserOptions { /** * Default `false`. Copies parsed query parameters into `req.params`. */ mapParams?: boolean | undefined; /** * Default `false`. Only applies when if mapParams true. When true, will stomp on req.params field when existing value is found. */ overrideParams?: boolean | undefined; /** * Default false. Transform `?foo.bar=baz` to a nested object: `{foo: {bar: 'baz'}}`. */ allowDots?: boolean | undefined; /** * Default 20. Only transform `?a[$index]=b` to an array if `$index` is less than `arrayLimit`. */ arrayLimit?: number | undefined; /** * Default 5. The depth limit for parsing nested objects, e.g. `?a[b][c][d][e][f][g][h][i]=j`. */ depth?: number | undefined; /** * Default 1000. Maximum number of query params parsed. Additional params are silently dropped. */ parameterLimit?: number | undefined; /** * Default true. Whether to parse `?a[]=b&a[1]=c` to an array, e.g. `{a: ['b', 'c']}`. */ parseArrays?: boolean | undefined; /** * Default false. Whether `req.query` is a "plain" object -- does not inherit from `Object`. * This can be used to allow query params whose names collide with Object methods, e.g. `?hasOwnProperty=blah`. */ plainObjects?: boolean | undefined; /** * Default false. If true, `?a&b=` results in `{a: null, b: ''}`. Otherwise, `{a: '', b: ''}`. */ strictNullHandling?: boolean | undefined; } /** * Parses URL query parameters into `req.query`. Many options correspond directly to option defined for the underlying [qs.parse](https://github.com/ljharb/qs) */ function queryParser(options?: QueryParserOptions): RequestHandler; interface RequestLogger { properties?: any; serializers?: any; headers?: any; log?: any; } /** * Adds timers for each handler in your request chain * * `options.properties` properties to pass to bunyan's `log.child()` method */ function requestLogger(options?: RequestLogger): RequestHandler; // ******************** The module includes the following response plugins: /** * expires requests based on current time + delta * @param delta - age in seconds */ function dateParser(delta?: number): RequestHandler; /** * gzips the response if client send `accept-encoding: gzip` * @param options options to pass to gzlib */ function gzipResponse(options?: zlib.ZlibOptions): RequestHandler; interface InflightRequestThrottleOptions { limit: number; server: Server; err: any; } function inflightRequestThrottle( opts: InflightRequestThrottleOptions, ): RequestHandler; interface ServeStatic { appendRequestPath?: boolean | undefined; directory?: string | undefined; maxAge?: number | undefined; match?: any; charSet?: string | undefined; file?: string | undefined; etag?: string | undefined; default?: any; gzip?: boolean | undefined; } /** * Used to serve static files */ function serveStatic(options?: ServeStatic): RequestHandler; interface ServeStaticFiles { maxAge?: number | undefined; etag?: string | undefined; setHeaders?: ((res: Response, path: string, stat: any) => any) | undefined; } /** * Used to serve static files from a given directory */ function serveStaticFiles( dir: string, options?: ServeStaticFiles, ): RequestHandler; interface ThrottleOptions { burst?: number | undefined; rate?: number | undefined; setHeaders?: boolean | undefined; ip?: boolean | undefined; username?: boolean | undefined; xff?: boolean | undefined; tokensTable?: any; maxKeys?: number | undefined; overrides?: any; // any } /** * throttles responses */ function throttle(options?: ThrottleOptions): RequestHandler; type MetricsCallback = ( /** * An error if the request had an error */ err: Error, /** * Object that contains the various metrics that are returned */ metrics: MetricsCallbackOptions, /** * The request obj */ req: Request, /** * The response obj */ res: Response, /** * The route obj that serviced the request */ route: Route, ) => void; type TMetricsCallback = "close" | "aborted" | undefined; interface MetricsCallbackOptions { /** * Status code of the response. Can be undefined in the case of an `uncaughtException`. * Otherwise, in most normal scenarios, even calling `res.send()` or `res.end()` should result in a 200 by default. */ statusCode: number; /** * HTTP request verb */ method: string; /** * latency includes both request is flushed and all handlers finished */ totalLatency: number; /** * Request latency */ latency: number; /** * pre handlers latency */ preLatency: number | null; /** * use handlers latency */ useLatency: number | null; /** * req.path() value */ path: string; /** * Number of inflight requests pending in restify */ inflightRequests: number; /** * Same as `inflightRequests` */ unfinishedRequests: number; /** * If this value is set, err will be a corresponding `RequestCloseError` or `RequestAbortedError`. * * If connectionState is either 'close' or 'aborted', then the statusCode is not applicable since the connection was severed before a response was written. */ connectionState: TMetricsCallback; } /** * Listens to the server's after event and emits information about that request (5.x compatible only). * * ``` * server.on('after', plugins.metrics({ server }, (err, metrics, req, res, route) => * { * // metrics is an object containing information about the request * })); * ``` */ function metrics( opts: { server: Server }, callback: MetricsCallback, ): (...args: any[]) => void; /** * Parse the client's request for an OAUTH2 access tokensTable * * Subsequent handlers will see `req.oauth2`, which looks like: * ``` * { * oauth2: {accessToken: 'mF_9.B5f-4.1JqM&p=q'} * } * ``` */ function oauth2TokenParser(): RequestHandler; interface RequestExpiryOptions { /** * Header name of the absolute time for request expiration */ absoluteHeader?: string | undefined; /** * Header name for the start time of the request */ startHeader?: string | undefined; /** * The header name for the time in milliseconds that should ellapse before the request is considered expired. */ timeoutHeader?: string | undefined; } /** * A request expiry will use headers to tell if the incoming request has expired or not. * * There are two options for this plugin: * 1. Absolute Time * * Time in Milliseconds since the Epoch when this request should be considered expired * 2. Timeout * * The request start time is supplied * * A timeout, in milliseconds, is given * * The timeout is added to the request start time to arrive at the absolute time * in which the request is considered expires */ function requestExpiry(options?: RequestExpiryOptions): RequestHandler; } export namespace pre { /** * Provide req.set(key, val) and req.get(key) methods for setting and retrieving context to a specific request. */ function context(): RequestHandler; function dedupeSlashes(): RequestHandler; /** * This pre handler fixes issues with node hanging when an asyncHandler is used prior to bodyParser. */ function pause(): RequestHandler; /** * Cleans up duplicate or trailing / on the URL */ function sanitizePath(): RequestHandler; /** * Automatically reuse incoming request header as the request id. */ function reqIdHeaders(options: { headers: string[] }): RequestHandler; /** * Checks req.urls query params with strict key/val format and rejects non-strict requests with status code 400. */ function strictQueryParams(options?: { message: string }): RequestHandler; /** * Regexp to capture curl user-agents */ function userAgentConnection(options?: { userAgentRegExp: any }): RequestHandler; }