import type { Primitive, RetainPrimitiveFields, TimeSpan } from '@travetto/runtime'; import type { Point } from '@travetto/schema'; export type QueryPrimitive = Primitive | Point; export type QueryPrimitiveArray = QueryPrimitive[]; export type DistanceUnit = 'mi' | 'm' | 'km' | 'ft' | 'rad'; export type RetainQueryPrimitiveFields = RetainPrimitiveFields; type General = { $eq?: T; $ne?: T; $exists?: boolean; }; type ScalarField = { $in?: T[]; $nin?: T[]; }; type ComparableField = { $lt?: T; $lte?: T; $gt?: T; $gte?: T; }; type ArrayField = { $exists?: boolean } | { $eq?: T | T[] } | { $ne?: T | T[] } | { $all?: T[] } | { $in?: T[] } | PropWhereClause> | T | T[]; type StringField = { $regex?: RegExp | string }; type GeoField = { $geoWithin?: Point[]; $near?: Point; $maxDistance?: number; $unit?: DistanceUnit; }; export type PropWhereClause = { [P in keyof T]?: (T[P] extends (number | undefined) ? (General | ScalarField | ComparableField | number) : (T[P] extends (string | undefined) ? (General | ScalarField | StringField | string) : (T[P] extends (boolean | undefined) ? (General | boolean) : (T[P] extends (Date | undefined) ? (General | ScalarField | ComparableField | Date) : (T[P] extends (Point | undefined) ? (General | ScalarField | GeoField | Point) : (T[P] extends ((infer U)[] | undefined) ? ArrayField : (T[P] extends (object | undefined) ? PropWhereClause> : never))))))); }; /** * Raw query type */ export type WhereClauseRaw = ({ $and: WhereClauseRaw[] } & { [P in keyof T]?: never }) | ({ $or: WhereClauseRaw[] } & { [P in keyof T]?: never }) | ({ $not: WhereClauseRaw } & { [P in keyof T]?: never }) | (PropWhereClause & { $and?: never, $or?: never, $not?: never }); /** * Full where clause, typed against the input type T */ export type WhereClause = WhereClauseRaw>; /** * Provides all the valid string type fields from a given type T */ export type ValidStringFields = { [K in Extract]: (T[K] extends (String | string | string[] | String[] | undefined) ? K : never) }[Extract];