@@ -4,9 +4,11 @@ import {
44 MonarchArray ,
55 MonarchDate ,
66 MonarchDecimal128 ,
7+ MonarchDefaulted ,
78 MonarchDouble ,
89 MonarchInt32 ,
910 MonarchLong ,
11+ MonarchNullable ,
1012 MonarchNumber ,
1113 MonarchOptional ,
1214 MonarchType ,
@@ -87,6 +89,20 @@ export function updateParser<T extends AnyMonarchType>(
8789 return input ;
8890}
8991
92+ function unwrapTo < T extends new ( ...args : any ) => AnyMonarchType > (
93+ type : AnyMonarchType ,
94+ target : T
95+ ) : InstanceType < T > {
96+ let unwrapped : any = type ;
97+ while ( ! ( unwrapped instanceof target ) ) {
98+ if ( unwrapped instanceof MonarchDefaulted ) unwrapped = MonarchDefaulted . type ( unwrapped ) ;
99+ else if ( unwrapped instanceof MonarchOptional ) unwrapped = MonarchOptional . type ( unwrapped ) ;
100+ else if ( unwrapped instanceof MonarchNullable ) unwrapped = MonarchNullable . type ( unwrapped ) ;
101+ else break ;
102+ }
103+ return unwrapped as InstanceType < T > ;
104+ }
105+
90106function parseFieldsOperator (
91107 op : "$set" | "$min" | "$max" ,
92108 schemaType : AnyMonarchType ,
@@ -127,7 +143,8 @@ function parseArrayOperator(
127143 cause : MonarchParseError . create ( `operator '${ op } ' requires an array field` ) ,
128144 } ) ;
129145 }
130- const elementType = MonarchArray . type ( pathType ) ;
146+ const arrayType = unwrapTo ( pathType , MonarchArray ) ;
147+ const elementType = MonarchArray . type ( arrayType ) ;
131148 const parser = MonarchType . parser ( elementType , path ) ;
132149 if ( typeof value === "object" && value !== null && "$each" in value ) {
133150 const ops = value as { $each : unknown [ ] ; [ k : string ] : unknown } ;
@@ -159,7 +176,8 @@ function parseArrayAllOperator(
159176 cause : MonarchParseError . create ( `operator '$pullAll' requires an array field` ) ,
160177 } ) ;
161178 }
162- const elementType = MonarchArray . type ( pathType ) ;
179+ const arrayType = unwrapTo ( pathType , MonarchArray ) ;
180+ const elementType = MonarchArray . type ( arrayType ) ;
163181 const parser = MonarchType . parser ( elementType , path ) ;
164182 parsed [ path ] = value . map ( parser ) ;
165183 if ( schemaUpdates ) removeUpdateConflict ( path , schemaUpdates ) ;
@@ -333,7 +351,8 @@ function parseRenameOperator(
333351 cause : MonarchParseError . create ( `operator '$rename' requires an optional field` ) ,
334352 } ) ;
335353 }
336- const sourceInner = MonarchOptional . type ( sourceType ) ;
354+ const sourceOptional = unwrapTo ( sourceType , MonarchOptional ) ;
355+ const sourceInner = MonarchOptional . type ( sourceOptional ) ;
337356 const destType = MonarchType . index ( schemaType , value . split ( "." ) , - 1 ) ;
338357 if ( ! MonarchType . isInstanceOf ( destType , sourceInner . constructor as new ( ...args : any [ ] ) => AnyMonarchType ) ) {
339358 throw MonarchParseError . fromCause ( {
0 commit comments