import type { FiltersPrimitives } from "./codelytv"; import { Criteria } from "./critera"; import { DEFAULT_ORDER, INITIAL_PAGE_INDEX, INITIAL_PAGE_SIZE } from "./defaults"; type defaultsType = { order: "asc" | "desc"; pageSize: number; pageNumber: number; }; const defaultOptions: defaultsType = { order: DEFAULT_ORDER, pageSize: INITIAL_PAGE_SIZE, pageNumber: INITIAL_PAGE_INDEX, } as const; export class CriteriaFromUrlConverter { /** * Converts a URL to a criteria object. * @param url - The URL to convert. * @returns The criteria object. */ public toCriteria( url: URL, options?: { defaults: defaultsType; } ): Criteria { const { searchParams: urlParams } = url; const defaults = { order: options?.defaults?.order ?? defaultOptions.order, pageSize: options?.defaults?.pageSize ?? defaultOptions.pageSize, pageNumber: options?.defaults?.pageNumber ?? defaultOptions.pageNumber, }; const quickSearch = urlParams.get("q"); const filters = this.parseFilters(urlParams); const orderBy = urlParams.get("orderBy"); const order = urlParams.has("order") ? String(urlParams.get("order")) : defaults.order; const pageSize = this.parseInteger(urlParams.get("pageSize"), defaults.pageSize); const pageNumber = this.parseInteger(urlParams.get("pageNumber"), defaults.pageNumber); return Criteria.fromPrimitives(filters, orderBy, order, pageSize, pageNumber, quickSearch); } public toFiltersPrimitives(url: URL): FiltersPrimitives[] { const { searchParams } = url; return this.parseFilters(searchParams); } private parseInteger(value: string | null, fallback: number): number { const parsed = Number.parseInt(value ?? "", 10); return Number.isNaN(parsed) ? fallback : parsed; } private parseFilters(searchParams: URLSearchParams): FiltersPrimitives[] { const tempFilters: Record> = {}; searchParams.forEach((value, key) => { const match = key.match(/filters\[(\d+)]\[(.+)]/); if (match) { const index = match[1]!; const property = match[2] as keyof FiltersPrimitives; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!tempFilters[index]) { tempFilters[index] = {}; } tempFilters[index][property] = value; } }); // @ts-expect-error return Object.values(tempFilters).filter( (filter) => filter.field !== undefined && filter.operator !== undefined && filter.value !== undefined ); } }