Skip to content

Commit 166ef67

Browse files
Merge pull request nestjs#6573 from MyAeroCode/lutz-feat/route-injection
feat(core): support route injection
2 parents 2cda45b + 3f154cf commit 166ef67

2 files changed

Lines changed: 87 additions & 8 deletions

File tree

packages/core/router/router-explorer.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,23 @@ export class RouterExplorer {
124124
prototype: object,
125125
methodName: string,
126126
): RoutePathProperties {
127-
const targetCallback = prototype[methodName];
128-
const routePath = Reflect.getMetadata(PATH_METADATA, targetCallback);
127+
const instanceCallback = instance[methodName];
128+
const prototypeCallback = prototype[methodName];
129+
const routePath = Reflect.getMetadata(PATH_METADATA, prototypeCallback);
129130
if (isUndefined(routePath)) {
130131
return null;
131132
}
132133
const requestMethod: RequestMethod = Reflect.getMetadata(
133134
METHOD_METADATA,
134-
targetCallback,
135+
prototypeCallback,
135136
);
136137
const path = isString(routePath)
137138
? [addLeadingSlash(routePath)]
138139
: routePath.map(p => addLeadingSlash(p));
139140
return {
140141
path,
141142
requestMethod,
142-
targetCallback,
143+
targetCallback: instanceCallback,
143144
methodName,
144145
};
145146
}

packages/core/test/router/router-explorer.spec.ts

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,55 +109,133 @@ describe('RouterExplorer', () => {
109109
const instanceProto = Object.getPrototypeOf(instance);
110110

111111
const route = routerBuilder.exploreMethodMetadata(
112-
new TestRoute(),
112+
instance,
113113
instanceProto,
114114
'getTest',
115115
);
116116

117117
expect(route.path).to.eql(['/test']);
118118
expect(route.requestMethod).to.eql(RequestMethod.GET);
119+
expect(route.targetCallback).to.eq(instance.getTest);
119120
});
120121

121122
it('should method return expected object which represent single route with alias', () => {
122123
const instance = new TestRouteAlias();
123124
const instanceProto = Object.getPrototypeOf(instance);
124125

125126
const route = routerBuilder.exploreMethodMetadata(
126-
new TestRouteAlias(),
127+
instance,
127128
instanceProto,
128129
'getTest',
129130
);
130131

131132
expect(route.path).to.eql(['/test']);
132133
expect(route.requestMethod).to.eql(RequestMethod.GET);
134+
expect(route.targetCallback).to.eq(instance.getTest);
133135
});
134136

135137
it('should method return expected object which represent multiple routes', () => {
136138
const instance = new TestRoute();
137139
const instanceProto = Object.getPrototypeOf(instance);
138140

139141
const route = routerBuilder.exploreMethodMetadata(
140-
new TestRoute(),
142+
instance,
141143
instanceProto,
142144
'getTestUsingArray',
143145
);
144146

145147
expect(route.path).to.eql(['/foo', '/bar']);
146148
expect(route.requestMethod).to.eql(RequestMethod.GET);
149+
expect(route.targetCallback).to.eq(instance.getTestUsingArray);
147150
});
148151

149152
it('should method return expected object which represent multiple routes with alias', () => {
150153
const instance = new TestRouteAlias();
151154
const instanceProto = Object.getPrototypeOf(instance);
152155

153156
const route = routerBuilder.exploreMethodMetadata(
154-
new TestRouteAlias(),
157+
instance,
155158
instanceProto,
156159
'getTestUsingArray',
157160
);
158161

159162
expect(route.path).to.eql(['/foo', '/bar']);
160163
expect(route.requestMethod).to.eql(RequestMethod.GET);
164+
expect(route.targetCallback).to.eq(instance.getTestUsingArray);
165+
});
166+
167+
describe('when new implementation is injected into router', () => {
168+
it('should method return changed impl of single route', () => {
169+
const instance = new TestRoute();
170+
const instanceProto = Object.getPrototypeOf(instance);
171+
172+
const newImpl = function () {};
173+
instance.getTest = newImpl;
174+
175+
const route = routerBuilder.exploreMethodMetadata(
176+
instance,
177+
instanceProto,
178+
'getTest',
179+
);
180+
181+
expect(route.targetCallback).to.eq(newImpl);
182+
expect(route.path).to.eql(['/test']);
183+
expect(route.requestMethod).to.eql(RequestMethod.GET);
184+
});
185+
186+
it('should method return changed impl of single route which alias applied', () => {
187+
const instance = new TestRouteAlias();
188+
const instanceProto = Object.getPrototypeOf(instance);
189+
190+
const newImpl = function () {};
191+
instance.getTest = newImpl;
192+
193+
const route = routerBuilder.exploreMethodMetadata(
194+
instance,
195+
instanceProto,
196+
'getTest',
197+
);
198+
199+
expect(route.targetCallback).to.eq(newImpl);
200+
expect(route.path).to.eql(['/test']);
201+
expect(route.requestMethod).to.eql(RequestMethod.GET);
202+
});
203+
204+
it('should method return changed impl of multiple routes', () => {
205+
const instance = new TestRoute();
206+
const instanceProto = Object.getPrototypeOf(instance);
207+
208+
const newImpl = function () {};
209+
instance.getTestUsingArray = newImpl;
210+
211+
const route = routerBuilder.exploreMethodMetadata(
212+
instance,
213+
instanceProto,
214+
'getTestUsingArray',
215+
);
216+
217+
expect(route.targetCallback).to.eq(newImpl);
218+
expect(route.path).to.eql(['/foo', '/bar']);
219+
expect(route.requestMethod).to.eql(RequestMethod.GET);
220+
});
221+
222+
it('should method return changed impl of multiple routes which alias applied', () => {
223+
const instance = new TestRouteAlias();
224+
const instanceProto = Object.getPrototypeOf(instance);
225+
226+
const newImpl = function () {};
227+
instance.getTestUsingArray = newImpl;
228+
229+
const route = routerBuilder.exploreMethodMetadata(
230+
instance,
231+
instanceProto,
232+
'getTestUsingArray',
233+
);
234+
235+
expect(route.targetCallback).to.eq(newImpl);
236+
expect(route.path).to.eql(['/foo', '/bar']);
237+
expect(route.requestMethod).to.eql(RequestMethod.GET);
238+
});
161239
});
162240
});
163241

0 commit comments

Comments
 (0)