1 |
|
2 | import accepts = require('accepts');
|
3 | import KoaApplication = require('koa');
|
4 | import KoaRouter = require('koa-router');
|
5 | import { EventEmitter } from 'events'
|
6 | import { Readable } from 'stream';
|
7 | import { Socket } from 'net';
|
8 | import { IncomingMessage, ServerResponse } from 'http';
|
9 | import { EggLogger, EggLoggers, LoggerLevel as EggLoggerLevel, EggContextLogger } from 'egg-logger';
|
10 | import { HttpClient, RequestOptions2 as RequestOptions } from 'urllib';
|
11 | import {
|
12 | EggCoreBase,
|
13 | FileLoaderOption,
|
14 | EggLoader as CoreLoader,
|
15 | EggCoreOptions as CoreOptions,
|
16 | EggLoaderOptions as CoreLoaderOptions,
|
17 | BaseContextClass as CoreBaseContextClass,
|
18 | } from 'egg-core';
|
19 | import EggCookies = require('egg-cookies');
|
20 | import 'egg-onerror';
|
21 | import 'egg-session';
|
22 | import 'egg-i18n';
|
23 | import 'egg-watcher';
|
24 | import 'egg-multipart';
|
25 | import 'egg-security';
|
26 | import 'egg-development';
|
27 | import 'egg-logrotator';
|
28 | import 'egg-schedule';
|
29 | import 'egg-static';
|
30 | import 'egg-jsonp';
|
31 | import 'egg-view';
|
32 |
|
33 | declare module 'egg' {
|
34 |
|
35 | type PlainObject<T = any> = { [key: string]: T };
|
36 |
|
37 |
|
38 | type RemoveSpecProp<T, P> = Pick<T, Exclude<keyof T, P>>;
|
39 |
|
40 | interface EggHttpClient extends HttpClient<RequestOptions> {}
|
41 | interface EggHttpConstructor {
|
42 | new (app: Application): EggHttpClient;
|
43 | }
|
44 |
|
45 | interface EggContextHttpClient extends HttpClient<RequestOptions> {}
|
46 | interface EggContextHttpClientConstructor {
|
47 | new (ctx: Context): EggContextHttpClient;
|
48 | }
|
49 |
|
50 | |
51 |
|
52 |
|
53 |
|
54 |
|
55 | export class BaseContextClass extends CoreBaseContextClass<Context, Application, EggAppConfig, IService> {
|
56 | |
57 |
|
58 |
|
59 | protected logger: EggLogger;
|
60 | }
|
61 |
|
62 | export class Boot {
|
63 | |
64 |
|
65 |
|
66 |
|
67 | protected logger: EggLogger;
|
68 |
|
69 | |
70 |
|
71 |
|
72 |
|
73 | protected config: EggAppConfig;
|
74 |
|
75 | |
76 |
|
77 |
|
78 |
|
79 | protected agent: Agent;
|
80 |
|
81 | |
82 |
|
83 |
|
84 |
|
85 | protected app: Application;
|
86 | }
|
87 |
|
88 | export type RequestArrayBody = any[];
|
89 | export type RequestObjectBody = PlainObject;
|
90 | export interface Request extends KoaApplication.Request {
|
91 | |
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 | acceptJSON: boolean;
|
101 |
|
102 | |
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 | ip: string;
|
113 |
|
114 | |
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 | ips: string[];
|
126 |
|
127 | protocol: string;
|
128 |
|
129 | |
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 | queries: PlainObject<string[]>;
|
146 |
|
147 | |
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 | query: PlainObject<string>;
|
168 |
|
169 | body: any;
|
170 | }
|
171 |
|
172 | export interface Response extends KoaApplication.Response {
|
173 | |
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 |
|
182 | realStatus: number;
|
183 | }
|
184 |
|
185 | export type LoggerLevel = EggLoggerLevel;
|
186 |
|
187 | |
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 | export interface EggAppInfo {
|
202 | pkg: any;
|
203 | name: string;
|
204 | baseDir: string;
|
205 | env: EggEnvType;
|
206 | HOME: string;
|
207 | root: string;
|
208 | }
|
209 |
|
210 | type IgnoreItem = string | RegExp | ((ctx: Context) => boolean);
|
211 | type IgnoreOrMatch = IgnoreItem | IgnoreItem[];
|
212 |
|
213 | /** Custom Loader Configuration */
|
214 | export interface CustomLoaderConfig extends RemoveSpecProp<FileLoaderOption, 'inject' | 'target'> {
|
215 | /**
|
216 | * an object you wanner load to, value can only be 'ctx' or 'app'. default to app
|
217 | */
|
218 | inject?: 'ctx' | 'app';
|
219 | /**
|
220 | * whether need to load files in plugins or framework, default to false
|
221 | */
|
222 | loadunit?: boolean;
|
223 | }
|
224 |
|
225 | export interface EggAppConfig {
|
226 | workerStartTimeout: number;
|
227 | baseDir: string;
|
228 | middleware: string[];
|
229 |
|
230 | /**
|
231 | * The option of `bodyParser` middleware
|
232 | *
|
233 | * @member Config#bodyParser
|
234 | * @property {Boolean} enable - enable bodyParser or not, default to true
|
235 | * @property {String | RegExp | Function | Array} ignore - won't parse request body when url path hit ignore pattern, can not set `ignore` when `match` presented
|
236 | * @property {String | RegExp | Function | Array} match - will parse request body only when url path hit match pattern
|
237 | * @property {String} encoding - body encoding config, default utf8
|
238 | * @property {String} formLimit - form body size limit, default 100kb
|
239 | * @property {String} jsonLimit - json body size limit, default 100kb
|
240 | * @property {Boolean} strict - json body strict mode, if set strict value true, then only receive object and array json body
|
241 | * @property {Number} queryString.arrayLimit - from item array length limit, default 100
|
242 | * @property {Number} queryString.depth - json value deep lenght, default 5
|
243 | * @property {Number} queryString.parameterLimit - paramter number limit ,default 1000
|
244 | * @property {string[]} enableTypes - parser will only parse when request type hits enableTypes, default is ['json', 'form']
|
245 | * @property {any} extendTypes - support extend types
|
246 | */
|
247 | bodyParser: {
|
248 | enable: boolean;
|
249 | encoding: string;
|
250 | formLimit: string;
|
251 | jsonLimit: string;
|
252 | strict: boolean;
|
253 | queryString: {
|
254 | arrayLimit: number;
|
255 | depth: number;
|
256 | parameterLimit: number;
|
257 | };
|
258 | ignore: IgnoreOrMatch;
|
259 | match: IgnoreOrMatch;
|
260 | enableTypes: string[];
|
261 | extendTypes: {
|
262 | json: string[];
|
263 | form: string[];
|
264 | text: string[];
|
265 | };
|
266 | };
|
267 |
|
268 | /**
|
269 | * logger options
|
270 | * @member Config#logger
|
271 | * @property {String} dir - directory of log files
|
272 | * @property {String} encoding - log file encloding, defaults to utf8
|
273 | * @property {String} level - default log level, could be: DEBUG, INFO, WARN, ERROR or NONE, defaults to INFO in production
|
274 | * @property {String} consoleLevel - log level of stdout, defaults to INFO in local serverEnv, defaults to WARN in unittest, defaults to NONE elsewise
|
275 | * @property {Boolean} disableConsoleAfterReady - disable logger console after app ready. defaults to `false` on local and unittest env, others is `true`.
|
276 | * @property {Boolean} outputJSON - log as JSON or not, defaults to false
|
277 | * @property {Boolean} buffer - if enabled, flush logs to disk at a certain frequency to improve performance, defaults to true
|
278 | * @property {String} errorLogName - file name of errorLogger
|
279 | * @property {String} coreLogName - file name of coreLogger
|
280 | * @property {String} agentLogName - file name of agent worker log
|
281 | * @property {Object} coreLogger - custom config of coreLogger
|
282 | * @property {Boolean} allowDebugAtProd - allow debug log at prod, defaults to true
|
283 | */
|
284 | logger: {
|
285 | dir: string;
|
286 | encoding: string;
|
287 | env: EggEnvType;
|
288 | level: LoggerLevel;
|
289 | consoleLevel: LoggerLevel;
|
290 | disableConsoleAfterReady: boolean;
|
291 | outputJSON: boolean;
|
292 | buffer: boolean;
|
293 | appLogName: string;
|
294 | coreLogName: string;
|
295 | agentLogName: string;
|
296 | errorLogName: string;
|
297 | coreLogger: any;
|
298 | allowDebugAtProd: boolean;
|
299 | };
|
300 |
|
301 | httpclient: {
|
302 | keepAlive: boolean;
|
303 | freeSocketKeepAliveTimeout?: number;
|
304 | freeSocketTimeout: number;
|
305 | timeout: number;
|
306 | maxSockets: number;
|
307 | maxFreeSockets: number;
|
308 | enableDNSCache: boolean;
|
309 | };
|
310 |
|
311 | development: {
|
312 | /**
|
313 | * dirs needed watch, when files under these change, application will reload, use relative path
|
314 | */
|
315 | watchDirs: string[];
|
316 | /**
|
317 | * dirs don't need watch, including subdirectories, use relative path
|
318 | */
|
319 | ignoreDirs: string[];
|
320 | /**
|
321 | * don't wait all plugins ready, default is true.
|
322 | */
|
323 | fastReady: boolean;
|
324 | /**
|
325 | * whether reload on debug, default is true.
|
326 | */
|
327 | reloadOnDebug: boolean;
|
328 | /**
|
329 | * whether override default watchDirs, default is false.
|
330 | */
|
331 | overrideDefault: boolean;
|
332 | /**
|
333 | * whether to reload, use https://github.com/sindresorhus/multimatch
|
334 | */
|
335 | reloadPattern: string[] | string;
|
336 | };
|
337 |
|
338 | /**
|
339 | * customLoader config
|
340 | */
|
341 | customLoader: {
|
342 | [key: string]: CustomLoaderConfig;
|
343 | };
|
344 |
|
345 | /**
|
346 | * It will ignore special keys when dumpConfig
|
347 | */
|
348 | dump: {
|
349 | ignore: Set<string>;
|
350 | };
|
351 |
|
352 | /**
|
353 | * The environment of egg
|
354 | */
|
355 | env: EggEnvType;
|
356 |
|
357 | /**
|
358 | * The current HOME directory
|
359 | */
|
360 | HOME: string;
|
361 |
|
362 | hostHeaders: string;
|
363 |
|
364 | /**
|
365 | * I18n options
|
366 | */
|
367 | i18n: {
|
368 | /**
|
369 | * default value EN_US
|
370 | */
|
371 | defaultLocale: string;
|
372 | /**
|
373 | * i18n resource file dir, not recommend to change default value
|
374 | */
|
375 | dir: string;
|
376 | /**
|
377 | * custom the locale value field, default `query.locale`, you can modify this config, such as `query.lang`
|
378 | */
|
379 | queryField: string;
|
380 | /**
|
381 | * The locale value key in the cookie, default is locale.
|
382 | */
|
383 | cookieField: string;
|
384 | /**
|
385 | * Locale cookie expire time, default `1y`, If pass number value, the unit will be ms
|
386 | */
|
387 | cookieMaxAge: string | number;
|
388 | };
|
389 |
|
390 | /**
|
391 | * Detect request' ip from specified headers, not case-sensitive. Only worked when config.proxy set to true.
|
392 | */
|
393 | ipHeaders: string;
|
394 |
|
395 | /**
|
396 | * jsonp options
|
397 | * @member Config#jsonp
|
398 | * @property {String} callback - jsonp callback method key, default to `_callback`
|
399 | * @property {Number} limit - callback method name's max length, default to `50`
|
400 | * @property {Boolean} csrf - enable csrf check or not. default to false
|
401 | * @property {String|RegExp|Array} whiteList - referrer white list
|
402 | */
|
403 | jsonp: {
|
404 | limit: number;
|
405 | callback: string;
|
406 | csrf: boolean;
|
407 | whiteList: string | RegExp | Array<string | RegExp>;
|
408 | };
|
409 |
|
410 | /**
|
411 | * The key that signing cookies. It can contain multiple keys seperated by .
|
412 | */
|
413 | keys: string;
|
414 |
|
415 | /**
|
416 | * The name of the application
|
417 | */
|
418 | name: string;
|
419 |
|
420 | /**
|
421 | * package.json
|
422 | */
|
423 | pkg: any;
|
424 |
|
425 | rundir: string;
|
426 |
|
427 | security: {
|
428 | domainWhiteList: string[];
|
429 | protocolWhiteList: string[];
|
430 | defaultMiddleware: string;
|
431 | csrf: any;
|
432 | xframe: {
|
433 | enable: boolean;
|
434 | value: 'SAMEORIGIN' | 'DENY' | 'ALLOW-FROM';
|
435 | };
|
436 | hsts: any;
|
437 | methodnoallow: { enable: boolean };
|
438 | noopen: { enable: boolean; }
|
439 | xssProtection: any;
|
440 | csp: any;
|
441 | };
|
442 |
|
443 | siteFile: PlainObject<string | Buffer>;
|
444 |
|
445 | static: {
|
446 | prefix: string;
|
447 | dir: string | string[];
|
448 | // support lazy load
|
449 | dynamic: boolean;
|
450 | preload: boolean;
|
451 | buffer: boolean;
|
452 | maxFiles: number;
|
453 | } & PlainObject;
|
454 |
|
455 | watcher: PlainObject;
|
456 |
|
457 | onClientError(err: Error, socket: Socket, app: EggApplication): ClientErrorResponse | Promise<ClientErrorResponse>;
|
458 |
|
459 | /**
|
460 | * server timeout in milliseconds, default to 2 minutes.
|
461 | *
|
462 | * for special request, just use `ctx.req.setTimeout(ms)`
|
463 | *
|
464 | * @see https://nodejs.org/api/http.html#http_server_timeout
|
465 | */
|
466 | serverTimeout: number | null;
|
467 |
|
468 | [prop: string]: any;
|
469 | }
|
470 |
|
471 | export interface ClientErrorResponse {
|
472 | body: string | Buffer;
|
473 | status: number;
|
474 | headers: { [key: string]: string };
|
475 | }
|
476 |
|
477 | export interface Router extends KoaRouter<any, Context> {
|
478 | /**
|
479 | * restful router api
|
480 | */
|
481 | resources(name: string, prefix: string, ...middleware: any[]): Router;
|
482 |
|
483 | /**
|
484 | * @param {String} name - Router name
|
485 | * @param {Object} params - more parameters
|
486 | * @example
|
487 | * ```js
|
488 | * router.url('edit_post', { id: 1, name: 'foo', page: 2 })
|
489 | * => /posts/1/edit?name=foo&page=2
|
490 | * router.url('posts', { name: 'foo&1', page: 2 })
|
491 | * => /posts?name=foo%261&page=2
|
492 | * ```
|
493 | * @return {String} url by path name and query params.
|
494 | * @since 1.0.0
|
495 | */
|
496 | url(name: string, params: any): any;
|
497 | }
|
498 |
|
499 | export interface EggApplication extends EggCoreBase<EggAppConfig> { // tslint:disable-line
|
500 | /**
|
501 | * HttpClient instance
|
502 | */
|
503 | httpclient: EggHttpClient;
|
504 |
|
505 | /**
|
506 | * Logger for Application, wrapping app.coreLogger with context infomation
|
507 | *
|
508 | * @member {ContextLogger} Context#logger
|
509 | * @since 1.0.0
|
510 | * @example
|
511 | * ```js
|
512 | * this.logger.info('some request data: %j', this.request.body);
|
513 | * this.logger.warn('WARNING!!!!');
|
514 | * ```
|
515 | */
|
516 | logger: EggLogger;
|
517 |
|
518 | /**
|
519 | * core logger for framework and plugins, log file is $HOME/logs/{appname}/egg-web
|
520 | */
|
521 | coreLogger: EggLogger;
|
522 |
|
523 | /**
|
524 | * All loggers contain logger, coreLogger and customLogger
|
525 | */
|
526 | loggers: EggLoggers;
|
527 |
|
528 | /**
|
529 | * messenger instance
|
530 | */
|
531 | messenger: Messenger;
|
532 |
|
533 | /**
|
534 | * get router
|
535 | */
|
536 | router: Router;
|
537 |
|
538 | /**
|
539 | * create a singleton instance
|
540 | */
|
541 | addSingleton(name: string, create: any): void;
|
542 |
|
543 | runSchedule(schedulePath: string): Promise<any>;
|
544 |
|
545 | /**
|
546 | * http request helper base on httpclient, it will auto save httpclient log.
|
547 | * Keep the same api with httpclient.request(url, args).
|
548 | * See https://github.com/node-modules/urllib#api-doc for more details.
|
549 | */
|
550 | curl<T = any>(url: string, opt?: RequestOptions): Promise<T>;
|
551 |
|
552 | /**
|
553 | * Get logger by name, it's equal to app.loggers['name'], but you can extend it with your own logical
|
554 | */
|
555 | getLogger(name: string): EggLogger;
|
556 |
|
557 | /**
|
558 | * print the infomation when console.log(app)
|
559 | */
|
560 | inspect(): any;
|
561 |
|
562 | /**
|
563 | * Alias to Router#url
|
564 | */
|
565 | url(name: string, params: any): any;
|
566 |
|
567 | /**
|
568 | * Create an anonymous context, the context isn't request level, so the request is mocked.
|
569 | * then you can use context level API like `ctx.service`
|
570 | * @member {String} EggApplication#createAnonymousContext
|
571 | * @param {Request} req - if you want to mock request like querystring, you can pass an object to this function.
|
572 | * @return {Context} context
|
573 | */
|
574 | createAnonymousContext(req?: Request): Context;
|
575 |
|
576 | /**
|
577 | * export context base classes, let framework can impl sub class and over context extend easily.
|
578 | */
|
579 | ContextCookies: typeof EggCookies;
|
580 | ContextLogger: typeof EggContextLogger;
|
581 | ContextHttpClient: EggContextHttpClientConstructor;
|
582 | HttpClient: EggHttpConstructor;
|
583 | Subscription: typeof Subscription;
|
584 | Controller: typeof Controller;
|
585 | Service: typeof Service;
|
586 | }
|
587 |
|
588 | // compatible
|
589 | export class EggApplication {
|
590 | constructor(options?: CoreOptions);
|
591 | }
|
592 |
|
593 | export type RouterPath = string | RegExp;
|
594 |
|
595 | export class Application extends EggApplication {
|
596 | /**
|
597 | * global locals for view
|
598 | * @see Context#locals
|
599 | */
|
600 | locals: IApplicationLocals;
|
601 |
|
602 | /**
|
603 | * HTTP get method
|
604 | */
|
605 | get(path: RouterPath, fn: string): void;
|
606 | get(path: RouterPath, ...middleware: any[]): void;
|
607 |
|
608 | /**
|
609 | * HTTP post method
|
610 | */
|
611 | post(path: RouterPath, fn: string): void;
|
612 | post(path: RouterPath, ...middleware: any[]): void;
|
613 |
|
614 | /**
|
615 | * HTTP put method
|
616 | */
|
617 | put(path: RouterPath, fn: string): void;
|
618 | put(path: RouterPath, ...middleware: any[]): void;
|
619 |
|
620 | /**
|
621 | * HTTP delete method
|
622 | */
|
623 | delete(path: RouterPath, fn: string): void;
|
624 | delete(path: RouterPath, ...middleware: any[]): void;
|
625 |
|
626 | /**
|
627 | * restful router api
|
628 | */
|
629 | resources(name: string, prefix: string, fn: string): Router;
|
630 | resources(path: string, prefix: string, ...middleware: any[]): Router;
|
631 |
|
632 | redirect(path: string, redirectPath: string): void;
|
633 |
|
634 | controller: IController;
|
635 |
|
636 | middleware: KoaApplication.Middleware[] & IMiddleware;
|
637 |
|
638 | /**
|
639 | * Run async function in the background
|
640 | * @see Context#runInBackground
|
641 | * @param {Function} scope - the first args is an anonymous ctx
|
642 | */
|
643 | runInBackground(scope: (ctx: Context) => void): void;
|
644 | }
|
645 |
|
646 | export interface IApplicationLocals extends PlainObject { }
|
647 |
|
648 | export interface FileStream extends Readable { // tslint:disable-line
|
649 | fields: any;
|
650 |
|
651 | filename: string;
|
652 |
|
653 | fieldname: string;
|
654 |
|
655 | mime: string;
|
656 |
|
657 | mimeType: string;
|
658 |
|
659 | transferEncoding: string;
|
660 |
|
661 | encoding: string;
|
662 |
|
663 | truncated: boolean;
|
664 | }
|
665 |
|
666 | interface GetFileStreamOptions {
|
667 | requireFile?: boolean; // required file submit, default is true
|
668 | defCharset?: string;
|
669 | limits?: {
|
670 | fieldNameSize?: number;
|
671 | fieldSize?: number;
|
672 | fields?: number;
|
673 | fileSize?: number;
|
674 | files?: number;
|
675 | parts?: number;
|
676 | headerPairs?: number;
|
677 | };
|
678 | checkFile?(
|
679 | fieldname: string,
|
680 | file: any,
|
681 | filename: string,
|
682 | encoding: string,
|
683 | mimetype: string
|
684 | ): void | Error;
|
685 | }
|
686 |
|
687 | /**
|
688 | * KoaApplication's Context will carry the default 'cookie' property in
|
689 | * the egg's Context interface, which is wrong here because we have our own
|
690 | * special properties (e.g: encrypted). So we must remove this property and
|
691 | * create our own with the same name.
|
692 | * @see https://github.com/eggjs/egg/pull/2958
|
693 | *
|
694 | * However, the latest version of Koa has "[key: string]: any" on the
|
695 | * context, and there'll be a type error for "keyof koa.Context".
|
696 | * So we have to directly inherit from "KoaApplication.BaseContext" and
|
697 | * rewrite all the properties to be compatible with types in Koa.
|
698 | * @see https://github.com/eggjs/egg/pull/3329
|
699 | */
|
700 | export interface Context extends KoaApplication.BaseContext {
|
701 | [key: string]: any;
|
702 |
|
703 | app: Application;
|
704 |
|
705 | // properties of koa.Context
|
706 | req: IncomingMessage;
|
707 | res: ServerResponse;
|
708 | originalUrl: string;
|
709 | respond?: boolean;
|
710 |
|
711 | service: IService;
|
712 |
|
713 | request: Request;
|
714 |
|
715 | response: Response;
|
716 |
|
717 | // The new 'cookies' instead of Koa's.
|
718 | cookies: EggCookies;
|
719 |
|
720 | helper: IHelper;
|
721 |
|
722 | /**
|
723 | * Resource Parameters
|
724 | * @example
|
725 | * ##### ctx.params.id {string}
|
726 | *
|
727 | * `GET /api/users/1` => `'1'`
|
728 | *
|
729 | * ##### ctx.params.ids {Array<String>}
|
730 | *
|
731 | * `GET /api/users/1,2,3` => `['1', '2', '3']`
|
732 | *
|
733 | * ##### ctx.params.fields {Array<String>}
|
734 | *
|
735 | * Expect request return data fields, for example
|
736 | * `GET /api/users/1?fields=name,title` => `['name', 'title']`.
|
737 | *
|
738 | * ##### ctx.params.data {Object}
|
739 | *
|
740 | * Tht request data object
|
741 | *
|
742 | * ##### ctx.params.page {Number}
|
743 | *
|
744 | * Page number, `GET /api/users?page=10` => `10`
|
745 | *
|
746 | * ##### ctx.params.per_page {Number}
|
747 | *
|
748 | * The number of every page, `GET /api/users?per_page=20` => `20`
|
749 | */
|
750 | params: any;
|
751 |
|
752 | /**
|
753 | * @see Request#accept
|
754 | */
|
755 | queries: PlainObject<string[]>;
|
756 |
|
757 | /**
|
758 | * @see Request#accept
|
759 | */
|
760 | accept: accepts.Accepts;
|
761 |
|
762 | /**
|
763 | * @see Request#acceptJSON
|
764 | */
|
765 | acceptJSON: boolean;
|
766 |
|
767 | /**
|
768 | * @see Request#ip
|
769 | */
|
770 | ip: string;
|
771 |
|
772 | /**
|
773 | * @see Response#realStatus
|
774 | */
|
775 | realStatus: number;
|
776 |
|
777 | /**
|
778 | * Set the ctx.body.data value
|
779 | *
|
780 | * @member {Object} Context#data=
|
781 | * @example
|
782 | * ```js
|
783 | * ctx.data = {
|
784 | * id: 1,
|
785 | * name: 'fengmk2'
|
786 | * };
|
787 | * ```
|
788 | *
|
789 | * will get responce
|
790 | *
|
791 | * ```js
|
792 | * HTTP/1.1 200 OK
|
793 | *
|
794 | * {
|
795 | * "data": {
|
796 | * "id": 1,
|
797 | * "name": "fengmk2"
|
798 | * }
|
799 | * }
|
800 | * ```
|
801 | */
|
802 | data: any;
|
803 |
|
804 | /**
|
805 | * set ctx.body.meta value
|
806 | *
|
807 | * @example
|
808 | * ```js
|
809 | * ctx.meta = {
|
810 | * count: 100
|
811 | * };
|
812 | * ```
|
813 | * will get responce
|
814 | *
|
815 | * ```js
|
816 | * HTTP/1.1 200 OK
|
817 | *
|
818 | * {
|
819 | * "meta": {
|
820 | * "count": 100
|
821 | * }
|
822 | * }
|
823 | * ```
|
824 | */
|
825 | meta: any;
|
826 |
|
827 | /**
|
828 | * locals is an object for view, you can use `app.locals` and `ctx.locals` to set variables,
|
829 | * which will be used as data when view is rendering.
|
830 | * The difference between `app.locals` and `ctx.locals` is the context level, `app.locals` is global level, and `ctx.locals` is request level. when you get `ctx.locals`, it will merge `app.locals`.
|
831 | *
|
832 | * when you set locals, only object is available
|
833 | *
|
834 | * ```js
|
835 | * this.locals = {
|
836 | * a: 1
|
837 | * };
|
838 | * this.locals = {
|
839 | * b: 1
|
840 | * };
|
841 | * this.locals.c = 1;
|
842 | * console.log(this.locals);
|
843 | * {
|
844 | * a: 1,
|
845 | * b: 1,
|
846 | * c: 1,
|
847 | * };
|
848 | * ```
|
849 | *
|
850 | * `ctx.locals` has cache, it only merges `app.locals` once in one request.
|
851 | *
|
852 | * @member {Object} Context#locals
|
853 | */
|
854 | locals: IApplicationLocals & IContextLocals;
|
855 |
|
856 | /**
|
857 | * alias to {@link locals}, compatible with koa that use this variable
|
858 | */
|
859 | state: any;
|
860 |
|
861 | /**
|
862 | * Logger for Application, wrapping app.coreLogger with context infomation
|
863 | *
|
864 | * @member {ContextLogger} Context#logger
|
865 | * @since 1.0.0
|
866 | * @example
|
867 | * ```js
|
868 | * this.logger.info('some request data: %j', this.request.body);
|
869 | * this.logger.warn('WARNING!!!!');
|
870 | * ```
|
871 | */
|
872 | logger: EggLogger;
|
873 |
|
874 | /**
|
875 | * Get logger by name, it's equal to app.loggers['name'], but you can extend it with your own logical
|
876 | */
|
877 | getLogger(name: string): EggLogger;
|
878 |
|
879 | /**
|
880 | * Request start time
|
881 | */
|
882 | starttime: number;
|
883 |
|
884 | /**
|
885 | * http request helper base on httpclient, it will auto save httpclient log.
|
886 | * Keep the same api with httpclient.request(url, args).
|
887 | * See https://github.com/node-modules/urllib#api-doc for more details.
|
888 | */
|
889 | curl<T = any>(url: string, opt?: RequestOptions): Promise<T>;
|
890 |
|
891 | __(key: string, ...values: string[]): string;
|
892 | gettext(key: string, ...values: string[]): string;
|
893 |
|
894 | /**
|
895 | * get upload file stream
|
896 | * @example
|
897 | * ```js
|
898 | * const stream = await this.getFileStream();
|
899 | *
|
900 | * console.log(stream.fields);
|
901 | * ```
|
902 | * @method Context#getFileStream
|
903 | * @param {Object} options
|
904 | * @return {ReadStream} stream
|
905 | * @since 1.0.0
|
906 | */
|
907 | getFileStream(options?: GetFileStreamOptions): Promise<FileStream>;
|
908 |
|
909 | /**
|
910 | * @see Responce.redirect
|
911 | */
|
912 | redirect(url: string, alt?: string): void;
|
913 | }
|
914 |
|
915 | export interface IContextLocals extends PlainObject { }
|
916 |
|
917 | export class Controller extends BaseContextClass { }
|
918 |
|
919 | export class Service extends BaseContextClass { }
|
920 |
|
921 | export class Subscription extends BaseContextClass { }
|
922 |
|
923 | /**
|
924 | * The empty interface `IService` is a placeholder, for egg
|
925 | * to auto injection service to ctx.service
|
926 | *
|
927 | * @example
|
928 | *
|
929 | * import { Service } from 'egg';
|
930 | * class FooService extends Service {
|
931 | * async bar() {}
|
932 | * }
|
933 | *
|
934 | * declare module 'egg' {
|
935 | * export interface IService {
|
936 | * foo: FooService;
|
937 | * }
|
938 | * }
|
939 | *
|
940 | * Now I can get ctx.service.foo at controller and other service file.
|
941 | */
|
942 | export interface IService extends PlainObject { } // tslint:disable-line
|
943 |
|
944 | export interface IController extends PlainObject { } // tslint:disable-line
|
945 |
|
946 | export interface IMiddleware extends PlainObject { } // tslint:disable-line
|
947 |
|
948 | export interface IHelper extends PlainObject, BaseContextClass {
|
949 | /**
|
950 | * Generate URL path(without host) for route. Takes the route name and a map of named params.
|
951 | * @method Helper#pathFor
|
952 | * @param {String} name - Router Name
|
953 | * @param {Object} params - Other params
|
954 | *
|
955 | * @example
|
956 | * ```js
|
957 | * app.get('home', '/index.htm', 'home.index');
|
958 | * ctx.helper.pathFor('home', { by: 'recent', limit: 20 })
|
959 | * => /index.htm?by=recent&limit=20
|
960 | * ```
|
961 | * @return {String} url path(without host)
|
962 | */
|
963 | pathFor(name: string, params?: PlainObject): string;
|
964 |
|
965 | /**
|
966 | * Generate full URL(with host) for route. Takes the route name and a map of named params.
|
967 | * @method Helper#urlFor
|
968 | * @param {String} name - Router name
|
969 | * @param {Object} params - Other params
|
970 | * @example
|
971 | * ```js
|
972 | * app.get('home', '/index.htm', 'home.index');
|
973 | * ctx.helper.urlFor('home', { by: 'recent', limit: 20 })
|
974 | * => http:
|
975 | * ```
|
976 | * @return {String} full url(with host)
|
977 | */
|
978 | urlFor(name: string, params?: PlainObject): string;
|
979 | }
|
980 |
|
981 | // egg env type
|
982 | export type EggEnvType = 'local' | 'unittest' | 'prod' | string;
|
983 |
|
984 | /**
|
985 | * plugin config item interface
|
986 | */
|
987 | export interface IEggPluginItem {
|
988 | env?: EggEnvType[];
|
989 | path?: string;
|
990 | package?: string;
|
991 | enable?: boolean;
|
992 | }
|
993 |
|
994 | export type EggPluginItem = IEggPluginItem | boolean;
|
995 |
|
996 | /**
|
997 | * build-in plugin list
|
998 | */
|
999 | export interface EggPlugin {
|
1000 | [key: string]: EggPluginItem | undefined;
|
1001 | onerror?: EggPluginItem;
|
1002 | session?: EggPluginItem;
|
1003 | i18n?: EggPluginItem;
|
1004 | watcher?: EggPluginItem;
|
1005 | multipart?: EggPluginItem;
|
1006 | security?: EggPluginItem;
|
1007 | development?: EggPluginItem;
|
1008 | logrotator?: EggPluginItem;
|
1009 | schedule?: EggPluginItem;
|
1010 | static?: EggPluginItem;
|
1011 | jsonp?: EggPluginItem;
|
1012 | view?: EggPluginItem;
|
1013 | }
|
1014 |
|
1015 | /**
|
1016 | * Singleton instance in Agent Worker, extend {@link EggApplication}
|
1017 | */
|
1018 | export class Agent extends EggApplication {
|
1019 | }
|
1020 |
|
1021 | export interface ClusterOptions {
|
1022 | /** specify framework that can be absolute path or npm package */
|
1023 | framework?: string;
|
1024 | /** directory of application, default to `process.cwd()` */
|
1025 | baseDir?: string;
|
1026 | /** customized plugins, for unittest */
|
1027 | plugins?: object | null;
|
1028 | /** numbers of app workers, default to `os.cpus().length` */
|
1029 | workers?: number;
|
1030 | /** listening port, default to 7001(http) or 8443(https) */
|
1031 | port?: number;
|
1032 | /** https or not */
|
1033 | https?: boolean;
|
1034 | /** ssl key */
|
1035 | key?: string;
|
1036 | /** ssl cert */
|
1037 | cert?: string;
|
1038 | [prop: string]: any;
|
1039 | }
|
1040 |
|
1041 | export function startCluster(options: ClusterOptions, callback: (...args: any[]) => any): void;
|
1042 |
|
1043 | export interface StartOptions{
|
1044 | /** specify framework that can be absolute path or npm package */
|
1045 | framework?: string;
|
1046 | /** directory of application, default to `process.cwd()` */
|
1047 | baseDir?: string;
|
1048 | /** ignore single process mode warning */
|
1049 | ignoreWarning? :boolean
|
1050 | }
|
1051 |
|
1052 | export function start(options?:StartOptions):Promise<Application>
|
1053 |
|
1054 | /**
|
1055 | * Powerful Partial, Support adding ? modifier to a mapped property in deep level
|
1056 | * @example
|
1057 | * import { PowerPartial, EggAppConfig } from 'egg';
|
1058 | *
|
1059 | * // { view: { defaultEngines: string } } => { view?: { defaultEngines?: string } }
|
1060 | * type EggConfig = PowerPartial<EggAppConfig>
|
1061 | */
|
1062 | export type PowerPartial<T> = {
|
1063 | [U in keyof T]?: T[U] extends object
|
1064 | ? PowerPartial<T[U]>
|
1065 | : T[U]
|
1066 | };
|
1067 |
|
1068 | // send data can be number|string|boolean|object but not Set|Map
|
1069 | export interface Messenger extends EventEmitter {
|
1070 | /**
|
1071 | * broadcast to all agent/app processes including itself
|
1072 | */
|
1073 | broadcast(action: string, data: any): void;
|
1074 |
|
1075 | /**
|
1076 | * send to agent from the app,
|
1077 | * send to an random app from the agent
|
1078 | */
|
1079 | sendRandom(action: string, data: any): void;
|
1080 |
|
1081 | /**
|
1082 | * send to specified process
|
1083 | */
|
1084 | sendTo(pid: number, action: string, data: any): void;
|
1085 |
|
1086 | /**
|
1087 | * send to agent from the app,
|
1088 | * send to itself from the agent
|
1089 | */
|
1090 | sendToAgent(action: string, data: any): void;
|
1091 |
|
1092 | /**
|
1093 | * send to all app including itself from the app,
|
1094 | * send to all app from the agent
|
1095 | */
|
1096 | sendToApp(action: string, data: any): void;
|
1097 | }
|
1098 |
|
1099 | // compatible
|
1100 | export interface EggLoaderOptions extends CoreLoaderOptions {}
|
1101 | export interface EggLoader extends CoreLoader {}
|
1102 |
|
1103 | /**
|
1104 | * App worker process Loader, will load plugins
|
1105 | * @see https://github.com/eggjs/egg-core
|
1106 | */
|
1107 | export class AppWorkerLoader extends CoreLoader {
|
1108 | loadConfig(): void;
|
1109 | load(): void;
|
1110 | }
|
1111 |
|
1112 | /**
|
1113 | * Agent worker process loader
|
1114 | * @see https://github.com/eggjs/egg-loader
|
1115 | */
|
1116 | export class AgentWorkerLoader extends CoreLoader {
|
1117 | loadConfig(): void;
|
1118 | load(): void;
|
1119 | }
|
1120 |
|
1121 | export interface IBoot {
|
1122 | /**
|
1123 | * Ready to call configDidLoad,
|
1124 | * Config, plugin files are referred,
|
1125 | * this is the last chance to modify the config.
|
1126 | */
|
1127 | configWillLoad?(): void;
|
1128 |
|
1129 | /**
|
1130 | * Config, plugin files have loaded
|
1131 | */
|
1132 | configDidLoad?(): void;
|
1133 |
|
1134 | /**
|
1135 | * All files have loaded, start plugin here
|
1136 | */
|
1137 | didLoad?(): Promise<void>;
|
1138 |
|
1139 | /**
|
1140 | * All plugins have started, can do some thing before app ready
|
1141 | */
|
1142 | willReady?(): Promise<void>;
|
1143 |
|
1144 | /**
|
1145 | * Worker is ready, can do some things,
|
1146 | * don't need to block the app boot
|
1147 | */
|
1148 | didReady?(): Promise<void>;
|
1149 |
|
1150 | /**
|
1151 | * Server is listening
|
1152 | */
|
1153 | serverDidReady?(): Promise<void>;
|
1154 |
|
1155 | /**
|
1156 | * Do some thing before app close
|
1157 | */
|
1158 | beforeClose?(): Promise<void>;
|
1159 | }
|
1160 |
|
1161 | export interface Singleton<T> {
|
1162 | get(id: string): T;
|
1163 | }
|
1164 | }
|
1165 |
|
\ | No newline at end of file |