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