Uecko_ERP/packages/rdx-criteria/src/criteria-from-url-converter.ts
2025-11-16 20:29:07 +01:00

84 lines
2.5 KiB
TypeScript

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<string, Partial<FiltersPrimitives>> = {};
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
);
}
}