import * as mongo from "mongodb" import { Condition as FilterCondition } from "./Condition" export type Filter = { [P in keyof T]?: FilterCondition | Filter> | any } export namespace Filter { export function toMongo( filter: Filter, ...prioritized: (string | undefined)[] ): mongo.Filter> { const result: any = {} let field: keyof Filter for (field in filter) if (Object.prototype.hasOwnProperty.call(filter, field)) { const value = filter[field] const r = FilterCondition.is(value) ? FilterCondition.toMongo(value) : typeof value == "object" ? Filter.toMongo(value as any, prioritized?.[0] == "*" ? "*" : undefined) : prioritized?.[0] == "*" || prioritized.some(p => p == field) ? value : undefined if (r != undefined && !(Object.keys(r).length == 0 && r.constructor == Object)) result[field] = r } return toDotNotation(result) } export type Condition = FilterCondition export namespace Condition { export const extract = FilterCondition.extract } } function toDotNotation(value: Record): Record { const result: Record = {} for (const key of Object.keys(value)) { if (!Array.isArray(value[key]) && typeof value[key] == "object") Object.entries(toDotNotation(value[key])).forEach(entry => entry[0].charAt(0) == "$" || key == "$elemMatch" ? (result[key] = { ...result[key], [entry[0]]: entry[1] }) : (result[key + "." + entry[0]] = entry[1]) ) else result[key] = value[key] } return result } type DeepPartial = { [P in keyof T]?: DeepPartial> }