feature/research-di #1

Merged
behnam merged 37 commits from feature/research-di into develop 2024-11-21 15:50:19 +00:00
9 changed files with 168 additions and 0 deletions
Showing only changes of commit 4c4b00c51f - Show all commits

View File

@ -16,6 +16,7 @@
"@radix-ui/react-slot": "^1.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"fp-ts": "^2.16.9",
"lucide-react": "^0.454.0",
"next": "15.0.2",
"postgres": "^3.4.5",

View File

@ -0,0 +1,8 @@
import { Either } from "fp-ts/lib/Either";
import { TaskEither } from "fp-ts/lib/TaskEither";
import BaseFailure from "@/feature/common/failures/base-failure";
type ApiTask<ResponseType> = TaskEither<BaseFailure, ResponseType>;
export type ApiEither<ResponseType> = Either<BaseFailure, ResponseType>;
export default ApiTask;

View File

@ -0,0 +1,22 @@
import { makeFailureMessage } from "@/feature/common/failures/failure-helpers";
/**
* This is a class called BaseFailure that extends the Error class. It is
* used as a base class for creating custom failure classes.
*/
export default abstract class BaseFailure {
/* ------------------------------- Attributes ------------------------------- */
private readonly BASE_FAILURE_MESSAGE = "failure";
/* -------------------------------------------------------------------------- */
/**
* Use this message as key lang for failure messages
*/
message = this.BASE_FAILURE_MESSAGE;
/* -------------------------------------------------------------------------- */
constructor(key: string) {
this.message = makeFailureMessage(this.message, key);
}
/* -------------------------------------------------------------------------- */
}

View File

@ -0,0 +1,12 @@
import BaseDevFailure from "@/feature/common/failures/dev/base-dev-failure";
/**
* Failure for needed arguments in a method but sent wrong one
*/
export default class ArgumentsFailure extends BaseDevFailure {
/* ------------------------------- Constructor ------------------------------ */
constructor() {
super("arguments");
}
/* -------------------------------------------------------------------------- */
}

View File

@ -0,0 +1,3 @@
import BaseFailure from "@/feature/common/failures/base-failure";
export default abstract class BaseDevFailure extends BaseFailure {}

View File

@ -0,0 +1,10 @@
import BaseDevFailure from "@/feature/common/failures/dev/base-dev-failure";
/**
* This is a failure of not having specific dependency
*/
export default class DependencyFailure extends BaseDevFailure {
constructor() {
super("DependencyFailure");
}
}

View File

@ -0,0 +1,95 @@
import BaseFailure from "@/feature/common/failures/base-failure";
/**
* This method is supposed to save previous failure of TaskEither
* to prevent it from loosing and overriding by the new one.
*
* Usage example:
* ```ts
* tryCatch(
* async () => {
* ...
* throw ValidationFailure();
* ...
* },
* (reason) => failureOr(reason, new UserCreationFailure()),
* )
* ```
* In this example `failureOr` will return already throwed
* instance of `BaseFailure` which is `ValidationFailure`.
*
*
* @param reason is throwed object.
* Basically it can be default `Error` or instance of `BaseFailure`.
* @param failure instance of `BaseFailure` that will be returned
* if reason is not instance of `BaseFailure`.
* @returns `BaseFailure`
*/
export function failureOr(reason: unknown, failure: BaseFailure): BaseFailure {
if (reason instanceof BaseFailure) {
return reason;
}
return failure;
}
/**
* Returns a function that maps a BaseFailure instance to a new BaseFailure instance of type IfType using the provided mapping function.
* @param f A function that maps an instance of IfType to a new instance of BaseFailure.
* @param ctor A constructor function for IfType.
* @returns A function that maps a BaseFailure instance to a new BaseFailure instance of type IfType.
*/
export function mapToFailureFrom<IfType extends BaseFailure>(
f: (t: IfType) => BaseFailure,
ctor: new (...args: never[]) => IfType,
): (t: BaseFailure) => BaseFailure {
return mapIfInstance<IfType, BaseFailure>(f, ctor);
}
/**
* Maps an instance of a class to a response using a provided function.
*
* @template IfType - The type of the instance to map.
* @template Response - The type of the response to map to.
* @param {function} f - The function to use to map the instance to a response.
* @param {new (...args: never[]) => IfType} ctor - The constructor function of the instance to map.
* @returns {(t: IfType | Response) => IfType | Response} - A function that maps the instance to a response using the provided function.
*/
export function mapIfInstance<IfType, Response>(
f: (t: IfType) => Response,
ctor: new (...args: never[]) => IfType,
) {
return (t: IfType | Response) => {
if (t instanceof ctor) {
return f(t);
}
return t;
};
}
/**
* Maps a function to a value if it is not an instance of a given class.
* @template IfType The type of the value to be mapped.
* @template Response The type of the mapped value.
* @param {function} f The function to map the value with.
* @param {new (...args: never[]) => IfType} ctor The class to check the value against.
* @returns {function} A function that maps the value if it is not an instance of the given class.
*/
export function mapIfNotInstance<IfType, Response>(
f: (t: IfType) => Response,
ctor: new (...args: never[]) => IfType,
) {
return (t: IfType | Response) => {
if (t! instanceof ctor) {
return f(t);
}
return t;
};
}
/**
* Gets Message key and it'll add it to the failure message key hierarchy
*/
export function makeFailureMessage(message: string, key: string) {
if (!key) return message;
return `${message}.${key}`;
}

View File

@ -0,0 +1,12 @@
import BaseFailure from "./base-failure";
/**
* Failure for HTTP response when response dosn't have base structure
*/
export default class NetworkFailure extends BaseFailure {
/* ------------------------------- Constructor ------------------------------ */
constructor() {
super("network");
}
/* -------------------------------------------------------------------------- */
}

View File

@ -2125,6 +2125,11 @@ form-data@^4.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
fp-ts@^2.16.9:
version "2.16.9"
resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-2.16.9.tgz#99628fc5e0bb3b432c4a16d8f4455247380bae8a"
integrity sha512-+I2+FnVB+tVaxcYyQkHUq7ZdKScaBlX53A41mxQtpIccsfyv8PzdzP7fzp2AY832T4aoK6UZ5WRX/ebGd8uZuQ==
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"