FactuGES_ERP/packages/rdx-criteria/src/Order/OrderCriteria.ts
2025-05-19 13:59:13 +02:00

128 lines
3.4 KiB
TypeScript

import { Result, ResultCollection, RuleValidator, UndefinedOr } from "@repo/rdx-utils";
import { StringValueObject } from "../helpers";
import { IOrderProps, Order } from "./Order";
import { IOrderCollection, OrderCollection } from "./OrderCollection";
export interface IOrderCriteria {
getOrderCollection(): IOrderCollection;
toJSON(): string;
toString(): string;
toObject(): Record<string, any>;
}
export class OrderCriteria extends StringValueObject implements IOrderCriteria {
private static parseOrderString = (orderString: UndefinedOr<string>): string[][] => {
// eslint-disable-next-line no-useless-escape
//return OrderString.match(/(.+)(([\[])([\w]+)([\]]))([\w\W]+)*/i);
const result: any[] = [];
if (orderString) {
const regex = /([+-]?)([\w_.]+)/gi;
let matches: any;
// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
while ((matches = regex.exec(orderString)) !== null) {
result.push([...matches]);
}
}
return result;
};
protected static validate(value: UndefinedOr<string>) {
let orderString = value;
if (RuleValidator.validate(RuleValidator.RULE_NOT_NULL_OR_UNDEFINED, orderString).isFailure) {
return Result.ok(value);
}
const stringOrError = RuleValidator.validate<string>(
RuleValidator.RULE_IS_TYPE_STRING,
orderString
);
if (stringOrError.isFailure) {
return stringOrError;
}
orderString = String(value);
const orderOrErrors = new ResultCollection();
// biome-ignore lint/complexity/noForEach: <explanation>
OrderCriteria.parseOrderString(orderString).forEach((token: string[]) => {
const orderOrError = Order.create({
type: token[1] || "+",
field: String(token[2]),
});
orderOrErrors.add(orderOrError);
});
if (orderOrErrors.hasSomeFaultyResult()) {
return orderOrErrors.getFirstFaultyResult() as Result<never, Error>;
}
return Result.ok<string>(orderString);
}
public static create(value: UndefinedOr<string>) {
const validatedProps = OrderCriteria.validate(value);
if (validatedProps.isFailure) {
return Result.fail(validatedProps.error);
}
return Result.ok<OrderCriteria>(new OrderCriteria(validatedProps.data));
}
public getOrderCollection(): IOrderCollection {
return this.buildOrderCollection();
}
public toJSON(): string {
return JSON.stringify(this.toObject());
}
public toPrimitive(): string {
throw new Error("NOT IMPLEMENT OrderCriteria.toPrimitive()");
}
public toObject(): Record<string, any> {
return this.getOrderCollection().toObject();
}
protected buildOrderCollection(): IOrderCollection {
let _orders: IOrderProps[] | undefined = undefined;
if (!this.isEmpty()) {
_orders = OrderCriteria.parseOrderString(this.props).map((token: string[]) => {
/** TOKEN
* [1] => type + / - (opcional)
* [2] => field / model.field
*/
const type = token[1] ? String(token[1]) : "+";
const orderOrError = Order.create({
type,
field: String(token[2]),
});
if (orderOrError.isFailure) {
throw new Error(`Order '${token.join()}' is not valid`);
}
return orderOrError.data;
});
}
return (
_orders === undefined
? OrderCollection.createEmpty()
: OrderCollection.create(_orders as Order[])
) as IOrderCollection;
}
}