feat(core): add shared utilities and types

Add shared layer:
- Result<T,E> type for error handling
- BaseError and error subclasses
- Guards for runtime type checking
- Application constants
This commit is contained in:
imfozilbek
2025-11-23 21:43:43 +05:00
parent 6e24fe6ba8
commit 3dc531886e
5 changed files with 128 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
export const APP_CONSTANTS = {
DEFAULT_TIMEOUT: 5000,
MAX_RETRIES: 3,
VERSION: '0.0.1',
} as const;
export const ERROR_MESSAGES = {
VALIDATION_FAILED: 'Validation failed',
NOT_FOUND: 'Resource not found',
UNAUTHORIZED: 'Unauthorized access',
INTERNAL_ERROR: 'Internal server error',
} as const;

View File

@@ -0,0 +1,39 @@
/**
* Base error class for custom application errors
*/
export abstract class BaseError extends Error {
public readonly timestamp: Date;
public readonly code: string;
constructor(message: string, code: string) {
super(message);
this.name = this.constructor.name;
this.code = code;
this.timestamp = new Date();
Error.captureStackTrace(this, this.constructor);
}
}
export class ValidationError extends BaseError {
constructor(message: string) {
super(message, 'VALIDATION_ERROR');
}
}
export class NotFoundError extends BaseError {
constructor(message: string) {
super(message, 'NOT_FOUND');
}
}
export class UnauthorizedError extends BaseError {
constructor(message: string) {
super(message, 'UNAUTHORIZED');
}
}
export class InternalError extends BaseError {
constructor(message: string) {
super(message, 'INTERNAL_ERROR');
}
}

View File

@@ -0,0 +1,4 @@
export * from './types/Result';
export * from './errors/BaseError';
export * from './utils/Guards';
export * from './constants';

View File

@@ -0,0 +1,29 @@
/**
* Result type for handling success/failure scenarios
*/
export type Result<T, E = Error> = Success<T> | Failure<E>;
export class Success<T> {
public readonly isSuccess = true;
public readonly isFailure = false;
constructor(public readonly value: T) {}
public static create<T>(value: T): Success<T> {
return new Success(value);
}
}
export class Failure<E> {
public readonly isSuccess = false;
public readonly isFailure = true;
constructor(public readonly error: E) {}
public static create<E>(error: E): Failure<E> {
return new Failure(error);
}
}
export const ok = <T>(value: T): Result<T> => new Success(value);
export const fail = <E>(error: E): Result<never, E> => new Failure(error);

View File

@@ -0,0 +1,44 @@
/**
* Type guard utilities for runtime type checking
*/
export class Guards {
public static isNullOrUndefined(value: unknown): value is null | undefined {
return value === null || value === undefined;
}
public static isString(value: unknown): value is string {
return typeof value === 'string';
}
public static isNumber(value: unknown): value is number {
return typeof value === 'number' && !isNaN(value);
}
public static isBoolean(value: unknown): value is boolean {
return typeof value === 'boolean';
}
public static isObject(value: unknown): value is object {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
public static isArray<T>(value: unknown): value is T[] {
return Array.isArray(value);
}
public static isEmpty(value: string | unknown[] | object | null | undefined): boolean {
if (Guards.isNullOrUndefined(value)) {
return true;
}
if (Guards.isString(value) || Guards.isArray(value)) {
return value.length === 0;
}
if (Guards.isObject(value)) {
return Object.keys(value).length === 0;
}
return false;
}
}