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,17 +1,21 @@
1
- 'use strict';
1
+ import querystring from 'node:querystring';
2
+ import { Request as EggCoreRequest } from '@eggjs/core';
3
+ import type { Application } from '../../lib/application.js';
4
+ import type { ContextDelegation } from './context.js';
5
+ import Response from './response.js';
2
6
 
3
- const querystring = require('querystring');
4
- const accepts = require('accepts');
5
-
6
- const _querycache = Symbol('_querycache');
7
- const _queriesCache = Symbol('_queriesCache');
8
- const PROTOCOL = Symbol('PROTOCOL');
9
- const HOST = Symbol('HOST');
10
- const ACCEPTS = Symbol('ACCEPTS');
11
- const IPS = Symbol('IPS');
7
+ const QUERY_CACHE = Symbol('request query cache');
8
+ const QUERIES_CACHE = Symbol('request queries cache');
9
+ const PROTOCOL = Symbol('request protocol');
10
+ const HOST = Symbol('request host');
11
+ const IPS = Symbol('request ips');
12
12
  const RE_ARRAY_KEY = /[^\[\]]+\[\]$/;
13
13
 
14
- module.exports = {
14
+ export default class Request extends EggCoreRequest {
15
+ declare app: Application;
16
+ declare ctx: ContextDelegation;
17
+ declare response: Response;
18
+
15
19
  /**
16
20
  * Parse the "Host" header field host
17
21
  * and support X-Forwarded-Host when a
@@ -29,17 +33,19 @@ module.exports = {
29
33
  * => 'demo.eggjs.org'
30
34
  * ```
31
35
  */
32
- get host() {
33
- if (this[HOST]) return this[HOST];
36
+ get host(): string {
37
+ let host = this[HOST] as string | undefined;
38
+ if (host) {
39
+ return host;
40
+ }
34
41
 
35
- let host;
36
42
  if (this.app.config.proxy) {
37
43
  host = getFromHeaders(this, this.app.config.hostHeaders);
38
44
  }
39
45
  host = host || this.get('host') || '';
40
- this[HOST] = host.split(/\s*,\s*/)[0];
41
- return this[HOST];
42
- },
46
+ this[HOST] = host = host.split(',')[0].trim();
47
+ return host;
48
+ }
43
49
 
44
50
  /**
45
51
  * @member {String} Request#protocol
@@ -49,25 +55,28 @@ module.exports = {
49
55
  * => 'https'
50
56
  * ```
51
57
  */
52
- get protocol() {
53
- if (this[PROTOCOL]) return this[PROTOCOL];
58
+ get protocol(): string {
59
+ let protocol = this[PROTOCOL] as string;
60
+ if (protocol) {
61
+ return protocol;
62
+ }
54
63
  // detect encrypted socket
55
- if (this.socket && this.socket.encrypted) {
56
- this[PROTOCOL] = 'https';
57
- return this[PROTOCOL];
64
+ if (this.socket?.encrypted) {
65
+ this[PROTOCOL] = protocol = 'https';
66
+ return protocol;
58
67
  }
59
68
  // get from headers specified in `app.config.protocolHeaders`
60
69
  if (this.app.config.proxy) {
61
70
  const proto = getFromHeaders(this, this.app.config.protocolHeaders);
62
71
  if (proto) {
63
- this[PROTOCOL] = proto.split(/\s*,\s*/)[0];
64
- return this[PROTOCOL];
72
+ this[PROTOCOL] = protocol = proto.split(/\s*,\s*/)[0];
73
+ return protocol;
65
74
  }
66
75
  }
67
- // use protocol specified in `app.conig.protocol`
68
- this[PROTOCOL] = this.app.config.protocol || 'http';
69
- return this[PROTOCOL];
70
- },
76
+ // use protocol specified in `app.config.protocol`
77
+ this[PROTOCOL] = protocol = this.app.config.protocol || 'http';
78
+ return protocol;
79
+ }
71
80
 
72
81
  /**
73
82
  * Get all pass through ip addresses from the request.
@@ -80,29 +89,34 @@ module.exports = {
80
89
  * => ['100.23.1.2', '201.10.10.2']
81
90
  * ```
82
91
  */
83
- get ips() {
84
- if (this[IPS]) return this[IPS];
92
+ get ips(): string[] {
93
+ let ips = this[IPS] as string[] | undefined;
94
+ if (ips) {
95
+ return ips;
96
+ }
85
97
 
86
98
  // return empty array when proxy=false
87
99
  if (!this.app.config.proxy) {
88
- this[IPS] = [];
89
- return this[IPS];
100
+ this[IPS] = ips = [];
101
+ return ips;
90
102
  }
91
103
 
92
- const val = getFromHeaders(this, this.app.config.ipHeaders) || '';
93
- this[IPS] = val ? val.split(/\s*,\s*/) : [];
104
+ const val = getFromHeaders(this, this.app.config.ipHeaders);
105
+ this[IPS] = ips = val ? val.split(/\s*,\s*/) : [];
94
106
 
95
107
  let maxIpsCount = this.app.config.maxIpsCount;
96
108
  // Compatible with maxProxyCount logic (previous logic is wrong, only for compatibility with legacy logic)
97
- if (!maxIpsCount && this.app.config.maxProxyCount) maxIpsCount = this.app.config.maxProxyCount + 1;
109
+ if (!maxIpsCount && this.app.config.maxProxyCount) {
110
+ maxIpsCount = this.app.config.maxProxyCount + 1;
111
+ }
98
112
 
99
113
  if (maxIpsCount > 0) {
100
114
  // if maxIpsCount present, only keep `maxIpsCount` ips
101
115
  // [ illegalIp, clientRealIp, proxyIp1, proxyIp2 ...]
102
- this[IPS] = this[IPS].slice(-maxIpsCount);
116
+ this[IPS] = ips = ips.slice(-maxIpsCount);
103
117
  }
104
- return this[IPS];
105
- },
118
+ return ips;
119
+ }
106
120
 
107
121
  /**
108
122
  * Get the request remote IPv4 address
@@ -115,16 +129,16 @@ module.exports = {
115
129
  * => '111.10.2.1'
116
130
  * ```
117
131
  */
118
- get ip() {
132
+ get ip(): string {
119
133
  if (this._ip) {
120
134
  return this._ip;
121
135
  }
122
- const ip = this.ips[0] || this.socket.remoteAddress;
136
+ const ip = this.ips[0] ?? this.socket.remoteAddress;
123
137
  // will be '::ffff:x.x.x.x', should convert to standard IPv4 format
124
138
  // https://zh.wikipedia.org/wiki/IPv6
125
- this._ip = ip && ip.indexOf('::ffff:') > -1 ? ip.substring(7) : ip;
139
+ this._ip = ip && ip.startsWith('::ffff:') ? ip.substring(7) : ip;
126
140
  return this._ip;
127
- },
141
+ }
128
142
 
129
143
  /**
130
144
  * Set the request remote IPv4 address
@@ -137,9 +151,9 @@ module.exports = {
137
151
  * => '111.10.2.1'
138
152
  * ```
139
153
  */
140
- set ip(ip) {
154
+ set ip(ip: string) {
141
155
  this._ip = ip;
142
- },
156
+ }
143
157
 
144
158
  /**
145
159
  * detect if response should be json
@@ -150,25 +164,25 @@ module.exports = {
150
164
  * @member {Boolean} Request#acceptJSON
151
165
  * @since 1.0.0
152
166
  */
153
- get acceptJSON() {
167
+ get acceptJSON(): boolean {
154
168
  if (this.path.endsWith('.json')) return true;
155
169
  if (this.response.type && this.response.type.indexOf('json') >= 0) return true;
156
170
  if (this.accepts('html', 'text', 'json') === 'json') return true;
157
171
  return false;
158
- },
172
+ }
159
173
 
160
174
  // How to read query safely
161
175
  // https://github.com/koajs/qs/issues/5
162
- _customQuery(cacheName, filter) {
176
+ _customQuery(cacheName: symbol, filter: (value: string | string[]) => string | string[]) {
163
177
  const str = this.querystring || '';
164
- let c = this[cacheName];
178
+ let c = this[cacheName] as Record<string, Record<string, string | string[]>>;
165
179
  if (!c) {
166
180
  c = this[cacheName] = {};
167
181
  }
168
182
  let cacheQuery = c[str];
169
183
  if (!cacheQuery) {
170
184
  cacheQuery = c[str] = {};
171
- const isQueries = cacheName === _queriesCache;
185
+ const isQueries = cacheName === QUERIES_CACHE;
172
186
  // `querystring.parse` CANNOT parse something like `a[foo]=1&a[bar]=2`
173
187
  const query = str ? querystring.parse(str) : {};
174
188
  for (const key in query) {
@@ -176,20 +190,19 @@ module.exports = {
176
190
  // key is '', like `a=b&`
177
191
  continue;
178
192
  }
179
- const value = filter(query[key]);
193
+ const value = filter(query[key]!);
180
194
  cacheQuery[key] = value;
181
195
  if (isQueries && RE_ARRAY_KEY.test(key)) {
182
196
  // `this.queries['key'] => this.queries['key[]']` is compatibly supported
183
- const subkey = key.substring(0, key.length - 2);
184
-
185
- if (!cacheQuery[subkey]) {
186
- cacheQuery[subkey] = value;
197
+ const subKey = key.substring(0, key.length - 2);
198
+ if (!cacheQuery[subKey]) {
199
+ cacheQuery[subKey] = value;
187
200
  }
188
201
  }
189
202
  }
190
203
  }
191
204
  return cacheQuery;
192
- },
205
+ }
193
206
 
194
207
  /**
195
208
  * get params pass by querystring, all values are of string type.
@@ -212,8 +225,8 @@ module.exports = {
212
225
  * ```
213
226
  */
214
227
  get query() {
215
- return this._customQuery(_querycache, firstValue);
216
- },
228
+ return this._customQuery(QUERY_CACHE, firstValue) as Record<string, string>;
229
+ }
217
230
 
218
231
  /**
219
232
  * get params pass by querystring, all value are Array type. {@link Request#query}
@@ -232,50 +245,39 @@ module.exports = {
232
245
  * ```
233
246
  */
234
247
  get queries() {
235
- return this._customQuery(_queriesCache, arrayValue);
236
- },
237
-
238
- get accept() {
239
- let accept = this[ACCEPTS];
240
- if (accept) {
241
- return accept;
242
- }
243
- accept = this[ACCEPTS] = accepts(this.req);
244
- return accept;
245
- },
248
+ return this._customQuery(QUERIES_CACHE, arrayValue) as Record<string, string[]>;
249
+ }
246
250
 
247
251
  /**
248
252
  * Set query-string as an object.
249
253
  *
250
254
  * @function Request#query
251
255
  * @param {Object} obj set querystring and query object for request.
252
- * @return {void}
253
256
  */
254
- set query(obj) {
257
+ set query(obj: Record<string, string>) {
255
258
  this.querystring = querystring.stringify(obj);
256
- },
257
- };
258
-
259
+ }
260
+ }
259
261
 
260
- function firstValue(value) {
262
+ function firstValue(value: string | string[]) {
261
263
  if (Array.isArray(value)) {
262
264
  value = value[0];
263
265
  }
264
266
  return value;
265
267
  }
266
268
 
267
- function arrayValue(value) {
269
+ function arrayValue(value: string | string[]) {
268
270
  if (!Array.isArray(value)) {
269
271
  value = [ value ];
270
272
  }
271
273
  return value;
272
274
  }
273
275
 
274
- function getFromHeaders(ctx, names) {
276
+ function getFromHeaders(request: Request, names: string) {
275
277
  if (!names) return '';
276
- names = names.split(/\s*,\s*/);
277
- for (const name of names) {
278
- const value = ctx.get(name);
278
+ const fields = names.split(/\s*,\s*/);
279
+ for (const name of fields) {
280
+ const value = request.get<string>(name);
279
281
  if (value) return value;
280
282
  }
281
283
  return '';
@@ -0,0 +1,36 @@
1
+ import { Response as KoaResponse } from '@eggjs/core';
2
+
3
+ const REAL_STATUS = Symbol('response realStatus');
4
+
5
+ export default class Response extends KoaResponse {
6
+ /**
7
+ * Get or set a real status code.
8
+ *
9
+ * e.g.: Using 302 status redirect to the global error page
10
+ * instead of show current 500 status page.
11
+ * And access log should save 500 not 302,
12
+ * then the `realStatus` can help us find out the real status code.
13
+ * @member {Number} Response#realStatus
14
+ * @return {Number} The status code to be set.
15
+ */
16
+ get realStatus(): number {
17
+ if (this[REAL_STATUS]) {
18
+ return this[REAL_STATUS] as number;
19
+ }
20
+ return this.status;
21
+ }
22
+
23
+ /**
24
+ * Set a real status code.
25
+ *
26
+ * e.g.: Using 302 status redirect to the global error page
27
+ * instead of show current 500 status page.
28
+ * And access log should save 500 not 302,
29
+ * then the `realStatus` can help us find out the real status code.
30
+ * @member {Number} Response#realStatus
31
+ * @param {Number} status The status code to be set.
32
+ */
33
+ set realStatus(status: number) {
34
+ this[REAL_STATUS] = status;
35
+ }
36
+ }
@@ -0,0 +1,3 @@
1
+ import bodyparser from 'koa-bodyparser';
2
+
3
+ export default bodyparser;
@@ -2,12 +2,19 @@
2
2
  * meta middleware, should be the first middleware
3
3
  */
4
4
 
5
- const { performance } = require('perf_hooks');
5
+ import { performance } from 'node:perf_hooks';
6
+ import type { ContextDelegation, Next } from '../../lib/egg.js';
6
7
 
7
- module.exports = options => {
8
- return async function meta(ctx, next) {
8
+ export interface MetaMiddlewareOptions {
9
+ enable: boolean;
10
+ logging: boolean;
11
+ }
12
+
13
+ export default (options: MetaMiddlewareOptions) => {
14
+ return async function meta(ctx: ContextDelegation, next: Next) {
9
15
  if (options.logging) {
10
- ctx.coreLogger.info('[meta] request started, host: %s, user-agent: %s', ctx.host, ctx.header['user-agent']);
16
+ ctx.coreLogger.info('[meta] request started, host: %s, user-agent: %s',
17
+ ctx.host, ctx.header['user-agent']);
11
18
  }
12
19
  await next();
13
20
  // total response time header
@@ -1,7 +1,12 @@
1
- 'use strict';
1
+ import type { Next, ContextDelegation } from '../../lib/egg.js';
2
2
 
3
- module.exports = options => {
4
- return async function notfound(ctx, next) {
3
+ export interface NotFoundMiddlewareOptions {
4
+ enable: boolean;
5
+ pageUrl: string;
6
+ }
7
+
8
+ export default (options: NotFoundMiddlewareOptions) => {
9
+ return async function notfound(ctx: ContextDelegation, next: Next) {
5
10
  await next();
6
11
 
7
12
  if (ctx.status !== 404 || ctx.body) {
@@ -0,0 +1,3 @@
1
+ import override from 'koa-override';
2
+
3
+ export default override;
@@ -0,0 +1,68 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { readFile } from 'node:fs/promises';
4
+ import type { Next, ContextDelegation } from '../../lib/egg.js';
5
+
6
+ export type SiteFileContentFun = (ctx: ContextDelegation) => Promise<Buffer | string>;
7
+
8
+ export interface SiteFileMiddlewareOptions {
9
+ enable: boolean;
10
+ cacheControl: string;
11
+ [key: string]: string | Buffer | boolean | SiteFileContentFun | URL;
12
+ }
13
+
14
+ const BUFFER_CACHE = Symbol('siteFile URL buffer cache');
15
+
16
+ export default (options: SiteFileMiddlewareOptions) => {
17
+ return async function siteFile(ctx: ContextDelegation, next: Next) {
18
+ if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {
19
+ return next();
20
+ }
21
+ if (ctx.path[0] !== '/') {
22
+ return next();
23
+ }
24
+
25
+ let content = options[ctx.path];
26
+ if (!content) {
27
+ return next();
28
+ }
29
+
30
+ // '/favicon.ico': 'https://eggjs.org/favicon.ico' or '/favicon.ico': async (ctx) => 'https://eggjs.org/favicon.ico'
31
+ // content is function
32
+ if (typeof content === 'function') {
33
+ content = await content(ctx);
34
+ }
35
+ // content is url
36
+ if (typeof content === 'string') {
37
+ return ctx.redirect(content);
38
+ }
39
+
40
+ // URL
41
+ if (content instanceof URL) {
42
+ if (content.protocol !== 'file:') {
43
+ return ctx.redirect(content.href);
44
+ }
45
+ // protocol = file:
46
+ let buffer = Reflect.get(content, BUFFER_CACHE) as Buffer;
47
+ if (!buffer) {
48
+ buffer = await readFile(fileURLToPath(content));
49
+ Reflect.set(content, BUFFER_CACHE, buffer);
50
+ }
51
+ ctx.set('cache-control', options.cacheControl);
52
+ ctx.body = content;
53
+ ctx.type = path.extname(ctx.path);
54
+ return;
55
+ }
56
+
57
+ // '/robots.txt': Buffer <xx..
58
+ // content is buffer
59
+ if (Buffer.isBuffer(content)) {
60
+ ctx.set('cache-control', options.cacheControl);
61
+ ctx.body = content;
62
+ ctx.type = path.extname(ctx.path);
63
+ return;
64
+ }
65
+
66
+ return next();
67
+ };
68
+ };
@@ -1,18 +1,16 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const path = require('path');
1
+ import path from 'node:path';
2
+ import { pathToFileURL } from 'node:url';
3
+ import type { EggAppInfo } from '@eggjs/core';
4
+ import type { EggAppConfig } from '../lib/type.js';
5
+ import { getSourceFile } from '../lib/utils.js';
5
6
 
6
7
  /**
7
8
  * The configuration of egg application, can be access by `app.config`
8
9
  * @class Config
9
10
  * @since 1.0.0
10
11
  */
11
-
12
- module.exports = appInfo => {
13
-
14
- const config = {
15
-
12
+ export default (appInfo: EggAppInfo) => {
13
+ const config: Partial<EggAppConfig> = {
16
14
  /**
17
15
  * The environment of egg
18
16
  * @member {String} Config#env
@@ -131,7 +129,7 @@ module.exports = appInfo => {
131
129
  HOME: appInfo.HOME,
132
130
 
133
131
  /**
134
- * The directory of server running. You can find `application_config.json` under it that is dumpped from `app.config`.
132
+ * The directory of server running. You can find `application_config.json` under it that is dumped from `app.config`.
135
133
  * @member {String} Config#rundir
136
134
  * @default
137
135
  * @since 1.0.0
@@ -153,7 +151,7 @@ module.exports = appInfo => {
153
151
  /secret/i,
154
152
  ]),
155
153
  timing: {
156
- // if boot action >= slowBootActionMinDuration, egg core will print it to warnning log
154
+ // if boot action >= slowBootActionMinDuration, egg core will print it to warning log
157
155
  slowBootActionMinDuration: 5000,
158
156
  },
159
157
  },
@@ -176,7 +174,7 @@ module.exports = appInfo => {
176
174
  };
177
175
 
178
176
  /**
179
- * The option of `notfound` middleware
177
+ * The options of `notfound` middleware
180
178
  *
181
179
  * It will return page or json depend on negotiation when 404,
182
180
  * If pageUrl is set, it will redirect to the page.
@@ -185,13 +183,14 @@ module.exports = appInfo => {
185
183
  * @property {String} pageUrl - the 404 page url
186
184
  */
187
185
  config.notfound = {
186
+ enable: true,
188
187
  pageUrl: '',
189
188
  };
190
189
 
191
190
  /**
192
191
  * The option of `siteFile` middleware
193
192
  *
194
- * You can map some files using this options, it will response immdiately when matching.
193
+ * You can map some files using this options, it will response immediately when matching.
195
194
  *
196
195
  * @member {Object} Config#siteFile - key is path, and value is url or buffer.
197
196
  * @property {String} cacheControl - files cache , default is public, max-age=2592000
@@ -202,13 +201,14 @@ module.exports = appInfo => {
202
201
  * };
203
202
  */
204
203
  config.siteFile = {
205
- '/favicon.ico': fs.readFileSync(path.join(__dirname, 'favicon.png')),
204
+ enable: true,
205
+ '/favicon.ico': pathToFileURL(getSourceFile('config/favicon.png')),
206
206
  // default cache in 30 days
207
207
  cacheControl: 'public, max-age=2592000',
208
208
  };
209
209
 
210
210
  /**
211
- * The option of `bodyParser` middleware
211
+ * The options of `bodyParser` middleware
212
212
  *
213
213
  * @member Config#bodyParser
214
214
  * @property {Boolean} enable - enable bodyParser or not, default is true
@@ -236,8 +236,9 @@ module.exports = appInfo => {
236
236
  depth: 5,
237
237
  parameterLimit: 1000,
238
238
  },
239
+ onProtoPoisoning: 'error',
239
240
  onerror(err, ctx) {
240
- err.message += ', check bodyParser config';
241
+ err.message = `${err.message}, check bodyParser config`;
241
242
  if (ctx.status === 404) {
242
243
  // set default status to 400, meaning client bad request
243
244
  ctx.status = 400;
@@ -264,8 +265,7 @@ module.exports = appInfo => {
264
265
  * @property {String} agentLogName - file name of agent worker log
265
266
  * @property {Object} coreLogger - custom config of coreLogger
266
267
  * @property {Boolean} allowDebugAtProd - allow debug log at prod, defaults to false
267
- * @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.
268
- * @property {Boolean} enableFastContextLogger - using the app logger instead of EggContextLogger, defaults to false
268
+ * @property {Boolean} enableFastContextLogger - using the app logger instead of EggContextLogger, defaults to true
269
269
  */
270
270
  config.logger = {
271
271
  dir: path.join(appInfo.root, 'logs', appInfo.name),
@@ -282,8 +282,7 @@ module.exports = appInfo => {
282
282
  errorLogName: 'common-error.log',
283
283
  coreLogger: {},
284
284
  allowDebugAtProd: false,
285
- enablePerformanceTimer: false,
286
- enableFastContextLogger: false,
285
+ enableFastContextLogger: true,
287
286
  };
288
287
 
289
288
  /**
@@ -303,39 +302,20 @@ module.exports = appInfo => {
303
302
  * @property {Number} httpsAgent.freeSocketTimeout - httpss agent socket keepalive max free time, default is 4000 ms.
304
303
  * @property {Number} httpsAgent.maxSockets - https agent max socket number of one host, default is `Number.MAX_SAFE_INTEGER` @ses https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
305
304
  * @property {Number} httpsAgent.maxFreeSockets - https agent max free socket number of one host, default is 256.
306
- * @property {Boolean} useHttpClientNext - use urllib@3 HttpClient, default is false
307
- * @property {Boolean} allowH2 - use urllib@4 HttpClient and enable H2, default is false. Only works on Node.js >= 18
305
+ * @property {Boolean} useHttpClientNext - use urllib@3 HttpClient
308
306
  */
309
307
  config.httpclient = {
310
- enableDNSCache: false,
311
- dnsCacheLookupInterval: 10000,
312
- dnsCacheMaxLength: 1000,
313
-
314
308
  request: {
315
309
  timeout: 5000,
316
310
  },
317
- httpAgent: {
318
- keepAlive: true,
319
- freeSocketTimeout: 4000,
320
- maxSockets: Number.MAX_SAFE_INTEGER,
321
- maxFreeSockets: 256,
322
- },
323
- httpsAgent: {
324
- keepAlive: true,
325
- freeSocketTimeout: 4000,
326
- maxSockets: Number.MAX_SAFE_INTEGER,
327
- maxFreeSockets: 256,
328
- },
329
- useHttpClientNext: false,
330
- // allowH2: false,
331
311
  };
332
312
 
333
313
  /**
334
- * The option of `meta` middleware
314
+ * The options of `meta` middleware
335
315
  *
336
316
  * @member Config#meta
337
- * @property {Boolean} enable - enable meta or not, default is true
338
- * @property {Boolean} logging - enable logging start request, default is false
317
+ * @property {Boolean} enable - enable meta or not, default is `true`
318
+ * @property {Boolean} logging - enable logging start request, default is `false`
339
319
  */
340
320
  config.meta = {
341
321
  enable: true,
@@ -371,7 +351,7 @@ module.exports = appInfo => {
371
351
  config.serverTimeout = null;
372
352
 
373
353
  /**
374
- *
354
+ * The options of cluster
375
355
  * @member {Object} Config#cluster
376
356
  * @property {Object} listen - listen options, see {@link https://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback}
377
357
  * @property {String} listen.path - set a unix sock path when server listen
@@ -418,7 +398,7 @@ module.exports = appInfo => {
418
398
  * };
419
399
  * }
420
400
  */
421
- config.onClientError = null;
401
+ config.onClientError = undefined;
422
402
 
423
403
  return config;
424
404
  };
@@ -0,0 +1,11 @@
1
+ import type { EggAppConfig } from '../lib/type.js';
2
+
3
+ export default () => {
4
+ return {
5
+ logger: {
6
+ coreLogger: {
7
+ consoleLevel: 'WARN',
8
+ },
9
+ },
10
+ } satisfies Partial<EggAppConfig>;
11
+ };
@@ -0,0 +1,10 @@
1
+ import type { EggAppConfig } from '../lib/type.js';
2
+
3
+ export default () => {
4
+ return {
5
+ logger: {
6
+ consoleLevel: 'WARN',
7
+ buffer: false,
8
+ },
9
+ } satisfies Partial<EggAppConfig>;
10
+ };
Binary file