egg 3.29.0 → 4.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/README.md +2 -1
  2. package/README.zh-CN.md +7 -5
  3. package/dist/commonjs/agent.d.ts +4 -0
  4. package/dist/commonjs/agent.js +10 -0
  5. package/dist/commonjs/app/extend/context.d.ts +154 -0
  6. package/dist/commonjs/app/extend/context.js +261 -0
  7. package/dist/commonjs/app/extend/context.types.d.ts +16 -0
  8. package/dist/commonjs/app/extend/context.types.js +3 -0
  9. package/dist/commonjs/app/extend/helper.d.ts +37 -0
  10. package/dist/commonjs/app/extend/helper.js +49 -0
  11. package/dist/commonjs/app/extend/request.d.ts +128 -0
  12. package/dist/commonjs/app/extend/request.js +270 -0
  13. package/dist/commonjs/app/extend/response.d.ts +25 -0
  14. package/dist/commonjs/app/extend/response.js +37 -0
  15. package/dist/commonjs/app/middleware/body_parser.d.ts +2 -0
  16. package/dist/commonjs/app/middleware/body_parser.js +8 -0
  17. package/dist/commonjs/app/middleware/meta.d.ts +10 -0
  18. package/dist/commonjs/app/middleware/meta.js +22 -0
  19. package/dist/commonjs/app/middleware/notfound.d.ts +7 -0
  20. package/dist/commonjs/app/middleware/notfound.js +31 -0
  21. package/dist/commonjs/app/middleware/override_method.d.ts +2 -0
  22. package/dist/commonjs/app/middleware/override_method.js +8 -0
  23. package/dist/commonjs/app/middleware/site_file.d.ts +9 -0
  24. package/dist/commonjs/app/middleware/site_file.js +58 -0
  25. package/dist/commonjs/config/config.default.d.ts +9 -0
  26. package/dist/commonjs/config/config.default.js +379 -0
  27. package/dist/commonjs/config/config.local.d.ts +8 -0
  28. package/dist/commonjs/config/config.local.js +12 -0
  29. package/dist/commonjs/config/config.unittest.d.ts +7 -0
  30. package/dist/commonjs/config/config.unittest.js +11 -0
  31. package/dist/commonjs/config/plugin.d.ts +122 -0
  32. package/dist/commonjs/config/plugin.js +125 -0
  33. package/dist/commonjs/index.d.ts +63 -0
  34. package/dist/commonjs/index.js +91 -0
  35. package/dist/commonjs/lib/agent.d.ts +19 -0
  36. package/dist/commonjs/lib/agent.js +58 -0
  37. package/dist/commonjs/lib/application.d.ts +59 -0
  38. package/dist/commonjs/lib/application.js +270 -0
  39. package/dist/commonjs/lib/core/base_context_class.d.ts +14 -0
  40. package/dist/commonjs/lib/core/base_context_class.js +22 -0
  41. package/dist/commonjs/lib/core/base_context_logger.d.ts +36 -0
  42. package/dist/commonjs/lib/core/base_context_logger.js +64 -0
  43. package/dist/commonjs/lib/core/base_hook_class.d.ts +11 -0
  44. package/dist/commonjs/lib/core/base_hook_class.js +30 -0
  45. package/dist/commonjs/lib/core/context_httpclient.d.ts +16 -0
  46. package/dist/commonjs/lib/core/context_httpclient.js +30 -0
  47. package/dist/commonjs/lib/core/httpclient.d.ts +13 -0
  48. package/dist/commonjs/lib/core/httpclient.js +37 -0
  49. package/dist/commonjs/lib/core/logger.d.ts +3 -0
  50. package/dist/commonjs/lib/core/logger.js +40 -0
  51. package/dist/commonjs/lib/core/messenger/IMessenger.d.ts +50 -0
  52. package/dist/commonjs/lib/core/messenger/IMessenger.js +3 -0
  53. package/dist/commonjs/lib/core/messenger/index.d.ts +7 -0
  54. package/dist/commonjs/lib/core/messenger/index.js +14 -0
  55. package/dist/commonjs/lib/core/messenger/ipc.d.ts +59 -0
  56. package/dist/commonjs/lib/core/messenger/ipc.js +137 -0
  57. package/dist/commonjs/lib/core/messenger/local.d.ts +61 -0
  58. package/dist/commonjs/lib/core/messenger/local.js +137 -0
  59. package/dist/commonjs/lib/core/singleton.d.ts +23 -0
  60. package/dist/commonjs/lib/core/singleton.js +120 -0
  61. package/dist/commonjs/lib/core/utils.d.ts +2 -0
  62. package/dist/commonjs/lib/core/utils.js +77 -0
  63. package/dist/commonjs/lib/egg.d.ts +276 -0
  64. package/dist/commonjs/lib/egg.js +617 -0
  65. package/dist/commonjs/lib/egg.types.d.ts +6 -0
  66. package/dist/commonjs/lib/egg.types.js +3 -0
  67. package/dist/commonjs/lib/loader/AgentWorkerLoader.d.ts +12 -0
  68. package/dist/commonjs/lib/loader/AgentWorkerLoader.js +24 -0
  69. package/dist/commonjs/lib/loader/AppWorkerLoader.d.ts +17 -0
  70. package/dist/commonjs/lib/loader/AppWorkerLoader.js +43 -0
  71. package/dist/commonjs/lib/loader/EggApplicationLoader.d.ts +4 -0
  72. package/dist/commonjs/lib/loader/EggApplicationLoader.js +8 -0
  73. package/dist/commonjs/lib/loader/index.d.ts +3 -0
  74. package/dist/commonjs/lib/loader/index.js +22 -0
  75. package/dist/commonjs/lib/start.d.ts +15 -0
  76. package/dist/commonjs/lib/start.js +49 -0
  77. package/dist/commonjs/lib/type.d.ts +293 -0
  78. package/dist/commonjs/lib/type.js +3 -0
  79. package/dist/commonjs/lib/utils.d.ts +2 -0
  80. package/dist/commonjs/lib/utils.js +21 -0
  81. package/dist/commonjs/package.json +3 -0
  82. package/dist/esm/agent.d.ts +4 -0
  83. package/dist/esm/agent.js +7 -0
  84. package/dist/esm/app/extend/context.d.ts +154 -0
  85. package/dist/esm/app/extend/context.js +255 -0
  86. package/dist/esm/app/extend/context.types.d.ts +16 -0
  87. package/dist/esm/app/extend/context.types.js +2 -0
  88. package/dist/esm/app/extend/helper.d.ts +37 -0
  89. package/dist/esm/app/extend/helper.js +43 -0
  90. package/dist/esm/app/extend/request.d.ts +128 -0
  91. package/dist/esm/app/extend/request.js +264 -0
  92. package/dist/esm/app/extend/response.d.ts +25 -0
  93. package/dist/esm/app/extend/response.js +34 -0
  94. package/dist/esm/app/middleware/body_parser.d.ts +2 -0
  95. package/dist/esm/app/middleware/body_parser.js +3 -0
  96. package/dist/esm/app/middleware/meta.d.ts +10 -0
  97. package/dist/esm/app/middleware/meta.js +20 -0
  98. package/dist/esm/app/middleware/notfound.d.ts +7 -0
  99. package/dist/esm/app/middleware/notfound.js +29 -0
  100. package/dist/esm/app/middleware/override_method.d.ts +2 -0
  101. package/dist/esm/app/middleware/override_method.js +3 -0
  102. package/dist/esm/app/middleware/site_file.d.ts +9 -0
  103. package/dist/esm/app/middleware/site_file.js +53 -0
  104. package/dist/esm/config/config.default.d.ts +9 -0
  105. package/dist/esm/config/config.default.js +374 -0
  106. package/dist/esm/config/config.local.d.ts +8 -0
  107. package/dist/esm/config/config.local.js +10 -0
  108. package/dist/esm/config/config.unittest.d.ts +7 -0
  109. package/dist/esm/config/config.unittest.js +9 -0
  110. package/dist/esm/config/favicon.png +0 -0
  111. package/dist/esm/config/plugin.d.ts +122 -0
  112. package/dist/esm/config/plugin.js +123 -0
  113. package/dist/esm/index.d.ts +63 -0
  114. package/dist/esm/index.js +66 -0
  115. package/dist/esm/lib/agent.d.ts +19 -0
  116. package/dist/esm/lib/agent.js +54 -0
  117. package/dist/esm/lib/application.d.ts +59 -0
  118. package/dist/esm/lib/application.js +263 -0
  119. package/dist/esm/lib/core/base_context_class.d.ts +14 -0
  120. package/dist/esm/lib/core/base_context_class.js +18 -0
  121. package/dist/esm/lib/core/base_context_logger.d.ts +36 -0
  122. package/dist/esm/lib/core/base_context_logger.js +60 -0
  123. package/dist/esm/lib/core/base_hook_class.d.ts +11 -0
  124. package/dist/esm/lib/core/base_hook_class.js +23 -0
  125. package/dist/esm/lib/core/context_httpclient.d.ts +16 -0
  126. package/dist/esm/lib/core/context_httpclient.js +26 -0
  127. package/dist/esm/lib/core/httpclient.d.ts +13 -0
  128. package/dist/esm/lib/core/httpclient.js +33 -0
  129. package/dist/esm/lib/core/logger.d.ts +3 -0
  130. package/dist/esm/lib/core/logger.js +37 -0
  131. package/dist/esm/lib/core/messenger/IMessenger.d.ts +50 -0
  132. package/dist/esm/lib/core/messenger/IMessenger.js +2 -0
  133. package/dist/esm/lib/core/messenger/index.d.ts +7 -0
  134. package/dist/esm/lib/core/messenger/index.js +11 -0
  135. package/dist/esm/lib/core/messenger/ipc.d.ts +59 -0
  136. package/dist/esm/lib/core/messenger/ipc.js +130 -0
  137. package/dist/esm/lib/core/messenger/local.d.ts +61 -0
  138. package/dist/esm/lib/core/messenger/local.js +130 -0
  139. package/dist/esm/lib/core/singleton.d.ts +23 -0
  140. package/dist/esm/lib/core/singleton.js +113 -0
  141. package/dist/esm/lib/core/utils.d.ts +2 -0
  142. package/dist/esm/lib/core/utils.js +70 -0
  143. package/dist/esm/lib/egg.d.ts +276 -0
  144. package/dist/esm/lib/egg.js +574 -0
  145. package/dist/esm/lib/egg.types.d.ts +6 -0
  146. package/dist/esm/lib/egg.types.js +2 -0
  147. package/dist/esm/lib/loader/AgentWorkerLoader.d.ts +12 -0
  148. package/dist/esm/lib/loader/AgentWorkerLoader.js +20 -0
  149. package/dist/esm/lib/loader/AppWorkerLoader.d.ts +17 -0
  150. package/dist/esm/lib/loader/AppWorkerLoader.js +39 -0
  151. package/dist/esm/lib/loader/EggApplicationLoader.d.ts +4 -0
  152. package/dist/esm/lib/loader/EggApplicationLoader.js +4 -0
  153. package/dist/esm/lib/loader/index.d.ts +3 -0
  154. package/dist/esm/lib/loader/index.js +4 -0
  155. package/dist/esm/lib/start.d.ts +15 -0
  156. package/dist/esm/lib/start.js +43 -0
  157. package/dist/esm/lib/type.d.ts +293 -0
  158. package/dist/esm/lib/type.js +2 -0
  159. package/dist/esm/lib/utils.d.ts +2 -0
  160. package/dist/esm/lib/utils.js +14 -0
  161. package/dist/esm/package.json +3 -0
  162. package/dist/package.json +4 -0
  163. package/package.json +97 -79
  164. package/src/agent.ts +7 -0
  165. package/src/app/extend/context.ts +303 -0
  166. package/src/app/extend/context.types.ts +24 -0
  167. package/{app/extend/helper.js → src/app/extend/helper.ts} +14 -13
  168. package/{app/extend/request.js → src/app/extend/request.ts} +81 -79
  169. package/src/app/extend/response.ts +36 -0
  170. package/src/app/middleware/body_parser.ts +3 -0
  171. package/{app/middleware/meta.js → src/app/middleware/meta.ts} +11 -4
  172. package/{app/middleware/notfound.js → src/app/middleware/notfound.ts} +8 -3
  173. package/src/app/middleware/override_method.ts +3 -0
  174. package/src/app/middleware/site_file.ts +68 -0
  175. package/{config/config.default.js → src/config/config.default.ts} +25 -45
  176. package/src/config/config.local.ts +11 -0
  177. package/src/config/config.unittest.ts +10 -0
  178. package/src/config/favicon.png +0 -0
  179. package/{config/plugin.js → src/config/plugin.ts} +3 -5
  180. package/src/index.ts +80 -0
  181. package/src/lib/agent.ts +66 -0
  182. package/{lib/application.js → src/lib/application.ts} +76 -124
  183. package/src/lib/core/base_context_class.ts +21 -0
  184. package/src/lib/core/base_context_logger.ts +67 -0
  185. package/src/lib/core/base_hook_class.ts +30 -0
  186. package/src/lib/core/context_httpclient.ts +33 -0
  187. package/src/lib/core/httpclient.ts +51 -0
  188. package/src/lib/core/logger.ts +42 -0
  189. package/src/lib/core/messenger/IMessenger.ts +58 -0
  190. package/src/lib/core/messenger/index.ts +15 -0
  191. package/src/lib/core/messenger/ipc.ts +148 -0
  192. package/{lib/core/messenger/local.js → src/lib/core/messenger/local.ts} +36 -28
  193. package/{lib/core/singleton.js → src/lib/core/singleton.ts} +56 -33
  194. package/src/lib/core/utils.ts +77 -0
  195. package/{lib/egg.js → src/lib/egg.ts} +287 -221
  196. package/src/lib/egg.types.ts +6 -0
  197. package/src/lib/loader/AgentWorkerLoader.ts +21 -0
  198. package/src/lib/loader/AppWorkerLoader.ts +42 -0
  199. package/src/lib/loader/EggApplicationLoader.ts +5 -0
  200. package/src/lib/loader/index.ts +3 -0
  201. package/src/lib/start.ts +56 -0
  202. package/src/lib/type.ts +329 -0
  203. package/src/lib/utils.ts +16 -0
  204. package/CHANGELOG.md +0 -2395
  205. package/History.md +0 -52
  206. package/agent.js +0 -11
  207. package/app/extend/context.js +0 -285
  208. package/app/extend/response.js +0 -101
  209. package/app/middleware/body_parser.js +0 -3
  210. package/app/middleware/override_method.js +0 -3
  211. package/app/middleware/site_file.js +0 -31
  212. package/config/config.local.js +0 -7
  213. package/config/config.unittest.js +0 -8
  214. package/index.d.ts +0 -1288
  215. package/index.js +0 -68
  216. package/lib/agent.js +0 -95
  217. package/lib/core/base_context_class.js +0 -20
  218. package/lib/core/base_context_logger.js +0 -64
  219. package/lib/core/base_hook_class.js +0 -31
  220. package/lib/core/context_httpclient.js +0 -26
  221. package/lib/core/dnscache_httpclient.js +0 -93
  222. package/lib/core/httpclient.js +0 -119
  223. package/lib/core/httpclient_next.js +0 -80
  224. package/lib/core/logger.js +0 -35
  225. package/lib/core/messenger/index.js +0 -14
  226. package/lib/core/messenger/ipc.js +0 -141
  227. package/lib/core/utils.js +0 -73
  228. package/lib/loader/agent_worker_loader.js +0 -27
  229. package/lib/loader/app_worker_loader.js +0 -48
  230. package/lib/loader/index.js +0 -5
  231. package/lib/start.js +0 -39
  232. /package/{config → dist/commonjs/config}/favicon.png +0 -0
@@ -1,37 +1,150 @@
1
- const { performance } = require('perf_hooks');
2
- const path = require('path');
3
- const fs = require('fs');
4
- const ms = require('ms');
5
- const http = require('http');
6
- const EggCore = require('egg-core').EggCore;
7
- const cluster = require('cluster-client');
8
- const extend = require('extend2');
9
- const ContextLogger = require('egg-logger').EggContextLogger;
10
- const ContextCookies = require('egg-cookies');
11
- const CircularJSON = require('circular-json-for-egg');
12
- const ContextHttpClient = require('./core/context_httpclient');
13
- const Messenger = require('./core/messenger');
14
- const DNSCacheHttpClient = require('./core/dnscache_httpclient');
15
- const HttpClient = require('./core/httpclient');
16
- const HttpClientNext = require('./core/httpclient_next');
17
- const createLoggers = require('./core/logger');
18
- const Singleton = require('./core/singleton');
19
- const utils = require('./core/utils');
20
- const BaseContextClass = require('./core/base_context_class');
21
- const BaseHookClass = require('./core/base_hook_class');
22
-
23
- const HTTPCLIENT = Symbol('EggApplication#httpclient');
24
- const LOGGERS = Symbol('EggApplication#loggers');
1
+ import { performance } from 'node:perf_hooks';
2
+ import path from 'node:path';
3
+ import fs from 'node:fs';
4
+ import http, { type IncomingMessage, type ServerResponse } from 'node:http';
5
+ import inspector from 'node:inspector';
6
+ import { AsyncLocalStorage } from 'node:async_hooks';
7
+ import {
8
+ EggCore,
9
+ Request as EggCoreRequest,
10
+ Response as EggCoreResponse,
11
+ Router,
12
+ } from '@eggjs/core';
13
+ import type {
14
+ EggCoreOptions,
15
+ Next, MiddlewareFunc as EggCoreMiddlewareFunc,
16
+ ILifecycleBoot,
17
+ } from '@eggjs/core';
18
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
19
+ // @ts-ignore
20
+ import createClusterClient, { close as closeClusterClient } from 'cluster-client';
21
+ import { extend } from 'extend2';
22
+ import { EggContextLogger as ContextLogger, EggLoggers, EggLogger } from 'egg-logger';
23
+ import { Cookies as ContextCookies } from '@eggjs/cookies';
24
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
25
+ // @ts-ignore
26
+ import CircularJSON from 'circular-json-for-egg';
27
+ import type { Agent } from './agent.js';
28
+ import type { Application } from './application.js';
29
+ import Context, { type ContextDelegation } from '../app/extend/context.js';
30
+ import type { EggAppConfig } from './type.js';
31
+ import { create as createMessenger, IMessenger } from './core/messenger/index.js';
32
+ import { ContextHttpClient } from './core/context_httpclient.js';
33
+ import {
34
+ HttpClient, type HttpClientRequestOptions, type HttpClientRequestURL, type HttpClientResponse,
35
+ } from './core/httpclient.js';
36
+ import { createLoggers } from './core/logger.js';
37
+ import {
38
+ Singleton, type SingletonCreateMethod, type SingletonOptions,
39
+ } from './core/singleton.js';
40
+ import { convertObject } from './core/utils.js';
41
+ import { BaseContextClass } from './core/base_context_class.js';
42
+ import { BaseHookClass } from './core/base_hook_class.js';
43
+ import type { EggApplicationLoader } from './loader/index.js';
44
+ import { getSourceDirname } from './utils.js';
45
+
46
+ import './egg.types.js';
47
+
25
48
  const EGG_PATH = Symbol.for('egg#eggPath');
26
- const CLUSTER_CLIENTS = Symbol.for('egg#clusterClients');
49
+
50
+ export interface EggApplicationCoreOptions extends Omit<EggCoreOptions, 'baseDir'> {
51
+ mode?: 'cluster' | 'single';
52
+ clusterPort?: number;
53
+ baseDir?: string;
54
+ }
55
+
56
+ // export egg classes
57
+ export {
58
+ Context,
59
+ Router,
60
+ EggLogger,
61
+ };
62
+
63
+ export class Request extends EggCoreRequest {
64
+ declare app: EggCore;
65
+ declare response: Response;
66
+ declare ctx: ContextDelegation;
67
+ }
68
+
69
+ export class Response extends EggCoreResponse {
70
+ declare app: EggCore;
71
+ declare request: Request;
72
+ declare ctx: ContextDelegation;
73
+ }
74
+
75
+ // export egg types
76
+ export type {
77
+ ContextDelegation,
78
+ ILifecycleBoot,
79
+ Next,
80
+ };
81
+ // keep compatible with egg version 3.x
82
+ export type EggContext = ContextDelegation;
83
+ export type MiddlewareFunc<T extends ContextDelegation = ContextDelegation> = EggCoreMiddlewareFunc<T>;
27
84
 
28
85
  /**
29
86
  * Based on koa's Application
30
87
  * @see https://github.com/eggjs/egg-core
31
- * @see http://koajs.com/#application
88
+ * @see https://github.com/eggjs/koa/blob/master/src/application.ts
32
89
  * @augments EggCore
33
90
  */
34
- class EggApplication extends EggCore {
91
+ export class EggApplicationCore extends EggCore {
92
+ declare ctxStorage: AsyncLocalStorage<ContextDelegation>;
93
+ // export context base classes, let framework can impl sub class and over context extend easily.
94
+ ContextCookies = ContextCookies;
95
+ ContextLogger = ContextLogger;
96
+ ContextHttpClient = ContextHttpClient;
97
+ HttpClient = HttpClient;
98
+ /**
99
+ * Retrieve base context class
100
+ * @member {BaseContextClass} BaseContextClass
101
+ * @since 1.0.0
102
+ */
103
+ BaseContextClass = BaseContextClass;
104
+
105
+ /**
106
+ * Retrieve base controller
107
+ * @member {Controller} Controller
108
+ * @since 1.0.0
109
+ */
110
+ Controller = BaseContextClass;
111
+
112
+ /**
113
+ * Retrieve base service
114
+ * @member {Service} Service
115
+ * @since 1.0.0
116
+ */
117
+ Service = BaseContextClass;
118
+
119
+ /**
120
+ * Retrieve base subscription
121
+ * @member {Subscription} Subscription
122
+ * @since 2.12.0
123
+ */
124
+ Subscription = BaseContextClass;
125
+
126
+ /**
127
+ * Retrieve base context class
128
+ * @member {BaseHookClass} BaseHookClass
129
+ */
130
+ BaseHookClass = BaseHookClass;
131
+
132
+ /**
133
+ * Retrieve base boot
134
+ * @member {Boot}
135
+ */
136
+ Boot = BaseHookClass;
137
+
138
+ declare options: Required<EggApplicationCoreOptions>;
139
+
140
+ #httpClient?: HttpClient;
141
+ #loggers?: EggLoggers;
142
+ #clusterClients: any[] = [];
143
+
144
+ readonly messenger: IMessenger;
145
+ agent?: Agent;
146
+ application?: Application;
147
+ declare loader: EggApplicationLoader;
35
148
 
36
149
  /**
37
150
  * @class
@@ -41,91 +154,73 @@ class EggApplication extends EggCore {
41
154
  * - {Object} [plugins] - custom plugin config, use it in unittest
42
155
  * - {String} [mode] - process mode, can be cluster / single, default is `cluster`
43
156
  */
44
- constructor(options = {}) {
45
- options.mode = options.mode || 'cluster';
157
+ constructor(options?: EggApplicationCoreOptions) {
158
+ options = {
159
+ mode: 'cluster',
160
+ type: 'application',
161
+ baseDir: process.cwd(),
162
+ ...options,
163
+ };
46
164
  super(options);
47
-
48
- // export context base classes, let framework can impl sub class and over context extend easily.
49
- this.ContextCookies = ContextCookies;
50
- this.ContextLogger = ContextLogger;
51
- this.ContextHttpClient = ContextHttpClient;
52
- this.HttpClient = HttpClient;
53
- this.HttpClientNext = HttpClientNext;
54
-
55
- this.loader.loadConfig();
56
-
57
165
  /**
58
166
  * messenger instance
59
167
  * @member {Messenger}
60
168
  * @since 1.0.0
61
169
  */
62
- this.messenger = Messenger.create(this);
170
+ this.messenger = createMessenger(this);
63
171
 
64
172
  // trigger `serverDidReady` hook when all the app workers
65
173
  // and agent worker are ready
66
174
  this.messenger.once('egg-ready', () => {
67
175
  this.lifecycle.triggerServerDidReady();
68
176
  });
177
+ this.lifecycle.registerBeforeStart(async () => {
178
+ await this.load();
179
+ }, 'load files');
180
+ }
181
+
182
+ /**
183
+ * @deprecated please use `options` property instead
184
+ */
185
+ get _options() {
186
+ return this.options;
187
+ }
69
188
 
189
+ protected async loadConfig() {
190
+ await this.loader.loadConfig();
191
+ }
192
+
193
+ protected async load() {
194
+ await this.loadConfig();
70
195
  // dump config after ready, ensure all the modifications during start will be recorded
71
196
  // make sure dumpConfig is the last ready callback
72
197
  this.ready(() => process.nextTick(() => {
73
198
  const dumpStartTime = Date.now();
74
199
  this.dumpConfig();
75
200
  this.dumpTiming();
76
- this.coreLogger.info('[egg:core] dump config after ready, %s', ms(Date.now() - dumpStartTime));
201
+ this.coreLogger.info('[egg] dump config after ready, %sms', Date.now() - dumpStartTime);
77
202
  }));
78
- this._setupTimeoutTimer();
203
+ this.#setupTimeoutTimer();
79
204
 
80
- this.console.info('[egg:core] App root: %s', this.baseDir);
81
- this.console.info('[egg:core] All *.log files save on %j', this.config.logger.dir);
82
- this.console.info('[egg:core] Loaded enabled plugin %j', this.loader.orderPlugins);
205
+ this.console.info('[egg] App root: %s', this.baseDir);
206
+ this.console.info('[egg] All *.log files save on %j', this.config.logger.dir);
207
+ this.console.info('[egg] Loaded enabled plugin %j', this.loader.orderPlugins);
83
208
 
84
209
  // Listen the error that promise had not catch, then log it in common-error
85
210
  this._unhandledRejectionHandler = this._unhandledRejectionHandler.bind(this);
86
211
  process.on('unhandledRejection', this._unhandledRejectionHandler);
87
212
 
88
- this[CLUSTER_CLIENTS] = [];
89
-
90
- /**
91
- * Wrap the Client with Leader/Follower Pattern
92
- *
93
- * @description almost the same as Agent.cluster API, the only different is that this method create Follower.
94
- *
95
- * @see https://github.com/node-modules/cluster-client
96
- * @param {Function} clientClass - client class function
97
- * @param {Object} [options]
98
- * - {Boolean} [autoGenerate] - whether generate delegate rule automatically, default is true
99
- * - {Function} [formatKey] - a method to tranform the subscription info into a string,default is JSON.stringify
100
- * - {Object} [transcode|JSON.stringify/parse]
101
- * - {Function} encode - custom serialize method
102
- * - {Function} decode - custom deserialize method
103
- * - {Boolean} [isBroadcast] - whether broadcast subscrption result to all followers or just one, default is true
104
- * - {Number} [responseTimeout] - response timeout, default is 3 seconds
105
- * - {Number} [maxWaitTime|30000] - leader startup max time, default is 30 seconds
106
- * @return {ClientWrapper} wrapper
107
- */
108
- this.cluster = (clientClass, options) => {
109
- options = Object.assign({}, this.config.clusterClient, options, {
110
- singleMode: this.options.mode === 'single',
111
- // cluster need a port that can't conflict on the environment
112
- port: this.options.clusterPort,
113
- // agent worker is leader, app workers are follower
114
- isLeader: this.type === 'agent',
115
- logger: this.coreLogger,
116
- // debug mode does not check heartbeat
117
- isCheckHeartbeat: this.config.env === 'prod' ? true : require('inspector').url() === undefined,
118
- });
119
- const client = cluster(clientClass, options);
120
- this._patchClusterClient(client);
121
- return client;
122
- };
123
-
124
213
  // register close function
125
- this.beforeClose(async () => {
214
+ this.lifecycle.registerBeforeClose(async () => {
215
+ // close all cluster clients
216
+ for (const clusterClient of this.#clusterClients) {
217
+ await closeClusterClient(clusterClient);
218
+ }
219
+ this.#clusterClients = [];
220
+
126
221
  // single process mode will close agent before app close
127
222
  if (this.type === 'application' && this.options.mode === 'single') {
128
- await this.agent.close();
223
+ await this.agent!.close();
129
224
  }
130
225
 
131
226
  for (const logger of this.loggers.values()) {
@@ -135,45 +230,43 @@ class EggApplication extends EggCore {
135
230
  process.removeListener('unhandledRejection', this._unhandledRejectionHandler);
136
231
  });
137
232
 
138
- /**
139
- * Retreive base context class
140
- * @member {BaseContextClass} BaseContextClass
141
- * @since 1.0.0
142
- */
143
- this.BaseContextClass = BaseContextClass;
144
-
145
- /**
146
- * Retreive base controller
147
- * @member {Controller} Controller
148
- * @since 1.0.0
149
- */
150
- this.Controller = BaseContextClass;
151
-
152
- /**
153
- * Retreive base service
154
- * @member {Service} Service
155
- * @since 1.0.0
156
- */
157
- this.Service = BaseContextClass;
158
-
159
- /**
160
- * Retreive base subscription
161
- * @member {Subscription} Subscription
162
- * @since 2.12.0
163
- */
164
- this.Subscription = BaseContextClass;
165
-
166
- /**
167
- * Retreive base context class
168
- * @member {BaseHookClass} BaseHookClass
169
- */
170
- this.BaseHookClass = BaseHookClass;
233
+ await this.loader.load();
234
+ }
171
235
 
172
- /**
173
- * Retreive base boot
174
- * @member {Boot}
175
- */
176
- this.Boot = BaseHookClass;
236
+ /**
237
+ * Wrap the Client with Leader/Follower Pattern
238
+ *
239
+ * @description almost the same as Agent.cluster API, the only different is that this method create Follower.
240
+ *
241
+ * @see https://github.com/node-modules/cluster-client
242
+ * @param {Function} clientClass - client class function
243
+ * @param {Object} [options]
244
+ * - {Boolean} [autoGenerate] - whether generate delegate rule automatically, default is true
245
+ * - {Function} [formatKey] - a method to transform the subscription info into a string,default is JSON.stringify
246
+ * - {Object} [transcode|JSON.stringify/parse]
247
+ * - {Function} encode - custom serialize method
248
+ * - {Function} decode - custom deserialize method
249
+ * - {Boolean} [isBroadcast] - whether broadcast subscription result to all followers or just one, default is true
250
+ * - {Number} [responseTimeout] - response timeout, default is 3 seconds
251
+ * - {Number} [maxWaitTime|30000] - leader startup max time, default is 30 seconds
252
+ * @return {ClientWrapper} wrapper
253
+ */
254
+ cluster(clientClass: unknown, options?: object) {
255
+ const clientClassOptions = {
256
+ ...this.config.clusterClient,
257
+ ...options,
258
+ singleMode: this.options.mode === 'single',
259
+ // cluster need a port that can't conflict on the environment
260
+ port: this.options.clusterPort,
261
+ // agent worker is leader, app workers are follower
262
+ isLeader: this.type === 'agent',
263
+ logger: this.coreLogger,
264
+ // debug mode does not check heartbeat
265
+ isCheckHeartbeat: this.config.env === 'prod' ? true : inspector.url() === undefined,
266
+ };
267
+ const client = createClusterClient(clientClass, clientClassOptions);
268
+ this.#patchClusterClient(client);
269
+ return client;
177
270
  }
178
271
 
179
272
  /**
@@ -185,7 +278,7 @@ class EggApplication extends EggCore {
185
278
  * console.log(app);
186
279
  * =>
187
280
  * {
188
- * name: 'mockapp',
281
+ * name: 'mock-app',
189
282
  * env: 'test',
190
283
  * subdomainOffset: 2,
191
284
  * config: '<egg config>',
@@ -197,23 +290,21 @@ class EggApplication extends EggCore {
197
290
  * }
198
291
  * ```
199
292
  */
200
- inspect() {
293
+ inspect(): any {
201
294
  const res = {
202
295
  env: this.config.env,
203
296
  };
204
297
 
205
- function delegate(res, app, keys) {
298
+ function delegate(res: any, app: any, keys: string[]) {
206
299
  for (const key of keys) {
207
- /* istanbul ignore else */
208
300
  if (app[key]) {
209
301
  res[key] = app[key];
210
302
  }
211
303
  }
212
304
  }
213
305
 
214
- function abbr(res, app, keys) {
306
+ function abbr(res: any, app: any, keys: string[]) {
215
307
  for (const key of keys) {
216
- /* istanbul ignore else */
217
308
  if (app[key]) {
218
309
  res[key] = `<egg ${key}>`;
219
310
  }
@@ -250,13 +341,13 @@ class EggApplication extends EggCore {
250
341
  * See https://github.com/node-modules/urllib#api-doc for more details.
251
342
  *
252
343
  * @param {String} url request url address.
253
- * @param {Object} opts
344
+ * @param {Object} options
254
345
  * - method {String} - Request method, defaults to GET. Could be GET, POST, DELETE or PUT. Alias 'type'.
255
346
  * - data {Object} - Data to be sent. Will be stringify automatically.
256
347
  * - dataType {String} - String - Type of response data. Could be `text` or `json`.
257
- * If it's `text`, the callbacked data would be a String.
348
+ * If it's `text`, the callback data would be a String.
258
349
  * If it's `json`, the data of callback would be a parsed JSON Object.
259
- * Default callbacked data would be a Buffer.
350
+ * Default callback data would be a Buffer.
260
351
  * - headers {Object} - Request headers.
261
352
  * - timeout {Number} - Request timeout in milliseconds. Defaults to exports.TIMEOUT.
262
353
  * Include remote server connecting timeout and response timeout.
@@ -266,10 +357,10 @@ class EggApplication extends EggCore {
266
357
  * - gzip {Boolean} - let you get the res object when request connected, default false. alias customResponse
267
358
  * - nestedQuerystring {Boolean} - urllib default use querystring to stringify form data which don't
268
359
  * support nested object, will use qs instead of querystring to support nested object by set this option to true.
269
- * - more options see https://www.npmjs.com/package/urllib
360
+ * - more options see https://github.com/node-modules/urllib
270
361
  * @return {Object}
271
362
  * - status {Number} - HTTP response status
272
- * - headers {Object} - HTTP response seaders
363
+ * - headers {Object} - HTTP response headers
273
364
  * - res {Object} - HTTP response meta
274
365
  * - data {Object} - HTTP response body
275
366
  *
@@ -282,24 +373,8 @@ class EggApplication extends EggCore {
282
373
  * console.log(result.status, result.headers, result.data);
283
374
  * ```
284
375
  */
285
- async curl(url, opts) {
286
- return await this.httpclient.request(url, opts);
287
- }
288
-
289
- /**
290
- * Create a new HttpClient instance with custom options
291
- * @param {Object} [options] HttpClient init options
292
- */
293
- createHttpClient(options) {
294
- let httpClient;
295
- if (this.config.httpclient.useHttpClientNext || this.config.httpclient.allowH2) {
296
- httpClient = new this.HttpClientNext(this, options);
297
- } else if (this.config.httpclient.enableDNSCache) {
298
- httpClient = new DNSCacheHttpClient(this, options);
299
- } else {
300
- httpClient = new this.HttpClient(this, options);
301
- }
302
- return httpClient;
376
+ async curl<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions): Promise<HttpClientResponse<T>> {
377
+ return await this.httpClient.request<T>(url, options);
303
378
  }
304
379
 
305
380
  /**
@@ -307,31 +382,32 @@ class EggApplication extends EggCore {
307
382
  * @see https://github.com/node-modules/urllib
308
383
  * @member {HttpClient}
309
384
  */
310
- get httpclient() {
311
- if (!this[HTTPCLIENT]) {
312
- this[HTTPCLIENT] = this.createHttpClient();
385
+ get httpClient() {
386
+ if (!this.#httpClient) {
387
+ this.#httpClient = new this.HttpClient(this);
313
388
  }
314
- return this[HTTPCLIENT];
389
+ return this.#httpClient;
315
390
  }
316
391
 
317
392
  /**
318
- * @alias httpclient
393
+ * @deprecated please use httpClient instead
394
+ * @alias httpClient
319
395
  * @member {HttpClient}
320
396
  */
321
- get httpClient() {
322
- return this.httpclient;
397
+ get httpclient() {
398
+ return this.httpClient;
323
399
  }
324
400
 
325
401
  /**
326
- * All loggers contain logger, coreLogger and customLogger
402
+ * All loggers contain logger, coreLogger and customLogger
327
403
  * @member {Object}
328
404
  * @since 1.0.0
329
405
  */
330
406
  get loggers() {
331
- if (!this[LOGGERS]) {
332
- this[LOGGERS] = createLoggers(this);
407
+ if (!this.#loggers) {
408
+ this.#loggers = createLoggers(this);
333
409
  }
334
- return this[LOGGERS];
410
+ return this.#loggers;
335
411
  }
336
412
 
337
413
  /**
@@ -340,7 +416,7 @@ class EggApplication extends EggCore {
340
416
  * @param {String} name - logger name
341
417
  * @return {Logger} logger
342
418
  */
343
- getLogger(name) {
419
+ getLogger(name: string): EggLogger {
344
420
  return this.loggers[name] || null;
345
421
  }
346
422
 
@@ -362,11 +438,10 @@ class EggApplication extends EggCore {
362
438
  return this.getLogger('coreLogger');
363
439
  }
364
440
 
365
- _unhandledRejectionHandler(err) {
441
+ _unhandledRejectionHandler(err: any) {
366
442
  if (!(err instanceof Error)) {
367
443
  const newError = new Error(String(err));
368
444
  // err maybe an object, try to copy the name, message and stack to the new error instance
369
- /* istanbul ignore else */
370
445
  if (err) {
371
446
  if (err.name) newError.name = err.name;
372
447
  if (err.message) newError.message = err.message;
@@ -374,7 +449,6 @@ class EggApplication extends EggCore {
374
449
  }
375
450
  err = newError;
376
451
  }
377
- /* istanbul ignore else */
378
452
  if (err.name === 'Error') {
379
453
  err.name = 'unhandledRejectionError';
380
454
  }
@@ -384,21 +458,23 @@ class EggApplication extends EggCore {
384
458
  /**
385
459
  * dump out the config and meta object
386
460
  * @private
387
- * @return {Object} the result
388
461
  */
389
462
  dumpConfigToObject() {
390
- let ignoreList;
463
+ let ignoreList: (string | RegExp)[];
391
464
  try {
392
465
  // support array and set
393
466
  ignoreList = Array.from(this.config.dump.ignore);
394
467
  } catch (_) {
395
468
  ignoreList = [];
396
469
  }
397
-
398
- const json = extend(true, {}, { config: this.config, plugins: this.loader.allPlugins, appInfo: this.loader.appInfo });
399
- utils.convertObject(json, ignoreList);
470
+ const config = extend(true, {}, {
471
+ config: this.config,
472
+ plugins: this.loader.allPlugins,
473
+ appInfo: this.loader.appInfo,
474
+ });
475
+ convertObject(config, ignoreList);
400
476
  return {
401
- config: json,
477
+ config,
402
478
  meta: this.loader.configMeta,
403
479
  };
404
480
  }
@@ -410,10 +486,11 @@ class EggApplication extends EggCore {
410
486
  dumpConfig() {
411
487
  const rundir = this.config.rundir;
412
488
  try {
413
- /* istanbul ignore if */
414
- if (!fs.existsSync(rundir)) fs.mkdirSync(rundir);
489
+ if (!fs.existsSync(rundir)) {
490
+ fs.mkdirSync(rundir);
491
+ }
415
492
 
416
- // get dumpped object
493
+ // get dumped object
417
494
  const { config, meta } = this.dumpConfigToObject();
418
495
 
419
496
  // dump config
@@ -423,8 +500,8 @@ class EggApplication extends EggCore {
423
500
  // dump config meta
424
501
  const dumpMetaFile = path.join(rundir, `${this.type}_config_meta.json`);
425
502
  fs.writeFileSync(dumpMetaFile, CircularJSON.stringify(meta, null, 2));
426
- } catch (err) {
427
- this.coreLogger.warn(`dumpConfig error: ${err.message}`);
503
+ } catch (err: any) {
504
+ this.coreLogger.warn(`[egg] dumpConfig error: ${err.message}`);
428
505
  }
429
506
  }
430
507
 
@@ -437,24 +514,24 @@ class EggApplication extends EggCore {
437
514
  this.coreLogger.info(this.timing.toString());
438
515
  // only disable, not clear bootstrap timing data.
439
516
  this.timing.disable();
440
- // show duration >= ${slowBootActionMinDuration}ms action to warnning log
517
+ // show duration >= ${slowBootActionMinDuration}ms action to warning log
441
518
  for (const item of items) {
442
519
  // ignore #0 name: Process Start
443
- if (item.index > 0 && item.duration >= this.config.dump.timing.slowBootActionMinDuration) {
444
- this.coreLogger.warn('[egg:core][slow-boot-action] #%d %dms, name: %s',
520
+ if (item.index > 0 && item.duration && item.duration >= this.config.dump.timing.slowBootActionMinDuration) {
521
+ this.coreLogger.warn('[egg][dumpTiming][slow-boot-action] #%d %dms, name: %s',
445
522
  item.index, item.duration, item.name);
446
523
  }
447
524
  }
448
- } catch (err) {
449
- this.coreLogger.warn(`dumpTiming error: ${err.message}`);
525
+ } catch (err: any) {
526
+ this.coreLogger.warn(`[egg] dumpTiming error: ${err.message}`);
450
527
  }
451
528
  }
452
529
 
453
530
  get [EGG_PATH]() {
454
- return path.join(__dirname, '..');
531
+ return getSourceDirname();
455
532
  }
456
533
 
457
- _setupTimeoutTimer() {
534
+ #setupTimeoutTimer() {
458
535
  const startTimeoutTimer = setTimeout(() => {
459
536
  this.coreLogger.error(this.timing.toString());
460
537
  this.coreLogger.error(`${this.type} still doesn't ready after ${this.config.workerStartTimeout} ms.`);
@@ -464,7 +541,8 @@ class EggApplication extends EggCore {
464
541
  if (item.end) continue;
465
542
  this.coreLogger.error(`unfinished timing item: ${CircularJSON.stringify(item)}`);
466
543
  }
467
- this.coreLogger.error(`check run/${this.type}_timing_${process.pid}.json for more details.`);
544
+ this.coreLogger.error('[egg][setupTimeoutTimer] check run/%s_timing_%s.json for more details.',
545
+ this.type, process.pid);
468
546
  this.emit('startTimeout');
469
547
  this.dumpConfig();
470
548
  this.dumpTiming();
@@ -472,6 +550,10 @@ class EggApplication extends EggCore {
472
550
  this.ready(() => clearTimeout(startTimeoutTimer));
473
551
  }
474
552
 
553
+ get config() {
554
+ return super.config as EggAppConfig;
555
+ }
556
+
475
557
  /**
476
558
  * app.env delegate app.config.env
477
559
  * @deprecated
@@ -488,7 +570,7 @@ class EggApplication extends EggCore {
488
570
  * @deprecated
489
571
  */
490
572
  get proxy() {
491
- this.deprecate('please use app.config.proxy instead');
573
+ // this.deprecate('please use app.config.proxy instead');
492
574
  return this.config.proxy;
493
575
  }
494
576
  /* eslint no-empty-function: off */
@@ -499,11 +581,12 @@ class EggApplication extends EggCore {
499
581
  * @param {String} name - unique name for singleton
500
582
  * @param {Function|AsyncFunction} create - method will be invoked when singleton instance create
501
583
  */
502
- addSingleton(name, create) {
503
- const options = {};
504
- options.name = name;
505
- options.create = create;
506
- options.app = this;
584
+ addSingleton(name: string, create: SingletonCreateMethod) {
585
+ const options: SingletonOptions = {
586
+ name,
587
+ create,
588
+ app: this,
589
+ };
507
590
  const singleton = new Singleton(options);
508
591
  const initPromise = singleton.init();
509
592
  if (initPromise) {
@@ -513,12 +596,11 @@ class EggApplication extends EggCore {
513
596
  }
514
597
  }
515
598
 
516
- _patchClusterClient(client) {
517
- const create = client.create;
518
- client.create = (...args) => {
519
- const realClient = create.apply(client, args);
520
- this[CLUSTER_CLIENTS].push(realClient);
521
- this.beforeClose(() => cluster.close(realClient));
599
+ #patchClusterClient(client: any) {
600
+ const rawCreate = client.create;
601
+ client.create = (...args: any) => {
602
+ const realClient = rawCreate.apply(client, args);
603
+ this.#clusterClients.push(realClient);
522
604
  return realClient;
523
605
  };
524
606
  }
@@ -530,8 +612,8 @@ class EggApplication extends EggCore {
530
612
  * @param {Request} [req] - if you want to mock request like querystring, you can pass an object to this function.
531
613
  * @return {Context} context
532
614
  */
533
- createAnonymousContext(req) {
534
- const request = {
615
+ createAnonymousContext(req?: any): EggContext {
616
+ const request: any = {
535
617
  headers: {
536
618
  host: '127.0.0.1',
537
619
  'x-forwarded-for': '127.0.0.1',
@@ -570,36 +652,20 @@ class EggApplication extends EggCore {
570
652
  * @param {Res} res - node native Response object
571
653
  * @return {Context} context object
572
654
  */
573
- createContext(req, res) {
574
- const app = this;
575
- const context = Object.create(app.context);
576
- const request = context.request = Object.create(app.request);
577
- const response = context.response = Object.create(app.response);
578
- context.app = request.app = response.app = app;
655
+ createContext(req: IncomingMessage, res: ServerResponse): EggContext {
656
+ const context = Object.create(this.context) as EggContext;
657
+ const request = context.request = Object.create(this.request);
658
+ const response = context.response = Object.create(this.response);
659
+ context.app = request.app = response.app = this as any;
579
660
  context.req = request.req = response.req = req;
580
661
  context.res = request.res = response.res = res;
581
662
  request.ctx = response.ctx = context;
582
663
  request.response = response;
583
664
  response.request = request;
584
665
  context.onerror = context.onerror.bind(context);
585
- context.originalUrl = request.originalUrl = req.url;
586
-
587
- /**
588
- * Request start time
589
- * @member {Number} Context#starttime
590
- */
666
+ context.originalUrl = request.originalUrl = req.url as string;
591
667
  context.starttime = Date.now();
592
-
593
- if (this.config.logger.enablePerformanceTimer) {
594
- /**
595
- * Request start timer using `performance.now()`
596
- * @member {Number} Context#performanceStarttime
597
- */
598
- context.performanceStarttime = performance.now();
599
- }
668
+ context.performanceStarttime = performance.now();
600
669
  return context;
601
670
  }
602
-
603
671
  }
604
-
605
- module.exports = EggApplication;