2023-10-06 12:08:58 +03:00
|
|
|
|
import type { TPaginationQuery } from './pagination'
|
2023-09-14 18:19:36 +03:00
|
|
|
|
|
|
|
|
|
import { z } from 'zod'
|
|
|
|
|
import { isEqual } from '../utils'
|
|
|
|
|
import { Pagination, paginationQuerySchema } from './pagination'
|
|
|
|
|
import { bFieldsSchema, cFieldsSchema, fieldSchema } from '../forms'
|
|
|
|
|
|
|
|
|
|
export const querySchema = cFieldsSchema
|
|
|
|
|
.pick({ q: true })
|
|
|
|
|
.extend(paginationQuerySchema.shape)
|
|
|
|
|
.extend({
|
|
|
|
|
sort: fieldSchema(bFieldsSchema.string.min(1).max(64), {
|
|
|
|
|
label: 'Сортировка'
|
|
|
|
|
})
|
|
|
|
|
})
|
2023-10-05 17:01:45 +03:00
|
|
|
|
.partial()
|
|
|
|
|
.describe('Параметры базового запроса')
|
2023-09-14 18:19:36 +03:00
|
|
|
|
|
|
|
|
|
export type TQuery = z.infer<typeof querySchema>
|
|
|
|
|
|
|
|
|
|
/**
|
2023-10-06 12:08:58 +03:00
|
|
|
|
* Класс для работы с запросами (для удобства).
|
2023-09-14 18:19:36 +03:00
|
|
|
|
*/
|
|
|
|
|
export type TFindFilter<T extends TQuery> = {
|
2023-10-06 12:43:46 +03:00
|
|
|
|
obj?: Omit<T, 'page' | 'limit' | 'sort'>
|
|
|
|
|
pagination?: TPaginationQuery
|
2023-09-14 18:19:36 +03:00
|
|
|
|
sort?: string
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-06 12:08:58 +03:00
|
|
|
|
/**
|
|
|
|
|
* Класс для работы с запросами (для удобства).
|
|
|
|
|
*/
|
2023-09-14 18:19:36 +03:00
|
|
|
|
export class FindFilter<T extends TQuery> implements TFindFilter<T> {
|
2023-10-06 12:43:46 +03:00
|
|
|
|
obj?: Omit<T, 'page' | 'limit' | 'sort'>
|
|
|
|
|
pagination?: TPaginationQuery
|
2023-09-14 18:19:36 +03:00
|
|
|
|
sort?: string
|
|
|
|
|
|
|
|
|
|
constructor(query?: T) {
|
2023-10-06 12:08:58 +03:00
|
|
|
|
// Copy fiends.
|
2023-10-05 17:01:45 +03:00
|
|
|
|
let queryCopy: T = Object.assign({}, query)
|
2023-09-14 18:19:36 +03:00
|
|
|
|
|
|
|
|
|
// Pagination.
|
2023-10-06 12:08:58 +03:00
|
|
|
|
this.pagination = new Pagination(queryCopy).getQuery()
|
|
|
|
|
// Delete pagination fields.
|
|
|
|
|
if (this.pagination as TPaginationQuery) {
|
2023-10-05 17:01:45 +03:00
|
|
|
|
const paginationKeys = Object.keys(this.pagination) as [keyof T]
|
|
|
|
|
for (const key of paginationKeys) {
|
|
|
|
|
if (queryCopy[key]) delete queryCopy[key]
|
|
|
|
|
}
|
2023-09-14 18:19:36 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sort.
|
|
|
|
|
if (queryCopy.sort) {
|
|
|
|
|
this.sort = queryCopy.sort
|
2023-10-06 12:08:58 +03:00
|
|
|
|
delete queryCopy.sort
|
2023-09-14 18:19:36 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Obj.
|
|
|
|
|
this.obj = queryCopy
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-06 12:08:58 +03:00
|
|
|
|
setPagination(pagination?: TPaginationQuery) {
|
|
|
|
|
this.pagination = new Pagination(pagination).getQuery()
|
2023-09-14 18:19:36 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toObject(): TFindFilter<T> {
|
|
|
|
|
return {
|
|
|
|
|
obj: this.obj,
|
|
|
|
|
pagination: this.pagination,
|
|
|
|
|
sort: this.sort
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isEqual(filters: TFindFilter<T>[]) {
|
|
|
|
|
return isEqual([this, ...filters])
|
|
|
|
|
}
|
2023-10-06 12:43:46 +03:00
|
|
|
|
|
|
|
|
|
toString(filter?: TFindFilter<TQuery>, opt?: { base?: string }): string {
|
|
|
|
|
let url = opt?.base?.replace(/[?]$/, '') || ''
|
|
|
|
|
|
|
|
|
|
if (filter) {
|
|
|
|
|
const query: string[] = []
|
|
|
|
|
|
|
|
|
|
// Params and Pagination.
|
|
|
|
|
for (const [key, val] of Object.entries({
|
|
|
|
|
...filter.obj,
|
|
|
|
|
...filter.pagination
|
|
|
|
|
})) {
|
|
|
|
|
if (val) {
|
|
|
|
|
const keyEncode = encodeURIComponent(key)
|
|
|
|
|
const valEncode = encodeURIComponent(val)
|
|
|
|
|
query.push(keyEncode + '=' + valEncode)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sort.
|
|
|
|
|
if (filter.sort) {
|
|
|
|
|
try {
|
|
|
|
|
query.push('sort=' + encodeURIComponent(filter.sort))
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (query.length) {
|
|
|
|
|
url += '?' + query.join('&')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return url
|
|
|
|
|
}
|
2023-09-14 18:19:36 +03:00
|
|
|
|
}
|