index.d.ts 32 KB

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