import { DomainConflictError } from '../../../common/errors/domain-conflict.error';
export type CostingInputRecord = Record<string, unknown>;
export function assertCostingInputObject(input: unknown, code: string): asserts input is CostingInputRecord {
if (!input || typeof input !== 'object' || Array.isArray(input)) {
throw new DomainConflictError(code);
}
}
export function assertCostingText(value: unknown, max: number, code: string): asserts value is string {
if (typeof value !== 'string' || value.trim().length === 0 || value.length > max) {
throw new DomainConflictError(code);
}
}
export function assertOptionalCostingText(value: unknown, max: number, code: string): void {
if (value !== undefined && value !== null) assertCostingText(value, max, code);
}
export function assertCostingScope(
input: unknown,
code: string,
options: { locationRequired?: boolean } = {},
): asserts input is CostingInputRecord {
assertCostingInputObject(input, code);
assertCostingText(input.organizationId, 200, code);
if (options.locationRequired === false) {
if (input.locationId !== undefined && input.locationId !== null) {
assertCostingText(input.locationId, 200, code);
}
} else {
assertCostingText(input.locationId, 200, code);
}
}
export function assertCostingId(value: unknown, code: string): asserts value is string {
assertCostingText(value, 200, code);
}
export function assertCostingEnum(value: unknown, allowed: readonly string[], code: string): asserts value is string {
if (typeof value !== 'string' || !allowed.includes(value)) {
throw new DomainConflictError(code);
}
}
export function assertCostingCurrency(value: unknown, code: string): asserts value is string {
if (typeof value !== 'string' || !/^[A-Z]{3}$/.test(value)) {
throw new DomainConflictError(code);
}
}
export function assertCostingBoolean(value: unknown, code: string): asserts value is boolean {
if (typeof value !== 'boolean') throw new DomainConflictError(code);
}
export function assertOptionalCostingBoolean(value: unknown, code: string): void {
if (value !== undefined && value !== null) assertCostingBoolean(value, code);
}
export function assertCostingDecimal(
value: unknown,
code: string,
options: { allowNegative?: boolean; maxLength?: number } = {},
): asserts value is string {
const maxLength = options.maxLength ?? 80;
if (typeof value !== 'string' || value.length === 0 || value.length > maxLength || !Number.isFinite(Number(value))) {
throw new DomainConflictError(code);
}
const pattern = options.allowNegative === false ? /^\d+(?:\.\d+)?$/ : /^-?\d+(?:\.\d+)?$/;
if (!pattern.test(value)) throw new DomainConflictError(code);
}
export function assertCostingIntegerText(
value: unknown,
code: string,
options: { allowNegative?: boolean; maxLength?: number } = {},
): asserts value is string {
const maxLength = options.maxLength ?? 80;
if (typeof value !== 'string' || value.length === 0 || value.length > maxLength) {
throw new DomainConflictError(code);
}
const pattern = options.allowNegative === false ? /^\d+$/ : /^-?\d+$/;
if (!pattern.test(value)) throw new DomainConflictError(code);
}
export function assertOptionalCostingDecimal(
value: unknown,
code: string,
options: { allowNegative?: boolean; maxLength?: number } = {},
): void {
if (value !== undefined && value !== null) assertCostingDecimal(value, code, options);
}
export function assertCostingSafeInteger(value: unknown, code: string, min: number, max: number): asserts value is number {
if (!Number.isSafeInteger(value) || Number(value) < min || Number(value) > max) {
throw new DomainConflictError(code);
}
}
