1- import { flatten } from '@nestjs/common' ;
1+ import { Provider } from '@nestjs/common' ;
22import { Connection , Document , Model } from 'mongoose' ;
33import { getConnectionToken , getModelToken } from './common/mongoose.utils' ;
44import {
@@ -9,50 +9,68 @@ import {
99
1010function addDiscriminators (
1111 model : Model < Document > ,
12- discriminators ?: DiscriminatorOptions [ ] ,
13- ) {
14- if ( discriminators ) {
15- for ( const { name, schema } of discriminators ) {
16- model . discriminator ( name , schema ) ;
17- }
18- }
19- return model ;
12+ discriminators : DiscriminatorOptions [ ] = [ ] ,
13+ ) : Model < Document > [ ] {
14+ return discriminators . map ( ( { name, schema } ) =>
15+ model . discriminator ( name , schema ) ,
16+ ) ;
2017}
2118
2219export function createMongooseProviders (
2320 connectionName ?: string ,
2421 options : ModelDefinition [ ] = [ ] ,
25- ) {
26- const providers = ( options || [ ] ) . map ( ( option ) => ( {
27- provide : getModelToken ( option . name ) ,
28- useFactory : ( connection : Connection ) => {
29- const model = connection . model (
30- option . name ,
31- option . schema ,
32- option . collection ,
33- ) ;
34- return addDiscriminators ( model , option . discriminators ) ;
35- } ,
36- inject : [ getConnectionToken ( connectionName ) ] ,
37- } ) ) ;
38- return providers ;
22+ ) : Provider [ ] {
23+ return options . reduce (
24+ ( providers , option ) => [
25+ ...providers ,
26+ ...createMongooseProviders ( connectionName , option . discriminators ) ,
27+ {
28+ provide : getModelToken ( option . name ) ,
29+ useFactory : ( connection : Connection ) => {
30+ const model = connection . model (
31+ option . name ,
32+ option . schema ,
33+ option . collection ,
34+ ) ;
35+ addDiscriminators ( model , option . discriminators ) ;
36+ return model ;
37+ } ,
38+ inject : [ getConnectionToken ( connectionName ) ] ,
39+ } ,
40+ ] ,
41+ [ ] as Provider [ ] ,
42+ ) ;
3943}
4044
4145export function createMongooseAsyncProviders (
4246 connectionName ?: string ,
4347 modelFactories : AsyncModelFactory [ ] = [ ] ,
44- ) {
45- const providers = ( modelFactories || [ ] ) . map ( ( option ) => [
46- {
47- provide : getModelToken ( option . name ) ,
48- useFactory : async ( connection : Connection , ...args : unknown [ ] ) => {
49- const schema = await option . useFactory ( ...args ) ;
50- const model = connection . model ( option . name , schema , option . collection ) ;
51- addDiscriminators ( model , option . discriminators ) ;
52- return model ;
48+ ) : Provider [ ] {
49+ return modelFactories . reduce ( ( providers , option ) => {
50+ return [
51+ ...providers ,
52+ {
53+ provide : getModelToken ( option . name ) ,
54+ useFactory : async ( connection : Connection , ...args : unknown [ ] ) => {
55+ const schema = await option . useFactory ( ...args ) ;
56+ const model = connection . model (
57+ option . name ,
58+ schema ,
59+ option . collection ,
60+ ) ;
61+ addDiscriminators ( model , option . discriminators ) ;
62+ return model ;
63+ } ,
64+ inject : [ getConnectionToken ( connectionName ) , ...( option . inject || [ ] ) ] ,
5365 } ,
54- inject : [ getConnectionToken ( connectionName ) , ...( option . inject || [ ] ) ] ,
55- } ,
56- ] ) ;
57- return flatten ( providers ) ;
66+ // discriminators must convert to `AsyncModelFactory`.
67+ // Otherwise, the discriminators will register as `Model` before `model.discriminator` and throw OverwriteModelError
68+ ...createMongooseAsyncProviders (
69+ connectionName ,
70+ ( option . discriminators || [ ] ) . map < AsyncModelFactory > (
71+ ( { name, schema } ) => ( { name, useFactory : async ( ) => schema } ) ,
72+ ) ,
73+ ) ,
74+ ] ;
75+ } , [ ] as Provider [ ] ) ;
5876}
0 commit comments