@@ -29,9 +29,31 @@ function getRepository(connectionName: string, repositoryType: Function, entityT
29
29
}
30
30
31
31
/**
32
- * Allows to inject a Repository, MongoRepository, TreeRepository
33
- * or custom repository using TypeDI's Container.
34
- * Be aware that you have to annotate the property with correct type!
32
+ * Satisfy typescript compiler about universal decorators.
33
+ */
34
+ export type ParamOrPropDecorator = ( object : object , propertyName : string , index ?: number ) => void ;
35
+
36
+ /**
37
+ * Allows to inject a custom repository using TypeDI's Container.
38
+ * Be aware that you have to annotate the param/property with correct type!
39
+ * ```ts
40
+ * class Sample {
41
+ * // constructor injection
42
+ * constructor(
43
+ * \@OrmRepository ()
44
+ * private userRepository: UserRepository,
45
+ * ) {}
46
+ *
47
+ * // property injection
48
+ * \@OrmRepository()
49
+ * userRepository: UserRepository;
50
+ * }
51
+ * ```
52
+ */
53
+ export function OrmRepository ( ) : ParamOrPropDecorator ;
54
+ /**
55
+ * Allows to inject a Repository, MongoRepository, TreeRepository using TypeDI's Container.
56
+ * Be aware that you have to annotate the param/property with correct type!
35
57
* ```ts
36
58
* class Sample {
37
59
* // constructor injection
@@ -46,16 +68,66 @@ function getRepository(connectionName: string, repositoryType: Function, entityT
46
68
* }
47
69
* ```
48
70
*/
49
- export function OrmRepository ( entityType : Function , connectionName = "default" ) {
71
+ export function OrmRepository ( entityType : Function ) : ParamOrPropDecorator ;
72
+ /**
73
+ * Allows to inject a custom repository using TypeDI's Container
74
+ * and specify the connection name in a parameter.
75
+ * Be aware that you have to annotate the param/property with correct type!
76
+ * ```ts
77
+ * class Sample {
78
+ * // constructor injection
79
+ * constructor(
80
+ * \@OrmRepository ("test-conn")
81
+ * private userRepository: UserRepository,
82
+ * ) {}
83
+ *
84
+ * // property injection
85
+ * \@OrmRepository("test-conn")
86
+ * userRepository: UserRepository;
87
+ * }
88
+ * ```
89
+ */
90
+ export function OrmRepository ( connectionName : string ) : ParamOrPropDecorator ;
91
+ /**
92
+ * Allows to inject a Repository, MongoRepository, TreeRepository using TypeDI's Container
93
+ * and specify the connection name in a parameter.
94
+ * Be aware that you have to annotate the param/property with correct type!
95
+ * ```ts
96
+ * class Sample {
97
+ * // constructor injection
98
+ * constructor(
99
+ * \@OrmRepository (User, "test-conn")
100
+ * private userRepository: Repository<User>,
101
+ * ) {}
102
+ *
103
+ * // property injection
104
+ * \@OrmRepository(User, "test-conn")
105
+ * userRepository: Repository<User>;
106
+ * }
107
+ * ```
108
+ */
109
+ export function OrmRepository ( entityType : Function , connectionName : string ) : ParamOrPropDecorator ;
110
+
111
+ export function OrmRepository ( entityTypeOrConnectionName ?: Function | string , paramConnectionName = "default" ) : ParamOrPropDecorator {
50
112
return ( object : object , propertyName : string , index ?: number ) => {
113
+ let entityType : Function | undefined ;
114
+ let connectionName : string ;
51
115
let repositoryType : Function ;
52
116
117
+ // handle first parameter overload
118
+ connectionName = paramConnectionName ;
119
+ if ( typeof entityTypeOrConnectionName === "string" ) {
120
+ connectionName = entityTypeOrConnectionName ;
121
+ } else if ( typeof entityTypeOrConnectionName === "function" ) {
122
+ entityType = entityTypeOrConnectionName ;
123
+ }
124
+
53
125
// if the decorator has been aplied to parameter (constructor injection)
54
126
if ( index ) {
55
127
const paramTypes : Function [ ] | undefined = Reflect . getOwnMetadata ( "design:paramtypes" , object , propertyName ) ;
56
128
if ( ! paramTypes || ! paramTypes [ index ] ) {
57
129
throw new Error (
58
- `Cannot get reflected type for a "${ propertyName } " method's parameter of ${ object . constructor . name } class. ` +
130
+ `Cannot get reflected type for a "${ propertyName } " method's ${ index + 1 } . parameter of ${ object . constructor . name } class. ` +
59
131
`Make sure you have turned on an "emitDecoratorMetadata": true, option in tsconfig.json. ` +
60
132
`and that you have imported "reflect-metadata" on top of the main entry file in your application.` +
61
133
`And make sure that you have annotated the property type correctly with: ` +
@@ -78,23 +150,30 @@ export function OrmRepository(entityType: Function, connectionName = "default")
78
150
}
79
151
repositoryType = propertyType ;
80
152
}
153
+
154
+ switch ( repositoryType ) {
155
+ case Repository :
156
+ case MongoRepository :
157
+ case TreeRepository :
158
+ if ( ! entityType ) {
159
+ throw new Error (
160
+ `Missing "entityType" parameter of "@OrmRepository" decorator ` +
161
+ index
162
+ ? `for a "${ propertyName } " method's ${ index ! + 1 } . parameter of ${ object . constructor . name } class. `
163
+ : `for a property "${ propertyName } " of ${ object . constructor . name } class. `
164
+ +
165
+ `For injecting Repository, MongoRepository or TreeRepository, ` +
166
+ `you have to specify the entity type due to TS reflection limitation` +
167
+ `"entityType" parameter can be ommited only for custom repositories.`
168
+ ) ;
169
+ }
170
+ }
81
171
82
172
Container . registerHandler ( {
83
173
index,
84
174
object,
85
175
propertyName,
86
- value : ( ) => getRepository ( connectionName , repositoryType , entityType ) ,
176
+ value : ( ) => getRepository ( connectionName , repositoryType , entityType ! ) ,
87
177
} ) ;
88
178
} ;
89
179
}
90
-
91
- class Test {
92
-
93
- constructor (
94
- @OrmRepository ( Test )
95
- private repo : MongoRepository < any > ,
96
- ) { }
97
-
98
- @OrmRepository ( Test )
99
- property : Repository < any > ;
100
- }
0 commit comments