Skip to content

Commit

Permalink
fix: should bind ctx to egg router controller this context (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 authored Jun 16, 2024
1 parent 3d2c33f commit b5b5588
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
19 changes: 15 additions & 4 deletions src/EggRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import assert from 'node:assert';
import { encodeURIComponent as safeEncodeURIComponent } from 'utility';
import inflection from 'inflection';
import methods from 'methods';
import { isGeneratorFunction } from 'is-type-of';
import { RegisterOptions, Router, RouterMethod, RouterOptions } from './Router.js';
import { MiddlewareFunc, ResourcesController } from './types.js';
import { MiddlewareFunc, Next, ResourcesController } from './types.js';

interface RestfulOptions {
suffix?: string;
Expand Down Expand Up @@ -146,8 +147,15 @@ export class EggRouter extends Router {
methods: string[],
middleware: MiddlewareFunc | string | (MiddlewareFunc | string | ResourcesController)[],
opts?: RegisterOptions) {
// patch register to support generator function middleware and string controller
// patch register to support bind ctx function middleware and string controller
middleware = Array.isArray(middleware) ? middleware : [ middleware ];
for (const mw of middleware) {
if (isGeneratorFunction(mw)) {
throw new TypeError(
methods.toString() + ' `' + path + '`: Please use async function instead of generator function',
);
}
}
const middlewares = convertMiddlewares(middleware, this.app);
return super.register(path, methods, middlewares, opts);
}
Expand Down Expand Up @@ -326,13 +334,16 @@ function resolveController(controller: string | MiddlewareFunc | ResourcesContro
* - [name, url(regexp), controller]: app.get('regRouter', /\/home\/index/, 'home.index');
* - [name, url, middleware, [...], controller]: `app.get(/user/:id', hasLogin, canGetUser, 'user.show');`
*
* 2. make middleware support generator function
* 2. bind ctx to controller `this`
*
* @param {Array} middlewares middlewares and controller(last middleware)
* @param {Application} app egg application instance
*/
function convertMiddlewares(middlewares: (MiddlewareFunc | string | ResourcesController)[], app: Application) {
// ensure controller is resolved
const controller = resolveController(middlewares.pop()!, app);
return [ ...middlewares as MiddlewareFunc[], controller ];
function wrappedController(ctx: any, next: Next) {
return controller.apply(ctx, [ ctx, next ]);
}
return [ ...middlewares as MiddlewareFunc[], wrappedController ];
}
19 changes: 19 additions & 0 deletions test/EggRouter.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
import { strict as assert } from 'node:assert';
import is from 'is-type-of';
import Koa from '@eggjs/koa';
import request from 'supertest';
import { EggRouter } from '../src/index.js';

describe('test/EggRouter.test.ts', () => {
it('auto bind ctx to this on controller', async () => {
const app = new Koa();
const router = new EggRouter({}, app as any);
router.get('home', '/', function(this: any) {
this.body = {
url: this.router.url('home'),
method: this.method,
};
});
app.use(router.routes());
const res = await request(app.callback())
.get('/')
.expect(200);
assert.equal(res.body.url, '/');
assert.equal(res.body.method, 'GET');
});

it('creates new router with egg app', () => {
const app = { controller: {} };
const router = new EggRouter({}, app);
Expand Down

0 comments on commit b5b5588

Please sign in to comment.