import { Maybe, Result } from "@repo/rdx-utils"; import * as z from "zod/v4"; import { ValueObject } from "./value-object"; // 📌 Validaciones usando `zod` const postalCodeSchema = z .string() .min(4, "Invalid postal code format") .max(10, "Invalid postal code format") .regex(/^\d{4,10}$/, { message: "Invalid postal code format", }); const streetSchema = z.string().max(255).default(""); const street2Schema = z.string().default(""); const citySchema = z.string().max(50).default(""); const stateSchema = z.string().max(50).default(""); const countrySchema = z.string().max(56).default(""); interface IPostalAddressProps { street: string; street2?: string; city: string; postalCode: string; state: string; country: string; } export class PostalAddress extends ValueObject { protected static validate(values: IPostalAddressProps) { return z .object({ street: streetSchema, street2: street2Schema, city: citySchema, postalCode: postalCodeSchema, state: stateSchema, country: countrySchema, }) .safeParse(values); } static create(values: IPostalAddressProps): Result { const valueIsValid = PostalAddress.validate(values); if (!valueIsValid.success) { return Result.fail(new Error(valueIsValid.error.issues[0].message)); } return Result.ok(new PostalAddress(values)); } static createNullable(values?: IPostalAddressProps): Result, Error> { if (!values || Object.values(values).every((value) => value.trim() === "")) { return Result.ok(Maybe.none()); } return PostalAddress.create(values).map((value) => Maybe.some(value)); } static update( oldAddress: PostalAddress, data: Partial ): Result { return PostalAddress.create({ street: data.street ?? oldAddress.street, street2: data.street2 ?? oldAddress.street2, city: data.city ?? oldAddress.city, postalCode: data.postalCode ?? oldAddress.postalCode, state: data.state ?? oldAddress.state, country: data.country ?? oldAddress.country, // biome-ignore lint/complexity/noThisInStatic: }).getOrElse(this); } get street(): string { return this.props.street; } get street2(): string { return this.props.street2 ?? ""; } get city(): string { return this.props.city; } get postalCode(): string { return this.props.postalCode; } get state(): string { return this.props.state; } get country(): string { return this.props.country; } getValue(): IPostalAddressProps { return this.props; } toPrimitive() { return this.getValue(); } toString(): string { return `${this.props.street}, ${this.props.street2}, ${this.props.city}, ${this.props.postalCode}, ${this.props.state}, ${this.props.country}`; } }