@@ -56,8 +56,9 @@ export type WithoutId<TSchema> = Omit<TSchema, '_id'>;
56
56
57
57
/** A MongoDB filter can be some portion of the schema or a set of operators @public */
58
58
export type Filter < TSchema > = {
59
- [ P in keyof TSchema ] ?: Condition < TSchema [ P ] > ;
60
- } & RootFilterOperators < TSchema > ;
59
+ [ P in Join < NestedPaths < TSchema > , '.' > ] ?: Condition < PropertyType < TSchema , P > > ;
60
+ } &
61
+ RootFilterOperators < TSchema > ;
61
62
62
63
/** @public */
63
64
export type Condition < T > = AlternativeType < T > | FilterOperators < AlternativeType < T > > ;
@@ -256,7 +257,8 @@ export type SetFields<TSchema> = ({
256
257
readonly [ key in KeysOfAType < TSchema , ReadonlyArray < any > | undefined > ] ?:
257
258
| OptionalId < Flatten < TSchema [ key ] > >
258
259
| AddToSetOperators < Array < OptionalId < Flatten < TSchema [ key ] > > > > ;
259
- } & NotAcceptedFields < TSchema , ReadonlyArray < any > | undefined > ) & {
260
+ } &
261
+ NotAcceptedFields < TSchema , ReadonlyArray < any > | undefined > ) & {
260
262
readonly [ key : string ] : AddToSetOperators < any > | any ;
261
263
} ;
262
264
@@ -265,7 +267,8 @@ export type PushOperator<TSchema> = ({
265
267
readonly [ key in KeysOfAType < TSchema , ReadonlyArray < any > > ] ?:
266
268
| Flatten < TSchema [ key ] >
267
269
| ArrayOperator < Array < Flatten < TSchema [ key ] > > > ;
268
- } & NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
270
+ } &
271
+ NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
269
272
readonly [ key : string ] : ArrayOperator < any > | any ;
270
273
} ;
271
274
@@ -274,14 +277,16 @@ export type PullOperator<TSchema> = ({
274
277
readonly [ key in KeysOfAType < TSchema , ReadonlyArray < any > > ] ?:
275
278
| Partial < Flatten < TSchema [ key ] > >
276
279
| FilterOperations < Flatten < TSchema [ key ] > > ;
277
- } & NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
280
+ } &
281
+ NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
278
282
readonly [ key : string ] : FilterOperators < any > | any ;
279
283
} ;
280
284
281
285
/** @public */
282
286
export type PullAllOperator < TSchema > = ( {
283
287
readonly [ key in KeysOfAType < TSchema , ReadonlyArray < any > > ] ?: TSchema [ key ] ;
284
- } & NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
288
+ } &
289
+ NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
285
290
readonly [ key : string ] : ReadonlyArray < any > ;
286
291
} ;
287
292
@@ -422,3 +427,50 @@ export class TypedEventEmitter<Events extends EventsDescription> extends EventEm
422
427
423
428
/** @public */
424
429
export class CancellationToken extends TypedEventEmitter < { cancel ( ) : void } > { }
430
+
431
+ /**
432
+ * Helper types for dot-notation filter attributes
433
+ */
434
+
435
+ // export type ArrayType<Type> = Type extends Array<infer Value> ? Value : never;
436
+
437
+ /** @public */
438
+ export type Join < T extends unknown [ ] , D extends string > = T extends [ ]
439
+ ? ''
440
+ : T extends [ string | number ]
441
+ ? `${T [ 0 ] } `
442
+ : T extends [ string | number , ...infer R ]
443
+ ? `${T [ 0 ] } ${D } ${Join < R , D > } `
444
+ : string | number ;
445
+
446
+ /** @public */
447
+ export type PropertyType < Type , Property extends string > = string extends Property
448
+ ? unknown
449
+ : Property extends keyof Type
450
+ ? Type [ Property ]
451
+ : Property extends `${infer Key } .${infer Rest } `
452
+ ? Key extends `${number } `
453
+ ? Type extends Array < infer ArrayType >
454
+ ? PropertyType < ArrayType , Rest >
455
+ : Type extends ReadonlyArray < infer ArrayType >
456
+ ? PropertyType < ArrayType , Rest >
457
+ : unknown
458
+ : Key extends keyof Type
459
+ ? PropertyType < Type [ Key ] , Rest >
460
+ : unknown
461
+ : unknown ;
462
+
463
+ // We dont't support nested circular references
464
+ /** @public */
465
+ export type NestedPaths < Type > = Type extends string | number | boolean | Date | ObjectId
466
+ ? [ ]
467
+ : Type extends Array < infer ArrayType >
468
+ ? [ number , ...NestedPaths < ArrayType > ]
469
+ : Type extends ReadonlyArray < infer ArrayType >
470
+ ? [ number , ...NestedPaths < ArrayType > ]
471
+ : // eslint-disable-next-line @typescript-eslint/ban-types
472
+ Type extends object
473
+ ? {
474
+ [ Key in Extract < keyof Type , string > ] : [ Key , ...NestedPaths < Type [ Key ] > ] ;
475
+ } [ Extract < keyof Type , string > ]
476
+ : [ ] ;
0 commit comments