UNPKG

@synet/patterns

Version:

Robust, battle-tested collection of stable patterns used in Synet packages

107 lines (106 loc) 3.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ResultCombinators = exports.ResultExtensions = void 0; const result_1 = require("../patterns/result"); /** * Extensions for the Result pattern following the Open/Closed Principle. * These add functionality without modifying the core Result class. */ exports.ResultExtensions = { /** * Maps error from one Result type to another, preserving error details * * @example * const emailResult = Email.create(input); * if (emailResult.isFailure) { * return ResultExtensions.mapError<Email, User>(emailResult); * } */ mapError(result) { if (result.isSuccess) { throw new Error("Cannot map error from a successful result"); } return result_1.Result.fail(result.errorMessage ?? "Unknown error occurred", result.errorCause); }, /** * Maps a successful result value to a different type * * @example * const userResult = User.create({ name: "John" }); * const userDtoResult = ResultExtensions.mapSuccess(userResult, user => UserDto.fromUser(user)); */ mapSuccess(result, mapper) { if (result.isFailure) { return exports.ResultExtensions.mapError(result); } try { const mappedValue = mapper(result.value); return result_1.Result.success(mappedValue); } catch (error) { return result_1.Result.fail(`Error mapping result: ${error instanceof Error ? error.message : String(error)}`); } }, /** * Chains multiple results together, short-circuiting on first failure * * @example * const finalResult = ResultExtensions.chain( * () => validateInput(input), * (validInput) => processInput(validInput), * (processedData) => saveToDatabase(processedData) * ); */ chain(result, fn) { if (result.isFailure) { return exports.ResultExtensions.mapError(result); } try { return fn(result.value); } catch (error) { return result_1.Result.fail(`Error in result chain: ${error instanceof Error ? error.message : String(error)}`); } }, }; /** * Additional useful Result transformations and combinations */ exports.ResultCombinators = { /** * Returns first success result or combines all error messages * * @example * const result = ResultCombinators.any([ * primaryValidator(input), * fallbackValidator(input) * ]); */ any(results) { const successes = results.filter((r) => r.isSuccess); if (successes.length > 0) { return successes[0]; } const errorMessage = results .filter((r) => r.isFailure && r.errorMessage) .map((r) => r.errorMessage) .join("; "); return result_1.Result.fail(errorMessage || "All operations failed"); }, /** * Collects all successful results or returns first failure * * @example * const usersResult = ResultCombinators.all( * userIds.map(id => userRepository.getById(id)) * ); */ all(results) { const failures = results.filter((r) => r.isFailure); if (failures.length > 0) { return exports.ResultExtensions.mapError(failures[0]); } const values = results.map((r) => r.value); return result_1.Result.success(values); }, };