@ignix/core
v1.6.0
Published
A TypeScript package for type-safe services with Result pattern, ORM-agnostic repositories, and framework-flexible API handlers.
Maintainers
Readme
@ignix/core 🚀
A TypeScript package for building type-safe, extensible services with Result pattern, ORM-agnostic repositories, and framework-flexible API handlers.
Table of Contents
About
@ignix/core solves the problem of repetitive boilerplate in backend development by providing a modular, type-safe architecture for services, data access, and API layers. It enables developers to build scalable applications with robust error handling (using the Result pattern), extensible repositories compatible with popular ORMs like TypeORM or Prisma, and API handlers that adapt to frameworks such as NestJS, Express, Fastify, or Hono. Born from the need for clean, testable code without framework lock-in, it promotes SOLID principles and type safety to reduce bugs and improve maintainability.
Features
- Result Pattern Integration: Handle operations with explicit success/failure types, avoiding exceptions and improving reliability.
- Generic Services:
IService<T>with CRUD operations, customizable DTOs (Create, Update, Response), and extensible error types. IncludesBaseServiceimplementation. - ORM-Agnostic Repositories:
IRepository<T>interface with base implementations for TypeORM, Prisma, and more, allowing easy extension. - Framework-Flexible API Handlers:
IAPIHandler<T>with adapters for NestJS (controllers) and Express-like (routes), supporting multiple request/response patterns. - Legacy Compatibility:
LegacyServicewrapper for promise-based APIs if Result pattern isn't desired. - Type Safety First: Full TypeScript generics for entities, DTOs, and errors, with discriminated unions for error handling.
- Extensibility: Users can override defaults, add custom methods, or integrate new ORMs/frameworks without modifying core code.
Tech Stack
- Language: TypeScript
- Package Manager: npm
- ORM Support: TypeORM, Prisma, Sequelize (extensible)
- Framework Adapters: NestJS, Express, Fastify, Hono
- Dev Tools: Jest (for testing), ESLint, Prettier
Architecture
@ignix/core follows a layered architecture inspired by Clean Architecture, separating concerns into Service (business logic), Repository (data access), and API (presentation) layers. This ensures testability, flexibility, and framework independence.
graph LR
A[Client] --> B[API Layer]
B --> C[Service Layer]
C --> D[Repository Layer]
D --> E[(Database)]
subgraph "API Layer"
F[IAPIHandler] --> G[Adapters: NestJS, Express]
end
subgraph "Service Layer"
H[IService<T>] --> I[Result<T, E>]
J[BaseService] --> H
K[LegacyService] --> H
end
subgraph "Repository Layer"
L[IRepository<T>] --> M[BaseRepository]
end- Service Layer: Core business logic with Result pattern for error handling.
BaseServiceprovides a ready-to-use implementation. - Repository Layer: Abstract data access, with
BaseRepositoryas extensible base class. - API Layer: Handlers that map HTTP requests to services, with adapters for different frameworks.
- Key Decisions: Generics for type safety, discriminated unions for errors, and interfaces for extensibility.
Installation
npm install @ignix/coreOr with yarn:
yarn add @ignix/coreUsage
Quick Start with BaseService
import { BaseService, IRepository, BaseRepository } from '@ignix/core';
// Define your entity
interface User {
id: number;
name: string;
email: string;
}
// Implement repository (extend BaseRepository for your ORM)
class UserRepository extends BaseRepository<User> {
constructor(ormClient: any) {
super(ormClient);
}
// Implement abstract methods for your ORM
}
// Create service
const repo = new UserRepository(ormClient);
const service = new BaseService<User>(repo);
// Use service
const result = await service.findAll();
if (result.type === 'success') {
console.log(result.data);
} else {
console.error(result.error.message);
}Custom Service with DTOs
import { IService, Result, BaseService } from '@ignix/core';
type CreateUserDto = Omit<User, 'id'>;
type UpdateUserDto = Partial<User>;
type UserResponseDto = Pick<User, 'id' | 'name'>;
class UserService extends BaseService<User, CreateUserDto, UpdateUserDto, UserResponseDto> {
// Override methods if needed
async mapToResponse(entity: User): Promise<UserResponseDto> {
return { id: entity.id, name: entity.name };
}
}Legacy Service for Promise-Based Code
import { LegacyService } from '@ignix/core';
const legacyService = new LegacyService<User, CreateUserDto, UpdateUserDto, UserResponseDto>(service);
try {
const users = await legacyService.findAll();
console.log(users);
} catch (error) {
console.error(error.message);
}API Handler for Express
import { IAPIHandler, BaseAPIHandler } from '@ignix/core';
class UserAPIHandler extends BaseAPIHandler<User, CreateUserDto, UpdateUserDto, UserResponseDto> {}
const handler = new UserAPIHandler(service);
// Use with Express adapter (when implemented)See the /examples folder for full implementations.
Roadmap
We have exciting plans for future versions to enhance DX and functionality:
- Validation Helpers: Integrate schema validation (e.g., with Zod) for DTOs, returning Result-based errors.
- Pagination & Filtering: Add utilities for paginated queries and advanced filtering options.
- Caching Layer: Implement a caching interface with adapters (Redis, In-Memory) and decorators.
- Event System: Introduce an event bus for decoupling and event-driven architectures (towards CQRS).
- Auth Helpers: Provide lightweight helpers for JWT and role-based access.
- CLI Tool: Create a CLI for code generation (services, repositories).
- More Adapters: Expand ORM and framework support (Sequelize, Koa, etc.).
- CQRS Support: Full CQRS implementation in v2 with commands and queries.
Stay tuned! Contributions welcome for these features.
Contributing
We welcome contributions! To get started:
- Fork the repo and clone it.
- Install dependencies:
npm install. - Run tests:
npm test. - Create a feature branch:
git checkout -b feature/your-amazing-your-feature. - Follow our coding standards: Use TypeScript strict mode, add tests for new features, and ensure Result pattern for error handling.
- Submit a PR with a clear description.
- Bug Fixes: Open an issue first.
- Features: Discuss in issues before implementing (e.g., new ORM adapters).
- Style: Follow ESLint config; prefer functional patterns over classes where possible.
- Publishing: The package is scoped as
@ignix/core; ensure compatibility when adding features.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contact
- Maintainer: Johny (Senior Architect, GDE, MVP)
- Email: [email protected] (placeholder)
- GitHub Issues: For bugs or features
- Discord: Join our community at discord.gg/ignix (placeholder)
Made with ❤️ for passionate developers who hate mediocrity.
