Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(RequestQueryBuilder): generic type #652

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import {
SCondition,
} from '../types';

export interface CreateQueryParams {
fields?: QueryFields;
search?: SCondition;
filter?: QueryFilter | QueryFilterArr | Array<QueryFilter | QueryFilterArr>;
or?: QueryFilter | QueryFilterArr | Array<QueryFilter | QueryFilterArr>;
join?: QueryJoin | QueryJoinArr | Array<QueryJoin | QueryJoinArr>;
sort?: QuerySort | QuerySortArr | Array<QuerySort | QuerySortArr>;
export interface CreateQueryParams<K extends string = string> {
fields?: QueryFields<K>;
search?: SCondition<K>;
filter?: QueryFilter<K> | QueryFilterArr<K> | Array<QueryFilter<K> | QueryFilterArr<K>>;
or?: QueryFilter<K> | QueryFilterArr<K> | Array<QueryFilter<K> | QueryFilterArr<K>>;
join?: QueryJoin<K> | QueryJoinArr<K> | Array<QueryJoin<K> | QueryJoinArr<K>>;
sort?: QuerySort<K> | QuerySortArr<K> | Array<QuerySort<K> | QuerySortArr<K>>;
limit?: number;
offset?: number;
page?: number;
Expand Down
46 changes: 28 additions & 18 deletions packages/crud-request/src/request-query.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
} from './types';

// tslint:disable:variable-name ban-types
export class RequestQueryBuilder {
export class RequestQueryBuilder<K extends string = string> {
constructor() {
this.setParamNames();
}
Expand Down Expand Up @@ -95,52 +95,60 @@ export class RequestQueryBuilder {
return this.queryString;
}

select(fields: QueryFields): this {
select(fields: QueryFields<K>): this {
if (isArrayFull(fields)) {
validateFields(fields);
this.queryObject[this.paramNames.fields] = fields.join(this.options.delimStr);
}
return this;
}

search(s: SCondition) {
search(s: SCondition<K>) {
if (!isNil(s) && isObject(s)) {
this.queryObject[this.paramNames.search] = JSON.stringify(s);
}
return this;
}

setFilter(f: QueryFilter | QueryFilterArr | Array<QueryFilter | QueryFilterArr>): this {
setFilter(
f: QueryFilter<K> | QueryFilterArr<K> | Array<QueryFilter<K> | QueryFilterArr<K>>,
): this {
this.setCondition(f, 'filter');
return this;
}

setOr(f: QueryFilter | QueryFilterArr | Array<QueryFilter | QueryFilterArr>): this {
setOr(
f: QueryFilter<K> | QueryFilterArr<K> | Array<QueryFilter<K> | QueryFilterArr<K>>,
): this {
this.setCondition(f, 'or');
return this;
}

setJoin(j: QueryJoin | QueryJoinArr | Array<QueryJoin | QueryJoinArr>): this {
setJoin(
j: QueryJoin<K> | QueryJoinArr<K> | Array<QueryJoin<K> | QueryJoinArr<K>>,
): this {
if (!isNil(j)) {
const param = this.checkQueryObjectParam('join', []);
this.queryObject[param] = [
...this.queryObject[param],
...(Array.isArray(j) && !isString(j[0])
? (j as Array<QueryJoin | QueryJoinArr>).map((o) => this.addJoin(o))
: [this.addJoin(j as QueryJoin | QueryJoinArr)]),
? (j as Array<QueryJoin<K> | QueryJoinArr<K>>).map((o) => this.addJoin(o))
: [this.addJoin(j as QueryJoin<K> | QueryJoinArr<K>)]),
];
}
return this;
}

sortBy(s: QuerySort | QuerySortArr | Array<QuerySort | QuerySortArr>): this {
sortBy(
s: QuerySort<K> | QuerySortArr<K> | Array<QuerySort<K> | QuerySortArr<K>>,
): this {
if (!isNil(s)) {
const param = this.checkQueryObjectParam('sort', []);
this.queryObject[param] = [
...this.queryObject[param],
...(Array.isArray(s) && !isString(s[0])
? (s as Array<QuerySort | QuerySortArr>).map((o) => this.addSortBy(o))
: [this.addSortBy(s as QuerySort | QuerySortArr)]),
? (s as Array<QuerySort<K> | QuerySortArr<K>>).map((o) => this.addSortBy(o))
: [this.addSortBy(s as QuerySort<K> | QuerySortArr<K>)]),
];
}
return this;
Expand All @@ -167,7 +175,7 @@ export class RequestQueryBuilder {
}

cond(
f: QueryFilter | QueryFilterArr,
f: QueryFilter<K> | QueryFilterArr<K>,
cond: 'filter' | 'or' | 'search' = 'search',
): string {
const filter = Array.isArray(f) ? { field: f[0], operator: f[1], value: f[2] } : f;
Expand All @@ -182,7 +190,7 @@ export class RequestQueryBuilder {
);
}

private addJoin(j: QueryJoin | QueryJoinArr): string {
private addJoin(j: QueryJoin<K> | QueryJoinArr<K>): string {
const join = Array.isArray(j) ? { field: j[0], select: j[1] } : j;
validateJoin(join);
const d = this.options.delim;
Expand All @@ -191,15 +199,15 @@ export class RequestQueryBuilder {
return join.field + (isArrayFull(join.select) ? d + join.select.join(ds) : '');
}

private addSortBy(s: QuerySort | QuerySortArr): string {
private addSortBy(s: QuerySort<K> | QuerySortArr<K>): string {
const sort = Array.isArray(s) ? { field: s[0], order: s[1] } : s;
validateSort(sort);
const ds = this.options.delimStr;

return sort.field + ds + sort.order;
}

private createFromParams(params: CreateQueryParams): this {
private createFromParams(params: CreateQueryParams<K>): this {
this.select(params.fields);
this.search(params.search);
this.setFilter(params.filter);
Expand Down Expand Up @@ -227,16 +235,18 @@ export class RequestQueryBuilder {
}

private setCondition(
f: QueryFilter | QueryFilterArr | Array<QueryFilter | QueryFilterArr>,
f: QueryFilter<K> | QueryFilterArr<K> | Array<QueryFilter<K> | QueryFilterArr<K>>,
cond: 'filter' | 'or',
): void {
if (!isNil(f)) {
const param = this.checkQueryObjectParam(cond, []);
this.queryObject[param] = [
...this.queryObject[param],
...(Array.isArray(f) && !isString(f[0])
? (f as Array<QueryFilter | QueryFilterArr>).map((o) => this.cond(o, cond))
: [this.cond(f as QueryFilter | QueryFilterArr, cond)]),
? (f as Array<QueryFilter<K> | QueryFilterArr<K>>).map((o) =>
this.cond(o, cond),
)
: [this.cond(f as QueryFilter<K> | QueryFilterArr<K>, cond)]),
];
}
}
Expand Down
35 changes: 18 additions & 17 deletions packages/crud-request/src/types/request-query.types.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
export type QueryFields = string[];
export type QueryFields<K extends string = string> = K[];

export type QueryFilter = {
field: string;
export type QueryFilter<K extends string = string> = {
field: K;
operator: ComparisonOperator;
value?: any;
};

export type QueryFilterArr = [string, ComparisonOperator, any?];
export type QueryFilterArr<K extends string = string> = [K, ComparisonOperator, any?];

export type QueryJoin = {
field: string;
select?: QueryFields;
export type QueryJoin<K extends string = string> = {
field: K;
select?: QueryFields<K>;
};

export type QueryJoinArr = [string, QueryFields?];
export type QueryJoinArr<K extends string = string> = [K, QueryFields<K>?];

export type QuerySort = {
field: string;
export type QuerySort<K extends string = string> = {
field: K;
order: QuerySortOperator;
};

export type QuerySortArr = [string, QuerySortOperator];
export type QuerySortArr<K extends string = string> = [K, QuerySortOperator];

export type QuerySortOperator = 'ASC' | 'DESC';

Expand Down Expand Up @@ -104,17 +104,18 @@ export type SFieldOperator = {

export type SField = SPrimitivesVal | SFieldOperator;

export type SFields = {
[key: string]: SField | Array<SFields | SConditionAND> | undefined;
$or?: Array<SFields | SConditionAND>;
export type SFields<K extends string = string> = {
$or?: Array<SFields<K> | SConditionAND<K>>;
$and?: never;
} & {
[key in K]?: SField | Array<SFields<K> | SConditionAND<K>> | undefined;
};

export type SConditionAND = {
$and?: Array<SFields | SConditionAND>;
export type SConditionAND<K extends string = string> = {
$and?: Array<SFields<K> | SConditionAND<K>>;
$or?: never;
};

export type SConditionKey = '$and' | '$or';

export type SCondition = SFields | SConditionAND;
export type SCondition<K extends string = string> = SFields<K> | SConditionAND<K>;