diff --git a/packages/core/src/shared/constants/index.ts b/packages/core/src/shared/constants/index.ts new file mode 100644 index 0000000..a9671b7 --- /dev/null +++ b/packages/core/src/shared/constants/index.ts @@ -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; diff --git a/packages/core/src/shared/errors/BaseError.ts b/packages/core/src/shared/errors/BaseError.ts new file mode 100644 index 0000000..68161be --- /dev/null +++ b/packages/core/src/shared/errors/BaseError.ts @@ -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'); + } +} diff --git a/packages/core/src/shared/index.ts b/packages/core/src/shared/index.ts new file mode 100644 index 0000000..4680489 --- /dev/null +++ b/packages/core/src/shared/index.ts @@ -0,0 +1,4 @@ +export * from './types/Result'; +export * from './errors/BaseError'; +export * from './utils/Guards'; +export * from './constants'; diff --git a/packages/core/src/shared/types/Result.ts b/packages/core/src/shared/types/Result.ts new file mode 100644 index 0000000..974d9ef --- /dev/null +++ b/packages/core/src/shared/types/Result.ts @@ -0,0 +1,29 @@ +/** + * Result type for handling success/failure scenarios + */ +export type Result = Success | Failure; + +export class Success { + public readonly isSuccess = true; + public readonly isFailure = false; + + constructor(public readonly value: T) {} + + public static create(value: T): Success { + return new Success(value); + } +} + +export class Failure { + public readonly isSuccess = false; + public readonly isFailure = true; + + constructor(public readonly error: E) {} + + public static create(error: E): Failure { + return new Failure(error); + } +} + +export const ok = (value: T): Result => new Success(value); +export const fail = (error: E): Result => new Failure(error); diff --git a/packages/core/src/shared/utils/Guards.ts b/packages/core/src/shared/utils/Guards.ts new file mode 100644 index 0000000..f4bc37d --- /dev/null +++ b/packages/core/src/shared/utils/Guards.ts @@ -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(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; + } +}