UNPKG

rich-domain

Version:

This package provide utils file and interfaces to assistant build a complex application with domain driving design

168 lines 6.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Combine = exports.Result = void 0; const iterator_1 = require("./iterator"); /** * @description The `Result` class represents the outcome of an operation, encapsulating both the success or failure state. * A `Result` instance can contain a payload (`data`), an error, and optional metadata for additional context. * This pattern encourages explicit handling of operation success or failure, making your code more robust and expressive. * * @typeParam T - The type of the payload when the result is successful. * @typeParam D - The type of the error when the result is a failure. Defaults to `string`. * @typeParam M - The type of the metadata object. Defaults to an empty object `{}`. * * @example * ```typescript * // Creating a success result with data * const successResult = Result.Ok({ name: "Alice" }); * if (successResult.isOk()) { * console.log("Success data:", successResult.value()); * } * * // Creating a failure result with a custom error message * const failResult = Result.fail("An error occurred"); * if (failResult.isFail()) { * console.error("Error:", failResult.error()); * } * ``` */ class Result { #isOk; #isFail; #data; #error; #metaData; constructor(isSuccess, data, error, metaData) { this.#isOk = isSuccess; this.#isFail = !isSuccess; this.#data = data ?? null; this.#error = error ?? null; this.#metaData = metaData ?? {}; } static Ok(data, metaData) { const _data = typeof data === 'undefined' ? null : data; const ok = new Result(true, _data, null, metaData); return Object.freeze(ok); } static fail(error, metaData) { const _error = (typeof error !== 'undefined' && error !== null) ? error : 'void error. no message!'; const fail = new Result(false, null, _error, metaData); return Object.freeze(fail); } /** * @description Creates an iterator over a collection of `Result` instances. This allows sequential processing of multiple results. * @param results An array of `Result` instances. * @returns An iterator over the provided results. */ static iterate(results) { return iterator_1.default.create({ initialData: results, returnCurrentOnReversion: true }); } /** * @description Combines multiple `Result` instances into a single `Result`. * If any of the provided results is a failure, the combined `Result` is a failure. * If all results are successful, the combined `Result` is considered a success. * * @param results An array of `Result` instances to combine. * @returns A `Result` instance representing the combined outcome. */ static combine(results) { const iterator = Result.iterate(results); if (iterator.isEmpty()) return Result.fail('No results provided on combine param'); while (iterator.hasNext()) { const currentResult = iterator.next(); if (currentResult.isFail()) return currentResult; } return iterator.first(); } /** * @description Executes a command based on the result state. You can specify whether the command executes on success, failure, or both. * Optionally, you can provide data to the command if required. * * @param command An object implementing `ICommand` interface. * @returns An object with methods to configure command execution based on the `Result` state. */ execute(command) { return { on: (option) => { if (option === 'Ok' && this.isOk()) return command.execute(); if (option === 'fail' && this.isFail()) return command.execute(); }, withData: (data) => { return { on: (option) => { if (option === 'Ok' && this.isOk()) return command.execute(data); if (option === 'fail' && this.isFail()) return command.execute(data); } }; } }; } /** * @description Retrieves the payload of the `Result`. If the `Result` is a failure, `value()` returns `null`. * @returns The payload `T` or `null` if the result is a failure. */ value() { return this.#data; } /** * @description Retrieves the error of the `Result`. If the `Result` is a success, `error()` returns `null`. * @returns The error `D` or `null` if the result is a success. */ error() { return this.#error; } /** * @description Determines if the `Result` represents a failure state. * @returns `true` if the result is a failure, `false` if it is a success. */ isFail() { return this.#isFail; } /** * @description Checks if the `Result` payload is `null`. * This can be useful for confirming the presence or absence of a value before proceeding. * @returns `true` if the payload is `null`, `false` otherwise. */ isNull() { return this.#data === null || this.#isFail; } /** * @description Determines if the `Result` represents a success state. * @returns `true` if the result is a success, `false` if it is a failure. */ isOk() { return this.#isOk; } /** * @description Retrieves the metadata associated with the `Result`. * @returns The metadata object `M`, or `{}` if no metadata was provided. */ metaData() { const metaData = this.#metaData; return Object.freeze(metaData); } /** * @description Converts the `Result` instance into a plain object for easier logging or serialization. * @returns An object containing `isOk`, `isFail`, `data`, `error`, and `metaData`. */ toObject() { const metaData = { isOk: this.#isOk, isFail: this.#isFail, data: this.#data, error: this.#error, metaData: this.#metaData }; return Object.freeze(metaData); } } exports.Result = Result; exports.default = Result; exports.Combine = Result.combine; //# sourceMappingURL=result.js.map