UNPKG

21.4 kBTypeScriptView Raw
1// Type definitions for Koa 2.13.1
2// Project: http://koajs.com
3// Definitions by: DavidCai1993 <https://github.com/DavidCai1993>
4// jKey Lu <https://github.com/jkeylu>
5// Brice Bernard <https://github.com/brikou>
6// harryparkdotio <https://github.com/harryparkdotio>
7// Wooram Jun <https://github.com/chatoo2412>
8// Christian Vaagland Tellnes <https://github.com/tellnes>
9// Piotr Kuczynski <https://github.com/pkuczynski>
10// vnoder <https://github.com/vnoder>
11// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
12// TypeScript Version: 3.0
13
14/* =================== USAGE ===================
15
16 import * as Koa from "koa"
17 const app = new Koa()
18
19 async function (ctx: Koa.Context, next: Koa.Next) {
20 // ...
21 }
22
23 =============================================== */
24/// <reference types="node" />
25import * as accepts from 'accepts';
26import * as Cookies from 'cookies';
27import { EventEmitter } from 'events';
28import { IncomingMessage, ServerResponse, Server, IncomingHttpHeaders, OutgoingHttpHeaders } from 'http';
29import { Http2ServerRequest, Http2ServerResponse } from 'http2';
30import httpAssert = require('http-assert');
31import * as HttpErrors from 'http-errors';
32import * as Keygrip from 'keygrip';
33import * as compose from 'koa-compose';
34import { Socket, ListenOptions } from 'net';
35import * as url from 'url';
36import * as contentDisposition from 'content-disposition';
37import { ParsedUrlQuery } from 'querystring';
38
39declare interface ContextDelegatedRequest {
40 /**
41 * Return request header.
42 */
43 header: IncomingHttpHeaders;
44
45 /**
46 * Return request header, alias as request.header
47 */
48 headers: IncomingHttpHeaders;
49
50 /**
51 * Get/Set request URL.
52 */
53 url: string;
54
55 /**
56 * Get origin of URL.
57 */
58 origin: string;
59
60 /**
61 * Get full request URL.
62 */
63 href: string;
64
65 /**
66 * Get/Set request method.
67 */
68 method: string;
69
70 /**
71 * Get request pathname.
72 * Set pathname, retaining the query-string when present.
73 */
74 path: string;
75
76 /**
77 * Get parsed query-string.
78 * Set query-string as an object.
79 */
80 query: ParsedUrlQuery;
81
82 /**
83 * Get/Set query string.
84 */
85 querystring: string;
86
87 /**
88 * Get the search string. Same as the querystring
89 * except it includes the leading ?.
90 *
91 * Set the search string. Same as
92 * response.querystring= but included for ubiquity.
93 */
94 search: string;
95
96 /**
97 * Parse the "Host" header field host
98 * and support X-Forwarded-Host when a
99 * proxy is enabled.
100 */
101 host: string;
102
103 /**
104 * Parse the "Host" header field hostname
105 * and support X-Forwarded-Host when a
106 * proxy is enabled.
107 */
108 hostname: string;
109
110 /**
111 * Get WHATWG parsed URL object.
112 */
113 URL: url.URL;
114
115 /**
116 * Check if the request is fresh, aka
117 * Last-Modified and/or the ETag
118 * still match.
119 */
120 fresh: boolean;
121
122 /**
123 * Check if the request is stale, aka
124 * "Last-Modified" and / or the "ETag" for the
125 * resource has changed.
126 */
127 stale: boolean;
128
129 /**
130 * Check if the request is idempotent.
131 */
132 idempotent: boolean;
133
134 /**
135 * Return the request socket.
136 */
137 socket: Socket;
138
139 /**
140 * Return the protocol string "http" or "https"
141 * when requested with TLS. When the proxy setting
142 * is enabled the "X-Forwarded-Proto" header
143 * field will be trusted. If you're running behind
144 * a reverse proxy that supplies https for you this
145 * may be enabled.
146 */
147 protocol: string;
148
149 /**
150 * Short-hand for:
151 *
152 * this.protocol == 'https'
153 */
154 secure: boolean;
155
156 /**
157 * Request remote address. Supports X-Forwarded-For when app.proxy is true.
158 */
159 ip: string;
160
161 /**
162 * When `app.proxy` is `true`, parse
163 * the "X-Forwarded-For" ip address list.
164 *
165 * For example if the value were "client, proxy1, proxy2"
166 * you would receive the array `["client", "proxy1", "proxy2"]`
167 * where "proxy2" is the furthest down-stream.
168 */
169 ips: string[];
170
171 /**
172 * Return subdomains as an array.
173 *
174 * Subdomains are the dot-separated parts of the host before the main domain
175 * of the app. By default, the domain of the app is assumed to be the last two
176 * parts of the host. This can be changed by setting `app.subdomainOffset`.
177 *
178 * For example, if the domain is "tobi.ferrets.example.com":
179 * If `app.subdomainOffset` is not set, this.subdomains is
180 * `["ferrets", "tobi"]`.
181 * If `app.subdomainOffset` is 3, this.subdomains is `["tobi"]`.
182 */
183 subdomains: string[];
184
185 /**
186 * Check if the given `type(s)` is acceptable, returning
187 * the best match when true, otherwise `false`, in which
188 * case you should respond with 406 "Not Acceptable".
189 *
190 * The `type` value may be a single mime type string
191 * such as "application/json", the extension name
192 * such as "json" or an array `["json", "html", "text/plain"]`. When a list
193 * or array is given the _best_ match, if any is returned.
194 *
195 * Examples:
196 *
197 * // Accept: text/html
198 * this.accepts('html');
199 * // => "html"
200 *
201 * // Accept: text/*, application/json
202 * this.accepts('html');
203 * // => "html"
204 * this.accepts('text/html');
205 * // => "text/html"
206 * this.accepts('json', 'text');
207 * // => "json"
208 * this.accepts('application/json');
209 * // => "application/json"
210 *
211 * // Accept: text/*, application/json
212 * this.accepts('image/png');
213 * this.accepts('png');
214 * // => undefined
215 *
216 * // Accept: text/*;q=.5, application/json
217 * this.accepts(['html', 'json']);
218 * this.accepts('html', 'json');
219 * // => "json"
220 */
221 accepts(): string[];
222 accepts(...types: string[]): string | false;
223 accepts(types: string[]): string | false;
224
225 /**
226 * Return accepted encodings or best fit based on `encodings`.
227 *
228 * Given `Accept-Encoding: gzip, deflate`
229 * an array sorted by quality is returned:
230 *
231 * ['gzip', 'deflate']
232 */
233 acceptsEncodings(): string[];
234 acceptsEncodings(...encodings: string[]): string | false;
235 acceptsEncodings(encodings: string[]): string | false;
236
237 /**
238 * Return accepted charsets or best fit based on `charsets`.
239 *
240 * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
241 * an array sorted by quality is returned:
242 *
243 * ['utf-8', 'utf-7', 'iso-8859-1']
244 */
245 acceptsCharsets(): string[];
246 acceptsCharsets(...charsets: string[]): string | false;
247 acceptsCharsets(charsets: string[]): string | false;
248
249 /**
250 * Return accepted languages or best fit based on `langs`.
251 *
252 * Given `Accept-Language: en;q=0.8, es, pt`
253 * an array sorted by quality is returned:
254 *
255 * ['es', 'pt', 'en']
256 */
257 acceptsLanguages(): string[];
258 acceptsLanguages(...langs: string[]): string | false;
259 acceptsLanguages(langs: string[]): string | false;
260
261 /**
262 * Check if the incoming request contains the "Content-Type"
263 * header field, and it contains any of the give mime `type`s.
264 * If there is no request body, `null` is returned.
265 * If there is no content type, `false` is returned.
266 * Otherwise, it returns the first `type` that matches.
267 *
268 * Examples:
269 *
270 * // With Content-Type: text/html; charset=utf-8
271 * this.is('html'); // => 'html'
272 * this.is('text/html'); // => 'text/html'
273 * this.is('text/*', 'application/json'); // => 'text/html'
274 *
275 * // When Content-Type is application/json
276 * this.is('json', 'urlencoded'); // => 'json'
277 * this.is('application/json'); // => 'application/json'
278 * this.is('html', 'application/*'); // => 'application/json'
279 *
280 * this.is('html'); // => false
281 */
282 // is(): string | boolean;
283 is(...types: string[]): string | false | null;
284 is(types: string[]): string | false | null;
285
286 /**
287 * Return request header. If the header is not set, will return an empty
288 * string.
289 *
290 * The `Referrer` header field is special-cased, both `Referrer` and
291 * `Referer` are interchangeable.
292 *
293 * Examples:
294 *
295 * this.get('Content-Type');
296 * // => "text/plain"
297 *
298 * this.get('content-type');
299 * // => "text/plain"
300 *
301 * this.get('Something');
302 * // => ''
303 */
304 get(field: string): string;
305}
306
307declare interface ContextDelegatedResponse {
308 /**
309 * Get/Set response status code.
310 */
311 status: number;
312
313 /**
314 * Get response status message
315 */
316 message: string;
317
318 /**
319 * Get/Set response body.
320 */
321 body: unknown;
322
323 /**
324 * Return parsed response Content-Length when present.
325 * Set Content-Length field to `n`.
326 */
327 length: number;
328
329 /**
330 * Check if a header has been written to the socket.
331 */
332 headerSent: boolean;
333
334 /**
335 * Vary on `field`.
336 */
337 vary(field: string): void;
338
339 /**
340 * Perform a 302 redirect to `url`.
341 *
342 * The string "back" is special-cased
343 * to provide Referrer support, when Referrer
344 * is not present `alt` or "/" is used.
345 *
346 * Examples:
347 *
348 * this.redirect('back');
349 * this.redirect('back', '/index.html');
350 * this.redirect('/login');
351 * this.redirect('http://google.com');
352 */
353 redirect(url: string, alt?: string): void;
354
355 /**
356 * Set Content-Disposition to "attachment" to signal the client to prompt for download.
357 * Optionally specify the filename of the download and some options.
358 */
359 attachment(filename?: string, options?: contentDisposition.Options): void;
360
361 /**
362 * Return the response mime type void of
363 * parameters such as "charset".
364 *
365 * Set Content-Type response header with `type` through `mime.lookup()`
366 * when it does not contain a charset.
367 *
368 * Examples:
369 *
370 * this.type = '.html';
371 * this.type = 'html';
372 * this.type = 'json';
373 * this.type = 'application/json';
374 * this.type = 'png';
375 */
376 type: string;
377
378 /**
379 * Get the Last-Modified date in Date form, if it exists.
380 * Set the Last-Modified date using a string or a Date.
381 *
382 * this.response.lastModified = new Date();
383 * this.response.lastModified = '2013-09-13';
384 */
385 lastModified: Date;
386
387 /**
388 * Get/Set the ETag of a response.
389 * This will normalize the quotes if necessary.
390 *
391 * this.response.etag = 'md5hashsum';
392 * this.response.etag = '"md5hashsum"';
393 * this.response.etag = 'W/"123456789"';
394 *
395 * @param {String} etag
396 * @api public
397 */
398 etag: string;
399
400 /**
401 * Set header `field` to `val`, or pass
402 * an object of header fields.
403 *
404 * Examples:
405 *
406 * this.set('Foo', ['bar', 'baz']);
407 * this.set('Accept', 'application/json');
408 * this.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
409 */
410 set(field: { [key: string]: string | string[] }): void;
411 set(field: string, val: string | string[]): void;
412
413 /**
414 * Append additional header `field` with value `val`.
415 *
416 * Examples:
417 *
418 * ```
419 * this.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']);
420 * this.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
421 * this.append('Warning', '199 Miscellaneous warning');
422 * ```
423 */
424 append(field: string, val: string | string[]): void;
425
426 /**
427 * Remove header `field`.
428 */
429 remove(field: string): void;
430
431 /**
432 * Checks if the request is writable.
433 * Tests for the existence of the socket
434 * as node sometimes does not set it.
435 */
436 writable: boolean;
437
438 /**
439 * Flush any set headers, and begin the body
440 */
441 flushHeaders(): void;
442}
443
444declare class Application<
445 StateT = Application.DefaultState,
446 ContextT = Application.DefaultContext
447> extends EventEmitter {
448 proxy: boolean;
449 proxyIpHeader: string;
450 maxIpsCount: number;
451 middleware: Application.Middleware<StateT, ContextT>[];
452 subdomainOffset: number;
453 env: string;
454 context: Application.BaseContext & ContextT;
455 request: Application.BaseRequest;
456 response: Application.BaseResponse;
457 silent: boolean;
458 keys: Keygrip | string[];
459
460 /**
461 *
462 * @param {object} [options] Application options
463 * @param {string} [options.env='development'] Environment
464 * @param {string[]} [options.keys] Signed cookie keys
465 * @param {boolean} [options.proxy] Trust proxy headers
466 * @param {number} [options.subdomainOffset] Subdomain offset
467 * @param {string} [options.proxyIpHeader] Proxy IP header, defaults to X-Forwarded-For
468 * @param {number} [options.maxIpsCount] Max IPs read from proxy IP header, default to 0 (means infinity)
469 *
470 */
471 constructor(options?: {
472 env?: string | undefined,
473 keys?: string[] | undefined,
474 proxy?: boolean | undefined,
475 subdomainOffset?: number | undefined,
476 proxyIpHeader?: string | undefined,
477 maxIpsCount?: number | undefined
478 });
479
480 /**
481 * Shorthand for:
482 *
483 * http.createServer(app.callback()).listen(...)
484 */
485 listen(port?: number, hostname?: string, backlog?: number, listeningListener?: () => void): Server;
486 listen(port: number, hostname?: string, listeningListener?: () => void): Server;
487 listen(port: number, backlog?: number, listeningListener?: () => void): Server;
488 listen(port: number, listeningListener?: () => void): Server;
489 listen(path: string, backlog?: number, listeningListener?: () => void): Server;
490 listen(path: string, listeningListener?: () => void): Server;
491 listen(options: ListenOptions, listeningListener?: () => void): Server;
492 listen(handle: any, backlog?: number, listeningListener?: () => void): Server;
493 listen(handle: any, listeningListener?: () => void): Server;
494
495 /**
496 * Return JSON representation.
497 * We only bother showing settings.
498 */
499 inspect(): any;
500
501 /**
502 * Return JSON representation.
503 * We only bother showing settings.
504 */
505 toJSON(): any;
506
507 /**
508 * Use the given middleware `fn`.
509 *
510 * Old-style middleware will be converted.
511 */
512 use<NewStateT = {}, NewContextT = {}>(
513 middleware: Application.Middleware<StateT & NewStateT, ContextT & NewContextT>
514 ): Application<StateT & NewStateT, ContextT & NewContextT>;
515
516 /**
517 * Return a request handler callback
518 * for node's native http/http2 server.
519 */
520 callback(): (req: IncomingMessage | Http2ServerRequest, res: ServerResponse | Http2ServerResponse) => void;
521
522 /**
523 * Initialize a new context.
524 *
525 * @api private
526 */
527 createContext<StateT = Application.DefaultState>(
528 req: IncomingMessage,
529 res: ServerResponse,
530 ): Application.ParameterizedContext<StateT>;
531
532 /**
533 * Default error handler.
534 *
535 * @api private
536 */
537 onerror(err: Error): void;
538}
539
540declare namespace Application {
541 type DefaultStateExtends = any;
542 /**
543 * This interface can be augmented by users to add types to Koa's default state
544 */
545 interface DefaultState extends DefaultStateExtends {}
546
547 type DefaultContextExtends = {};
548 /**
549 * This interface can be augmented by users to add types to Koa's default context
550 */
551 interface DefaultContext extends DefaultContextExtends {
552 /**
553 * Custom properties.
554 */
555 [key: string]: any;
556 }
557
558 type Middleware<StateT = DefaultState, ContextT = DefaultContext, ResponseBodyT = any> = compose.Middleware<
559 ParameterizedContext<StateT, ContextT, ResponseBodyT>
560 >;
561
562 interface BaseRequest extends ContextDelegatedRequest {
563 /**
564 * Get the charset when present or undefined.
565 */
566 charset: string;
567
568 /**
569 * Return parsed Content-Length when present.
570 */
571 length: number;
572
573 /**
574 * Return the request mime type void of
575 * parameters such as "charset".
576 */
577 type: string;
578
579 /**
580 * Inspect implementation.
581 */
582 inspect(): any;
583
584 /**
585 * Return JSON representation.
586 */
587 toJSON(): any;
588 }
589
590 interface BaseResponse extends ContextDelegatedResponse {
591 /**
592 * Return the request socket.
593 *
594 * @return {Connection}
595 * @api public
596 */
597 socket: Socket;
598
599 /**
600 * Return response header.
601 */
602 header: OutgoingHttpHeaders;
603
604 /**
605 * Return response header, alias as response.header
606 */
607 headers: OutgoingHttpHeaders;
608
609 /**
610 * Check whether the response is one of the listed types.
611 * Pretty much the same as `this.request.is()`.
612 *
613 * @param {String|Array} types...
614 * @return {String|false}
615 * @api public
616 */
617 // is(): string;
618 is(...types: string[]): string | false | null;
619 is(types: string[]): string | false | null;
620
621 /**
622 * Return response header. If the header is not set, will return an empty
623 * string.
624 *
625 * The `Referrer` header field is special-cased, both `Referrer` and
626 * `Referer` are interchangeable.
627 *
628 * Examples:
629 *
630 * this.get('Content-Type');
631 * // => "text/plain"
632 *
633 * this.get('content-type');
634 * // => "text/plain"
635 *
636 * this.get('Something');
637 * // => ''
638 */
639 get(field: string): string;
640
641 /**
642 * Inspect implementation.
643 */
644 inspect(): any;
645
646 /**
647 * Return JSON representation.
648 */
649 toJSON(): any;
650 }
651
652 interface BaseContext extends ContextDelegatedRequest, ContextDelegatedResponse {
653 /**
654 * util.inspect() implementation, which
655 * just returns the JSON output.
656 */
657 inspect(): any;
658
659 /**
660 * Return JSON representation.
661 *
662 * Here we explicitly invoke .toJSON() on each
663 * object, as iteration will otherwise fail due
664 * to the getters and cause utilities such as
665 * clone() to fail.
666 */
667 toJSON(): any;
668
669 /**
670 * Similar to .throw(), adds assertion.
671 *
672 * this.assert(this.user, 401, 'Please login!');
673 *
674 * See: https://github.com/jshttp/http-assert
675 */
676 assert: typeof httpAssert;
677
678 /**
679 * Throw an error with `msg` and optional `status`
680 * defaulting to 500. Note that these are user-level
681 * errors, and the message may be exposed to the client.
682 *
683 * this.throw(403)
684 * this.throw('name required', 400)
685 * this.throw(400, 'name required')
686 * this.throw('something exploded')
687 * this.throw(new Error('invalid'), 400);
688 * this.throw(400, new Error('invalid'));
689 *
690 * See: https://github.com/jshttp/http-errors
691 */
692 throw(message: string, code?: number, properties?: {}): never;
693 throw(status: number): never;
694 throw(...properties: Array<number | string | {}>): never;
695
696 /**
697 * Default error handling.
698 */
699 onerror(err: Error): void;
700 }
701
702 interface Request extends BaseRequest {
703 app: Application;
704 req: IncomingMessage;
705 res: ServerResponse;
706 ctx: Context;
707 response: Response;
708 originalUrl: string;
709 ip: string;
710 accept: accepts.Accepts;
711 }
712
713 interface Response extends BaseResponse {
714 app: Application;
715 req: IncomingMessage;
716 res: ServerResponse;
717 ctx: Context;
718 request: Request;
719 }
720
721 interface ExtendableContext extends BaseContext {
722 app: Application;
723 request: Request;
724 response: Response;
725 req: IncomingMessage;
726 res: ServerResponse;
727 originalUrl: string;
728 cookies: Cookies;
729 accept: accepts.Accepts;
730 /**
731 * To bypass Koa's built-in response handling, you may explicitly set `ctx.respond = false;`
732 */
733 respond?: boolean | undefined;
734 }
735
736 type ParameterizedContext<StateT = DefaultState, ContextT = DefaultContext, ResponseBodyT = unknown> = ExtendableContext
737 & { state: StateT; }
738 & ContextT
739 & { body: ResponseBodyT; response: { body: ResponseBodyT }; };
740
741 interface Context extends ParameterizedContext {}
742
743 type Next = () => Promise<any>;
744
745 /**
746 * A re-export of `HttpError` from the `http-error` package.
747 *
748 * This is the error type that is thrown by `ctx.assert()` and `ctx.throw()`.
749 */
750 const HttpError: typeof HttpErrors.HttpError;
751}
752
753export = Application;