import { CommonFieldComparisonBetweenType , FilterComparisonOperators } from '@nestjs-query/core' ; import { Op , WhereOptions , Rangable } from 'sequelize' ; internal export type EntityComparisonField < Entity , F extends keyof Entity > = Entity [ F ] | Entity [ F ] [ ] | CommonFieldComparisonBetweenType < Entity [ F ] > | true | false | null ; internal export class SQLComparisonBuilder < Entity > { static DEFAULT_COMPARISON_MAP : Record < string , symbol > = { eq : Op . eq , neq : Op . ne , gt : Op . gt , gte : Op . gte , lt : Op . lt , lte : Op . lte , like : Op . like , in : Op . in , notin : Op . notIn , notlike : Op . notLike , ilike : Op . iLike , notilike : Op . notILike , is : Op . is , isnot : Op . not , } ; constructor ( readonly comparisonMap = SQLComparisonBuilder . DEFAULT_COMPARISON_MAP ) { } param field param cmp param val build < F extends keyof Entity > ( field , cmp , val , alias ? ) { const col = alias ? `$${ alias }.${ field as string }$` : `${ field as string }` ; const normalizedCmp = ( cmp as string ) . toLowerCase ( ) ; if ( this . comparisonMap [ normalizedCmp ] ) { return { [ col ] : { [ this . comparisonMap [ normalizedCmp ] ] : val } } ; } if ( normalizedCmp === 'between' ) { return this . betweenComparisonSQL ( col , val ) ; } if ( normalizedCmp === 'notbetween' ) { return this . notBetweenComparisonSQL ( col , val ) ; } throw new Error ( `unknown operator ${ JSON . stringify ( cmp ) }` ) ; } private betweenComparisonSQL < F extends keyof Entity > ( col , val ) { if ( this . isBetweenVal ( val ) ) { return { [ col ] : { [ Op . between ] : [ val . lower , val . upper ] as unknown as Rangable } , } ; } throw new Error ( `Invalid value for between expected {lower: val, upper: val} got ${ JSON . stringify ( val ) }` ) ; } private notBetweenComparisonSQL < F extends keyof Entity > ( col , val ) { if ( this . isBetweenVal ( val ) ) { return { [ col ] : { [ Op . notBetween ] : [ val . lower , val . upper ] as unknown as Rangable } , } ; } throw new Error ( `Invalid value for not between expected {lower: val, upper: val} got ${ JSON . stringify ( val ) }` ) ; } private isBetweenVal < F extends keyof Entity > ( val ) { return val !== null && typeof val === 'object' && 'lower' in val && 'upper' in val ; } }