128 lines
3.4 KiB
TypeScript
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;
|
|
}
|
|
}
|