Uecko_ERP/packages/rdx-ddd/src/value-objects/postal-address.ts

111 lines
2.9 KiB
TypeScript
Raw Normal View History

2025-05-09 10:45:32 +00:00
import { Maybe, Result } from "@repo/rdx-utils";
2025-06-24 18:38:57 +00:00
import * as z from "zod/v4";
2025-02-20 18:55:24 +00:00
import { ValueObject } from "./value-object";
// 📌 Validaciones usando `zod`
const postalCodeSchema = z
.string()
2025-02-25 10:16:34 +00:00
.min(4, "Invalid postal code format")
.max(10, "Invalid postal code format")
2025-02-20 18:55:24 +00:00
.regex(/^\d{4,10}$/, {
message: "Invalid postal code format",
});
const streetSchema = z.string().min(2).max(255);
2025-02-25 19:17:30 +00:00
const street2Schema = z.string().optional();
2025-03-04 17:08:33 +00:00
const citySchema = z.string().min(2).max(50);
const stateSchema = z.string().min(2).max(50);
const countrySchema = z.string().min(2).max(56);
2025-02-20 18:55:24 +00:00
interface IPostalAddressProps {
street: string;
2025-02-25 19:17:30 +00:00
street2?: string;
2025-02-20 18:55:24 +00:00
city: string;
postalCode: string;
state: string;
country: string;
}
export class PostalAddress extends ValueObject<IPostalAddressProps> {
protected static validate(values: IPostalAddressProps) {
return z
.object({
street: streetSchema,
2025-02-25 19:17:30 +00:00
street2: street2Schema,
2025-02-20 18:55:24 +00:00
city: citySchema,
postalCode: postalCodeSchema,
2025-03-04 17:08:33 +00:00
state: stateSchema,
2025-02-20 18:55:24 +00:00
country: countrySchema,
})
.safeParse(values);
}
static create(values: IPostalAddressProps): Result<PostalAddress, Error> {
const valueIsValid = PostalAddress.validate(values);
if (!valueIsValid.success) {
2025-02-24 19:00:28 +00:00
return Result.fail(new Error(valueIsValid.error.errors[0].message));
2025-02-20 18:55:24 +00:00
}
2025-02-25 19:17:30 +00:00
return Result.ok(new PostalAddress(values));
2025-02-20 18:55:24 +00:00
}
static createNullable(values?: IPostalAddressProps): Result<Maybe<PostalAddress>, Error> {
if (!values || Object.values(values).every((value) => value.trim() === "")) {
2025-02-25 19:17:30 +00:00
return Result.ok(Maybe.none<PostalAddress>());
2025-02-20 18:55:24 +00:00
}
2025-05-09 10:45:32 +00:00
return PostalAddress.create(values).map((value) => Maybe.some(value));
2025-02-20 18:55:24 +00:00
}
2025-03-04 17:08:33 +00:00
static update(
oldAddress: PostalAddress,
data: Partial<PostalAddress>
): Result<PostalAddress, Error> {
return PostalAddress.create({
street: data.street ?? oldAddress.street,
street2: data.street2?.getOrUndefined() ?? oldAddress.street2.getOrUndefined(),
city: data.city ?? oldAddress.city,
postalCode: data.postalCode ?? oldAddress.postalCode,
state: data.state ?? oldAddress.state,
country: data.country ?? oldAddress.country,
2025-05-09 10:45:32 +00:00
// biome-ignore lint/complexity/noThisInStatic: <explanation>
2025-03-04 17:08:33 +00:00
}).getOrElse(this);
}
2025-02-20 18:55:24 +00:00
get street(): string {
return this.props.street;
}
2025-02-25 19:17:30 +00:00
get street2(): Maybe<string> {
return Maybe.fromNullable(this.props.street2);
}
2025-02-20 18:55:24 +00:00
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;
}
2025-04-01 14:26:15 +00:00
toPrimitive() {
return this.getValue();
}
2025-02-20 18:55:24 +00:00
toString(): string {
2025-02-25 19:17:30 +00:00
return `${this.props.street}, ${this.props.street2}, ${this.props.city}, ${this.props.postalCode}, ${this.props.state}, ${this.props.country}`;
2025-02-20 18:55:24 +00:00
}
}