forked from nestjs/nest
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request nestjs#1215 from nestjs/5.4.0
chore() 5.4.0 minor release
- Loading branch information
Showing
28 changed files
with
483 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
integration/injector/e2e/circular-property-injection.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { Test } from '@nestjs/testing'; | ||
import { expect } from 'chai'; | ||
import { CircularPropertiesModule } from '../src/circular-properties/circular-properties.module'; | ||
import { CircularService } from '../src/circular-properties/circular.service'; | ||
import { InputPropertiesModule } from '../src/circular-properties/input-properties.module'; | ||
import { InputService } from '../src/circular-properties/input.service'; | ||
|
||
describe('Circular properties dependency (modules)', () => { | ||
it('should resolve circular dependency between providers', async () => { | ||
const builder = Test.createTestingModule({ | ||
imports: [CircularPropertiesModule, InputPropertiesModule], | ||
}); | ||
const testingModule = await builder.compile(); | ||
const inputService = testingModule.get<InputService>(InputService); | ||
const circularService = testingModule.get<CircularService>(CircularService); | ||
|
||
expect(inputService.service).to.be.eql(circularService); | ||
expect(circularService.service).to.be.eql(inputService); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Test } from '@nestjs/testing'; | ||
import { expect } from 'chai'; | ||
import { DependencyService } from '../src/properties/dependency.service'; | ||
import { PropertiesModule } from '../src/properties/properties.module'; | ||
import { PropertiesService } from '../src/properties/properties.service'; | ||
|
||
describe('Injector', () => { | ||
it('should resolve property-based dependencies', async () => { | ||
const builder = Test.createTestingModule({ | ||
imports: [PropertiesModule], | ||
}); | ||
const app = await builder.compile(); | ||
const dependency = app.get(DependencyService); | ||
|
||
expect(app.get(PropertiesService).service).to.be.eql(dependency); | ||
expect(app.get(PropertiesService).token).to.be.true; | ||
}); | ||
}); |
10 changes: 10 additions & 0 deletions
10
integration/injector/src/circular-properties/circular-properties.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { forwardRef, Module } from '@nestjs/common'; | ||
import { CircularService } from './circular.service'; | ||
import { InputPropertiesModule } from './input-properties.module'; | ||
|
||
@Module({ | ||
imports: [forwardRef(() => InputPropertiesModule)], | ||
providers: [CircularService], | ||
exports: [CircularService], | ||
}) | ||
export class CircularPropertiesModule {} |
8 changes: 8 additions & 0 deletions
8
integration/injector/src/circular-properties/circular.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { forwardRef, Inject, Injectable } from '@nestjs/common'; | ||
import { InputService } from './input.service'; | ||
|
||
@Injectable() | ||
export class CircularService { | ||
@Inject(forwardRef(() => InputService)) | ||
public readonly service: InputService; | ||
} |
10 changes: 10 additions & 0 deletions
10
integration/injector/src/circular-properties/input-properties.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { forwardRef, Module } from '@nestjs/common'; | ||
import { CircularPropertiesModule } from './circular-properties.module'; | ||
import { InputService } from './input.service'; | ||
|
||
@Module({ | ||
imports: [forwardRef(() => CircularPropertiesModule)], | ||
providers: [InputService], | ||
exports: [InputService], | ||
}) | ||
export class InputPropertiesModule {} |
8 changes: 8 additions & 0 deletions
8
integration/injector/src/circular-properties/input.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { forwardRef, Inject, Injectable } from '@nestjs/common'; | ||
import { CircularService } from './circular.service'; | ||
|
||
@Injectable() | ||
export class InputService { | ||
@Inject(forwardRef(() => CircularService)) | ||
public readonly service: CircularService; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
|
||
@Injectable() | ||
export class DependencyService {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { DependencyService } from './dependency.service'; | ||
import { PropertiesService } from './properties.service'; | ||
|
||
@Module({ | ||
providers: [ | ||
DependencyService, | ||
PropertiesService, | ||
{ | ||
provide: 'token', | ||
useValue: true, | ||
}, | ||
], | ||
}) | ||
export class PropertiesModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Inject, Injectable } from '@nestjs/common'; | ||
import { DependencyService } from './dependency.service'; | ||
|
||
@Injectable() | ||
export class PropertiesService { | ||
@Inject() service: DependencyService; | ||
@Inject('token') token: boolean; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,35 @@ | ||
import { SELF_DECLARED_DEPS_METADATA } from '../../constants'; | ||
import { isFunction } from '../../utils/shared.utils'; | ||
import { | ||
PROPERTY_DEPS_METADATA, | ||
SELF_DECLARED_DEPS_METADATA, | ||
} from '../../constants'; | ||
import { isFunction, isUndefined } from '../../utils/shared.utils'; | ||
|
||
/** | ||
* Injects provider which has to be available in the current injector (module) scope. | ||
* Providers are recognized by types or tokens. | ||
*/ | ||
export function Inject<T = any>(token: T): ParameterDecorator { | ||
return (target, key, index) => { | ||
const args = Reflect.getMetadata(SELF_DECLARED_DEPS_METADATA, target) || []; | ||
const type = isFunction(token) ? (token as any as Function).name : token; | ||
export function Inject<T = any>(token?: T) { | ||
return (target: Object, key: string | symbol, index?: number) => { | ||
token = token || Reflect.getMetadata('design:type', target, key); | ||
const type = | ||
token && isFunction(token) ? ((token as any) as Function).name : token; | ||
|
||
args.push({ index, param: type }); | ||
Reflect.defineMetadata(SELF_DECLARED_DEPS_METADATA, args, target); | ||
if (!isUndefined(index)) { | ||
const dependencies = | ||
Reflect.getMetadata(SELF_DECLARED_DEPS_METADATA, target) || []; | ||
|
||
dependencies.push({ index, param: type }); | ||
Reflect.defineMetadata(SELF_DECLARED_DEPS_METADATA, dependencies, target); | ||
return; | ||
} | ||
const properties = | ||
Reflect.getMetadata(PROPERTY_DEPS_METADATA, target.constructor) || []; | ||
|
||
properties.push({ key, type }); | ||
Reflect.defineMetadata( | ||
PROPERTY_DEPS_METADATA, | ||
properties, | ||
target.constructor, | ||
); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,28 @@ | ||
import { OPTIONAL_DEPS_METADATA } from '../../constants'; | ||
import { | ||
OPTIONAL_DEPS_METADATA, | ||
OPTIONAL_PROPERTY_DEPS_METADATA, | ||
} from '../../constants'; | ||
import { isUndefined } from '../../utils/shared.utils'; | ||
|
||
/** | ||
* Sets dependency as an optional one. | ||
*/ | ||
export function Optional(): ParameterDecorator { | ||
return (target, key, index) => { | ||
const args = Reflect.getMetadata(OPTIONAL_DEPS_METADATA, target) || []; | ||
Reflect.defineMetadata(OPTIONAL_DEPS_METADATA, [...args, index], target); | ||
export function Optional() { | ||
return (target: Object, key: string | symbol, index?: number) => { | ||
if (!isUndefined(index)) { | ||
const args = Reflect.getMetadata(OPTIONAL_DEPS_METADATA, target) || []; | ||
Reflect.defineMetadata(OPTIONAL_DEPS_METADATA, [...args, index], target); | ||
return; | ||
} | ||
const properties = | ||
Reflect.getMetadata( | ||
OPTIONAL_PROPERTY_DEPS_METADATA, | ||
target.constructor, | ||
) || []; | ||
Reflect.defineMetadata( | ||
OPTIONAL_PROPERTY_DEPS_METADATA, | ||
[...properties, key], | ||
target.constructor, | ||
); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { INVALID_CLASS_MESSAGE } from '../messages'; | ||
import { RuntimeException } from './runtime.exception'; | ||
|
||
export class InvalidClassException extends RuntimeException { | ||
constructor(value: any) { | ||
super(INVALID_CLASS_MESSAGE`${value}`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { Type } from '@nestjs/common'; | ||
import { isFunction } from '@nestjs/common/utils/shared.utils'; | ||
import { UnknownElementException } from '../errors/exceptions/unknown-element.exception'; | ||
import { InstanceWrapper, NestContainer } from './container'; | ||
import { Module } from './module'; | ||
|
||
export class ContainerScanner { | ||
private flatContainer: Partial<Module>; | ||
|
||
constructor(private readonly container: NestContainer) {} | ||
|
||
public find<TInput = any, TResult = TInput>( | ||
typeOrToken: Type<TInput> | string | symbol, | ||
): TResult { | ||
this.initFlatContainer(); | ||
return this.findInstanceByPrototypeOrToken<TInput, TResult>( | ||
typeOrToken, | ||
this.flatContainer, | ||
); | ||
} | ||
|
||
public findInstanceByPrototypeOrToken<TInput = any, TResult = TInput>( | ||
metatypeOrToken: Type<TInput> | string | symbol, | ||
contextModule: Partial<Module>, | ||
): TResult { | ||
const dependencies = new Map([ | ||
...contextModule.components, | ||
...contextModule.routes, | ||
...contextModule.injectables, | ||
]); | ||
const name = isFunction(metatypeOrToken) | ||
? (metatypeOrToken as Function).name | ||
: metatypeOrToken; | ||
const instanceWrapper = dependencies.get(name as string); | ||
if (!instanceWrapper) { | ||
throw new UnknownElementException(); | ||
} | ||
return (instanceWrapper as InstanceWrapper<any>).instance; | ||
} | ||
|
||
private initFlatContainer() { | ||
if (this.flatContainer) { | ||
return undefined; | ||
} | ||
const modules = this.container.getModules(); | ||
const initialValue = { | ||
components: [], | ||
routes: [], | ||
injectables: [], | ||
}; | ||
const merge = <T = any>( | ||
initial: Map<string, T> | T[], | ||
arr: Map<string, T>, | ||
) => [...initial, ...arr]; | ||
|
||
this.flatContainer = ([...modules.values()].reduce( | ||
(current, next) => ({ | ||
components: merge(current.components, next.components), | ||
routes: merge(current.routes, next.routes), | ||
injectables: merge(current.injectables, next.injectables), | ||
}), | ||
initialValue, | ||
) as any) as Partial<Module>; | ||
} | ||
} |
Oops, something went wrong.