Skip to content

Commit

Permalink
refactor(query.builder.ts): add abstract QueryBuilder class and two s…
Browse files Browse the repository at this point in the history
…ubclasses for Movie and Person

feat(special-value.enum.ts): add NOT_NULL special value
refactor(movie.service.ts): remove paginationParams from getByFilters and getAwardsByFilters methods and pass filters directly to request.get method. Change return type to include IResponseError in case of error. Remove pagination from getBySearchQuery method. Update getPossibleValuesByField method to include IResponseError in case of error.
  • Loading branch information
mdwitr0 committed Jun 22, 2023
1 parent ac1fd4b commit 1f1685b
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 23 deletions.
79 changes: 79 additions & 0 deletions src/builder/query.builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { SORT_TYPE } from '../enums/sort-type.enum';
import { SPECIAL_VALUE } from '../enums/special-value.enum';
import { IQueryFields } from '../interfaces/query-fields.interface';
import { MovieFields } from '../types/movie-fields.type';
import { PersonFields } from '../types/person-fields.type';

export abstract class QueryBuilder<T extends IQueryFields> {
protected query: any;

constructor() {
this.query = {};
}

select(
fields: (
| T['BooleanFields']
| T['NumberFields']
| T['DateFields']
| T['StringFields']
)[],
): this {
this.query.selectFields = fields;
return this;
}

sort(
field:
| T['BooleanFields']
| T['NumberFields']
| T['DateFields']
| T['StringFields'],
sortType: SORT_TYPE | '1' | '-1',
): this {
if (!this.query.sortField) {
this.query.sortField = [];
this.query.sortType = [];
}
this.query.sortField.push(field);
this.query.sortType.push(sortType);
return this;
}

filterExact(
field:
| T['BooleanFields']
| T['NumberFields']
| T['DateFields']
| T['StringFields'],
value: string | number | boolean | SPECIAL_VALUE,
): this {
this.query[field] = value;
return this;
}

filterRange(field: T['NumberFields'], range: [number, number]): this {
this.query[field] = range.join('-');
return this;
}

filterDateRange(field: T['DateFields'], range: [Date, Date]): this {
this.query[field] = range
.map(date => date.toISOString().split('T')[0])
.join('-');
return this;
}

paginate(page: number, limit: number): this {
this.query.page = page;
this.query.limit = limit;
return this;
}

build(): any {
return this.query;
}
}

export class MovieQueryBuilder extends QueryBuilder<MovieFields> {}
export class PersonQueryBuilder extends QueryBuilder<PersonFields> {}
3 changes: 3 additions & 0 deletions src/enums/special-value.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum SPECIAL_VALUE {
NOT_NULL = '!null',
}
34 changes: 11 additions & 23 deletions src/services/movie.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,55 +9,43 @@ import {
import { IPagination } from '../interfaces/pagination.interface';
import { Pagination } from '../classes/pagination';
import { VERSIONS } from '../enums/version.enum';
import { IResponseError } from '../interfaces/error.interface';

export class MovieService {
constructor(private readonly request: ClientRequest) {}

async getById(id: number): Promise<MovieDtoV13> {
async getById(id: number): Promise<IResponseError | MovieDtoV13> {
return await this.request.get(VERSIONS.V1_3, `/movie/${id}`);
}

async getRandom(): Promise<MovieDtoV13> {
async getRandom(): Promise<IResponseError | MovieDtoV13> {
return await this.request.get(VERSIONS.V1_3, `/movie/random`);
}

async getByFilters(
filters: Record<string, string>,
paginationParams?: IPagination,
): Promise<MovieDocsResponseDtoV13> {
const pagination = new Pagination(paginationParams);

return await this.request.get(VERSIONS.V1_3, `/movie`, {
...filters,
...pagination,
});
): Promise<IResponseError | MovieDocsResponseDtoV13> {
return await this.request.get(VERSIONS.V1_3, `/movie`, filters);
}

async getBySearchQuery(
query: string,
paginationParams?: IPagination,
): Promise<SearchMovieResponseDto> {
const pagination = new Pagination(paginationParams);

): Promise<IResponseError | SearchMovieResponseDto> {
return await this.request.get(VERSIONS.V1_2, `/movie/search`, {
query,
...pagination,
});
}

async getAwardsByFilters(
filters: Record<string, string>,
paginationParams?: IPagination,
): Promise<MovieDocsResponseDtoV13> {
const pagination = new Pagination(paginationParams);

return await this.request.get(VERSIONS.V1_1, `/movie/awards`, {
...filters,
...pagination,
});
): Promise<IResponseError | MovieDocsResponseDtoV13> {
return await this.request.get(VERSIONS.V1_1, `/movie/awards`, filters);
}

getPossibleValuesByField(field: string): Promise<PossibleValueDto[]> {
getPossibleValuesByField(
field: string,
): Promise<IResponseError | PossibleValueDto[]> {
return this.request.get(VERSIONS.V1, `/movie/possibleValues`, {
field,
});
Expand Down

0 comments on commit 1f1685b

Please sign in to comment.