2024-04-23 15:29:38 +00:00
|
|
|
import { v4 as uuidv4 } from "uuid";
|
|
|
|
|
|
|
|
|
|
import Joi from "joi";
|
|
|
|
|
import { NullOr, UndefinedOr } from "../../../../utilities";
|
|
|
|
|
import { RuleValidator } from "../RuleValidator";
|
|
|
|
|
import { DomainError, handleDomainError } from "../errors";
|
|
|
|
|
import {
|
|
|
|
|
INullableValueObjectOptions,
|
|
|
|
|
NullableValueObject,
|
|
|
|
|
} from "./NullableValueObject";
|
|
|
|
|
import { Result } from "./Result";
|
|
|
|
|
|
|
|
|
|
export interface IUniqueIDOptions extends INullableValueObjectOptions {
|
|
|
|
|
generateOnEmpty?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class UniqueID extends NullableValueObject<string> {
|
|
|
|
|
protected static validate(
|
|
|
|
|
value: UndefinedOr<string>,
|
2024-05-16 19:40:07 +00:00
|
|
|
options: IUniqueIDOptions,
|
2024-04-23 15:29:38 +00:00
|
|
|
) {
|
|
|
|
|
const ruleIsEmpty = RuleValidator.RULE_ALLOW_EMPTY.default("");
|
|
|
|
|
|
|
|
|
|
const ruleIsGuid = Joi.string()
|
|
|
|
|
.guid({
|
|
|
|
|
version: ["uuidv4"],
|
|
|
|
|
})
|
|
|
|
|
.label(options.label ? options.label : "id");
|
|
|
|
|
|
|
|
|
|
const rules = Joi.alternatives(ruleIsEmpty, ruleIsGuid);
|
|
|
|
|
|
|
|
|
|
return RuleValidator.validate<string>(rules, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static sanitize(id: string): string {
|
|
|
|
|
return id.trim();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static create(value: NullOr<string>, options: IUniqueIDOptions = {}) {
|
|
|
|
|
const _options: IUniqueIDOptions = {
|
|
|
|
|
label: "id",
|
|
|
|
|
generateOnEmpty: false,
|
|
|
|
|
...options,
|
|
|
|
|
};
|
|
|
|
|
|
2024-05-16 19:40:07 +00:00
|
|
|
if (!value && !_options.generateOnEmpty) {
|
|
|
|
|
return Result.fail(
|
|
|
|
|
handleDomainError(
|
|
|
|
|
DomainError.INVALID_INPUT_DATA,
|
|
|
|
|
"ID is null or empty",
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-23 15:29:38 +00:00
|
|
|
if (value) {
|
|
|
|
|
const validationResult = UniqueID.validate(value, _options);
|
|
|
|
|
|
|
|
|
|
if (validationResult.isFailure) {
|
|
|
|
|
return Result.fail(
|
|
|
|
|
handleDomainError(
|
|
|
|
|
DomainError.INVALID_INPUT_DATA,
|
2024-04-24 10:48:49 +00:00
|
|
|
validationResult.error.message,
|
2024-05-16 19:40:07 +00:00
|
|
|
_options,
|
|
|
|
|
),
|
2024-04-23 15:29:38 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Result.ok<UniqueID>(
|
2024-05-16 19:40:07 +00:00
|
|
|
new UniqueID(UniqueID.sanitize(validationResult.object)),
|
2024-04-23 15:29:38 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_options.generateOnEmpty) {
|
|
|
|
|
return UniqueID.generateNewID();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Result.ok<UniqueID>(new UniqueID(null));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static generateNewID(): Result<UniqueID, never> {
|
|
|
|
|
return Result.ok<UniqueID>(new UniqueID(uuidv4()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get value(): string {
|
|
|
|
|
return String(this.props);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public toString(): string {
|
|
|
|
|
return String(this.props);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public toPrimitive(): string {
|
|
|
|
|
return this.toString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class InvalidUniqueIDError extends Error {}
|