egg 4.0.0-beta.5 → 4.0.0-beta.7

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 (98) hide show
  1. package/dist/commonjs/app/extend/context.d.ts +154 -2
  2. package/dist/commonjs/app/extend/context.js +82 -84
  3. package/dist/commonjs/app/extend/context.types.d.ts +16 -0
  4. package/dist/commonjs/app/extend/context.types.js +3 -0
  5. package/dist/commonjs/app/extend/helper.d.ts +37 -0
  6. package/dist/commonjs/app/extend/helper.js +49 -0
  7. package/dist/commonjs/app/extend/request.d.ts +128 -0
  8. package/dist/commonjs/app/extend/request.js +270 -0
  9. package/dist/commonjs/app/extend/response.d.ts +25 -0
  10. package/dist/commonjs/app/extend/response.js +37 -0
  11. package/dist/commonjs/app/middleware/meta.d.ts +2 -3
  12. package/dist/commonjs/app/middleware/meta.js +1 -1
  13. package/dist/commonjs/app/middleware/notfound.d.ts +2 -3
  14. package/dist/commonjs/app/middleware/notfound.js +1 -1
  15. package/dist/commonjs/app/middleware/site_file.d.ts +4 -2
  16. package/dist/commonjs/app/middleware/site_file.js +2 -3
  17. package/dist/commonjs/config/config.default.js +3 -2
  18. package/dist/commonjs/lib/application.d.ts +5 -12
  19. package/dist/commonjs/lib/application.js +9 -20
  20. package/dist/commonjs/lib/core/base_context_class.d.ts +2 -2
  21. package/dist/commonjs/lib/core/context_httpclient.d.ts +3 -3
  22. package/dist/commonjs/lib/core/context_httpclient.js +1 -1
  23. package/dist/commonjs/lib/core/httpclient.d.ts +2 -3
  24. package/dist/commonjs/lib/core/httpclient.js +3 -6
  25. package/dist/commonjs/lib/core/messenger/IMessenger.d.ts +2 -2
  26. package/dist/commonjs/lib/core/messenger/index.js +2 -2
  27. package/dist/commonjs/lib/core/messenger/ipc.d.ts +5 -3
  28. package/dist/commonjs/lib/core/messenger/ipc.js +23 -17
  29. package/dist/commonjs/lib/core/messenger/local.d.ts +2 -2
  30. package/dist/commonjs/lib/core/messenger/local.js +14 -11
  31. package/dist/commonjs/lib/egg.d.ts +20 -15
  32. package/dist/commonjs/lib/egg.js +15 -11
  33. package/dist/commonjs/lib/egg.types.d.ts +6 -0
  34. package/dist/commonjs/lib/egg.types.js +3 -0
  35. package/dist/commonjs/lib/type.d.ts +4 -7
  36. package/dist/commonjs/lib/utils.d.ts +2 -0
  37. package/dist/commonjs/lib/utils.js +21 -0
  38. package/dist/esm/app/extend/context.d.ts +154 -2
  39. package/dist/esm/app/extend/context.js +82 -85
  40. package/dist/esm/app/extend/context.types.d.ts +16 -0
  41. package/dist/esm/app/extend/context.types.js +2 -0
  42. package/dist/esm/app/extend/helper.d.ts +37 -0
  43. package/dist/esm/app/extend/helper.js +43 -0
  44. package/dist/esm/app/extend/request.d.ts +128 -0
  45. package/dist/esm/app/extend/request.js +264 -0
  46. package/dist/esm/app/extend/response.d.ts +25 -0
  47. package/dist/esm/app/extend/response.js +34 -0
  48. package/dist/esm/app/middleware/meta.d.ts +2 -3
  49. package/dist/esm/app/middleware/meta.js +1 -1
  50. package/dist/esm/app/middleware/notfound.d.ts +2 -3
  51. package/dist/esm/app/middleware/notfound.js +1 -1
  52. package/dist/esm/app/middleware/site_file.d.ts +4 -2
  53. package/dist/esm/app/middleware/site_file.js +2 -3
  54. package/dist/esm/config/config.default.js +3 -2
  55. package/dist/esm/lib/application.d.ts +5 -12
  56. package/dist/esm/lib/application.js +9 -20
  57. package/dist/esm/lib/core/base_context_class.d.ts +2 -2
  58. package/dist/esm/lib/core/context_httpclient.d.ts +3 -3
  59. package/dist/esm/lib/core/context_httpclient.js +1 -1
  60. package/dist/esm/lib/core/httpclient.d.ts +2 -3
  61. package/dist/esm/lib/core/httpclient.js +2 -2
  62. package/dist/esm/lib/core/messenger/IMessenger.d.ts +2 -2
  63. package/dist/esm/lib/core/messenger/index.js +2 -2
  64. package/dist/esm/lib/core/messenger/ipc.d.ts +5 -3
  65. package/dist/esm/lib/core/messenger/ipc.js +23 -17
  66. package/dist/esm/lib/core/messenger/local.d.ts +2 -2
  67. package/dist/esm/lib/core/messenger/local.js +14 -11
  68. package/dist/esm/lib/egg.d.ts +20 -15
  69. package/dist/esm/lib/egg.js +13 -12
  70. package/dist/esm/lib/egg.types.d.ts +6 -0
  71. package/dist/esm/lib/egg.types.js +2 -0
  72. package/dist/esm/lib/type.d.ts +4 -7
  73. package/dist/esm/lib/utils.d.ts +2 -0
  74. package/dist/esm/lib/utils.js +14 -0
  75. package/dist/package.json +1 -1
  76. package/package.json +16 -13
  77. package/src/app/extend/context.ts +124 -102
  78. package/src/app/extend/context.types.ts +24 -0
  79. package/src/app/extend/{helper.js → helper.ts} +14 -13
  80. package/src/app/extend/{request.js → request.ts} +81 -79
  81. package/src/app/extend/response.ts +36 -0
  82. package/src/app/middleware/meta.ts +2 -3
  83. package/src/app/middleware/notfound.ts +2 -3
  84. package/src/app/middleware/site_file.ts +4 -6
  85. package/src/config/config.default.ts +2 -1
  86. package/src/lib/application.ts +14 -21
  87. package/src/lib/core/base_context_class.ts +2 -2
  88. package/src/lib/core/context_httpclient.ts +3 -3
  89. package/src/lib/core/httpclient.ts +4 -5
  90. package/src/lib/core/messenger/IMessenger.ts +2 -2
  91. package/src/lib/core/messenger/index.ts +1 -1
  92. package/src/lib/core/messenger/ipc.ts +23 -17
  93. package/src/lib/core/messenger/local.ts +12 -10
  94. package/src/lib/egg.ts +47 -24
  95. package/src/lib/egg.types.ts +6 -0
  96. package/src/lib/type.ts +6 -13
  97. package/src/lib/utils.ts +16 -0
  98. package/src/app/extend/response.js +0 -101
@@ -1,15 +1,13 @@
1
1
  import type { Socket } from 'node:net';
2
- import type { EggCoreContext } from '@eggjs/core';
3
2
  import type { RequestOptions as HttpClientRequestOptions } from 'urllib';
4
3
  import type { EggLoggerOptions, EggLoggersOptions } from 'egg-logger';
5
4
  import type { FileLoaderOptions } from '@eggjs/core';
6
- import type { EggApplicationCore } from './egg.js';
5
+ import type { EggApplicationCore, ContextDelegation } from './egg.js';
7
6
  import type { MetaMiddlewareOptions } from '../app/middleware/meta.js';
8
7
  import type { NotFoundMiddlewareOptions } from '../app/middleware/notfound.js';
9
8
  import type { SiteFileMiddlewareOptions } from '../app/middleware/site_file.js';
10
- type IgnoreItem = string | RegExp | ((ctx: EggCoreContext) => boolean);
9
+ type IgnoreItem = string | RegExp | ((ctx: ContextDelegation) => boolean);
11
10
  type IgnoreOrMatch = IgnoreItem | IgnoreItem[];
12
- export type Next = () => Promise<void>;
13
11
  export interface ClientErrorResponse {
14
12
  body: string | Buffer;
15
13
  status: number;
@@ -89,7 +87,7 @@ export interface EggAppConfig {
89
87
  };
90
88
  /** Default is `'error'`, it will return `400` response when `Prototype-Poisoning` happen. */
91
89
  onProtoPoisoning: 'error' | 'remove' | 'ignore';
92
- onerror(err: any, ctx: EggCoreContext): void;
90
+ onerror(err: any, ctx: ContextDelegation): void;
93
91
  };
94
92
  /**
95
93
  * logger options
@@ -292,5 +290,4 @@ export interface EggAppConfig {
292
290
  };
293
291
  [prop: string]: any;
294
292
  }
295
- export type { EggLogger, } from 'egg-logger';
296
- export type { ILifecycleBoot, } from '@eggjs/core';
293
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare function getSourceDirname(): string;
2
+ export declare function getSourceFile(filename: string): string;
@@ -0,0 +1,14 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ export function getSourceDirname() {
4
+ if (typeof __dirname !== 'undefined') {
5
+ return path.dirname(__dirname);
6
+ }
7
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
8
+ // @ts-ignore
9
+ return path.dirname(path.dirname(fileURLToPath(import.meta.url)));
10
+ }
11
+ export function getSourceFile(filename) {
12
+ return path.join(getSourceDirname(), filename);
13
+ }
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUM3QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRXpDLE1BQU0sVUFBVSxnQkFBZ0I7SUFDOUIsSUFBSSxPQUFPLFNBQVMsS0FBSyxXQUFXLEVBQUUsQ0FBQztRQUNyQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUNELDZEQUE2RDtJQUM3RCxhQUFhO0lBQ2IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3BFLENBQUM7QUFFRCxNQUFNLFVBQVUsYUFBYSxDQUFDLFFBQWdCO0lBQzVDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ2pELENBQUMifQ==
package/dist/package.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "egg",
3
- "version": "4.0.0-beta.5"
3
+ "version": "4.0.0-beta.7"
4
4
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "egg",
3
- "version": "4.0.0-beta.5",
3
+ "version": "4.0.0-beta.7",
4
4
  "engines": {
5
5
  "node": ">= 18.19.0"
6
6
  },
@@ -21,13 +21,10 @@
21
21
  "dependencies": {
22
22
  "@eggjs/cluster": "beta",
23
23
  "@eggjs/cookies": "^3.0.0",
24
- "@eggjs/core": "^6.1.0",
25
- "@eggjs/schedule": "^5.0.1",
24
+ "@eggjs/core": "^6.2.3",
25
+ "@eggjs/schedule": "^5.0.2",
26
26
  "@eggjs/utils": "^4.0.2",
27
- "@eggjs/watcher": "^4.0.0",
28
- "@types/accepts": "^1.3.5",
29
- "accepts": "^1.3.8",
30
- "cache-content-type": "^2.0.0",
27
+ "@eggjs/watcher": "^4.0.1",
31
28
  "circular-json-for-egg": "^1.0.0",
32
29
  "cluster-client": "^3.7.0",
33
30
  "delegates": "^1.0.0",
@@ -44,13 +41,13 @@
44
41
  "egg-static": "^2.2.0",
45
42
  "egg-view": "^2.1.3",
46
43
  "extend2": "^4.0.0",
47
- "graceful": "^1.1.0",
44
+ "graceful": "^2.0.0",
45
+ "humanize-ms": "^2.0.0",
48
46
  "is-type-of": "^2.1.0",
49
47
  "koa-bodyparser": "^4.4.1",
50
- "koa-is-json": "^1.0.0",
51
48
  "koa-override": "^4.0.0",
52
- "ms": "^2.1.3",
53
49
  "onelogger": "^1.0.0",
50
+ "performance-ms": "^1.1.0",
54
51
  "sendmessage": "^3.0.1",
55
52
  "urllib": "^4.0.0",
56
53
  "utility": "^2.1.0",
@@ -71,7 +68,7 @@
71
68
  "coffee": "5",
72
69
  "cross-env": "7",
73
70
  "egg-bin": "beta",
74
- "egg-mock": "beta",
71
+ "@eggjs/mock": "beta",
75
72
  "egg-plugin-puml": "^2.4.0",
76
73
  "egg-tracer": "^2.1.0",
77
74
  "egg-view-nunjucks": "^2.3.0",
@@ -79,6 +76,7 @@
79
76
  "eslint-config-egg": "14",
80
77
  "formstream": "^1.5.1",
81
78
  "koa-static": "^5.0.0",
79
+ "mm": "^3.4.0",
82
80
  "pedding": "^1.1.0",
83
81
  "prettier": "^2.7.1",
84
82
  "runscript": "^2.0.1",
@@ -93,6 +91,7 @@
93
91
  "lint": "eslint src test --ext .ts",
94
92
  "pretest": "npm run lint -- --fix && npm run prepublishOnly",
95
93
  "test": "egg-bin test",
94
+ "test-local": "egg-bin test",
96
95
  "test:changed": "egg-bin test --changed",
97
96
  "preci": "npm run lint && npm run prepublishOnly && attw --pack",
98
97
  "ci": "egg-bin cov",
@@ -110,11 +109,15 @@
110
109
  "url": "git://github.com/eggjs/egg.git"
111
110
  },
112
111
  "license": "MIT",
112
+ "tnpm": {
113
+ "mode": "npm"
114
+ },
113
115
  "egg": {
114
116
  "framework": true,
115
- "baseDir": {
117
+ "exports": {
116
118
  "import": "./dist/esm",
117
- "require": "./dist/commonjs"
119
+ "require": "./dist/commonjs",
120
+ "typescript": "./src"
118
121
  }
119
122
  },
120
123
  "files": [
@@ -1,38 +1,81 @@
1
- import { performance } from 'node:perf_hooks';
2
1
  import delegate from 'delegates';
3
2
  import { assign } from 'utility';
4
- import { utils } from '@eggjs/core';
3
+ import { now, diff } from 'performance-ms';
4
+ import {
5
+ utils, Context as EggCoreContext, Router,
6
+ type ContextDelegation as EggCoreContextDelegation,
7
+ } from '@eggjs/core';
8
+ import type { Cookies as ContextCookies } from '@eggjs/cookies';
9
+ import { EggLogger } from 'egg-logger';
10
+ import type { Application } from '../../lib/application.js';
11
+ import type {
12
+ HttpClientRequestURL, HttpClientRequestOptions, HttpClient,
13
+ } from '../../lib/core/httpclient.js';
14
+ import type { ContextHttpClient } from '../../lib/core/context_httpclient.js';
15
+ import type { BaseContextClass } from '../../lib//core/base_context_class.js';
16
+ import Request from './request.js';
17
+ import Response from './response.js';
18
+ import type Helper from './helper.js';
5
19
 
6
- const HELPER = Symbol('Context#helper');
7
- const LOCALS = Symbol('Context#locals');
8
- const LOCALS_LIST = Symbol('Context#localsList');
9
- const COOKIES = Symbol('Context#cookies');
10
- const CONTEXT_LOGGERS = Symbol('Context#logger');
11
- const CONTEXT_HTTPCLIENT = Symbol('Context#httpclient');
12
- const CONTEXT_ROUTER = Symbol('Context#router');
20
+ import './context.types.js';
21
+
22
+ const HELPER = Symbol('ctx helper');
23
+ const LOCALS = Symbol('ctx locals');
24
+ const LOCALS_LIST = Symbol('ctx localsList');
25
+ const COOKIES = Symbol('ctx cookies');
26
+ const CONTEXT_HTTPCLIENT = Symbol('ctx httpclient');
27
+ const CONTEXT_ROUTER = Symbol('ctx router');
28
+
29
+ interface Cookies extends ContextCookies {
30
+ request: any;
31
+ response: any;
32
+ }
33
+
34
+ export default class Context extends EggCoreContext {
35
+ declare app: Application;
36
+ declare request: Request;
37
+ declare service: BaseContextClass;
38
+
39
+ /**
40
+ * Request start time
41
+ * @member {Number} Context#starttime
42
+ */
43
+ starttime: number;
44
+ /**
45
+ * Request start timer using `performance.now()`
46
+ * @member {Number} Context#performanceStarttime
47
+ */
48
+ performanceStarttime: number;
13
49
 
14
- const Context = {
15
50
  /**
16
51
  * Get the current visitor's cookies.
17
52
  */
18
53
  get cookies() {
19
- if (!this[COOKIES]) {
20
- this[COOKIES] = new this.app.ContextCookies(this, this.app.keys, this.app.config.cookies);
54
+ let cookies = this[COOKIES];
55
+ if (!cookies) {
56
+ this[COOKIES] = cookies = new this.app.ContextCookies(this, this.app.keys, this.app.config.cookies);
21
57
  }
22
- return this[COOKIES];
23
- },
58
+ return cookies as Cookies;
59
+ }
24
60
 
25
61
  /**
26
62
  * Get a wrapper httpclient instance contain ctx in the hold request process
27
63
  *
28
64
  * @return {ContextHttpClient} the wrapper httpclient instance
29
65
  */
30
- get httpclient() {
66
+ get httpclient(): ContextHttpClient {
31
67
  if (!this[CONTEXT_HTTPCLIENT]) {
32
- this[CONTEXT_HTTPCLIENT] = new this.app.ContextHttpClient(this);
68
+ this[CONTEXT_HTTPCLIENT] = new this.app.ContextHttpClient(this as any);
33
69
  }
34
- return this[CONTEXT_HTTPCLIENT];
35
- },
70
+ return this[CONTEXT_HTTPCLIENT] as ContextHttpClient;
71
+ }
72
+
73
+ /**
74
+ * Alias to {@link Context#httpclient}
75
+ */
76
+ get httpClient(): ContextHttpClient {
77
+ return this.httpclient;
78
+ }
36
79
 
37
80
  /**
38
81
  * Shortcut for httpclient.curl
@@ -42,9 +85,9 @@ const Context = {
42
85
  * @param {Object} [options] - options for request.
43
86
  * @return {Object} see {@link ContextHttpClient#curl}
44
87
  */
45
- curl(url: string, options?: object) {
46
- return this.httpclient.curl(url, options);
47
- },
88
+ async curl(url: HttpClientRequestURL, options?: HttpClientRequestOptions): ReturnType<HttpClient['request']> {
89
+ return await this.httpclient.curl(url, options);
90
+ }
48
91
 
49
92
  /**
50
93
  * Alias to {@link Application#router}
@@ -56,20 +99,20 @@ const Context = {
56
99
  * this.router.pathFor('post', { id: 12 });
57
100
  * ```
58
101
  */
59
- get router() {
60
- if (!this[CONTEXT_ROUTER]) {
61
- this[CONTEXT_ROUTER] = this.app.router;
102
+ get router(): Router {
103
+ if (this[CONTEXT_ROUTER]) {
104
+ return this[CONTEXT_ROUTER] as Router;
62
105
  }
63
- return this[CONTEXT_ROUTER];
64
- },
106
+ return this.app.router;
107
+ }
65
108
 
66
109
  /**
67
110
  * Set router to Context, only use on EggRouter
68
- * @param {EggRouter} val router instance
111
+ * @param {Router} val router instance
69
112
  */
70
- set router(val) {
113
+ set router(val: Router) {
71
114
  this[CONTEXT_ROUTER] = val;
72
- },
115
+ }
73
116
 
74
117
  /**
75
118
  * Get helper instance from {@link Application#Helper}
@@ -77,45 +120,27 @@ const Context = {
77
120
  * @member {Helper} Context#helper
78
121
  * @since 1.0.0
79
122
  */
80
- get helper() {
123
+ get helper(): Helper {
81
124
  if (!this[HELPER]) {
82
- this[HELPER] = new this.app.Helper(this);
125
+ this[HELPER] = new this.app.Helper(this as any);
83
126
  }
84
- return this[HELPER];
85
- },
127
+ return this[HELPER] as Helper;
128
+ }
86
129
 
87
130
  /**
88
131
  * Wrap app.loggers with context information,
89
132
  * if a custom logger is defined by naming aLogger, then you can `ctx.getLogger('aLogger')`
90
133
  *
91
134
  * @param {String} name - logger name
92
- * @return {Logger} logger
93
135
  */
94
- getLogger(name: string) {
95
- if (this.app.config.logger.enableFastContextLogger) {
96
- return this.app.getLogger(name);
97
- }
98
- let cache = this[CONTEXT_LOGGERS];
99
- if (!cache) {
100
- cache = this[CONTEXT_LOGGERS] = {};
101
- }
102
-
103
- // read from cache
104
- if (cache[name]) return cache[name];
105
-
106
- // get no exist logger
107
- const appLogger = this.app.getLogger(name);
108
- if (!appLogger) return null;
109
-
110
- // write to cache
111
- cache[name] = new this.app.ContextLogger(this, appLogger);
112
- return cache[name];
113
- },
136
+ getLogger(name: string): EggLogger {
137
+ return this.app.getLogger(name);
138
+ }
114
139
 
115
140
  /**
116
- * Logger for Application, wrapping app.coreLogger with context infomation
141
+ * Logger for Application
117
142
  *
118
- * @member {ContextLogger} Context#logger
143
+ * @member {Logger} Context#logger
119
144
  * @since 1.0.0
120
145
  * @example
121
146
  * ```js
@@ -123,20 +148,19 @@ const Context = {
123
148
  * this.logger.warn('WARNING!!!!');
124
149
  * ```
125
150
  */
126
- get logger() {
151
+ get logger(): EggLogger {
127
152
  return this.getLogger('logger');
128
- },
153
+ }
129
154
 
130
155
  /**
131
- * Logger for frameworks and plugins,
132
- * wrapping app.coreLogger with context infomation
156
+ * Logger for frameworks and plugins
133
157
  *
134
- * @member {ContextLogger} Context#coreLogger
158
+ * @member {Logger} Context#coreLogger
135
159
  * @since 1.0.0
136
160
  */
137
- get coreLogger() {
161
+ get coreLogger(): EggLogger {
138
162
  return this.getLogger('coreLogger');
139
- },
163
+ }
140
164
 
141
165
  /**
142
166
  * locals is an object for view, you can use `app.locals` and `ctx.locals` to set variables,
@@ -169,19 +193,18 @@ const Context = {
169
193
  if (!this[LOCALS]) {
170
194
  this[LOCALS] = assign({}, this.app.locals);
171
195
  }
172
- if (this[LOCALS_LIST] && this[LOCALS_LIST].length) {
196
+ if (Array.isArray(this[LOCALS_LIST]) && this[LOCALS_LIST].length > 0) {
173
197
  assign(this[LOCALS], this[LOCALS_LIST]);
174
198
  this[LOCALS_LIST] = null;
175
199
  }
176
- return this[LOCALS];
177
- },
200
+ return this[LOCALS] as Record<string, any>;
201
+ }
178
202
 
179
203
  set locals(val) {
180
- if (!this[LOCALS_LIST]) {
181
- this[LOCALS_LIST] = [];
182
- }
183
- this[LOCALS_LIST].push(val);
184
- },
204
+ const localsList = this[LOCALS_LIST] as Record<string, any>[] ?? [];
205
+ localsList.push(val);
206
+ this[LOCALS_LIST] = localsList;
207
+ }
185
208
 
186
209
  /**
187
210
  * alias to {@link Context#locals}, compatible with koa that use this variable
@@ -190,11 +213,11 @@ const Context = {
190
213
  */
191
214
  get state() {
192
215
  return this.locals;
193
- },
216
+ }
194
217
 
195
218
  set state(val) {
196
219
  this.locals = val;
197
- },
220
+ }
198
221
 
199
222
  /**
200
223
  * Run async function in the background
@@ -208,43 +231,40 @@ const Context = {
208
231
  * });
209
232
  * ```
210
233
  */
211
- runInBackground(scope: (ctx: any) => Promise<void>) {
234
+ runInBackground(scope: (ctx: ContextDelegation) => Promise<void>, taskName?: string): void {
212
235
  // try to use custom function name first
213
- /* istanbul ignore next */
214
- const taskName = Reflect.get(scope, '_name') || scope.name || utils.getCalleeFromStack(true);
215
- this._runInBackground(scope, taskName);
216
- },
236
+ if (!taskName) {
237
+ taskName = Reflect.get(scope, '_name') || scope.name || utils.getCalleeFromStack(true);
238
+ }
239
+ // use setImmediate to ensure all sync logic will run async
240
+ setImmediate(() => {
241
+ this._runInBackground(scope, taskName!);
242
+ });
243
+ }
217
244
 
218
245
  // let plugins or frameworks to reuse _runInBackground in some cases.
219
246
  // e.g.: https://github.com/eggjs/egg-mock/pull/78
220
- _runInBackground(scope: (ctx: any) => Promise<void>, taskName: string) {
221
- // eslint-disable-next-line @typescript-eslint/no-this-alias
222
- const ctx = this;
223
- const start = performance.now();
224
- // use setImmediate to ensure all sync logic will run async
225
- return new Promise(resolve => setImmediate(resolve))
226
- .then(() => scope(ctx))
227
- .then(() => {
228
- ctx.coreLogger.info('[egg:background] task:%s success (%dms)',
229
- taskName, Math.floor((performance.now() - start) * 1000) / 1000);
230
- })
231
- .catch(err => {
232
- // background task process log
233
- ctx.coreLogger.info('[egg:background] task:%s fail (%dms)',
234
- taskName, Math.floor((performance.now() - start) * 1000) / 1000);
247
+ async _runInBackground(scope: (ctx: ContextDelegation) => Promise<void>, taskName: string) {
248
+ const startTime = now();
249
+ try {
250
+ await scope(this as any);
251
+ this.coreLogger.info('[egg:background] task:%s success (%dms)', taskName, diff(startTime));
252
+ } catch (err: any) {
253
+ // background task process log
254
+ this.coreLogger.info('[egg:background] task:%s fail (%dms)', taskName, diff(startTime));
235
255
 
236
- // emit error when promise catch, and set err.runInBackground flag
237
- err.runInBackground = true;
238
- ctx.app.emit('error', err, ctx);
239
- });
240
- },
241
- } as any;
256
+ // emit error when promise catch, and set err.runInBackground flag
257
+ err.runInBackground = true;
258
+ this.app.emit('error', err, this);
259
+ }
260
+ }
261
+ }
242
262
 
243
263
  /**
244
264
  * Context delegation.
245
265
  */
246
266
 
247
- delegate(Context, 'request')
267
+ delegate(Context.prototype, 'request')
248
268
  /**
249
269
  * @member {Boolean} Context#acceptJSON
250
270
  * @see Request#acceptJSON
@@ -270,7 +290,7 @@ delegate(Context, 'request')
270
290
  */
271
291
  .access('ip');
272
292
 
273
- delegate(Context, 'response')
293
+ delegate(Context.prototype, 'response')
274
294
  /**
275
295
  * @member {Number} Context#realStatus
276
296
  * @see Response#realStatus
@@ -278,4 +298,6 @@ delegate(Context, 'response')
278
298
  */
279
299
  .access('realStatus');
280
300
 
281
- export default Context;
301
+ export type ContextDelegation = EggCoreContextDelegation & Context
302
+ & Pick<Request, 'acceptJSON' | 'queries' | 'accept' | 'ip'>
303
+ & Pick<Response, 'realStatus'>;
@@ -0,0 +1,24 @@
1
+ import type {
2
+ Router,
3
+ } from '@eggjs/core';
4
+ import type {
5
+ HttpClientRequestURL, HttpClientRequestOptions, HttpClient,
6
+ } from '../../lib/core/httpclient.js';
7
+ import type {
8
+ ContextHttpClient,
9
+ } from '../../lib/core/context_httpclient.js';
10
+ import type Helper from './helper.js';
11
+ import type { EggLogger } from 'egg-logger';
12
+
13
+ declare module '@eggjs/core' {
14
+ // add Context overrides types
15
+ interface Context {
16
+ curl(url: HttpClientRequestURL, options?: HttpClientRequestOptions): ReturnType<HttpClient['request']>;
17
+ get router(): Router;
18
+ set router(val: Router);
19
+ get helper(): Helper;
20
+ get httpclient(): ContextHttpClient;
21
+ get httpClient(): ContextHttpClient;
22
+ getLogger(name: string): EggLogger;
23
+ }
24
+ }
@@ -1,10 +1,12 @@
1
- 'use strict';
2
-
3
- const url = require('url');
4
-
5
-
6
- module.exports = {
1
+ import url from 'node:url';
2
+ import { BaseContextClass } from '../../lib/core/base_context_class.js';
7
3
 
4
+ /**
5
+ * The Helper class which can be used as utility function.
6
+ * We support developers to extend Helper through ${baseDir}/app/extend/helper.js ,
7
+ * then you can use all method on `ctx.helper` that is a instance of Helper.
8
+ */
9
+ export default class Helper extends BaseContextClass {
8
10
  /**
9
11
  * Generate URL path(without host) for route. Takes the route name and a map of named params.
10
12
  * @function Helper#pathFor
@@ -19,9 +21,9 @@ module.exports = {
19
21
  * ```
20
22
  * @return {String} url path(without host)
21
23
  */
22
- pathFor(name, params) {
24
+ pathFor(name: string, params: Record<string, any>): string {
23
25
  return this.app.router.url(name, params);
24
- },
26
+ }
25
27
 
26
28
  /**
27
29
  * Generate full URL(with host) for route. Takes the route name and a map of named params.
@@ -36,8 +38,7 @@ module.exports = {
36
38
  * ```
37
39
  * @return {String} full url(with host)
38
40
  */
39
- urlFor(name, params) {
40
- return this.ctx.protocol + '://' + this.ctx.host + url.resolve('/', this.app.router.url(name, params));
41
- },
42
-
43
- };
41
+ urlFor(name: string, params: Record<string, any>): string {
42
+ return this.ctx.protocol + '://' + this.ctx.host + url.resolve('/', this.pathFor(name, params));
43
+ }
44
+ }