diff --git a/index-old.d.ts b/index-old.d.ts index 9a884f0d15..b055d8874c 100644 --- a/index-old.d.ts +++ b/index-old.d.ts @@ -32,7 +32,6 @@ // BaseContextClass as CoreBaseContextClass, // } from 'egg-core'; // import EggCookies = require('egg-cookies'); -// import 'egg-onerror'; // import 'egg-multipart'; // import 'egg-logrotator'; // import 'egg-view'; diff --git a/package.json b/package.json index 7e8c9b08af..b28ce39d36 100644 --- a/package.json +++ b/package.json @@ -19,49 +19,47 @@ "egg" ], "dependencies": { - "@eggjs/cluster": "^3.0.0", - "@eggjs/cookies": "^3.0.0", - "@eggjs/core": "^6.3.0", + "@eggjs/cluster": "^3.0.1", + "@eggjs/cookies": "^3.1.0", + "@eggjs/core": "^6.3.1", "@eggjs/development": "^4.0.0", "@eggjs/i18n": "^3.0.1", "@eggjs/jsonp": "^3.0.0", + "@eggjs/onerror": "^3.0.0", "@eggjs/schedule": "^5.0.2", "@eggjs/security": "^4.0.0", - "@eggjs/session": "^4.0.0", + "@eggjs/session": "^4.0.1", "@eggjs/static": "^3.0.0", - "@eggjs/utils": "^4.2.4", - "@eggjs/watcher": "^4.0.3", + "@eggjs/utils": "^4.2.5", + "@eggjs/watcher": "^4.0.4", "circular-json-for-egg": "^1.0.0", "cluster-client": "^3.7.0", - "egg-errors": "^2.3.1", - "egg-logger": "^3.6.0", - "egg-logrotator": "^3.1.0", - "egg-multipart": "^3.1.0", - "egg-onerror": "^2.1.1", - "egg-view": "^2.1.3", + "egg-errors": "^2.3.2", + "egg-logger": "^3.6.1", + "egg-logrotator": "^3.2.0", + "egg-multipart": "^3.5.0", + "egg-view": "^2.1.4", "extend2": "^4.0.0", "graceful": "^2.0.0", "humanize-ms": "^2.0.0", - "is-type-of": "^2.1.0", + "is-type-of": "^2.2.0", "koa-bodyparser": "^4.4.1", "koa-override": "^4.0.0", "onelogger": "^1.0.1", "performance-ms": "^1.1.0", "sendmessage": "^3.0.1", "urllib": "^4.6.11", - "utility": "^2.1.0", - "ylru": "^1.3.2" + "utility": "^2.5.0" }, "devDependencies": { - "@arethetypeswrong/cli": "^0.17.1", - "@eggjs/bin": "^7.0.0", - "@eggjs/koa": "^2.19.1", + "@arethetypeswrong/cli": "^0.17.3", + "@eggjs/bin": "^7.0.2", + "@eggjs/koa": "^2.20.6", "@eggjs/mock": "^6.0.5", - "@eggjs/supertest": "^8.1.1", + "@eggjs/supertest": "^8.2.0", "@eggjs/tsconfig": "1", "@types/koa-bodyparser": "^4.3.12", - "@types/mocha": "^10.0.7", - "@types/ms": "^0.7.34", + "@types/mocha": "^10.0.10", "@types/node": "22", "address": "2", "assert-file": "1", @@ -75,12 +73,12 @@ "eslint-config-egg": "14", "formstream": "^1.5.1", "koa-static": "^5.0.0", - "mm": "^3.4.0", + "mm": "^4.0.2", "pedding": "^2.0.1", - "prettier": "^2.7.1", + "prettier": "^3.4.2", "rimraf": "6", "runscript": "^2.0.1", - "sdk-base": "^4.2.1", + "sdk-base": "^5.0.1", "spy": "^1.0.0", "tsd": "^0.31.2", "tshy": "^3.0.2", diff --git a/site/docs/advanced/cluster-client.md b/site/docs/advanced/cluster-client.md index bbe6b834f2..a36a72b683 100644 --- a/site/docs/advanced/cluster-client.md +++ b/site/docs/advanced/cluster-client.md @@ -70,7 +70,7 @@ We abstract the client interface into the following two broad categories, which Client example ```js -const Base = require('sdk-base'); +const { Base } = require('sdk-base'); class Client extends Base { constructor(options) { @@ -168,8 +168,8 @@ In the following I will use a simple example to introduce how to make a client s ```js // registry_client.js -const URL = require('url'); -const Base = require('sdk-base'); +const { parse } = require('node:url'); +const { Base } = require('sdk-base'); class RegistryClient extends Base { constructor(options) { @@ -236,7 +236,7 @@ class RegistryClient extends Base { if (changed) { this.emit( key, - this._registered.get(key).map((url) => URL.parse(url, true)), + this._registered.get(key).map((url) => parse(url, true)), ); } } diff --git a/site/docs/advanced/cluster-client.zh-CN.md b/site/docs/advanced/cluster-client.zh-CN.md index 9e6ba1a33a..df39c9e324 100644 --- a/site/docs/advanced/cluster-client.zh-CN.md +++ b/site/docs/advanced/cluster-client.zh-CN.md @@ -69,7 +69,7 @@ win / +------------------+ \ lose 客户端示例 ```js -const Base = require('sdk-base'); +const { Base } = require('sdk-base'); class Client extends Base { constructor(options) { @@ -165,8 +165,8 @@ Leader 和 Follower 通过下面的协议进行数据交换: ```js // registry_client.js -const URL = require('url'); -const Base = require('sdk-base'); +const { parse } = require('node:url'); +const { Base } = require('sdk-base'); class RegistryClient extends Base { constructor(options) { @@ -233,7 +233,7 @@ class RegistryClient extends Base { if (changed) { this.emit( key, - this._registered.get(key).map(url => URL.parse(url, true)), + this._registered.get(key).map(url => parse(url, true)), ); } } @@ -554,4 +554,4 @@ class APIClient extends APIClientBase { } module.exports = APIClient; -``` \ No newline at end of file +``` diff --git a/site/docs/basics/plugin.md b/site/docs/basics/plugin.md index 0dfc9b36ce..1b09fd093d 100644 --- a/site/docs/basics/plugin.md +++ b/site/docs/basics/plugin.md @@ -160,7 +160,7 @@ Specific consolidation rules can be found in [Configuration](./config.md). ## Plugin List - Framework has default built-in plugins for enterprise applications [Common plugins](https://eggjs.org/zh-cn/plugins/): -   - [onerror](https://github.com/eggjs/egg-onerror) Uniform Exception Handling +   - [onerror](https://github.com/eggjs/onerror) Uniform Exception Handling   - [session](https://github.com/eggjs/session) Session implementation   - [i18n](https://github.com/eggjs/i18n) Multilingual   - [watcher](https://github.com/eggjs/watcher) File and folder monitoring diff --git a/site/docs/basics/plugin.zh-CN.md b/site/docs/basics/plugin.zh-CN.md index f940b2f98f..4075883383 100644 --- a/site/docs/basics/plugin.zh-CN.md +++ b/site/docs/basics/plugin.zh-CN.md @@ -160,7 +160,7 @@ exports.mysql = { ## 插件列表 - 框架默认内置了企业级应用[常用的插件](https://eggjs.org/zh-cn/plugins/): - - [onerror](https://github.com/eggjs/egg-onerror) 统一异常处理 + - [onerror](https://github.com/eggjs/onerror) 统一异常处理 - [session](https://github.com/eggjs/session) Session 实现 - [i18n](https://github.com/eggjs/i18n) 多语言 - [watcher](https://github.com/eggjs/watcher) 文件和文件夹监控 diff --git a/site/docs/core/cookie-and-session.md b/site/docs/core/cookie-and-session.md index 0f54c2aab0..f1e40acfc0 100644 --- a/site/docs/core/cookie-and-session.md +++ b/site/docs/core/cookie-and-session.md @@ -220,18 +220,18 @@ module.exports = (app) => { ``` The implementation of `sessionStore` can also be encapsulated into a plugin. -For example, [egg-session-redis] stores Session in Redis. -To apply it, import [egg-redis] and [egg-session-redis] plugin in your application. +For example, [@eggjs/session-redis] stores Session in Redis. +To apply it, import [@eggjs/redis] and [@eggjs/session-redis] plugin in your application. ```js // plugin.js exports.redis = { enable: true, - package: 'egg-redis', + package: '@eggjs/redis', }; exports.sessionRedis = { enable: true, - package: 'egg-session-redis', + package: '@eggjs/session-redis', }; ``` @@ -283,5 +283,5 @@ module.exports = { }; ``` -[egg-redis]: https://github.com/eggjs/egg-redis -[egg-session-redis]: https://github.com/eggjs/egg-session-redis +[@eggjs/redis]: https://github.com/eggjs/redis +[@eggjs/session-redis]: https://github.com/eggjs/session-redis diff --git a/site/docs/core/cookie-and-session.zh-CN.md b/site/docs/core/cookie-and-session.zh-CN.md index 28c67500d5..defe546582 100644 --- a/site/docs/core/cookie-and-session.zh-CN.md +++ b/site/docs/core/cookie-and-session.zh-CN.md @@ -183,17 +183,17 @@ module.exports = app => { }; ``` -例如,通过引入 [egg-redis](https://github.com/eggjs/egg-redis) 和 [egg-session-redis](https://github.com/eggjs/egg-session-redis) 插件,可以将 Session 存储到 redis 中。 +例如,通过引入 [@eggjs/redis](https://github.com/eggjs/redis) 和 [@eggjs/session-redis](https://github.com/eggjs/session-redis) 插件,可以将 Session 存储到 redis 中。 ```js // plugin.js exports.redis = { enable: true, - package: 'egg-redis', + package: '@eggjs/redis', }; exports.sessionRedis = { enable: true, - package: 'egg-session-redis', + package: '@eggjs/session-redis', }; ``` @@ -231,6 +231,3 @@ exports.session = { renew: true, }; ``` - -[egg-redis]: https://github.com/eggjs/egg-redis -[egg-session-redis]: https://github.com/eggjs/egg-session-redis diff --git a/site/docs/core/error-handling.md b/site/docs/core/error-handling.md index 490ec444a1..1eb17ffb4a 100644 --- a/site/docs/core/error-handling.md +++ b/site/docs/core/error-handling.md @@ -61,7 +61,7 @@ For convenience of locating problems, exceptions must be guaranteed to be Error ## Egg Takes Charge of Exceptions -[egg-onerror](https://github.com/eggjs/egg-onerror), one of Egg's plugin, handles all exceptions thrown in Middleware, Controller and Service, and returns the error as response based on "Accept" in request header field. +[@eggjs/onerror](https://github.com/eggjs/onerror), one of Egg's plugin, handles all exceptions thrown in Middleware, Controller and Service, and returns the error as response based on "Accept" in request header field. | Accept | ENV | errorPageUrl | response | | ------------ | ---------------- | ------------ | ---------------------------------------------------- | diff --git a/site/docs/core/error-handling.zh-CN.md b/site/docs/core/error-handling.zh-CN.md index 512af4c547..13780e74f7 100644 --- a/site/docs/core/error-handling.zh-CN.md +++ b/site/docs/core/error-handling.zh-CN.md @@ -59,7 +59,7 @@ class HomeController extends Controller { ## 框架层统一异常处理 -框架通过 [onerror](https://github.com/eggjs/egg-onerror) 插件提供统一的错误处理机制。此机制将捕获所有处理方法(Middleware、Controller、Service)中抛出的任何异常,并根据请求预期的响应类型返回不同的错误内容。 +框架通过 [@eggjs/onerror](https://github.com/eggjs/onerror) 插件提供统一的错误处理机制。此机制将捕获所有处理方法(Middleware、Controller、Service)中抛出的任何异常,并根据请求预期的响应类型返回不同的错误内容。 | 请求格式需求 | 环境 | `errorPageUrl` 配置 | 返回内容 | | ------------ | ---- | ------------------- | -------- | diff --git a/site/docs/tutorials/socketio.md b/site/docs/tutorials/socketio.md index 08717d67b8..90c40d2ac7 100644 --- a/site/docs/tutorials/socketio.md +++ b/site/docs/tutorials/socketio.md @@ -84,7 +84,7 @@ exports.io = { > Here `redis` is only used to store connection instance information, see [# server.adapter](https://socket.io/docs/server-api/#server-adapter-value) **Note:** -If the project also uses the `egg-redis`, please configure it separately. Do not share it. +If the project also uses the `@eggjs/redis`, please configure it separately. Do not share it. ### Deployment diff --git a/site/docs/tutorials/socketio.zh-CN.md b/site/docs/tutorials/socketio.zh-CN.md index 0c45212616..4d3ef80a26 100644 --- a/site/docs/tutorials/socketio.zh-CN.md +++ b/site/docs/tutorials/socketio.zh-CN.md @@ -84,7 +84,7 @@ exports.io = { > 开启 `redis` 后,程序在启动时会尝试连接到 redis 服务器。此处的 `redis` 仅用于存储连接实例信息,详见 [#server.adapter](https://socket.io/docs/server-api/#server-adapter-value)。 **注意:** -如果项目中同时使用了 `egg-redis`,请分别配置,不可共用。 +如果项目中同时使用了 `@eggjs/redis`,请分别配置,不可共用。 ### 部署 diff --git a/src/config/plugin.ts b/src/config/plugin.ts index 8e0a3b4454..9c51dbc04c 100644 --- a/src/config/plugin.ts +++ b/src/config/plugin.ts @@ -6,7 +6,7 @@ export default { */ onerror: { enable: true, - package: 'egg-onerror', + package: '@eggjs/onerror', }, /** diff --git a/src/lib/egg.ts b/src/lib/egg.ts index eefee70d9e..f9d038ec50 100644 --- a/src/lib/egg.ts +++ b/src/lib/egg.ts @@ -690,11 +690,13 @@ declare module '@eggjs/core' { get currentContext(): EggContext | undefined; ctxStorage: AsyncLocalStorage; getLogger(name: string): EggLogger; + get loggers(): EggLoggers; createHttpClient(options?: HttpClientOptions): HttpClient; HttpClient: typeof HttpClient; get httpClient(): HttpClient; curl(url: HttpClientRequestURL, options?: HttpClientRequestOptions): Promise>; createAnonymousContext(req?: any): EggContext; runInAnonymousContextScope(scope: (ctx: Context) => Promise, req?: unknown): Promise; + readonly messenger: IMessenger; } } diff --git a/src/lib/types.ts b/src/lib/types.ts index ab9344430e..db96f8f154 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -25,7 +25,7 @@ import '@eggjs/static'; import '@eggjs/security'; import '@eggjs/schedule'; import '@eggjs/session'; - +import '@eggjs/onerror'; export type { EggAppInfo, } from '@eggjs/core'; diff --git a/test/cluster1/cluster-client.test.ts b/test/cluster1/cluster-client.test.ts index bdea52dfb7..cbbd71b0df 100644 --- a/test/cluster1/cluster-client.test.ts +++ b/test/cluster1/cluster-client.test.ts @@ -1,4 +1,5 @@ import { strict as assert } from 'node:assert'; +import { scheduler } from 'node:timers/promises'; import { mm } from '@eggjs/mock'; import { MockApplication, createApp, singleProcessApp } from '../utils.js'; @@ -15,45 +16,35 @@ describe('test/cluster1/cluster-client.test.ts', () => { after(async () => { await app.close(); const agentInnerClient = app.agent.registryClient[innerClient]; - assert(agentInnerClient._realClient.closed === true); - mm.restore(); + assert.equal(agentInnerClient._realClient.closed, true); + await mm.restore(); }); - it('should publish & subscribe', () => { - return app.httpRequest() + it('should publish & subscribe', async () => { + await app.httpRequest() .post('/publish') .send({ value: 'www.testme.com' }) .expect('ok') - .expect(200) - .then(() => { - return new Promise(resolve => { - setTimeout(resolve, 500); - }); - }) - .then(() => { - return app.httpRequest() - .get('/getHosts') - .expect('www.testme.com:20880') - .expect(200); - }); + .expect(200); + await scheduler.wait(500); + await app.httpRequest() + .get('/getHosts') + .expect('www.testme.com:20880') + .expect(200); }); - it('should get default cluster response timeout', () => { - return app.httpRequest() + it('should get default cluster response timeout', async () => { + const res = await app.httpRequest() .get('/getDefaultTimeout') - .expect(200) - .then(res => { - assert(res.text === '60000'); - }); + .expect(200); + assert.equal(res.text, '60000'); }); - it('should get overwrite cluster response timeout', () => { - return app.httpRequest() + it('should get overwrite cluster response timeout', async () => { + const res = await app.httpRequest() .get('/getOverwriteTimeout') - .expect(200) - .then(res => { - assert(res.text === '1000'); - }); + .expect(200); + assert.equal(res.text, '1000'); }); }); @@ -65,45 +56,35 @@ describe('test/cluster1/cluster-client.test.ts', () => { after(async () => { await app.close(); const agentInnerClient = app.agent.registryClient[innerClient]; - assert(agentInnerClient._realClient.closed === true); + assert.equal(agentInnerClient._realClient.closed, true); mm.restore(); }); - it('should publish & subscribe', () => { - return app.httpRequest() + it('should publish & subscribe', async () => { + await app.httpRequest() .post('/publish') .send({ value: 'www.testme.com' }) .expect('ok') - .expect(200) - .then(() => { - return new Promise(resolve => { - setTimeout(resolve, 500); - }); - }) - .then(() => { - return app.httpRequest() - .get('/getHosts') - .expect('www.testme.com:20880') - .expect(200); - }); + .expect(200); + await scheduler.wait(500); + await app.httpRequest() + .get('/getHosts') + .expect('www.testme.com:20880') + .expect(200); }); - it('should get default cluster response timeout', () => { - return app.httpRequest() + it('should get default cluster response timeout', async () => { + const res = await app.httpRequest() .get('/getDefaultTimeout') - .expect(200) - .then(res => { - assert(res.text === '60000'); - }); + .expect(200); + assert.equal(res.text, '60000'); }); - it('should get overwrite cluster response timeout', () => { - return app.httpRequest() + it('should get overwrite cluster response timeout', async () => { + const res = await app.httpRequest() .get('/getOverwriteTimeout') - .expect(200) - .then(res => { - assert(res.text === '1000'); - }); + .expect(200); + assert.equal(res.text, '1000'); }); }); }); diff --git a/test/fixtures/apps/cluster_mod_app/agent.js b/test/fixtures/apps/cluster_mod_app/agent.js index 1abc3bc6c6..9142c8ffb8 100644 --- a/test/fixtures/apps/cluster_mod_app/agent.js +++ b/test/fixtures/apps/cluster_mod_app/agent.js @@ -2,18 +2,26 @@ const ApiClient = require('./lib/api_client'); const ApiClient2 = require('./lib/api_client_2'); const RegistryClient = require('./lib/registry_client'); -module.exports = function(agent) { - agent.registryClient = agent.cluster(RegistryClient).create(); - agent.apiClient = new ApiClient({ - cluster: agent.cluster, - }); - agent.apiClient2 = new ApiClient2({ - cluster: agent.cluster, - }); +module.exports = class Boot { + constructor(agent) { + this.agent = agent; + } - agent.beforeStart(async function() { + async didLoad() { + const agent = this.agent; + agent.registryClient = agent.cluster(RegistryClient).create(); + agent.apiClient = new ApiClient({ + cluster: agent.cluster, + }); + agent.apiClient2 = new ApiClient2({ + cluster: agent.cluster, + }); + } + + async willReady() { + const agent = this.agent; await agent.registryClient.ready(); await agent.apiClient.ready(); await agent.apiClient2.ready(); - }); + } }; diff --git a/test/fixtures/apps/cluster_mod_app/lib/registry_client.js b/test/fixtures/apps/cluster_mod_app/lib/registry_client.js index e5969ff3a8..c97a72418a 100644 --- a/test/fixtures/apps/cluster_mod_app/lib/registry_client.js +++ b/test/fixtures/apps/cluster_mod_app/lib/registry_client.js @@ -1,7 +1,5 @@ -'use strict'; - -const URL = require('url'); -const Base = require('sdk-base'); +const { parse } = require('node:url'); +const { Base } = require('sdk-base'); class RegistryClient extends Base { constructor() { @@ -45,7 +43,7 @@ class RegistryClient extends Base { } else { this._registered.set(key, [reg.publishData]); } - this.emit(key, this._registered.get(key).map(url => new URL.parse(url, true))); + this.emit(key, this._registered.get(key).map(url => parse(url, true))); } close() { diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 20015d36dd..10a337a3dd 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -10,8 +10,13 @@ import { Singleton, } from '../src/index.js'; import { HttpClient } from '../src/urllib.js'; +import { IMessenger } from '../src/lib/core/messenger/IMessenger.js'; const app = {} as EggCore; +expectType(app.messenger); +expectType(app.messenger.broadcast('test')); +expectType(app.loggers.reload()); + const ctx = app.createAnonymousContext(); expectType>(app.runInAnonymousContextScope(async ctx => { @@ -59,6 +64,10 @@ expectType(app.config.security.csrf.headerName); // session plugin types expectType(app.config.session.httpOnly); +// onerror plugin types +expectType<(err: any, ctx: any) => void>(app.config.onerror.html!); +expectType(app.config.onerror.errorPageUrl as string); + class AppBoot implements ILifecycleBoot { private readonly app: Application; @@ -103,7 +112,8 @@ class AppBoot implements ILifecycleBoot { } } -const appBoot = new AppBoot(app); +const app1 = {} as Application; +const appBoot = new AppBoot(app1); expectType(appBoot); expectType(appBoot); diff --git a/test/lib/core/loader/load_plugin.test.ts b/test/lib/core/loader/load_plugin.test.ts index e80ea76828..e6acef820f 100644 --- a/test/lib/core/loader/load_plugin.test.ts +++ b/test/lib/core/loader/load_plugin.test.ts @@ -54,9 +54,9 @@ describe('test/lib/core/loader/load_plugin.test.ts', () => { from: path.join(baseDir, 'config/plugin.js'), }); assert.equal( - appLoader.plugins.onerror.path, path.join(EGG_BASE, 'node_modules/egg-onerror'), + appLoader.plugins.onerror.path, path.join(EGG_BASE, 'node_modules/@eggjs/onerror/dist/esm'), ); - assert(appLoader.plugins.onerror.package === 'egg-onerror'); + assert.equal(appLoader.plugins.onerror.package, '@eggjs/onerror'); assert.match(appLoader.plugins.onerror.version!, /\d+\.\d+\.\d+/); assert(Array.isArray(appLoader.orderPlugins)); }); diff --git a/test/lib/core/messenger/local.test.ts b/test/lib/core/messenger/local.test.ts index ebac375cbc..8b1126eb80 100644 --- a/test/lib/core/messenger/local.test.ts +++ b/test/lib/core/messenger/local.test.ts @@ -1,10 +1,10 @@ import { strict as assert } from 'node:assert'; import { mm } from '@eggjs/mock'; import { pending } from 'pedding'; -import { singleProcessApp, MockApplication } from '../../../utils.js'; +import { singleProcessApp, SingleModeApplication } from '../../../utils.js'; describe('test/lib/core/messenger/local.test.ts', () => { - let app: MockApplication; + let app: SingleModeApplication; before(async () => { app = await singleProcessApp('apps/demo'); @@ -144,10 +144,11 @@ describe('test/lib/core/messenger/local.test.ts', () => { done(); }); - let res = app.messenger.sendTo(process.pid, 'sendTo-event', { foo: 'bar' }); + // keep compatible with old code, use process.pid as number + let res = (app.messenger as any).sendTo(process.pid, 'sendTo-event', { foo: 'bar' }); assert(res === app.messenger); // should ignore if target process is not self - res = app.messenger.sendTo(1, 'sendTo-event', { foo: 'bar' }); + res = app.messenger.sendTo('1', 'sendTo-event', { foo: 'bar' }); assert(res === app.messenger); }); @@ -162,7 +163,7 @@ describe('test/lib/core/messenger/local.test.ts', () => { done(); }); - app.agent.messenger.sendTo(process.pid, 'sendTo-event', { foo: 'bar' }); + app.agent.messenger.sendTo(String(process.pid), 'sendTo-event', { foo: 'bar' }); }); }); @@ -201,7 +202,7 @@ describe('test/lib/core/messenger/local.test.ts', () => { describe('onMessage()', () => { it('should ignore if message format error', () => { - app.messenger.onMessage(); + (app.messenger as any).onMessage(); app.messenger.onMessage('foo'); app.messenger.onMessage({ action: 1 }); }); diff --git a/test/utils.ts b/test/utils.ts index ac06760b4d..d7d254d23f 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -13,6 +13,7 @@ import { Application as Koa } from '@eggjs/koa'; import { request } from '@eggjs/supertest'; import { startEgg, StartEggOptions, + type SingleModeAgent, } from '../src/index.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -24,6 +25,10 @@ export async function rimraf(target: string) { } export { MockApplication, MockOptions, MockClusterOptions, mm }; +export interface SingleModeApplication extends MockApplication { + agent: SingleModeAgent; +} + export const restore = () => mm.restore(); export function app(name: string | MockOptions, options?: MockOptions) { @@ -54,7 +59,7 @@ export function cluster(name: string | MockClusterOptions, options?: MockCluster * @param {Object} [options] - optional * @return {App} app - Application object. */ -export async function singleProcessApp(baseDir: string, options: StartEggOptions = {}): Promise { +export async function singleProcessApp(baseDir: string, options: StartEggOptions = {}): Promise { if (!baseDir.startsWith('/')) { baseDir = path.join(__dirname, 'fixtures', baseDir); } @@ -62,7 +67,7 @@ export async function singleProcessApp(baseDir: string, options: StartEggOptions options.baseDir = baseDir; const app = await startEgg(options); Reflect.set(app, 'httpRequest', () => request(app.callback())); - return app as unknown as MockApplication; + return app as unknown as SingleModeApplication; } let localServer: http.Server | undefined;