@sentzunhat/zacatl 0.0.0-alpha.9 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -52
- package/package.json +1 -1
- package/src/utils/base64.ts +0 -10
- package/src/nullable.ts +0 -1
- package/src/stringify.ts +0 -11
- package/src/summarize.ts +0 -23
package/README.md
CHANGED
|
@@ -1,64 +1,67 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Zacatl
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@sentzunhat/zacatl)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
A blazing fast, minimal, and straightforward microservice framework for Node.js, designed for rapid development of high-performance APIs and distributed systems. Zacatl provides a clean, modular architecture with robust typing support, letting you focus on business logic instead of infrastructure concerns.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
## Table of Contents
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
- **Type-safe route and hook handlers**: Strongly-typed REST entry points using Zod and Fastify.
|
|
19
|
-
- **Testing utilities**: Vitest configuration and helpers for fast, isolated unit tests.
|
|
20
|
-
|
|
21
|
-
## Architecture Overview
|
|
11
|
+
- [Features](#features)
|
|
12
|
+
- [Installation](#installation)
|
|
13
|
+
- [Usage](#usage)
|
|
14
|
+
- [Architecture](#architecture)
|
|
15
|
+
- [Configuration](#configuration)
|
|
16
|
+
- [API Reference](#api-reference)
|
|
17
|
+
- [Testing](#testing)
|
|
18
|
+
- [Contributing](#contributing)
|
|
19
|
+
- [License](#license)
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- **Application**: Defines REST entry points (routes and hooks) and configures i18n.
|
|
26
|
-
- **Domain**: Registers business logic providers.
|
|
27
|
-
- **Infrastructure**: Manages repositories and external dependencies.
|
|
28
|
-
- **Platform**: Orchestrates service startup, database connections, and server/gateway configuration.
|
|
21
|
+
## Features
|
|
29
22
|
|
|
30
|
-
|
|
23
|
+
- **Fastify-based HTTP server**: Ultra-fast routing and extensibility
|
|
24
|
+
- **Mongoose integration**: Easy MongoDB data modeling and repository pattern
|
|
25
|
+
- **Modular architecture**: Clean separation of application, domain, infrastructure, and platform layers
|
|
26
|
+
- **Dependency injection**: Powered by `tsyringe` for testability and flexibility
|
|
27
|
+
- **Gateway support**: Proxy requests to upstream services with minimal setup
|
|
28
|
+
- **Internationalization (i18n)**: Built-in support for multiple locales
|
|
29
|
+
- **Comprehensive error handling**: Custom error classes and route error utilities
|
|
30
|
+
- **Type-safe route handlers**: Strongly-typed REST entry points using Zod and Fastify
|
|
31
|
+
- **Testing utilities**: Vitest configuration and helpers for fast, isolated unit tests
|
|
31
32
|
|
|
32
33
|
## Installation
|
|
33
34
|
|
|
34
35
|
```bash
|
|
35
|
-
bun install
|
|
36
|
-
# or
|
|
37
36
|
npm install @sentzunhat/zacatl
|
|
37
|
+
# or
|
|
38
|
+
yarn add @sentzunhat/zacatl
|
|
39
|
+
# or
|
|
40
|
+
bun install @sentzunhat/zacatl
|
|
38
41
|
```
|
|
39
42
|
|
|
40
43
|
## Usage
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
### Basic Setup
|
|
43
46
|
|
|
44
|
-
```
|
|
47
|
+
```typescript
|
|
45
48
|
import Fastify from "fastify";
|
|
46
49
|
import { MicroService } from "@sentzunhat/zacatl";
|
|
47
50
|
|
|
48
51
|
const fastifyApp = Fastify();
|
|
49
52
|
|
|
50
|
-
const
|
|
53
|
+
const microservice = new MicroService({
|
|
51
54
|
architecture: {
|
|
52
55
|
application: {
|
|
53
56
|
entryPoints: {
|
|
54
57
|
rest: {
|
|
55
|
-
hookHandlers: [], // Add
|
|
56
|
-
routeHandlers: [], // Add
|
|
58
|
+
hookHandlers: [], // Add hook handler classes
|
|
59
|
+
routeHandlers: [], // Add route handler classes
|
|
57
60
|
},
|
|
58
61
|
},
|
|
59
62
|
},
|
|
60
|
-
domain: { providers: [] }, // Add
|
|
61
|
-
infrastructure: { repositories: [] }, // Add
|
|
63
|
+
domain: { providers: [] }, // Add domain provider classes
|
|
64
|
+
infrastructure: { repositories: [] }, // Add repository classes
|
|
62
65
|
service: {
|
|
63
66
|
name: "my-service",
|
|
64
67
|
server: {
|
|
@@ -78,43 +81,134 @@ const microServer = new MicroService({
|
|
|
78
81
|
},
|
|
79
82
|
});
|
|
80
83
|
|
|
81
|
-
|
|
84
|
+
await microservice.start({ port: 9000 });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Creating Route Handlers
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { z } from "zod";
|
|
91
|
+
import { GetRouteHandler } from "@sentzunhat/zacatl";
|
|
92
|
+
|
|
93
|
+
const UserSchema = z.object({
|
|
94
|
+
id: z.string(),
|
|
95
|
+
name: z.string(),
|
|
96
|
+
email: z.string().email(),
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
type User = z.infer<typeof UserSchema>;
|
|
100
|
+
|
|
101
|
+
class GetUserHandler extends GetRouteHandler<unknown, User, unknown> {
|
|
102
|
+
constructor() {
|
|
103
|
+
super({
|
|
104
|
+
url: "/users/:id",
|
|
105
|
+
schema: {
|
|
106
|
+
response: {
|
|
107
|
+
200: UserSchema,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async handler(request, reply): Promise<User> {
|
|
114
|
+
const userId = request.params.id;
|
|
115
|
+
// Fetch user from database, etc.
|
|
116
|
+
return {
|
|
117
|
+
id: userId,
|
|
118
|
+
name: "John Doe",
|
|
119
|
+
email: "john@example.com",
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Database Integration
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { Schema } from "mongoose";
|
|
129
|
+
import { singleton } from "tsyringe";
|
|
130
|
+
import { BaseRepository } from "@sentzunhat/zacatl";
|
|
131
|
+
|
|
132
|
+
interface Product {
|
|
133
|
+
name: string;
|
|
134
|
+
price: number;
|
|
135
|
+
description: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const productSchema = new Schema<Product>({
|
|
139
|
+
name: { type: String, required: true },
|
|
140
|
+
price: { type: Number, required: true },
|
|
141
|
+
description: { type: String, required: true },
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
@singleton()
|
|
145
|
+
export class ProductRepository extends BaseRepository<Product> {
|
|
146
|
+
constructor() {
|
|
147
|
+
super({ name: "Product", schema: productSchema });
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async findByName(name: string) {
|
|
151
|
+
return this.model.findOne({ name }).exec();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
82
154
|
```
|
|
83
155
|
|
|
156
|
+
## Architecture
|
|
157
|
+
|
|
158
|
+
The framework is organized into four main layers:
|
|
159
|
+
|
|
160
|
+
- **Application**: REST entry points (routes and hooks) and i18n configuration
|
|
161
|
+
- **Domain**: Business logic providers and services
|
|
162
|
+
- **Infrastructure**: Repositories and external dependencies
|
|
163
|
+
- **Platform**: Service startup, database connections, and server configuration
|
|
164
|
+
|
|
165
|
+
Each layer is designed to be extensible and testable, supporting clean code principles.
|
|
166
|
+
|
|
84
167
|
## Configuration
|
|
85
168
|
|
|
86
|
-
- **Localization**: Place
|
|
87
|
-
- **Environment Variables**:
|
|
88
|
-
-
|
|
169
|
+
- **Localization**: Place locale JSON files in `src/locales/` (e.g., `en.json`)
|
|
170
|
+
- **Environment Variables**:
|
|
171
|
+
- `SERVICE_NAME` - Service name
|
|
172
|
+
- `NODE_ENV` - Environment (development, production, test)
|
|
173
|
+
- `CONNECTION_STRING` - Database connection string
|
|
174
|
+
|
|
175
|
+
## API Reference
|
|
176
|
+
|
|
177
|
+
### Core Components
|
|
178
|
+
|
|
179
|
+
- `MicroService`: Central orchestrator for all architecture layers
|
|
180
|
+
- `AbstractRouteHandler`: Base class for all route handlers
|
|
181
|
+
- `BaseRepository`: Base class for MongoDB repositories
|
|
182
|
+
- `CustomError`: Base class for typed error handling
|
|
89
183
|
|
|
90
184
|
## Testing
|
|
91
185
|
|
|
92
|
-
Run
|
|
186
|
+
Run tests with:
|
|
93
187
|
|
|
94
188
|
```bash
|
|
95
|
-
bun run test
|
|
96
|
-
# or
|
|
97
189
|
npm run test
|
|
190
|
+
# or
|
|
191
|
+
npm run test:coverage
|
|
98
192
|
```
|
|
99
193
|
|
|
100
|
-
Test configuration uses Vitest with in-memory MongoDB for
|
|
101
|
-
|
|
102
|
-
## API Reference
|
|
103
|
-
|
|
104
|
-
- **Application Layer**: See `src/micro-service/architecture/application/`
|
|
105
|
-
- **Domain Layer**: See `src/micro-service/architecture/domain/`
|
|
106
|
-
- **Infrastructure Layer**: See `src/micro-service/architecture/infrastructure/`
|
|
107
|
-
- **Platform Layer**: See `src/micro-service/architecture/platform/`
|
|
108
|
-
- **Error Handling**: See `src/error/` for custom error classes and utilities.
|
|
194
|
+
Test configuration uses Vitest with in-memory MongoDB for isolated tests.
|
|
109
195
|
|
|
110
196
|
## Contributing
|
|
111
197
|
|
|
112
|
-
Contributions are welcome!
|
|
198
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
199
|
+
|
|
200
|
+
1. Fork the repository
|
|
201
|
+
2. Create your feature branch: `git checkout -b feature/amazing-feature`
|
|
202
|
+
3. Commit your changes: `git commit -m 'Add some amazing feature'`
|
|
203
|
+
4. Push to the branch: `git push origin feature/amazing-feature`
|
|
204
|
+
5. Open a Pull Request
|
|
113
205
|
|
|
114
206
|
## License
|
|
115
207
|
|
|
116
|
-
MIT License © 2025
|
|
208
|
+
MIT License © 2025 Sentzunhat - See the [LICENSE](./LICENSE) file for details.
|
|
117
209
|
|
|
118
210
|
---
|
|
119
211
|
|
|
120
|
-
|
|
212
|
+
Built by [Diego Beltran](https://sentzunhat.com) with [Fastify](https://fastify.io/), [Mongoose](https://mongoosejs.com/), and [tsyringe](https://github.com/microsoft/tsyringe).
|
|
213
|
+
|
|
214
|
+
For questions or issues, please visit [GitHub](https://github.com/sentzunhat/zacatl/issues).
|
package/package.json
CHANGED
package/src/utils/base64.ts
CHANGED
|
@@ -15,13 +15,3 @@ export const encodeBase64 = (input: string): string => {
|
|
|
15
15
|
export const decodeBase64 = (input: string): string => {
|
|
16
16
|
return Buffer.from(input, "base64").toString("utf-8");
|
|
17
17
|
};
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Encodes a token by prefixing it with "Bearer " and converting it to Base64 format.
|
|
21
|
-
*
|
|
22
|
-
* @param token - The raw token string to encode.
|
|
23
|
-
* @returns The Base64-encoded token string with the "Bearer " prefix.
|
|
24
|
-
*/
|
|
25
|
-
export const encodeToken = (token: string): string => {
|
|
26
|
-
return encodeBase64(`Bearer ${token}`);
|
|
27
|
-
};
|
package/src/nullable.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type Nullable<T> = T | undefined;
|
package/src/stringify.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const stringify = (input: any): string => {
|
|
2
|
-
if (Array.isArray(input)) {
|
|
3
|
-
return input.map(stringify).join("");
|
|
4
|
-
} else if (typeof input === "object" && input !== null) {
|
|
5
|
-
return Object.values(input).map(stringify).join("");
|
|
6
|
-
} else {
|
|
7
|
-
return input;
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export { stringify };
|
package/src/summarize.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// const summarize = async ({ context }: { context: string }): Promise<string> => {
|
|
2
|
-
// const { env, pipeline } = await import("@xenova/transformers");
|
|
3
|
-
|
|
4
|
-
// // cacheDir
|
|
5
|
-
// env.cacheDir = "./.cache";
|
|
6
|
-
|
|
7
|
-
// // Specify a custom location for models (defaults to '/models/').
|
|
8
|
-
// env.localModelPath = "./.models/";
|
|
9
|
-
|
|
10
|
-
// // Create a text-generation pipeline
|
|
11
|
-
// const generator = await pipeline(
|
|
12
|
-
// "text2text-generation",
|
|
13
|
-
// "Xenova/LaMini-Flan-T5-783M"
|
|
14
|
-
// );
|
|
15
|
-
|
|
16
|
-
// const result = (await generator(`Summarize the following text: ${context}.`, {
|
|
17
|
-
// max_new_tokens: 250,
|
|
18
|
-
// })) as { generated_text: string }[];
|
|
19
|
-
|
|
20
|
-
// return result[0]?.generated_text ?? "";
|
|
21
|
-
// };
|
|
22
|
-
|
|
23
|
-
// export { summarize };
|