Skip to content

Commit 97afee9

Browse files
fix(core): fix override and replace logic nestjs#2070
1 parent c60b1ac commit 97afee9

5 files changed

Lines changed: 46 additions & 15 deletions

File tree

packages/core/injector/injector.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export class Injector {
8080
}
8181
const loadInstance = (instances: any[]) => {
8282
targetWrapper.instance = targetWrapper.isDependencyTreeStatic()
83-
? new metatype(...instances)
83+
? new (metatype as Type<any>)(...instances)
8484
: Object.create(metatype.prototype);
8585
};
8686
await this.resolveConstructorParams(
@@ -190,7 +190,7 @@ export class Injector {
190190
throw new RuntimeException();
191191
}
192192
if (instanceHost.isResolved) {
193-
return;
193+
return done();
194194
}
195195
const callback = async (instances: any[]) => {
196196
const properties = await this.resolveProperties(
@@ -235,10 +235,10 @@ export class Injector {
235235
return callback(deps);
236236
}
237237
const dependencies = isNil(inject)
238-
? this.reflectConstructorParams(wrapper.metatype)
238+
? this.reflectConstructorParams(wrapper.metatype as Type<any>)
239239
: inject;
240240
const optionalDependenciesIds = isNil(inject)
241-
? this.reflectOptionalParams(wrapper.metatype)
241+
? this.reflectOptionalParams(wrapper.metatype as Type<any>)
242242
: [];
243243

244244
let isResolved = true;
@@ -504,7 +504,7 @@ export class Injector {
504504
if (metadata && contextId !== STATIC_CONTEXT) {
505505
return this.loadPropertiesMetadata(metadata, contextId, inquirer);
506506
}
507-
const properties = this.reflectProperties(wrapper.metatype);
507+
const properties = this.reflectProperties(wrapper.metatype as Type<any>);
508508
const instances = await Promise.all(
509509
properties.map(async (item: PropertyDependency) => {
510510
try {
@@ -589,8 +589,11 @@ export class Injector {
589589

590590
if (isNil(inject) && isInContext) {
591591
instanceHost.instance = wrapper.forwardRef
592-
? Object.assign(instanceHost.instance, new metatype(...instances))
593-
: new metatype(...instances);
592+
? Object.assign(
593+
instanceHost.instance,
594+
new (metatype as Type<any>)(...instances),
595+
)
596+
: new (metatype as Type<any>)(...instances);
594597
} else if (isInContext) {
595598
const factoryReturnValue = ((targetMetatype.metatype as any) as Function)(
596599
...instances,

packages/core/injector/instance-wrapper.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { Scope, Type } from '@nestjs/common';
1+
import { Provider, Scope, Type } from '@nestjs/common';
2+
import {
3+
ClassProvider,
4+
FactoryProvider,
5+
ValueProvider,
6+
} from '@nestjs/common/interfaces';
27
import { randomStringGenerator } from '@nestjs/common/utils/random-string-generator.util';
38
import { isNil, isUndefined } from '@nestjs/common/utils/shared.utils';
49
import { STATIC_CONTEXT } from './constants';
@@ -30,11 +35,11 @@ interface InstanceMetadataStore {
3035

3136
export class InstanceWrapper<T = any> {
3237
public readonly name: any;
33-
public readonly metatype: Type<T>;
34-
public readonly inject?: (string | symbol | Function | Type<any>)[];
3538
public readonly async?: boolean;
3639
public readonly host?: Module;
3740
public readonly scope?: Scope = Scope.DEFAULT;
41+
public metatype: Type<T> | Function;
42+
public inject?: (string | symbol | Function | Type<any>)[];
3843
public forwardRef?: boolean;
3944

4045
private readonly values = new WeakMap<ContextId, InstancePerContext<T>>();
@@ -293,6 +298,22 @@ export class InstanceWrapper<T = any> {
293298
.filter(item => !!item);
294299
}
295300

301+
public mergeWith(provider: Provider) {
302+
if ((provider as ValueProvider).useValue) {
303+
this.metatype = null;
304+
this.setInstanceByContextId(STATIC_CONTEXT, {
305+
instance: (provider as ValueProvider).useValue,
306+
isResolved: true,
307+
isPending: false,
308+
});
309+
} else if ((provider as ClassProvider).useClass) {
310+
this.metatype = (provider as ClassProvider).useClass;
311+
} else if ((provider as FactoryProvider).useFactory) {
312+
this.metatype = (provider as FactoryProvider).useFactory;
313+
this.inject = (provider as FactoryProvider).inject || [];
314+
}
315+
}
316+
296317
private isNewable(): boolean {
297318
return isNil(this.inject) && this.metatype && this.metatype.prototype;
298319
}

packages/core/injector/module.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,13 @@ export class Module {
365365

366366
public replace(toReplace: string | symbol | Type<any>, options: any) {
367367
if (options.isProvider && this.hasProvider(toReplace)) {
368-
return this.addProvider({ provide: toReplace, ...options });
368+
const name = this.getProviderStaticToken(toReplace);
369+
const originalProvider = this._providers.get(name);
370+
return originalProvider.mergeWith({ provide: toReplace, ...options });
369371
} else if (!options.isProvider && this.hasInjectable(toReplace)) {
370-
this.addInjectable({
372+
const name = this.getProviderStaticToken(toReplace);
373+
const originalInjectable = this._injectables.get(name);
374+
return originalInjectable.mergeWith({
371375
provide: toReplace,
372376
...options,
373377
});

packages/core/router/routes-resolver.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { BadRequestException, NotFoundException } from '@nestjs/common';
22
import { MODULE_PATH } from '@nestjs/common/constants';
3-
import { HttpServer } from '@nestjs/common/interfaces';
3+
import { HttpServer, Type } from '@nestjs/common/interfaces';
44
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
55
import { Logger } from '@nestjs/common/services/logger.service';
66
import { ApplicationConfig } from '../application-config';
@@ -60,7 +60,10 @@ export class RoutesResolver implements Resolver {
6060
) {
6161
routes.forEach(instanceWrapper => {
6262
const { metatype } = instanceWrapper;
63-
const path = this.routerBuilder.extractRouterPath(metatype, basePath);
63+
const path = this.routerBuilder.extractRouterPath(
64+
metatype as Type<any>,
65+
basePath,
66+
);
6467
const controllerName = metatype.name;
6568

6669
this.logger.log(CONTROLLER_MAPPING_MESSAGE(controllerName, path));

packages/websockets/web-sockets-controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class WebSocketsController {
2828

2929
public mergeGatewayAndServer(
3030
instance: NestGateway,
31-
metatype: Type<any>,
31+
metatype: Type<any> | Function,
3232
module: string,
3333
) {
3434
const options = Reflect.getMetadata(GATEWAY_OPTIONS, metatype) || {};

0 commit comments

Comments
 (0)