egg 3.26.0 → 4.0.0-beta.0
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.
- package/README.md +1 -1
- package/README.zh-CN.md +6 -5
- package/dist/commonjs/agent.d.ts +4 -0
- package/dist/commonjs/agent.js +10 -0
- package/dist/commonjs/app/middleware/body_parser.d.ts +2 -0
- package/dist/commonjs/app/middleware/body_parser.js +8 -0
- package/dist/commonjs/app/middleware/meta.d.ts +11 -0
- package/dist/commonjs/app/middleware/meta.js +22 -0
- package/dist/commonjs/app/middleware/notfound.d.ts +8 -0
- package/dist/commonjs/app/middleware/notfound.js +31 -0
- package/dist/commonjs/app/middleware/override_method.d.ts +2 -0
- package/dist/commonjs/app/middleware/override_method.js +8 -0
- package/dist/commonjs/app/middleware/site_file.d.ts +7 -0
- package/dist/commonjs/app/middleware/site_file.js +40 -0
- package/dist/commonjs/config/config.default.d.ts +9 -0
- package/dist/commonjs/config/config.default.js +378 -0
- package/dist/commonjs/config/config.local.d.ts +8 -0
- package/dist/commonjs/config/config.local.js +12 -0
- package/dist/commonjs/config/config.unittest.d.ts +7 -0
- package/dist/commonjs/config/config.unittest.js +11 -0
- package/dist/commonjs/config/plugin.d.ts +122 -0
- package/dist/commonjs/config/plugin.js +125 -0
- package/dist/commonjs/index.d.ts +61 -0
- package/dist/commonjs/index.js +89 -0
- package/dist/commonjs/lib/agent.d.ts +19 -0
- package/dist/commonjs/lib/agent.js +58 -0
- package/dist/commonjs/lib/application.d.ts +66 -0
- package/dist/commonjs/lib/application.js +281 -0
- package/dist/commonjs/lib/core/base_context_class.d.ts +14 -0
- package/dist/commonjs/lib/core/base_context_class.js +22 -0
- package/dist/commonjs/lib/core/base_context_logger.d.ts +36 -0
- package/dist/commonjs/lib/core/base_context_logger.js +64 -0
- package/dist/commonjs/lib/core/base_hook_class.d.ts +11 -0
- package/dist/commonjs/lib/core/base_hook_class.js +30 -0
- package/dist/commonjs/lib/core/context_httpclient.d.ts +16 -0
- package/dist/commonjs/lib/core/context_httpclient.js +30 -0
- package/dist/commonjs/lib/core/httpclient.d.ts +14 -0
- package/dist/commonjs/lib/core/httpclient.js +40 -0
- package/dist/commonjs/lib/core/logger.d.ts +3 -0
- package/dist/commonjs/lib/core/logger.js +40 -0
- package/dist/commonjs/lib/core/messenger/IMessenger.d.ts +50 -0
- package/dist/commonjs/lib/core/messenger/IMessenger.js +3 -0
- package/dist/commonjs/lib/core/messenger/index.d.ts +7 -0
- package/dist/commonjs/lib/core/messenger/index.js +14 -0
- package/dist/commonjs/lib/core/messenger/ipc.d.ts +57 -0
- package/dist/commonjs/lib/core/messenger/ipc.js +126 -0
- package/dist/commonjs/lib/core/messenger/local.d.ts +61 -0
- package/dist/commonjs/lib/core/messenger/local.js +134 -0
- package/dist/commonjs/lib/core/singleton.d.ts +23 -0
- package/dist/commonjs/lib/core/singleton.js +120 -0
- package/dist/commonjs/lib/core/utils.d.ts +2 -0
- package/dist/commonjs/lib/core/utils.js +77 -0
- package/dist/commonjs/lib/egg.d.ts +267 -0
- package/dist/commonjs/lib/egg.js +595 -0
- package/dist/commonjs/lib/loader/AgentWorkerLoader.d.ts +12 -0
- package/dist/commonjs/lib/loader/AgentWorkerLoader.js +24 -0
- package/dist/commonjs/lib/loader/AppWorkerLoader.d.ts +17 -0
- package/dist/commonjs/lib/loader/AppWorkerLoader.js +43 -0
- package/dist/commonjs/lib/loader/EggApplicationLoader.d.ts +4 -0
- package/dist/commonjs/lib/loader/EggApplicationLoader.js +8 -0
- package/dist/commonjs/lib/loader/index.d.ts +3 -0
- package/dist/commonjs/lib/loader/index.js +22 -0
- package/dist/commonjs/lib/start.d.ts +15 -0
- package/dist/commonjs/lib/start.js +49 -0
- package/dist/commonjs/lib/type.d.ts +295 -0
- package/dist/commonjs/lib/type.js +3 -0
- package/dist/commonjs/package.json +3 -0
- package/dist/esm/agent.d.ts +4 -0
- package/dist/esm/agent.js +7 -0
- package/dist/esm/app/middleware/body_parser.d.ts +2 -0
- package/dist/esm/app/middleware/body_parser.js +3 -0
- package/dist/esm/app/middleware/meta.d.ts +11 -0
- package/dist/esm/app/middleware/meta.js +20 -0
- package/dist/esm/app/middleware/notfound.d.ts +8 -0
- package/dist/esm/app/middleware/notfound.js +29 -0
- package/dist/esm/app/middleware/override_method.d.ts +2 -0
- package/dist/esm/app/middleware/override_method.js +3 -0
- package/dist/esm/app/middleware/site_file.d.ts +7 -0
- package/dist/esm/app/middleware/site_file.js +35 -0
- package/dist/esm/config/config.default.d.ts +9 -0
- package/dist/esm/config/config.default.js +373 -0
- package/dist/esm/config/config.local.d.ts +8 -0
- package/dist/esm/config/config.local.js +10 -0
- package/dist/esm/config/config.unittest.d.ts +7 -0
- package/dist/esm/config/config.unittest.js +9 -0
- package/dist/esm/config/favicon.png +0 -0
- package/dist/esm/config/plugin.d.ts +122 -0
- package/dist/esm/config/plugin.js +123 -0
- package/dist/esm/index.d.ts +61 -0
- package/dist/esm/index.js +65 -0
- package/dist/esm/lib/agent.d.ts +19 -0
- package/dist/esm/lib/agent.js +54 -0
- package/dist/esm/lib/application.d.ts +66 -0
- package/dist/esm/lib/application.js +274 -0
- package/dist/esm/lib/core/base_context_class.d.ts +14 -0
- package/dist/esm/lib/core/base_context_class.js +18 -0
- package/dist/esm/lib/core/base_context_logger.d.ts +36 -0
- package/dist/esm/lib/core/base_context_logger.js +60 -0
- package/dist/esm/lib/core/base_hook_class.d.ts +11 -0
- package/dist/esm/lib/core/base_hook_class.js +23 -0
- package/dist/esm/lib/core/context_httpclient.d.ts +16 -0
- package/dist/esm/lib/core/context_httpclient.js +26 -0
- package/dist/esm/lib/core/httpclient.d.ts +14 -0
- package/dist/esm/lib/core/httpclient.js +33 -0
- package/dist/esm/lib/core/logger.d.ts +3 -0
- package/dist/esm/lib/core/logger.js +37 -0
- package/dist/esm/lib/core/messenger/IMessenger.d.ts +50 -0
- package/dist/esm/lib/core/messenger/IMessenger.js +2 -0
- package/dist/esm/lib/core/messenger/index.d.ts +7 -0
- package/dist/esm/lib/core/messenger/index.js +11 -0
- package/dist/esm/lib/core/messenger/ipc.d.ts +57 -0
- package/dist/esm/lib/core/messenger/ipc.js +119 -0
- package/dist/esm/lib/core/messenger/local.d.ts +61 -0
- package/dist/esm/lib/core/messenger/local.js +127 -0
- package/dist/esm/lib/core/singleton.d.ts +23 -0
- package/dist/esm/lib/core/singleton.js +113 -0
- package/dist/esm/lib/core/utils.d.ts +2 -0
- package/dist/esm/lib/core/utils.js +70 -0
- package/dist/esm/lib/egg.d.ts +267 -0
- package/dist/esm/lib/egg.js +565 -0
- package/dist/esm/lib/loader/AgentWorkerLoader.d.ts +12 -0
- package/dist/esm/lib/loader/AgentWorkerLoader.js +20 -0
- package/dist/esm/lib/loader/AppWorkerLoader.d.ts +17 -0
- package/dist/esm/lib/loader/AppWorkerLoader.js +39 -0
- package/dist/esm/lib/loader/EggApplicationLoader.d.ts +4 -0
- package/dist/esm/lib/loader/EggApplicationLoader.js +4 -0
- package/dist/esm/lib/loader/index.d.ts +3 -0
- package/dist/esm/lib/loader/index.js +4 -0
- package/dist/esm/lib/start.d.ts +15 -0
- package/dist/esm/lib/start.js +43 -0
- package/dist/esm/lib/type.d.ts +295 -0
- package/dist/esm/lib/type.js +2 -0
- package/dist/esm/package.json +3 -0
- package/dist/package.json +4 -0
- package/package.json +83 -70
- package/src/agent.ts +7 -0
- package/src/app/middleware/body_parser.ts +3 -0
- package/{app/middleware/meta.js → src/app/middleware/meta.ts} +12 -4
- package/{app/middleware/notfound.js → src/app/middleware/notfound.ts} +9 -3
- package/src/app/middleware/override_method.ts +3 -0
- package/src/app/middleware/site_file.ts +49 -0
- package/{config/config.default.js → src/config/config.default.ts} +21 -42
- package/src/config/config.local.ts +11 -0
- package/src/config/config.unittest.ts +10 -0
- package/src/config/favicon.png +0 -0
- package/{config/plugin.js → src/config/plugin.ts} +1 -3
- package/src/index.ts +78 -0
- package/src/lib/agent.ts +66 -0
- package/{lib/application.js → src/lib/application.ts} +79 -120
- package/src/lib/core/base_context_class.ts +21 -0
- package/src/lib/core/base_context_logger.ts +67 -0
- package/src/lib/core/base_hook_class.ts +30 -0
- package/src/lib/core/context_httpclient.ts +33 -0
- package/src/lib/core/httpclient.ts +52 -0
- package/src/lib/core/logger.ts +42 -0
- package/src/lib/core/messenger/IMessenger.ts +58 -0
- package/src/lib/core/messenger/index.ts +15 -0
- package/{lib/core/messenger/ipc.js → src/lib/core/messenger/ipc.ts} +25 -29
- package/{lib/core/messenger/local.js → src/lib/core/messenger/local.ts} +27 -21
- package/{lib/core/singleton.js → src/lib/core/singleton.ts} +56 -33
- package/src/lib/core/utils.ts +77 -0
- package/{lib/egg.js → src/lib/egg.ts} +252 -218
- package/src/lib/loader/AgentWorkerLoader.ts +21 -0
- package/src/lib/loader/AppWorkerLoader.ts +42 -0
- package/src/lib/loader/EggApplicationLoader.ts +5 -0
- package/src/lib/loader/index.ts +3 -0
- package/src/lib/start.ts +56 -0
- package/src/lib/type.ts +329 -0
- package/agent.js +0 -11
- package/app/middleware/body_parser.js +0 -3
- package/app/middleware/override_method.js +0 -3
- package/app/middleware/site_file.js +0 -31
- package/config/config.local.js +0 -7
- package/config/config.unittest.js +0 -8
- package/index.d.ts +0 -1285
- package/index.js +0 -68
- package/lib/agent.js +0 -95
- package/lib/core/base_context_class.js +0 -20
- package/lib/core/base_context_logger.js +0 -64
- package/lib/core/base_hook_class.js +0 -31
- package/lib/core/context_httpclient.js +0 -26
- package/lib/core/dnscache_httpclient.js +0 -93
- package/lib/core/httpclient.js +0 -108
- package/lib/core/httpclient_next.js +0 -45
- package/lib/core/logger.js +0 -35
- package/lib/core/messenger/index.js +0 -14
- package/lib/core/utils.js +0 -73
- package/lib/loader/agent_worker_loader.js +0 -27
- package/lib/loader/app_worker_loader.js +0 -48
- package/lib/loader/index.js +0 -5
- package/lib/start.js +0 -39
- /package/{config → dist/commonjs/config}/favicon.png +0 -0
- /package/{app → src/app}/extend/context.js +0 -0
- /package/{app → src/app}/extend/helper.js +0 -0
- /package/{app → src/app}/extend/request.js +0 -0
- /package/{app → src/app}/extend/response.js +0 -0
|
@@ -1,27 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import http from 'node:http';
|
|
4
|
+
import { Socket } from 'node:net';
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
import graceful from 'graceful';
|
|
8
|
+
import { assign } from 'utility';
|
|
9
|
+
import { utils as eggUtils } from '@eggjs/core';
|
|
10
|
+
import { EggApplicationCore, EggContext, EggApplicationCoreOptions } from './egg.js';
|
|
11
|
+
import { AppWorkerLoader } from './loader/index.js';
|
|
12
|
+
import { BaseContextClass } from './core/base_context_class.js';
|
|
2
13
|
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const ms = require('ms');
|
|
6
|
-
const is = require('is-type-of');
|
|
7
|
-
const graceful = require('graceful');
|
|
8
|
-
const http = require('http');
|
|
9
|
-
const cluster = require('cluster-client');
|
|
10
|
-
const onFinished = require('on-finished');
|
|
11
|
-
const { assign } = require('utility');
|
|
12
|
-
const eggUtils = require('egg-core').utils;
|
|
13
|
-
const EggApplication = require('./egg');
|
|
14
|
-
const AppWorkerLoader = require('./loader').AppWorkerLoader;
|
|
15
|
-
|
|
16
|
-
const KEYS = Symbol('Application#keys');
|
|
17
|
-
const HELPER = Symbol('Application#Helper');
|
|
18
|
-
const LOCALS = Symbol('Application#locals');
|
|
19
|
-
const BIND_EVENTS = Symbol('Application#bindEvents');
|
|
20
|
-
const WARN_CONFUSED_CONFIG = Symbol('Application#warnConfusedConfig');
|
|
21
14
|
const EGG_LOADER = Symbol.for('egg#loader');
|
|
22
|
-
const EGG_PATH = Symbol.for('egg#eggPath');
|
|
23
|
-
const CLUSTER_CLIENTS = Symbol.for('egg#clusterClients');
|
|
24
|
-
const RESPONSE_RAW = Symbol('Application#responseRaw');
|
|
25
15
|
|
|
26
16
|
// client error => 400 Bad Request
|
|
27
17
|
// Refs: https://nodejs.org/dist/latest-v8.x/docs/api/http.html#http_event_clienterror
|
|
@@ -38,59 +28,60 @@ const DEFAULT_BAD_REQUEST_RESPONSE =
|
|
|
38
28
|
`\r\n\r\n${DEFAULT_BAD_REQUEST_HTML}`;
|
|
39
29
|
|
|
40
30
|
// Refs: https://github.com/nodejs/node/blob/b38c81/lib/_http_outgoing.js#L706-L710
|
|
41
|
-
function escapeHeaderValue(value) {
|
|
31
|
+
function escapeHeaderValue(value: string) {
|
|
42
32
|
// Protect against response splitting. The regex test is there to
|
|
43
33
|
// minimize the performance impact in the common case.
|
|
44
34
|
return /[\r\n]/.test(value) ? value.replace(/[\r\n]+[ \t]*/g, '') : value;
|
|
45
35
|
}
|
|
46
36
|
|
|
47
|
-
// Refs: https://github.com/nodejs/node/blob/b38c81/lib/_http_outgoing.js#L706-L710
|
|
48
37
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
38
|
+
* The Helper class which can be used as utility function.
|
|
39
|
+
* We support developers to extend Helper through ${baseDir}/app/extend/helper.js ,
|
|
40
|
+
* then you can use all method on `ctx.helper` that is a instance of Helper.
|
|
51
41
|
*/
|
|
52
|
-
class
|
|
42
|
+
class HelperClass extends BaseContextClass {}
|
|
53
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Singleton instance in App Worker, extend {@link EggApplicationCore}
|
|
46
|
+
* @augments EggApplicationCore
|
|
47
|
+
*/
|
|
48
|
+
export class Application extends EggApplicationCore {
|
|
49
|
+
// will auto set after 'server' event emit
|
|
50
|
+
server?: http.Server;
|
|
51
|
+
#locals: Record<string, any> = {};
|
|
54
52
|
/**
|
|
55
|
-
* @
|
|
56
|
-
* @
|
|
53
|
+
* reference to {@link Helper}
|
|
54
|
+
* @member {Helper} Application#Helper
|
|
57
55
|
*/
|
|
58
|
-
|
|
59
|
-
options.type = 'application';
|
|
60
|
-
super(options);
|
|
61
|
-
|
|
62
|
-
// will auto set after 'server' event emit
|
|
63
|
-
this.server = null;
|
|
56
|
+
Helper = HelperClass;
|
|
64
57
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this.dumpConfig();
|
|
76
|
-
this.coreLogger.info('[egg:core] dump config after load, %s', ms(Date.now() - dumpStartTime));
|
|
58
|
+
/**
|
|
59
|
+
* @class
|
|
60
|
+
* @param {Object} options - see {@link EggApplicationCore}
|
|
61
|
+
*/
|
|
62
|
+
constructor(options?: Omit<EggApplicationCoreOptions, 'type'>) {
|
|
63
|
+
super({
|
|
64
|
+
...options,
|
|
65
|
+
type: 'application',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
77
68
|
|
|
78
|
-
|
|
79
|
-
|
|
69
|
+
protected async load() {
|
|
70
|
+
await super.load();
|
|
71
|
+
this.#warnConfusedConfig();
|
|
72
|
+
this.#bindEvents();
|
|
80
73
|
}
|
|
81
74
|
|
|
82
75
|
get [EGG_LOADER]() {
|
|
83
76
|
return AppWorkerLoader;
|
|
84
77
|
}
|
|
85
78
|
|
|
86
|
-
|
|
87
|
-
return path.join(__dirname, '..');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
[RESPONSE_RAW](socket, raw) {
|
|
79
|
+
#responseRaw(socket: Socket, raw?: any) {
|
|
91
80
|
/* istanbul ignore next */
|
|
92
81
|
if (!socket.writable) return;
|
|
93
|
-
if (!raw)
|
|
82
|
+
if (!raw) {
|
|
83
|
+
return socket.end(DEFAULT_BAD_REQUEST_RESPONSE);
|
|
84
|
+
}
|
|
94
85
|
|
|
95
86
|
const body = (raw.body == null) ? DEFAULT_BAD_REQUEST_HTML : raw.body;
|
|
96
87
|
const headers = raw.headers || {};
|
|
@@ -114,10 +105,10 @@ class Application extends EggApplication {
|
|
|
114
105
|
socket.end(`${firstLine}\r\n${responseHeaderLines}\r\n${body.toString()}`);
|
|
115
106
|
}
|
|
116
107
|
|
|
117
|
-
onClientError(err, socket) {
|
|
108
|
+
onClientError(err: any, socket: Socket) {
|
|
118
109
|
// ignore when there is no http body, it almost like an ECONNRESET
|
|
119
110
|
if (err.rawPacket) {
|
|
120
|
-
this.logger.warn('A client (%s:%d) error [%s] occurred: %s',
|
|
111
|
+
this.logger.warn('[egg:application] A client (%s:%d) error [%s] occurred: %s',
|
|
121
112
|
socket.remoteAddress,
|
|
122
113
|
socket.remotePort,
|
|
123
114
|
err.code,
|
|
@@ -143,19 +134,19 @@ class Application extends EggApplication {
|
|
|
143
134
|
// + headers: {}
|
|
144
135
|
// + status: 400
|
|
145
136
|
p.then(ret => {
|
|
146
|
-
this
|
|
137
|
+
this.#responseRaw(socket, ret || {});
|
|
147
138
|
}).catch(err => {
|
|
148
139
|
this.logger.error(err);
|
|
149
|
-
this
|
|
140
|
+
this.#responseRaw(socket);
|
|
150
141
|
});
|
|
151
142
|
} else {
|
|
152
143
|
// because it's a raw socket object, we should return the raw HTTP response
|
|
153
144
|
// packet.
|
|
154
|
-
this
|
|
145
|
+
this.#responseRaw(socket);
|
|
155
146
|
}
|
|
156
147
|
}
|
|
157
148
|
|
|
158
|
-
onServer(server) {
|
|
149
|
+
onServer(server: http.Server) {
|
|
159
150
|
// expose app.server
|
|
160
151
|
this.server = server;
|
|
161
152
|
// set ignore code
|
|
@@ -164,14 +155,14 @@ class Application extends EggApplication {
|
|
|
164
155
|
/* istanbul ignore next */
|
|
165
156
|
graceful({
|
|
166
157
|
server: [ server ],
|
|
167
|
-
error: (err, throwErrorCount) => {
|
|
158
|
+
error: (err: Error, throwErrorCount: number) => {
|
|
168
159
|
const originMessage = err.message;
|
|
169
160
|
if (originMessage) {
|
|
170
161
|
// shouldjs will override error property but only getter
|
|
171
162
|
// https://github.com/shouldjs/should.js/blob/889e22ebf19a06bc2747d24cf34b25cc00b37464/lib/assertion-error.js#L26
|
|
172
163
|
Object.defineProperty(err, 'message', {
|
|
173
164
|
get() {
|
|
174
|
-
return originMessage
|
|
165
|
+
return `${originMessage} (uncaughtException throw ${throwErrorCount} times on pid: ${process.pid})`;
|
|
175
166
|
},
|
|
176
167
|
configurable: true,
|
|
177
168
|
enumerable: false,
|
|
@@ -182,10 +173,12 @@ class Application extends EggApplication {
|
|
|
182
173
|
ignoreCode: serverGracefulIgnoreCode,
|
|
183
174
|
});
|
|
184
175
|
|
|
185
|
-
server.on('clientError', (err, socket) => this.onClientError(err, socket));
|
|
176
|
+
server.on('clientError', (err, socket) => this.onClientError(err, socket as Socket));
|
|
186
177
|
|
|
187
178
|
// server timeout
|
|
188
|
-
if (
|
|
179
|
+
if (typeof this.config.serverTimeout === 'number') {
|
|
180
|
+
server.setTimeout(this.config.serverTimeout);
|
|
181
|
+
}
|
|
189
182
|
}
|
|
190
183
|
|
|
191
184
|
/**
|
|
@@ -194,24 +187,11 @@ class Application extends EggApplication {
|
|
|
194
187
|
* @see Context#locals
|
|
195
188
|
*/
|
|
196
189
|
get locals() {
|
|
197
|
-
|
|
198
|
-
this[LOCALS] = {};
|
|
199
|
-
}
|
|
200
|
-
return this[LOCALS];
|
|
190
|
+
return this.#locals;
|
|
201
191
|
}
|
|
202
192
|
|
|
203
|
-
set locals(val) {
|
|
204
|
-
|
|
205
|
-
this[LOCALS] = {};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
assign(this[LOCALS], val);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
handleRequest(ctx, fnMiddleware) {
|
|
212
|
-
this.emit('request', ctx);
|
|
213
|
-
onFinished(ctx.res, () => this.emit('response', ctx));
|
|
214
|
-
return super.handleRequest(ctx, fnMiddleware);
|
|
193
|
+
set locals(val: Record<string, any>) {
|
|
194
|
+
assign(this.#locals, val);
|
|
215
195
|
}
|
|
216
196
|
|
|
217
197
|
/**
|
|
@@ -234,11 +214,11 @@ class Application extends EggApplication {
|
|
|
234
214
|
paramNames: layer.paramNames,
|
|
235
215
|
path: layer.path,
|
|
236
216
|
regexp: layer.regexp.toString(),
|
|
237
|
-
stack: layer.stack.map(stack => stack[FULLPATH] || stack._name || stack.name || 'anonymous'),
|
|
217
|
+
stack: layer.stack.map((stack: any) => stack[FULLPATH] || stack._name || stack.name || 'anonymous'),
|
|
238
218
|
});
|
|
239
219
|
}
|
|
240
220
|
fs.writeFileSync(dumpRouterFile, JSON.stringify(routers, null, 2));
|
|
241
|
-
} catch (err) {
|
|
221
|
+
} catch (err: any) {
|
|
242
222
|
this.coreLogger.warn(`dumpConfig router.json error: ${err.message}`);
|
|
243
223
|
}
|
|
244
224
|
}
|
|
@@ -248,9 +228,11 @@ class Application extends EggApplication {
|
|
|
248
228
|
* @see Context#runInBackground
|
|
249
229
|
* @param {Function} scope - the first args is an anonymous ctx
|
|
250
230
|
*/
|
|
251
|
-
runInBackground(scope) {
|
|
231
|
+
runInBackground(scope: (ctx: EggContext) => void) {
|
|
252
232
|
const ctx = this.createAnonymousContext();
|
|
253
|
-
if (!scope.name)
|
|
233
|
+
if (!scope.name) {
|
|
234
|
+
Reflect.set(scope, '_name', eggUtils.getCalleeFromStack(true));
|
|
235
|
+
}
|
|
254
236
|
this.ctxStorage.run(ctx, () => {
|
|
255
237
|
ctx.runInBackground(scope);
|
|
256
238
|
});
|
|
@@ -262,11 +244,13 @@ class Application extends EggApplication {
|
|
|
262
244
|
* @param {Function} scope - the first args is an anonymous ctx, scope should be async function
|
|
263
245
|
* @param {Request} [req] - if you want to mock request like querystring, you can pass an object to this function.
|
|
264
246
|
*/
|
|
265
|
-
async runInAnonymousContextScope(scope
|
|
247
|
+
async runInAnonymousContextScope(scope: (ctx: EggContext) => Promise<void>, req?: unknown) {
|
|
266
248
|
const ctx = this.createAnonymousContext(req);
|
|
267
|
-
if (!scope.name)
|
|
249
|
+
if (!scope.name) {
|
|
250
|
+
Reflect.set(scope, '_name', eggUtils.getCalleeFromStack(true));
|
|
251
|
+
}
|
|
268
252
|
return await this.ctxStorage.run(ctx, async () => {
|
|
269
|
-
return await scope(ctx);
|
|
253
|
+
return await scope(ctx as EggContext);
|
|
270
254
|
});
|
|
271
255
|
}
|
|
272
256
|
|
|
@@ -275,7 +259,7 @@ class Application extends EggApplication {
|
|
|
275
259
|
* @member {String} Application#keys
|
|
276
260
|
*/
|
|
277
261
|
get keys() {
|
|
278
|
-
if (!this
|
|
262
|
+
if (!this._keys) {
|
|
279
263
|
if (!this.config.keys) {
|
|
280
264
|
if (this.config.env === 'local' || this.config.env === 'unittest') {
|
|
281
265
|
const configPath = path.join(this.config.baseDir, 'config/config.default.js');
|
|
@@ -284,31 +268,9 @@ class Application extends EggApplication {
|
|
|
284
268
|
}
|
|
285
269
|
throw new Error('Please set config.keys first');
|
|
286
270
|
}
|
|
287
|
-
|
|
288
|
-
this[KEYS] = this.config.keys.split(',').map(s => s.trim());
|
|
289
|
-
}
|
|
290
|
-
return this[KEYS];
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
set keys(_) {
|
|
294
|
-
// ignore
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* reference to {@link Helper}
|
|
299
|
-
* @member {Helper} Application#Helper
|
|
300
|
-
*/
|
|
301
|
-
get Helper() {
|
|
302
|
-
if (!this[HELPER]) {
|
|
303
|
-
/**
|
|
304
|
-
* The Helper class which can be used as utility function.
|
|
305
|
-
* We support developers to extend Helper through ${baseDir}/app/extend/helper.js ,
|
|
306
|
-
* then you can use all method on `ctx.helper` that is a instance of Helper.
|
|
307
|
-
*/
|
|
308
|
-
class Helper extends this.BaseContextClass {}
|
|
309
|
-
this[HELPER] = Helper;
|
|
271
|
+
this._keys = this.config.keys.split(',').map(s => s.trim());
|
|
310
272
|
}
|
|
311
|
-
return this
|
|
273
|
+
return this._keys;
|
|
312
274
|
}
|
|
313
275
|
|
|
314
276
|
/**
|
|
@@ -316,17 +278,15 @@ class Application extends EggApplication {
|
|
|
316
278
|
*
|
|
317
279
|
* @private
|
|
318
280
|
*/
|
|
319
|
-
|
|
281
|
+
#bindEvents() {
|
|
320
282
|
// Browser Cookie Limits: http://browsercookielimits.squawky.net/
|
|
321
283
|
this.on('cookieLimitExceed', ({ name, value, ctx }) => {
|
|
322
284
|
const err = new Error(`cookie ${name}'s length(${value.length}) exceed the limit(4093)`);
|
|
323
285
|
err.name = 'CookieLimitExceedError';
|
|
324
|
-
err.key = name;
|
|
325
|
-
err.cookie = value;
|
|
326
286
|
ctx.coreLogger.error(err);
|
|
327
287
|
});
|
|
328
288
|
// expose server to support websocket
|
|
329
|
-
this.once('server', server => this.onServer(server));
|
|
289
|
+
this.once('server', (server: http.Server) => this.onServer(server));
|
|
330
290
|
}
|
|
331
291
|
|
|
332
292
|
/**
|
|
@@ -334,15 +294,14 @@ class Application extends EggApplication {
|
|
|
334
294
|
*
|
|
335
295
|
* @private
|
|
336
296
|
*/
|
|
337
|
-
|
|
297
|
+
#warnConfusedConfig() {
|
|
338
298
|
const confusedConfigurations = this.config.confusedConfigurations;
|
|
339
299
|
Object.keys(confusedConfigurations).forEach(key => {
|
|
340
300
|
if (this.config[key] !== undefined) {
|
|
341
|
-
this.logger.warn('Unexpected config key `%
|
|
301
|
+
this.logger.warn('[egg:application] Unexpected config key `%o` exists, Please use `%o` instead.',
|
|
342
302
|
key, confusedConfigurations[key]);
|
|
343
303
|
}
|
|
344
304
|
});
|
|
345
305
|
}
|
|
346
306
|
}
|
|
347
307
|
|
|
348
|
-
module.exports = Application;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseContextClass as EggCoreBaseContextClass } from '@eggjs/core';
|
|
2
|
+
import type { EggContext } from '../egg.js';
|
|
3
|
+
import { BaseContextLogger } from './base_context_logger.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* BaseContextClass is a base class that can be extended,
|
|
7
|
+
* it's instantiated in context level,
|
|
8
|
+
* {@link Helper}, {@link Service} is extending it.
|
|
9
|
+
*/
|
|
10
|
+
export class BaseContextClass extends EggCoreBaseContextClass {
|
|
11
|
+
declare ctx: EggContext;
|
|
12
|
+
protected pathName?: string;
|
|
13
|
+
#logger?: BaseContextLogger;
|
|
14
|
+
|
|
15
|
+
get logger() {
|
|
16
|
+
if (!this.#logger) {
|
|
17
|
+
this.#logger = new BaseContextLogger(this.ctx, this.pathName);
|
|
18
|
+
}
|
|
19
|
+
return this.#logger;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { EggContext } from '../egg.js';
|
|
2
|
+
|
|
3
|
+
export class BaseContextLogger {
|
|
4
|
+
readonly #ctx: EggContext;
|
|
5
|
+
readonly #pathName?: string;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @class
|
|
9
|
+
* @param {Context} ctx - context instance
|
|
10
|
+
* @param {String} pathName - class path name
|
|
11
|
+
* @since 1.0.0
|
|
12
|
+
*/
|
|
13
|
+
constructor(ctx: EggContext, pathName?: string) {
|
|
14
|
+
/**
|
|
15
|
+
* @member {Context} BaseContextLogger#ctx
|
|
16
|
+
* @since 1.2.0
|
|
17
|
+
*/
|
|
18
|
+
this.#ctx = ctx;
|
|
19
|
+
this.#pathName = pathName;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
protected _log(method: 'info' | 'warn' | 'error' | 'debug', args: any[]) {
|
|
23
|
+
// add `[${pathName}]` in log
|
|
24
|
+
if (this.#pathName && typeof args[0] === 'string') {
|
|
25
|
+
args[0] = `[${this.#pathName}] ${args[0]}`;
|
|
26
|
+
}
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
this.#ctx.app.logger[method](...args);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @member {Function} BaseContextLogger#debug
|
|
34
|
+
* @param {...any} args - log msg
|
|
35
|
+
* @since 1.2.0
|
|
36
|
+
*/
|
|
37
|
+
debug(...args: any[]) {
|
|
38
|
+
this._log('debug', args);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @member {Function} BaseContextLogger#info
|
|
43
|
+
* @param {...any} args - log msg
|
|
44
|
+
* @since 1.2.0
|
|
45
|
+
*/
|
|
46
|
+
info(...args: any[]) {
|
|
47
|
+
this._log('info', args);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @member {Function} BaseContextLogger#warn
|
|
52
|
+
* @param {...any} args - log msg
|
|
53
|
+
* @since 1.2.0
|
|
54
|
+
*/
|
|
55
|
+
warn(...args: any[]) {
|
|
56
|
+
this._log('warn', args);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @member {Function} BaseContextLogger#error
|
|
61
|
+
* @param {...any} args - log msg
|
|
62
|
+
* @since 1.2.0
|
|
63
|
+
*/
|
|
64
|
+
error(...args: any[]) {
|
|
65
|
+
this._log('error', args);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import type { ILifecycleBoot } from '@eggjs/core';
|
|
3
|
+
import type { Application, Agent } from '../../index.js';
|
|
4
|
+
|
|
5
|
+
export class BaseHookClass implements ILifecycleBoot {
|
|
6
|
+
fullPath?: string;
|
|
7
|
+
#instance: Application | Agent;
|
|
8
|
+
|
|
9
|
+
constructor(instance: Application | Agent) {
|
|
10
|
+
this.#instance = instance;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
get logger() {
|
|
14
|
+
return this.#instance.logger;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get config() {
|
|
18
|
+
return this.#instance.config;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get app() {
|
|
22
|
+
assert(this.#instance.type === 'application', 'agent boot should not use app instance');
|
|
23
|
+
return this.#instance as Application;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get agent() {
|
|
27
|
+
assert(this.#instance.type === 'agent', 'app boot should not use agent instance');
|
|
28
|
+
return this.#instance as Agent;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { EggContext, EggApplicationCore } from '../egg.js';
|
|
2
|
+
import type {
|
|
3
|
+
HttpClientRequestURL, HttpClientRequestOptions,
|
|
4
|
+
} from './httpclient.js';
|
|
5
|
+
|
|
6
|
+
export class ContextHttpClient {
|
|
7
|
+
ctx: EggContext;
|
|
8
|
+
app: EggApplicationCore;
|
|
9
|
+
|
|
10
|
+
constructor(ctx: EggContext) {
|
|
11
|
+
this.ctx = ctx;
|
|
12
|
+
this.app = ctx.app;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* http request helper base on {@link HttpClient}, it will auto save httpclient log.
|
|
17
|
+
* Keep the same api with {@link Application#curl}.
|
|
18
|
+
*
|
|
19
|
+
* @param {String|Object} url - request url address.
|
|
20
|
+
* @param {Object} [options] - options for request.
|
|
21
|
+
*/
|
|
22
|
+
async curl<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions) {
|
|
23
|
+
options = {
|
|
24
|
+
...options,
|
|
25
|
+
ctx: this.ctx,
|
|
26
|
+
};
|
|
27
|
+
return await this.app.curl<T>(url, options);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async request<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions) {
|
|
31
|
+
return await this.curl<T>(url, options);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { EggCoreContext } from '@eggjs/core';
|
|
2
|
+
import {
|
|
3
|
+
HttpClient as RawHttpClient,
|
|
4
|
+
RequestURL as HttpClientRequestURL,
|
|
5
|
+
RequestOptions,
|
|
6
|
+
} from 'urllib';
|
|
7
|
+
import ms from 'ms';
|
|
8
|
+
import type { EggApplicationCore } from '../egg.js';
|
|
9
|
+
|
|
10
|
+
export type {
|
|
11
|
+
HttpClientResponse,
|
|
12
|
+
RequestURL as HttpClientRequestURL,
|
|
13
|
+
} from 'urllib';
|
|
14
|
+
|
|
15
|
+
export interface HttpClientRequestOptions extends RequestOptions {
|
|
16
|
+
ctx?: EggCoreContext;
|
|
17
|
+
tracer?: unknown;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class HttpClient extends RawHttpClient {
|
|
21
|
+
readonly #app: EggApplicationCore & { tracer?: unknown };
|
|
22
|
+
|
|
23
|
+
constructor(app: EggApplicationCore) {
|
|
24
|
+
normalizeConfig(app);
|
|
25
|
+
const config = app.config.httpclient;
|
|
26
|
+
super({
|
|
27
|
+
defaultArgs: config.request,
|
|
28
|
+
});
|
|
29
|
+
this.#app = app;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async request<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions) {
|
|
33
|
+
options = options ?? {};
|
|
34
|
+
if (options.ctx?.tracer) {
|
|
35
|
+
options.tracer = options.ctx.tracer;
|
|
36
|
+
} else {
|
|
37
|
+
options.tracer = options.tracer ?? this.#app.tracer;
|
|
38
|
+
}
|
|
39
|
+
return await super.request<T>(url, options);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async curl<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions) {
|
|
43
|
+
return await this.request<T>(url, options);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function normalizeConfig(app: EggApplicationCore) {
|
|
48
|
+
const config = app.config.httpclient;
|
|
49
|
+
if (typeof config.request?.timeout === 'string') {
|
|
50
|
+
config.request.timeout = ms(config.request.timeout as string);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { EggLoggers, EggLoggersOptions } from 'egg-logger';
|
|
2
|
+
import { setCustomLogger } from 'onelogger';
|
|
3
|
+
import type { EggApplicationCore } from '../egg.js';
|
|
4
|
+
|
|
5
|
+
export function createLoggers(app: EggApplicationCore) {
|
|
6
|
+
const loggerOptions = {
|
|
7
|
+
...app.config.logger,
|
|
8
|
+
type: app.type,
|
|
9
|
+
localStorage: app.ctxStorage,
|
|
10
|
+
} as EggLoggersOptions;
|
|
11
|
+
|
|
12
|
+
// set DEBUG level into INFO on prod env
|
|
13
|
+
if (app.config.env === 'prod' && loggerOptions.level === 'DEBUG' && !app.config.logger.allowDebugAtProd) {
|
|
14
|
+
loggerOptions.level = 'INFO';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const loggers = new EggLoggers({
|
|
18
|
+
logger: loggerOptions,
|
|
19
|
+
customLogger: app.config.customLogger,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// won't print to console after started, except for local and unittest
|
|
23
|
+
app.ready(() => {
|
|
24
|
+
if (app.config.logger.disableConsoleAfterReady) {
|
|
25
|
+
loggers.disableConsole();
|
|
26
|
+
loggers.coreLogger.info('[egg:lib:core:logger] disable console log after app ready');
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// set global logger
|
|
31
|
+
for (const loggerName of Object.keys(loggers)) {
|
|
32
|
+
setCustomLogger(loggerName, loggers[loggerName]);
|
|
33
|
+
}
|
|
34
|
+
// reset global logger on beforeClose hook
|
|
35
|
+
app.lifecycle.registerBeforeClose(() => {
|
|
36
|
+
for (const loggerName of Object.keys(loggers)) {
|
|
37
|
+
setCustomLogger(loggerName, undefined);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
loggers.coreLogger.info('[egg:lib:core:logger] init all loggers with options: %j', loggerOptions);
|
|
41
|
+
return loggers;
|
|
42
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { EventEmitter } from 'node:events';
|
|
2
|
+
|
|
3
|
+
export interface IMessenger extends EventEmitter {
|
|
4
|
+
/**
|
|
5
|
+
* Send message to all agent and app
|
|
6
|
+
* @param {String} action - message key
|
|
7
|
+
* @param {Object} data - message value
|
|
8
|
+
* @return {Messenger} this
|
|
9
|
+
*/
|
|
10
|
+
broadcast(action: string, data?: unknown): IMessenger;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* send message to the specified process
|
|
14
|
+
* @param {String} pid - the process id of the receiver
|
|
15
|
+
* @param {String} action - message key
|
|
16
|
+
* @param {Object} data - message value
|
|
17
|
+
* @return {Messenger} this
|
|
18
|
+
*/
|
|
19
|
+
sendTo(pid: string, action: string, data?: unknown): IMessenger;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* send message to one app worker by random
|
|
23
|
+
* - if it's running in agent, it will send to one of app workers
|
|
24
|
+
* - if it's running in app, it will send to agent
|
|
25
|
+
* @param {String} action - message key
|
|
26
|
+
* @param {Object} data - message value
|
|
27
|
+
* @return {Messenger} this
|
|
28
|
+
*/
|
|
29
|
+
sendRandom(action: string, data?: unknown): IMessenger;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* send message to app
|
|
33
|
+
* @param {String} action - message key
|
|
34
|
+
* @param {Object} data - message value
|
|
35
|
+
* @return {Messenger} this
|
|
36
|
+
*/
|
|
37
|
+
sendToApp(action: string, data?: unknown): IMessenger;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* send message to agent
|
|
41
|
+
* @param {String} action - message key
|
|
42
|
+
* @param {Object} data - message value
|
|
43
|
+
* @return {Messenger} this
|
|
44
|
+
*/
|
|
45
|
+
sendToAgent(action: string, data?: unknown): IMessenger;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {String} action - message key
|
|
49
|
+
* @param {Object} data - message value
|
|
50
|
+
* @param {String} to - let master know how to send message
|
|
51
|
+
* @return {Messenger} this
|
|
52
|
+
*/
|
|
53
|
+
send(action: string, data: unknown | undefined, to: string): IMessenger;
|
|
54
|
+
|
|
55
|
+
close(): void;
|
|
56
|
+
|
|
57
|
+
onMessage(message: any): void;
|
|
58
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Messenger as LocalMessenger } from './local.js';
|
|
2
|
+
import { Messenger as IPCMessenger } from './ipc.js';
|
|
3
|
+
import type { IMessenger } from './IMessenger.js';
|
|
4
|
+
import type { EggApplicationCore } from '../../egg.js';
|
|
5
|
+
|
|
6
|
+
export type { IMessenger } from './IMessenger.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @class Messenger
|
|
10
|
+
*/
|
|
11
|
+
export function create(egg: EggApplicationCore): IMessenger {
|
|
12
|
+
return egg.options.mode === 'single'
|
|
13
|
+
? new LocalMessenger(egg)
|
|
14
|
+
: new IPCMessenger();
|
|
15
|
+
}
|