egg 4.0.0-beta.9 → 4.0.1

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 (142) hide show
  1. package/dist/commonjs/app/extend/context.d.ts +52 -12
  2. package/dist/commonjs/app/extend/context.js +25 -24
  3. package/dist/commonjs/app/extend/request.d.ts +15 -2
  4. package/dist/commonjs/app/extend/request.js +1 -1
  5. package/dist/commonjs/app/extend/response.d.ts +6 -0
  6. package/dist/commonjs/app/middleware/meta.d.ts +2 -2
  7. package/dist/commonjs/app/middleware/meta.js +1 -1
  8. package/dist/commonjs/app/middleware/notfound.d.ts +2 -2
  9. package/dist/commonjs/app/middleware/notfound.js +1 -1
  10. package/dist/commonjs/app/middleware/site_file.d.ts +3 -3
  11. package/dist/commonjs/app/middleware/site_file.js +1 -1
  12. package/dist/commonjs/config/config.default.d.ts +1 -1
  13. package/dist/commonjs/config/plugin.js +5 -6
  14. package/dist/commonjs/index.d.ts +12 -7
  15. package/dist/commonjs/index.js +11 -22
  16. package/dist/commonjs/lib/application.d.ts +7 -3
  17. package/dist/commonjs/lib/application.js +15 -4
  18. package/dist/commonjs/lib/core/base_context_class.d.ts +6 -3
  19. package/dist/commonjs/lib/core/base_context_class.js +1 -2
  20. package/dist/commonjs/lib/core/base_hook_class.d.ts +2 -2
  21. package/dist/commonjs/lib/core/base_hook_class.js +1 -2
  22. package/dist/commonjs/lib/core/context_httpclient.d.ts +3 -3
  23. package/dist/commonjs/lib/core/context_httpclient.js +1 -1
  24. package/dist/commonjs/lib/core/httpclient.d.ts +7 -6
  25. package/dist/commonjs/lib/core/httpclient.js +10 -5
  26. package/dist/commonjs/lib/core/messenger/base.d.ts +8 -0
  27. package/dist/commonjs/lib/core/messenger/base.js +31 -0
  28. package/dist/commonjs/lib/core/messenger/index.js +3 -2
  29. package/dist/commonjs/lib/core/messenger/ipc.d.ts +2 -3
  30. package/dist/commonjs/lib/core/messenger/ipc.js +4 -6
  31. package/dist/commonjs/lib/core/messenger/local.d.ts +2 -3
  32. package/dist/commonjs/lib/core/messenger/local.js +4 -9
  33. package/dist/commonjs/lib/core/utils.d.ts +1 -1
  34. package/dist/commonjs/lib/core/utils.js +3 -3
  35. package/dist/commonjs/lib/egg.d.ts +37 -13
  36. package/dist/commonjs/lib/egg.js +21 -6
  37. package/dist/commonjs/lib/error/CookieLimitExceedError.d.ts +5 -0
  38. package/dist/commonjs/lib/error/CookieLimitExceedError.js +16 -0
  39. package/dist/commonjs/lib/error/MessageUnhandledRejectionError.d.ts +5 -0
  40. package/dist/commonjs/lib/error/MessageUnhandledRejectionError.js +16 -0
  41. package/dist/commonjs/lib/error/index.d.ts +2 -0
  42. package/dist/commonjs/lib/error/index.js +19 -0
  43. package/dist/commonjs/lib/start.d.ts +10 -1
  44. package/dist/commonjs/lib/start.js +1 -1
  45. package/dist/commonjs/lib/{type.d.ts → types.d.ts} +51 -85
  46. package/dist/commonjs/lib/types.js +9 -0
  47. package/dist/commonjs/lib/utils.js +1 -1
  48. package/dist/commonjs/urllib.d.ts +1 -0
  49. package/dist/commonjs/urllib.js +18 -0
  50. package/dist/esm/app/extend/context.d.ts +52 -12
  51. package/dist/esm/app/extend/context.js +24 -20
  52. package/dist/esm/app/extend/request.d.ts +15 -2
  53. package/dist/esm/app/extend/request.js +1 -1
  54. package/dist/esm/app/extend/response.d.ts +6 -0
  55. package/dist/esm/app/middleware/meta.d.ts +2 -2
  56. package/dist/esm/app/middleware/meta.js +1 -1
  57. package/dist/esm/app/middleware/notfound.d.ts +2 -2
  58. package/dist/esm/app/middleware/notfound.js +1 -1
  59. package/dist/esm/app/middleware/site_file.d.ts +3 -3
  60. package/dist/esm/app/middleware/site_file.js +1 -1
  61. package/dist/esm/config/config.default.d.ts +1 -1
  62. package/dist/esm/config/plugin.js +5 -6
  63. package/dist/esm/index.d.ts +12 -7
  64. package/dist/esm/index.js +13 -8
  65. package/dist/esm/lib/application.d.ts +7 -3
  66. package/dist/esm/lib/application.js +15 -4
  67. package/dist/esm/lib/core/base_context_class.d.ts +6 -3
  68. package/dist/esm/lib/core/base_context_class.js +1 -2
  69. package/dist/esm/lib/core/base_hook_class.d.ts +2 -2
  70. package/dist/esm/lib/core/base_hook_class.js +1 -2
  71. package/dist/esm/lib/core/context_httpclient.d.ts +3 -3
  72. package/dist/esm/lib/core/context_httpclient.js +1 -1
  73. package/dist/esm/lib/core/httpclient.d.ts +7 -6
  74. package/dist/esm/lib/core/httpclient.js +10 -5
  75. package/dist/esm/lib/core/messenger/base.d.ts +8 -0
  76. package/dist/esm/lib/core/messenger/base.js +27 -0
  77. package/dist/esm/lib/core/messenger/index.js +3 -2
  78. package/dist/esm/lib/core/messenger/ipc.d.ts +2 -3
  79. package/dist/esm/lib/core/messenger/ipc.js +4 -6
  80. package/dist/esm/lib/core/messenger/local.d.ts +2 -3
  81. package/dist/esm/lib/core/messenger/local.js +4 -6
  82. package/dist/esm/lib/core/utils.d.ts +1 -1
  83. package/dist/esm/lib/core/utils.js +3 -3
  84. package/dist/esm/lib/egg.d.ts +37 -13
  85. package/dist/esm/lib/egg.js +23 -7
  86. package/dist/esm/lib/error/CookieLimitExceedError.d.ts +5 -0
  87. package/dist/esm/lib/error/CookieLimitExceedError.js +12 -0
  88. package/dist/esm/lib/error/MessageUnhandledRejectionError.d.ts +5 -0
  89. package/dist/esm/lib/error/MessageUnhandledRejectionError.js +12 -0
  90. package/dist/esm/lib/error/index.d.ts +2 -0
  91. package/dist/esm/lib/error/index.js +3 -0
  92. package/dist/esm/lib/start.d.ts +10 -1
  93. package/dist/esm/lib/start.js +1 -1
  94. package/dist/esm/lib/{type.d.ts → types.d.ts} +51 -85
  95. package/dist/esm/lib/types.js +7 -0
  96. package/dist/esm/lib/utils.js +1 -1
  97. package/dist/esm/urllib.d.ts +1 -0
  98. package/dist/esm/urllib.js +2 -0
  99. package/dist/package.json +1 -1
  100. package/package.json +30 -22
  101. package/src/app/extend/context.ts +53 -34
  102. package/src/app/extend/request.ts +18 -2
  103. package/src/app/extend/response.ts +8 -0
  104. package/src/app/middleware/meta.ts +2 -2
  105. package/src/app/middleware/notfound.ts +2 -2
  106. package/src/app/middleware/site_file.ts +3 -3
  107. package/src/config/config.default.ts +1 -1
  108. package/src/config/config.local.ts +1 -1
  109. package/src/config/config.unittest.ts +1 -1
  110. package/src/config/plugin.ts +4 -6
  111. package/src/index.ts +40 -7
  112. package/src/lib/agent.ts +1 -1
  113. package/src/lib/application.ts +18 -6
  114. package/src/lib/core/base_context_class.ts +6 -3
  115. package/src/lib/core/base_hook_class.ts +2 -2
  116. package/src/lib/core/context_httpclient.ts +3 -3
  117. package/src/lib/core/httpclient.ts +21 -8
  118. package/src/lib/core/messenger/base.ts +30 -0
  119. package/src/lib/core/messenger/index.ts +2 -1
  120. package/src/lib/core/messenger/ipc.ts +3 -5
  121. package/src/lib/core/messenger/local.ts +3 -5
  122. package/src/lib/core/utils.ts +2 -2
  123. package/src/lib/egg.ts +58 -23
  124. package/src/lib/error/CookieLimitExceedError.ts +12 -0
  125. package/src/lib/error/MessageUnhandledRejectionError.ts +12 -0
  126. package/src/lib/error/index.ts +2 -0
  127. package/src/lib/start.ts +12 -2
  128. package/src/lib/{type.ts → types.ts} +65 -89
  129. package/src/lib/utils.ts +0 -1
  130. package/src/urllib.ts +1 -0
  131. package/dist/commonjs/app/extend/context.types.d.ts +0 -16
  132. package/dist/commonjs/app/extend/context.types.js +0 -3
  133. package/dist/commonjs/lib/egg.types.d.ts +0 -6
  134. package/dist/commonjs/lib/egg.types.js +0 -3
  135. package/dist/commonjs/lib/type.js +0 -3
  136. package/dist/esm/app/extend/context.types.d.ts +0 -16
  137. package/dist/esm/app/extend/context.types.js +0 -2
  138. package/dist/esm/lib/egg.types.d.ts +0 -6
  139. package/dist/esm/lib/egg.types.js +0 -2
  140. package/dist/esm/lib/type.js +0 -2
  141. package/src/app/extend/context.types.ts +0 -24
  142. package/src/lib/egg.types.ts +0 -6
@@ -1,4 +1,4 @@
1
- import type { Next, ContextDelegation } from '../../lib/egg.js';
1
+ import type { Next, Context } from '../../lib/egg.js';
2
2
 
3
3
  export interface NotFoundMiddlewareOptions {
4
4
  enable: boolean;
@@ -6,7 +6,7 @@ export interface NotFoundMiddlewareOptions {
6
6
  }
7
7
 
8
8
  export default (options: NotFoundMiddlewareOptions) => {
9
- return async function notfound(ctx: ContextDelegation, next: Next) {
9
+ return async function notfound(ctx: Context, next: Next) {
10
10
  await next();
11
11
 
12
12
  if (ctx.status !== 404 || ctx.body) {
@@ -1,9 +1,9 @@
1
1
  import path from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { readFile } from 'node:fs/promises';
4
- import type { Next, ContextDelegation } from '../../lib/egg.js';
4
+ import type { Next, Context } from '../../lib/egg.js';
5
5
 
6
- export type SiteFileContentFun = (ctx: ContextDelegation) => Promise<Buffer | string>;
6
+ export type SiteFileContentFun = (ctx: Context) => Promise<Buffer | string>;
7
7
 
8
8
  export interface SiteFileMiddlewareOptions {
9
9
  enable: boolean;
@@ -14,7 +14,7 @@ export interface SiteFileMiddlewareOptions {
14
14
  const BUFFER_CACHE = Symbol('siteFile URL buffer cache');
15
15
 
16
16
  export default (options: SiteFileMiddlewareOptions) => {
17
- return async function siteFile(ctx: ContextDelegation, next: Next) {
17
+ return async function siteFile(ctx: Context, next: Next) {
18
18
  if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {
19
19
  return next();
20
20
  }
@@ -1,7 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import { pathToFileURL } from 'node:url';
3
3
  import type { EggAppInfo } from '@eggjs/core';
4
- import type { EggAppConfig } from '../lib/type.js';
4
+ import type { EggAppConfig } from '../lib/types.js';
5
5
  import { getSourceFile } from '../lib/utils.js';
6
6
 
7
7
  /**
@@ -1,4 +1,4 @@
1
- import type { EggAppConfig } from '../lib/type.js';
1
+ import type { EggAppConfig } from '../lib/types.js';
2
2
 
3
3
  export default () => {
4
4
  return {
@@ -1,4 +1,4 @@
1
- import type { EggAppConfig } from '../lib/type.js';
1
+ import type { EggAppConfig } from '../lib/types.js';
2
2
 
3
3
  export default () => {
4
4
  return {
@@ -1,6 +1,4 @@
1
1
  export default {
2
- // enable plugins
3
-
4
2
  /**
5
3
  * app global Error Handling
6
4
  * @member {Object} Plugin#onerror
@@ -30,7 +28,7 @@ export default {
30
28
  */
31
29
  i18n: {
32
30
  enable: true,
33
- package: 'egg-i18n',
31
+ package: '@eggjs/i18n',
34
32
  },
35
33
 
36
34
  /**
@@ -74,7 +72,7 @@ export default {
74
72
  */
75
73
  development: {
76
74
  enable: true,
77
- package: 'egg-development',
75
+ package: '@eggjs/development',
78
76
  },
79
77
 
80
78
  /**
@@ -107,7 +105,7 @@ export default {
107
105
  */
108
106
  static: {
109
107
  enable: true,
110
- package: 'egg-static',
108
+ package: '@eggjs/static',
111
109
  },
112
110
 
113
111
  /**
@@ -118,7 +116,7 @@ export default {
118
116
  */
119
117
  jsonp: {
120
118
  enable: true,
121
- package: 'egg-jsonp',
119
+ package: '@eggjs/jsonp',
122
120
  },
123
121
 
124
122
  /**
package/src/index.ts CHANGED
@@ -3,17 +3,40 @@
3
3
  */
4
4
 
5
5
  import { BaseContextClass } from './lib/core/base_context_class.js';
6
- import { startEgg } from './lib/start.js';
6
+ import {
7
+ startEgg,
8
+ SingleModeApplication,
9
+ SingleModeAgent,
10
+ } from './lib/start.js';
7
11
  import Helper from './app/extend/helper.js';
8
12
 
9
13
  // export extends
10
- export { Helper };
14
+ export {
15
+ Helper,
16
+ };
17
+ export type {
18
+ // keep compatible with egg v3
19
+ Helper as IHelper,
20
+ };
11
21
 
12
22
  // export types
13
23
  export * from './lib/egg.js';
14
- export * from './lib/type.js';
24
+ export * from './lib/types.js';
15
25
  export * from './lib/start.js';
16
26
 
27
+ // export errors
28
+ export * from './lib/error/index.js';
29
+
30
+ // export loggers
31
+ export type {
32
+ LoggerLevel,
33
+ EggLogger,
34
+ } from 'egg-logger';
35
+
36
+ // export httpClients
37
+ export * from './lib/core/httpclient.js';
38
+ export * from './lib/core/context_httpclient.js';
39
+
17
40
  /**
18
41
  * Start egg application with cluster mode
19
42
  * @since 1.0.0
@@ -24,7 +47,11 @@ export * from '@eggjs/cluster';
24
47
  * Start egg application with single process mode
25
48
  * @since 1.0.0
26
49
  */
27
- export const start = startEgg;
50
+ export {
51
+ startEgg as start,
52
+ SingleModeApplication,
53
+ SingleModeAgent,
54
+ };
28
55
 
29
56
  /**
30
57
  * @member {Application} Egg#Application
@@ -54,19 +81,25 @@ export { AppWorkerLoader, AgentWorkerLoader } from './lib/loader/index.js';
54
81
  * @member {Controller} Egg#Controller
55
82
  * @since 1.1.0
56
83
  */
57
- export const Controller = BaseContextClass;
84
+ export {
85
+ BaseContextClass as Controller,
86
+ };
58
87
 
59
88
  /**
60
89
  * @member {Service} Egg#Service
61
90
  * @since 1.1.0
62
91
  */
63
- export const Service = BaseContextClass;
92
+ export {
93
+ BaseContextClass as Service,
94
+ };
64
95
 
65
96
  /**
66
97
  * @member {Subscription} Egg#Subscription
67
98
  * @since 1.10.0
68
99
  */
69
- export const Subscription = BaseContextClass;
100
+ export {
101
+ BaseContextClass as Subscription,
102
+ };
70
103
 
71
104
  /**
72
105
  * @member {BaseContextClass} Egg#BaseContextClass
package/src/lib/agent.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { EggLogger } from 'egg-logger';
1
+ import type { EggLogger } from 'egg-logger';
2
2
  import { EggApplicationCore, EggApplicationCoreOptions } from './egg.js';
3
3
  import { AgentWorkerLoader } from './loader/index.js';
4
4
 
@@ -5,13 +5,15 @@ import { Socket } from 'node:net';
5
5
  import { graceful } from 'graceful';
6
6
  import { assign } from 'utility';
7
7
  import { utils as eggUtils } from '@eggjs/core';
8
+ import { isGeneratorFunction } from 'is-type-of';
8
9
  import {
9
10
  EggApplicationCore,
10
11
  type EggApplicationCoreOptions,
11
- type ContextDelegation,
12
+ type Context,
12
13
  } from './egg.js';
13
14
  import { AppWorkerLoader } from './loader/index.js';
14
15
  import Helper from '../app/extend/helper.js';
16
+ import { CookieLimitExceedError } from './error/index.js';
15
17
 
16
18
  const EGG_LOADER = Symbol.for('egg#loader');
17
19
 
@@ -221,7 +223,7 @@ export class Application extends EggApplicationCore {
221
223
  * @see Context#runInBackground
222
224
  * @param {Function} scope - the first args is an anonymous ctx
223
225
  */
224
- runInBackground(scope: (ctx: ContextDelegation) => Promise<void>, req?: unknown) {
226
+ runInBackground(scope: (ctx: Context) => Promise<void>, req?: unknown) {
225
227
  const ctx = this.createAnonymousContext(req);
226
228
  if (!scope.name) {
227
229
  Reflect.set(scope, '_name', eggUtils.getCalleeFromStack(true));
@@ -237,7 +239,7 @@ export class Application extends EggApplicationCore {
237
239
  * @param {Function} scope - the first args is an anonymous ctx, scope should be async function
238
240
  * @param {Request} [req] - if you want to mock request like querystring, you can pass an object to this function.
239
241
  */
240
- async runInAnonymousContextScope(scope: (ctx: ContextDelegation) => Promise<void>, req?: unknown) {
242
+ async runInAnonymousContextScope(scope: (ctx: Context) => Promise<void>, req?: unknown) {
241
243
  const ctx = this.createAnonymousContext(req);
242
244
  if (!scope.name) {
243
245
  Reflect.set(scope, '_name', eggUtils.getCalleeFromStack(true));
@@ -266,16 +268,26 @@ export class Application extends EggApplicationCore {
266
268
  return this._keys;
267
269
  }
268
270
 
271
+ /**
272
+ * @deprecated keep compatible with egg 3.x
273
+ */
274
+ toAsyncFunction(fn: (...args: any[]) => any) {
275
+ if (isGeneratorFunction(fn)) {
276
+ throw new Error('Generator function is not supported');
277
+ }
278
+ return fn;
279
+ }
280
+
269
281
  /**
270
282
  * bind app's events
271
283
  *
272
284
  * @private
273
285
  */
274
286
  #bindEvents() {
275
- // Browser Cookie Limits: http://browsercookielimits.squawky.net/
287
+ // Browser Cookie Limits: http://browsercookielimits.iain.guru/
288
+ // https://github.com/eggjs/egg-cookies/blob/58ef4ea497a0eb4dd711d7e9751e56bc5fcee004/src/cookies.ts#L145
276
289
  this.on('cookieLimitExceed', ({ name, value, ctx }) => {
277
- const err = new Error(`cookie ${name}'s length(${value.length}) exceed the limit(4093)`);
278
- err.name = 'CookieLimitExceedError';
290
+ const err = new CookieLimitExceedError(name, value);
279
291
  ctx.coreLogger.error(err);
280
292
  });
281
293
  // expose server to support websocket
@@ -1,5 +1,5 @@
1
1
  import { BaseContextClass as EggCoreBaseContextClass } from '@eggjs/core';
2
- import type { ContextDelegation } from '../egg.js';
2
+ import type { Context, EggApplicationCore } from '../egg.js';
3
3
  import { BaseContextLogger } from './base_context_logger.js';
4
4
 
5
5
  /**
@@ -8,8 +8,11 @@ import { BaseContextLogger } from './base_context_logger.js';
8
8
  * {@link Helper}, {@link Service} is extending it.
9
9
  */
10
10
  export class BaseContextClass extends EggCoreBaseContextClass {
11
- declare ctx: ContextDelegation;
12
- protected pathName?: string;
11
+ [key: string | symbol]: any;
12
+ declare ctx: Context;
13
+ declare pathName?: string;
14
+ declare app: EggApplicationCore;
15
+ declare service: BaseContextClass;
13
16
  #logger?: BaseContextLogger;
14
17
 
15
18
  get logger() {
@@ -3,14 +3,14 @@ import type { ILifecycleBoot } from '@eggjs/core';
3
3
  import type { Application, Agent } from '../../index.js';
4
4
 
5
5
  export class BaseHookClass implements ILifecycleBoot {
6
- fullPath?: string;
6
+ declare fullPath?: string;
7
7
  #instance: Application | Agent;
8
8
 
9
9
  constructor(instance: Application | Agent) {
10
10
  this.#instance = instance;
11
11
  }
12
12
 
13
- get logger(): any {
13
+ get logger() {
14
14
  return this.#instance.logger;
15
15
  }
16
16
 
@@ -1,13 +1,13 @@
1
- import type { ContextDelegation, EggApplicationCore } from '../egg.js';
1
+ import type { Context, EggApplicationCore } from '../egg.js';
2
2
  import type {
3
3
  HttpClientRequestURL, HttpClientRequestOptions,
4
4
  } from './httpclient.js';
5
5
 
6
6
  export class ContextHttpClient {
7
- ctx: ContextDelegation;
7
+ ctx: Context;
8
8
  app: EggApplicationCore;
9
9
 
10
- constructor(ctx: ContextDelegation) {
10
+ constructor(ctx: Context) {
11
11
  this.ctx = ctx;
12
12
  this.app = ctx.app;
13
13
  }
@@ -2,29 +2,36 @@ import {
2
2
  HttpClient as RawHttpClient,
3
3
  RequestURL as HttpClientRequestURL,
4
4
  RequestOptions,
5
+ ClientOptions as HttpClientOptions,
5
6
  } from 'urllib';
6
7
  import { ms } from 'humanize-ms';
7
- import type { EggApplicationCore, ContextDelegation } from '../egg.js';
8
+ import type { EggApplicationCore } from '../egg.js';
8
9
 
9
10
  export type {
10
11
  HttpClientResponse,
11
12
  RequestURL as HttpClientRequestURL,
13
+ ClientOptions as HttpClientOptions,
12
14
  } from 'urllib';
13
15
 
14
16
  export interface HttpClientRequestOptions extends RequestOptions {
15
- ctx?: ContextDelegation;
16
- tracer?: unknown;
17
+ ctx?: any;
18
+ tracer?: any;
17
19
  }
18
20
 
19
21
  export class HttpClient extends RawHttpClient {
20
- readonly #app: EggApplicationCore & { tracer?: unknown };
22
+ readonly #app: EggApplicationCore & { tracer?: any };
21
23
 
22
- constructor(app: EggApplicationCore) {
24
+ constructor(app: EggApplicationCore, options: HttpClientOptions = {}) {
23
25
  normalizeConfig(app);
24
26
  const config = app.config.httpclient;
25
- super({
26
- defaultArgs: config.request,
27
- });
27
+ const initOptions: HttpClientOptions = {
28
+ ...options,
29
+ defaultArgs: {
30
+ ...config.request,
31
+ ...options.defaultArgs,
32
+ },
33
+ };
34
+ super(initOptions);
28
35
  this.#app = app;
29
36
  }
30
37
 
@@ -43,6 +50,12 @@ export class HttpClient extends RawHttpClient {
43
50
  }
44
51
  }
45
52
 
53
+ // keep compatible
54
+ export type {
55
+ HttpClient as EggHttpClient,
56
+ HttpClient as EggContextHttpClient,
57
+ };
58
+
46
59
  function normalizeConfig(app: EggApplicationCore) {
47
60
  const config = app.config.httpclient;
48
61
  if (typeof config.request?.timeout === 'string') {
@@ -0,0 +1,30 @@
1
+ import { EventEmitter, captureRejectionSymbol } from 'node:events';
2
+ import { MessageUnhandledRejectionError } from '../../error/index.js';
3
+ import { EggApplicationCore } from '../../egg.js';
4
+
5
+ export class BaseMessenger extends EventEmitter {
6
+ protected readonly egg: EggApplicationCore;
7
+
8
+ constructor(egg: EggApplicationCore) {
9
+ super({ captureRejections: true });
10
+ this.egg = egg;
11
+ }
12
+
13
+ [captureRejectionSymbol](err: Error, event: string | symbol, ...args: any[]) {
14
+ this.egg.coreLogger.error(new MessageUnhandledRejectionError(err, event, args));
15
+ }
16
+
17
+ emit(eventName: string | symbol, ...args: any[]): boolean {
18
+ const hasListeners = this.listenerCount(eventName) > 0;
19
+ try {
20
+ return super.emit(eventName, ...args);
21
+ } catch (e: unknown) {
22
+ let err = e as Error;
23
+ if (!(err instanceof Error)) {
24
+ err = new Error(String(err));
25
+ }
26
+ this.egg.coreLogger.error(new MessageUnhandledRejectionError(err, eventName, args));
27
+ return hasListeners;
28
+ }
29
+ }
30
+ }
@@ -9,7 +9,8 @@ export type { IMessenger } from './IMessenger.js';
9
9
  * @class Messenger
10
10
  */
11
11
  export function create(egg: EggApplicationCore): IMessenger {
12
- return egg.options.mode === 'single'
12
+ const messenger = egg.options.mode === 'single'
13
13
  ? new LocalMessenger(egg)
14
14
  : new IPCMessenger(egg);
15
+ return messenger;
15
16
  }
@@ -1,24 +1,22 @@
1
- import { EventEmitter } from 'node:events';
2
1
  import { debuglog } from 'node:util';
3
2
  import workerThreads from 'node:worker_threads';
4
3
  import { sendmessage } from 'sendmessage';
5
4
  import type { IMessenger } from './IMessenger.js';
6
5
  import type { EggApplicationCore } from '../../egg.js';
6
+ import { BaseMessenger } from './base.js';
7
7
 
8
8
  const debug = debuglog('egg/lib/core/messenger/ipc');
9
9
 
10
10
  /**
11
11
  * Communication between app worker and agent worker by IPC channel
12
12
  */
13
- export class Messenger extends EventEmitter implements IMessenger {
13
+ export class Messenger extends BaseMessenger implements IMessenger {
14
14
  readonly pid: string;
15
- readonly egg: EggApplicationCore;
16
15
  opids: string[] = [];
17
16
 
18
17
  constructor(egg: EggApplicationCore) {
19
- super();
18
+ super(egg);
20
19
  this.pid = String(process.pid);
21
- this.egg = egg;
22
20
  // pids of agent or app managed by master
23
21
  // - retrieve app worker pids when it's an agent worker
24
22
  // - retrieve agent worker pids when it's an app worker
@@ -1,20 +1,18 @@
1
1
  import { debuglog } from 'node:util';
2
- import EventEmitter from 'node:events';
3
2
  import type { IMessenger } from './IMessenger.js';
4
3
  import type { EggApplicationCore } from '../../egg.js';
4
+ import { BaseMessenger } from './base.js';
5
5
 
6
6
  const debug = debuglog('egg/lib/core/messenger/local');
7
7
 
8
8
  /**
9
9
  * Communication between app worker and agent worker with EventEmitter
10
10
  */
11
- export class Messenger extends EventEmitter implements IMessenger {
11
+ export class Messenger extends BaseMessenger implements IMessenger {
12
12
  readonly pid: string;
13
- readonly egg: EggApplicationCore;
14
13
 
15
14
  constructor(egg: EggApplicationCore) {
16
- super();
17
- this.egg = egg;
15
+ super(egg);
18
16
  this.pid = String(process.pid);
19
17
  }
20
18
 
@@ -4,7 +4,7 @@ import {
4
4
  isClass, isFunction, isGeneratorFunction, isAsyncFunction,
5
5
  } from 'is-type-of';
6
6
 
7
- export function convertObject(obj: any, ignore: string | RegExp | (string | RegExp)[]) {
7
+ export function convertObject(obj: any, ignore: string | RegExp | (string | RegExp)[] = []) {
8
8
  if (!Array.isArray(ignore)) {
9
9
  ignore = [ ignore ];
10
10
  }
@@ -30,7 +30,7 @@ function convertValue(key: string, value: any, ignore: (string | RegExp)[]) {
30
30
  }
31
31
  }
32
32
  if (!hit) {
33
- if (isSymbol(value) || isRegExp(value)) {
33
+ if (isSymbol(value) || isRegExp(value) || value instanceof URL) {
34
34
  return value.toString();
35
35
  }
36
36
  if (isPrimitive(value) || Array.isArray(value)) {
package/src/lib/egg.ts CHANGED
@@ -26,12 +26,14 @@ import { Cookies as ContextCookies } from '@eggjs/cookies';
26
26
  import CircularJSON from 'circular-json-for-egg';
27
27
  import type { Agent } from './agent.js';
28
28
  import type { Application } from './application.js';
29
- import Context, { type ContextDelegation } from '../app/extend/context.js';
30
- import type { EggAppConfig } from './type.js';
29
+ import Context from '../app/extend/context.js';
30
+ import type { EggAppConfig } from './types.js';
31
31
  import { create as createMessenger, IMessenger } from './core/messenger/index.js';
32
32
  import { ContextHttpClient } from './core/context_httpclient.js';
33
33
  import {
34
- HttpClient, type HttpClientRequestOptions, type HttpClientRequestURL, type HttpClientResponse,
34
+ HttpClient,
35
+ type HttpClientRequestOptions, type HttpClientRequestURL, type HttpClientResponse,
36
+ type HttpClientOptions,
35
37
  } from './core/httpclient.js';
36
38
  import { createLoggers } from './core/logger.js';
37
39
  import {
@@ -43,8 +45,6 @@ import { BaseHookClass } from './core/base_hook_class.js';
43
45
  import type { EggApplicationLoader } from './loader/index.js';
44
46
  import { getSourceDirname } from './utils.js';
45
47
 
46
- import './egg.types.js';
47
-
48
48
  const EGG_PATH = Symbol.for('egg#eggPath');
49
49
 
50
50
  export interface EggApplicationCoreOptions extends Omit<EggCoreOptions, 'baseDir'> {
@@ -53,34 +53,34 @@ export interface EggApplicationCoreOptions extends Omit<EggCoreOptions, 'baseDir
53
53
  baseDir?: string;
54
54
  }
55
55
 
56
- // export egg classes
57
- export {
58
- Context,
59
- Router,
60
- EggLogger,
61
- };
62
-
63
56
  export class Request extends EggCoreRequest {
64
57
  declare app: EggCore;
65
58
  declare response: Response;
66
- declare ctx: ContextDelegation;
59
+ declare ctx: Context;
67
60
  }
68
61
 
69
62
  export class Response extends EggCoreResponse {
70
63
  declare app: EggCore;
71
64
  declare request: Request;
72
- declare ctx: ContextDelegation;
65
+ declare ctx: Context;
73
66
  }
74
67
 
75
68
  // export egg types
76
69
  export type {
77
- ContextDelegation,
78
70
  ILifecycleBoot,
71
+ // keep compatible with egg version 3.x
72
+ ILifecycleBoot as IBoot,
79
73
  Next,
80
74
  };
81
75
  // keep compatible with egg version 3.x
82
- export type EggContext = ContextDelegation;
83
- export type MiddlewareFunc<T extends ContextDelegation = ContextDelegation> = EggCoreMiddlewareFunc<T>;
76
+ export type EggContext = Context;
77
+ export type MiddlewareFunc<T extends Context = Context> = EggCoreMiddlewareFunc<T>;
78
+
79
+ // export egg classes
80
+ export {
81
+ Context,
82
+ Router,
83
+ };
84
84
 
85
85
  /**
86
86
  * Based on koa's Application
@@ -89,12 +89,14 @@ export type MiddlewareFunc<T extends ContextDelegation = ContextDelegation> = Eg
89
89
  * @augments EggCore
90
90
  */
91
91
  export class EggApplicationCore extends EggCore {
92
- declare ctxStorage: AsyncLocalStorage<ContextDelegation>;
92
+ declare ctxStorage: AsyncLocalStorage<Context>;
93
93
  // export context base classes, let framework can impl sub class and over context extend easily.
94
94
  ContextCookies = ContextCookies;
95
95
  ContextLogger = ContextLogger;
96
96
  ContextHttpClient = ContextHttpClient;
97
97
  HttpClient = HttpClient;
98
+ // keep compatible with egg version 3.x
99
+ HttpClientNext = HttpClient;
98
100
  /**
99
101
  * Retrieve base context class
100
102
  * @member {BaseContextClass} BaseContextClass
@@ -132,6 +134,7 @@ export class EggApplicationCore extends EggCore {
132
134
  /**
133
135
  * Retrieve base boot
134
136
  * @member {Boot}
137
+ * @alias BaseHookClass
135
138
  */
136
139
  Boot = BaseHookClass;
137
140
 
@@ -233,6 +236,13 @@ export class EggApplicationCore extends EggCore {
233
236
  await this.loader.load();
234
237
  }
235
238
 
239
+ /**
240
+ * Usage: new ApiClient({ cluster: app.cluster })
241
+ */
242
+ get cluster() {
243
+ return this.clusterWrapper.bind(this);
244
+ }
245
+
236
246
  /**
237
247
  * Wrap the Client with Leader/Follower Pattern
238
248
  *
@@ -251,7 +261,7 @@ export class EggApplicationCore extends EggCore {
251
261
  * - {Number} [maxWaitTime|30000] - leader startup max time, default is 30 seconds
252
262
  * @return {ClientWrapper} wrapper
253
263
  */
254
- cluster(clientClass: unknown, options?: object) {
264
+ clusterWrapper(clientClass: unknown, options?: object) {
255
265
  const clientClassOptions = {
256
266
  ...this.config.clusterClient,
257
267
  ...options,
@@ -377,14 +387,22 @@ export class EggApplicationCore extends EggCore {
377
387
  return await this.httpClient.request<T>(url, options);
378
388
  }
379
389
 
390
+ /**
391
+ * Create a new HttpClient instance with custom options
392
+ * @param {Object} [options] HttpClient init options
393
+ */
394
+ createHttpClient(options?: HttpClientOptions): HttpClient {
395
+ return new this.HttpClient(this, options);
396
+ }
397
+
380
398
  /**
381
399
  * HttpClient instance
382
400
  * @see https://github.com/node-modules/urllib
383
401
  * @member {HttpClient}
384
402
  */
385
- get httpClient() {
403
+ get httpClient(): HttpClient {
386
404
  if (!this.#httpClient) {
387
- this.#httpClient = new this.HttpClient(this);
405
+ this.#httpClient = this.createHttpClient();
388
406
  }
389
407
  return this.#httpClient;
390
408
  }
@@ -439,6 +457,7 @@ export class EggApplicationCore extends EggCore {
439
457
  }
440
458
 
441
459
  _unhandledRejectionHandler(err: any) {
460
+ this.coreLogger.error('[egg:unhandledRejection] %s', err && err.message || err);
442
461
  if (!(err instanceof Error)) {
443
462
  const newError = new Error(String(err));
444
463
  // err maybe an object, try to copy the name, message and stack to the new error instance
@@ -652,8 +671,8 @@ export class EggApplicationCore extends EggCore {
652
671
  * @param {Res} res - node native Response object
653
672
  * @return {Context} context object
654
673
  */
655
- createContext(req: IncomingMessage, res: ServerResponse): EggContext {
656
- const context = Object.create(this.context) as EggContext;
674
+ createContext(req: IncomingMessage, res: ServerResponse): Context {
675
+ const context = Object.create(this.context) as Context;
657
676
  const request = context.request = Object.create(this.request);
658
677
  const response = context.response = Object.create(this.response);
659
678
  context.app = request.app = response.app = this as any;
@@ -669,3 +688,19 @@ export class EggApplicationCore extends EggCore {
669
688
  return context;
670
689
  }
671
690
  }
691
+
692
+ declare module '@eggjs/core' {
693
+ // add EggApplicationCore overrides types
694
+ interface EggCore {
695
+ inspect(): any;
696
+ get currentContext(): EggContext | undefined;
697
+ ctxStorage: AsyncLocalStorage<EggContext>;
698
+ get logger(): EggLogger;
699
+ get coreLogger(): EggLogger;
700
+ getLogger(name: string): EggLogger;
701
+ createHttpClient(options?: HttpClientOptions): HttpClient;
702
+ HttpClient: typeof HttpClient;
703
+ get httpClient(): HttpClient;
704
+ curl<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions): Promise<HttpClientResponse<T>>;
705
+ }
706
+ }