@colocho87/logs
v1.4.0
Published
Puntored library for NestJS microservices
Readme
🏛️ Themis
Themis is a modular library built with NestJS and designed to centralize common functionalities across microservices, providing consistent tools for messaging, tracing, logging, security and standardized responses. It simplifies cross-service communication while enforcing uniformity and scalability in distributed systems.
- Contracts Module: Centralized communication contracts, application error codes, response builder, and exception filters for HTTP/gRPC.
- Kafka Module: Strongly-typed event builder, producer/consumer services, multi-consumer group support, async registration, and integrated logging/tracing.
- Tracing Module: Automatic propagation of
event-id,causation-id, andcorrelation-idacross HTTP, gRPC, and Kafka events consuming and producing. - Logging System: Custom logger enriched with tracing IDs, multiple log levels, and flexible outputs (console, file, external service).
- Error Handling: Unified exceptions and filters for HTTP/gRPC, plus standardized responses for consistent client communication.
- Security Module: Tools for data encryption, decryption, and hashing to enhance application security.
- Changelog
- Project Structure
- Dependencies
- Quick Start
- Development Guide
- Development
- Testing
- Resource Export
- Building
- Distribution
- Linking
📜 Changelog
Check here for detailed changelog.
Last version: v1.4.0
This release introduces the Retry Topics pattern for Kafka consumers, enabling automated retry flows with delayed topics and robust DLQ handling via a dispatcher and a retry consumer manager.
🏗️ Project Structure
This project follows a modular architecture inspired by Domain-Driven Design (DDD) principles. The main folders are organized as follows:
📁 src/
├── 📁 modules/ # Application modules
│ ├── 📁 contracts/
│ │ ├── 📁 application/
│ │ │ ├── 📁 builders/ # Builders for standardized responses
│ │ │ └── 📁 mappers/ # Mappers for HTTP and gRPC
│ │ ├── 📁 domain/
│ │ └── 📁 infrastructure/
│ │ ├── 📁 filters/ # Exception filters for HTTP and gRPC
│ │ ├── 📁 interceptors/ # Interceptors for standardized responses
│ │ └── 📁 utils/ # Utility functions
│ ├── 📁 kafka/
│ │ ├── 📁 application/
│ │ │ ├── 📁 dto/ # Data Transfer Objects
│ │ ├── 📁 domain/
│ │ └── 📁 infrastructure/
│ │ ├── 📁 builders/ # Builders for Kafka events
│ │ ├── 📁 services/ # Kafka producer and consumer services
│ │ └── 📁 utils/ # Utility functions
│ ├── 📁 tracing/
│ │ ├── 📁 domain/
│ │ └── 📁 infrastructure/
│ │ ├── 📁 interceptors/ # Interceptors for tracing propagation
│ │ ├── 📁 outputs/ # Tracing outputs
│ │ ├── 📁 services/ # Tracing services
│ │ ├── 📁 utils/ # Utility functions
│ │ └── 📁 wrappers/ # Wrappers for tracing
├── 📁 shared/ # Shared resources across modules
│ ├── 📁 infrastructure/
│ │ └── 📁 exceptions/ # Custom exceptions
│ ├── 📁 utils/ # Shared utility functions
📁 tests/ # Application tests
├── 📁 mocks/ # shared mocks for tests
├── 📁 modules/ # tests for each module
└── 📁 shared/ # tests for shared resources📦 Dependencies
Node.js framework for building efficient, scalable server-side applications.
Strongly typed programming language that builds on JavaScript for safer and more maintainable code.
Fast, disk space–efficient package manager for JavaScript and TypeScript projects.
Reactive programming library for composing asynchronous and event-based programs using observables.
High-performance, open-source universal RPC framework for microservices communication.
Native Apache Kafka client for Node.js for distributed event streaming platform integration.
Decorator-based validation library for TypeScript classes and objects.
Library for transforming plain objects to class instances and vice versa.
RFC4122 compliant UUID generator for creating unique identifiers.
Continuation-local storage implementation for maintaining context across asynchronous calls.
JavaScript testing framework with built-in support for unit and integration tests.
Linting utility for identifying and fixing code quality issues.
Code formatter that enforces a consistent style across the codebase.
⚡ Quick Start
If you are a developer looking to contribute to the library, follow these steps to set up your development environment:
# 1. Clone the repository
git clone [email protected]:brainwinner/themis.git
cd themis
# 2. Install dependencies
pnpm install📘 Development Guide
For more detailed information on how to use the library, refer to the dedicated Development Guide
This guide contains:
It serves as the main entry point for developers working with the library.
🔧 Development
This project uses Prettier for code formatting and ESLint for code quality checks. It is necessary to run these tools before committing any code to ensure consistency and maintainability.
Prettier
To check the format of all project files, you can use:
pnpm format:checkTo automatically apply formatting to all files, run:
pnpm formatESLint
To check code quality with ESLint, run:
pnpm lintTo automatically apply ESLint fixes, use:
pnpm lint:fix⚠️ Note: ESLint only fixes errors it can resolve automatically, so you should review the execution result to ensure there are no remaining errors.
🧪 Testing
To run all tests, execute:
pnpm testTo run tests with code coverage, use:
pnpm test:covYou can view the coverage report openning the following file in your browser: coverage/index.html
Coverage Thresholds
- Statements: ≥ 60%
- Branches: ≥ 60%
- Functions: ≥ 60%
- Lines: ≥ 60%
📤 Resource Export
Library resources are exported from the main index.ts file located in the src folder, which groups the exports
exposed by each submodule (for example: kafka, shared, etc.).
// src/index.ts
export * from './modules/kafka';
export * from './shared';Example of how they are grouped internally:
// src/kafka/index.ts
export {ThKafkaModule} from '@kafka/infrastructure/th-kafka.module';
export {ThKafkaProducerService} from '@kafka/infrastructure/services/th-kafka-producer.service';
// ...other kafka exports
// src/shared/index.ts
export {ThParserUtils} from '@shared/utils/th-parser.utils';⚠️ Recommendation: The use of
export *within submodules should be avoided to maintain greater control over what is exposed and prevent accidental leaks of code not intended to be public. Instead, use explicit exports.
Naming Conventions
All resources that are intended to be exported from the library (services, decorators, utilities, modules, classes,
etc.) must have the Th prefix in their name.
This prefix functions as a unique identifier to facilitate traceability and clearly distinguish which components come
from this library.
🔨 Building
To build the library, run the following command:
pnpm buildThis will generate the output files in the dist folder.
🔗 Linking
Option 1: Global linking (auto-reflects changes)
After building the library, run this command in the project root of the library to create a global symbolic link:
pnpm link --globalTo link the library in your project, navigate to its root folder and run:
pnpm link themisThis command adds the library as a dependency in your project's package.json, using link: protocol.
With this method, changes made in the library are automatically reflected in your project after rebuilding.
Option 2: Using a tarball (no global link)
Alternatively, you can generate a .tgz package without using global linking:
pnpm packThis command creates a tarball (e.g., themis-1.0.0.tgz) in the library root.
You can install it in your project running the following command in the project root:
pnpm add /path/to/themis-1.0.0.tgzThis command adds the library as a dependency in your project's package.json, using file: protocol.
When using this approach, changes in the library will not be reflected automatically in your project. You’ll need to regenerate the tarball (pnpm pack) and reinstall it each time you update the library.
📦 Distribution
Themis is not published on the public npm registry. Instead, it is distributed as a .tgz package stored in a private
artifact registry.
Publishing
The library is packed into a tarball using:
pnpm packThis generates a file such as themis-1.2.0.tgz that is pushed to a private registry.
The publishing process is automated through CI/CD pipelines to ensure that the latest version is always available in the registry.
Pulling
To consume the library, you need to download the corresponding .tgz file from the private registry. A shell script is
available to facilitate this process.
sh script.sh <version>Replace <version> with the desired version number (e.g., 1.2.0). The script will download the specified version of
the library
Installing in a project
Once downloaded, install the .tgz package into your project as a local dependency:
pnpm add /path/to/themis-1.2.0.tgz