Skip to content

Commit 51bde52

Browse files
resolve conflicts
2 parents e974283 + 3c340b8 commit 51bde52

4 files changed

Lines changed: 121 additions & 3 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { INestApplication, MiddlewareConsumer, Module } from '@nestjs/common';
2+
import { Test } from '@nestjs/testing';
3+
import * as request from 'supertest';
4+
5+
const RETURN_VALUE_A = 'test_A';
6+
const RETURN_VALUE_B = 'test_B';
7+
8+
@Module({
9+
imports: [],
10+
})
11+
class TestAModule {
12+
configure(consumer: MiddlewareConsumer) {
13+
consumer
14+
.apply((req, res, next) => {
15+
res.send(RETURN_VALUE_A);
16+
})
17+
.forRoutes('hello');
18+
}
19+
}
20+
21+
@Module({
22+
imports: [TestAModule],
23+
})
24+
class TestBModule {
25+
configure(consumer: MiddlewareConsumer) {
26+
consumer
27+
.apply((req, res, next) => {
28+
res.send(RETURN_VALUE_B);
29+
})
30+
.forRoutes('hello');
31+
}
32+
}
33+
34+
@Module({
35+
imports: [TestBModule],
36+
})
37+
class TestModule {
38+
}
39+
40+
describe('Middleware Execute Order', () => {
41+
let app: INestApplication;
42+
43+
beforeEach(async () => {
44+
app = (await Test.createTestingModule({
45+
imports: [TestModule],
46+
}).compile()).createNestApplication();
47+
48+
await app.init();
49+
});
50+
51+
it(`Execute middleware of dependent modules first `, () => {
52+
return request(app.getHttpServer())
53+
.get('/hello')
54+
.expect(200, RETURN_VALUE_A);
55+
});
56+
57+
afterEach(async () => {
58+
await app.close();
59+
});
60+
});

packages/core/injector/module.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export class Module {
4444
InstanceWrapper<Controller>
4545
>();
4646
private readonly _exports = new Set<string | symbol>();
47+
private _distance: number = 0;
4748

4849
constructor(
4950
private readonly _metatype: Type<any>,
@@ -115,6 +116,17 @@ export class Module {
115116
return this._metatype;
116117
}
117118

119+
get distance(): number {
120+
return this._distance;
121+
}
122+
123+
set distance(distance: number) {
124+
this._distance = distance;
125+
Array.from(this._imports)
126+
.filter(module => module && !module.imports.has(this))
127+
.forEach(module => (module.distance = distance + 1));
128+
}
129+
118130
public addCoreProviders(container: NestContainer) {
119131
this.addModuleAsProvider();
120132
this.addModuleRef();
@@ -399,8 +411,12 @@ export class Module {
399411
);
400412
}
401413

402-
public addRelatedModule(module: any) {
414+
public addRelatedModule(module: Module) {
403415
this._imports.add(module);
416+
module.distance =
417+
this._distance + 1 > module._distance
418+
? this._distance + 1
419+
: module._distance;
404420
}
405421

406422
public replace(toReplace: string | symbol | Type<any>, options: any) {

packages/core/middleware/middleware-module.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,18 @@ export class MiddlewareModule {
114114
);
115115
});
116116

117-
const configEntries = [...configs.entries()];
117+
const entriesSortedByDistance = [...configs.entries()].sort(
118+
([moduleA], [moduleB]) => {
119+
return (
120+
this.container.getModuleByKey(moduleB).distance -
121+
this.container.getModuleByKey(moduleA).distance
122+
);
123+
},
124+
);
118125
const registerModuleConfigs = async ([module, moduleConfigs]) => {
119126
await Promise.all(registerAllConfigs(module, [...moduleConfigs]));
120127
};
121-
await Promise.all(configEntries.map(registerModuleConfigs));
128+
await Promise.all(entriesSortedByDistance.map(registerModuleConfigs));
122129
}
123130

124131
public async registerMiddlewareConfig(

packages/core/test/injector/module.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,4 +481,39 @@ describe('Module', () => {
481481
});
482482
});
483483
});
484+
485+
describe('getter "distance"', () => {
486+
@ModuleDecorator({})
487+
class ModuleA {}
488+
489+
@ModuleDecorator({})
490+
class ModuleB {}
491+
492+
@ModuleDecorator({})
493+
class ModuleC {}
494+
495+
let moduleA, moduleB, moduleC;
496+
beforeEach(() => {
497+
moduleA = new Module(ModuleA as any, [], container);
498+
moduleB = new Module(ModuleB as any, [], container);
499+
moduleC = new Module(ModuleC as any, [], container);
500+
});
501+
502+
it('should get "distance" correct', () => {
503+
moduleA.addRelatedModule(moduleB);
504+
moduleC.addRelatedModule(moduleB);
505+
moduleA.addRelatedModule(moduleC);
506+
507+
expect(moduleA.distance).to.be.equal(0);
508+
expect(moduleB.distance).to.be.equal(2);
509+
expect(moduleC.distance).to.be.equal(1);
510+
});
511+
512+
it('should don`t throw exception when circular dependency', () => {
513+
expect(() => {
514+
moduleA.addRelatedModule(moduleB);
515+
moduleB.addRelatedModule(moduleA);
516+
}).to.not.throw;
517+
});
518+
});
484519
});

0 commit comments

Comments
 (0)