Skip to content

Commit

Permalink
feat: add array operators
Browse files Browse the repository at this point in the history
More info here: nestjsx#754
  • Loading branch information
afilp committed Oct 31, 2023
1 parent 1f5899f commit 528162e
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 31 deletions.
2 changes: 2 additions & 0 deletions packages/crud-request/src/request-query.parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ export class RequestQueryParser implements ParsedRequestParams {
'$between',
'$inL',
'$notinL',
'$contArr',
'$intersectsArr',
].concat(Object.keys(customOperators).filter((op) => customOperators[op].isArray));
const isEmptyValue = ['isnull', 'notnull', '$isnull', '$notnull'];
const param = data.split(this._options.delim);
Expand Down
2 changes: 2 additions & 0 deletions packages/crud-request/src/request-query.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export const deprecatedComparisonOperatorsList = [
'isnull',
'notnull',
'between',
'contArr',
'intersectsArr',
];
export const comparisonOperatorsList = [
...deprecatedComparisonOperatorsList,
Expand Down
60 changes: 34 additions & 26 deletions packages/crud-request/src/types/request-query.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ type DeprecatedCondOperator =
| 'notin'
| 'isnull'
| 'notnull'
| 'between';
| 'between'
| 'contArr'
| 'intersectsArr';

export enum CondOperator {
EQUALS = '$eq',
Expand All @@ -68,39 +70,45 @@ export enum CondOperator {
EXCLUDES_LOW = '$exclL',
IN_LOW = '$inL',
NOT_IN_LOW = '$notinL',
CONTAINS_ARRAY = '$contArr',
INTERSECTS_ARRAY = '$intersectsArr',
}

export type ComparisonOperator = DeprecatedCondOperator | keyof SFieldOperator | string;

// new search
export type SPrimitivesVal = string | number | boolean;

export type SFiledValues = SPrimitivesVal | SPrimitivesVal[];
export type SFieldValues = SPrimitivesVal | Array<SPrimitivesVal>;
// DEPRECATED: remove before next major release (or other breaking change)
export type SFiledValues = SFieldValues;

export interface SFieldOperator {
$eq?: SFiledValues;
$ne?: SFiledValues;
$gt?: SFiledValues;
$lt?: SFiledValues;
$gte?: SFiledValues;
$lte?: SFiledValues;
$starts?: SFiledValues;
$ends?: SFiledValues;
$cont?: SFiledValues;
$excl?: SFiledValues;
$in?: SFiledValues;
$notin?: SFiledValues;
$between?: SFiledValues;
$isnull?: SFiledValues;
$notnull?: SFiledValues;
$eqL?: SFiledValues;
$neL?: SFiledValues;
$startsL?: SFiledValues;
$endsL?: SFiledValues;
$contL?: SFiledValues;
$exclL?: SFiledValues;
$inL?: SFiledValues;
$notinL?: SFiledValues;
$eq?: SFieldValues;
$ne?: SFieldValues;
$gt?: SFieldValues;
$lt?: SFieldValues;
$gte?: SFieldValues;
$lte?: SFieldValues;
$starts?: SFieldValues;
$ends?: SFieldValues;
$cont?: SFieldValues;
$excl?: SFieldValues;
$in?: SFieldValues;
$notin?: SFieldValues;
$between?: SFieldValues;
$isnull?: SFieldValues;
$notnull?: SFieldValues;
$eqL?: SFieldValues;
$neL?: SFieldValues;
$startsL?: SFieldValues;
$endsL?: SFieldValues;
$contL?: SFieldValues;
$exclL?: SFieldValues;
$inL?: SFieldValues;
$notinL?: SFieldValues;
$contArr?: Array<SPrimitivesVal>;
$intersectsArr?: Array<SPrimitivesVal>;
$or?: SFieldOperator;
$and?: never;
$not?: never;
Expand All @@ -109,7 +117,7 @@ export interface SFieldOperator {
export type SField =
| SPrimitivesVal
| SFieldOperator
| { [$custom: string]: SFiledValues };
| { [$custom: string]: SFieldValues };

export interface SFields {
[key: string]: SField | Array<SFields | SConditionAND | SConditionNOT> | undefined;
Expand Down
17 changes: 12 additions & 5 deletions packages/crud-typeorm/src/typeorm-crud.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,8 @@ export class TypeOrmCrudService<T> extends CrudService<T, DeepPartial<T>> {
const likeOperator =
this.dbName === 'postgres' ? 'ILIKE' : /* istanbul ignore next */ 'LIKE';
let str: string;
let params: ObjectLiteral;
// NOTE: may be overridden by specific operators
let params: ObjectLiteral = { [param]: cond.value };

if (cond.operator[0] !== '$') {
cond.operator = ('$' + cond.operator) as ComparisonOperator;
Expand Down Expand Up @@ -1183,6 +1184,16 @@ export class TypeOrmCrudService<T> extends CrudService<T, DeepPartial<T>> {
str = `LOWER(${field}) NOT IN (:...${param})`;
break;

case '$contArr':
this.checkFilterIsArray(cond);
str = `${field} @> ARRAY[:...${param}]`;
break;

case '$intersectsArr':
this.checkFilterIsArray(cond);
str = `${field} && ARRAY[:...${param}]`;
break;

/* istanbul ignore next */
default:
const customOperator = customOperators[cond.operator];
Expand All @@ -1203,10 +1214,6 @@ export class TypeOrmCrudService<T> extends CrudService<T, DeepPartial<T>> {
break;
}

if (typeof params === 'undefined') {
params = { [param]: cond.value };
}

return { str, params };
}

Expand Down

0 comments on commit 528162e

Please sign in to comment.