@venizia/ignis-docs 0.0.1-1
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/mcp-server/dist/common/config.d.ts +27 -0
- package/mcp-server/dist/common/config.d.ts.map +1 -0
- package/mcp-server/dist/common/config.js +27 -0
- package/mcp-server/dist/common/config.js.map +1 -0
- package/mcp-server/dist/common/index.d.ts +3 -0
- package/mcp-server/dist/common/index.d.ts.map +1 -0
- package/mcp-server/dist/common/index.js +19 -0
- package/mcp-server/dist/common/index.js.map +1 -0
- package/mcp-server/dist/common/paths.d.ts +13 -0
- package/mcp-server/dist/common/paths.d.ts.map +1 -0
- package/mcp-server/dist/common/paths.js +23 -0
- package/mcp-server/dist/common/paths.js.map +1 -0
- package/mcp-server/dist/helpers/docs.helper.d.ts +81 -0
- package/mcp-server/dist/helpers/docs.helper.d.ts.map +1 -0
- package/mcp-server/dist/helpers/docs.helper.js +171 -0
- package/mcp-server/dist/helpers/docs.helper.js.map +1 -0
- package/mcp-server/dist/helpers/index.d.ts +3 -0
- package/mcp-server/dist/helpers/index.d.ts.map +1 -0
- package/mcp-server/dist/helpers/index.js +19 -0
- package/mcp-server/dist/helpers/index.js.map +1 -0
- package/mcp-server/dist/helpers/logger.helper.d.ts +7 -0
- package/mcp-server/dist/helpers/logger.helper.d.ts.map +1 -0
- package/mcp-server/dist/helpers/logger.helper.js +22 -0
- package/mcp-server/dist/helpers/logger.helper.js.map +1 -0
- package/mcp-server/dist/index.d.ts +3 -0
- package/mcp-server/dist/index.d.ts.map +1 -0
- package/mcp-server/dist/index.js +62 -0
- package/mcp-server/dist/index.js.map +1 -0
- package/mcp-server/dist/tools/base.tool.d.ts +98 -0
- package/mcp-server/dist/tools/base.tool.d.ts.map +1 -0
- package/mcp-server/dist/tools/base.tool.js +47 -0
- package/mcp-server/dist/tools/base.tool.js.map +1 -0
- package/mcp-server/dist/tools/get-doc-content.tool.d.ts +30 -0
- package/mcp-server/dist/tools/get-doc-content.tool.d.ts.map +1 -0
- package/mcp-server/dist/tools/get-doc-content.tool.js +127 -0
- package/mcp-server/dist/tools/get-doc-content.tool.js.map +1 -0
- package/mcp-server/dist/tools/get-doc-metadata.tool.d.ts +40 -0
- package/mcp-server/dist/tools/get-doc-metadata.tool.d.ts.map +1 -0
- package/mcp-server/dist/tools/get-doc-metadata.tool.js +121 -0
- package/mcp-server/dist/tools/get-doc-metadata.tool.js.map +1 -0
- package/mcp-server/dist/tools/index.d.ts +8 -0
- package/mcp-server/dist/tools/index.d.ts.map +1 -0
- package/mcp-server/dist/tools/index.js +18 -0
- package/mcp-server/dist/tools/index.js.map +1 -0
- package/mcp-server/dist/tools/list-categories.tool.d.ts +20 -0
- package/mcp-server/dist/tools/list-categories.tool.d.ts.map +1 -0
- package/mcp-server/dist/tools/list-categories.tool.js +105 -0
- package/mcp-server/dist/tools/list-categories.tool.js.map +1 -0
- package/mcp-server/dist/tools/list-docs.tool.d.ts +32 -0
- package/mcp-server/dist/tools/list-docs.tool.d.ts.map +1 -0
- package/mcp-server/dist/tools/list-docs.tool.js +121 -0
- package/mcp-server/dist/tools/list-docs.tool.js.map +1 -0
- package/mcp-server/dist/tools/search-docs.tool.d.ts +32 -0
- package/mcp-server/dist/tools/search-docs.tool.d.ts.map +1 -0
- package/mcp-server/dist/tools/search-docs.tool.js +120 -0
- package/mcp-server/dist/tools/search-docs.tool.js.map +1 -0
- package/package.json +102 -0
- package/wiki/get-started/5-minute-quickstart.md +266 -0
- package/wiki/get-started/best-practices/api-usage-examples.md +222 -0
- package/wiki/get-started/best-practices/architectural-patterns.md +129 -0
- package/wiki/get-started/best-practices/code-style-standards.md +122 -0
- package/wiki/get-started/best-practices/common-pitfalls.md +136 -0
- package/wiki/get-started/best-practices/contribution-workflow.md +145 -0
- package/wiki/get-started/best-practices/deployment-strategies.md +121 -0
- package/wiki/get-started/best-practices/performance-optimization.md +88 -0
- package/wiki/get-started/best-practices/security-guidelines.md +97 -0
- package/wiki/get-started/best-practices/troubleshooting-tips.md +100 -0
- package/wiki/get-started/building-a-crud-api.md +717 -0
- package/wiki/get-started/core-concepts/application.md +168 -0
- package/wiki/get-started/core-concepts/components.md +96 -0
- package/wiki/get-started/core-concepts/controllers.md +441 -0
- package/wiki/get-started/core-concepts/dependency-injection.md +160 -0
- package/wiki/get-started/core-concepts/persistent.md +591 -0
- package/wiki/get-started/core-concepts/services.md +88 -0
- package/wiki/get-started/index.md +65 -0
- package/wiki/get-started/mcp-docs-server.md +840 -0
- package/wiki/get-started/philosophy.md +123 -0
- package/wiki/get-started/prerequisites.md +113 -0
- package/wiki/get-started/quickstart.md +382 -0
- package/wiki/index.md +48 -0
- package/wiki/references/base/application.md +67 -0
- package/wiki/references/base/components.md +80 -0
- package/wiki/references/base/controllers.md +361 -0
- package/wiki/references/base/datasources.md +105 -0
- package/wiki/references/base/dependency-injection.md +83 -0
- package/wiki/references/base/models.md +104 -0
- package/wiki/references/base/repositories.md +118 -0
- package/wiki/references/base/services.md +97 -0
- package/wiki/references/components/authentication.md +224 -0
- package/wiki/references/components/health-check.md +190 -0
- package/wiki/references/components/index.md +61 -0
- package/wiki/references/components/request-tracker.md +35 -0
- package/wiki/references/components/socket-io.md +127 -0
- package/wiki/references/components/swagger.md +175 -0
- package/wiki/references/helpers/cron.md +94 -0
- package/wiki/references/helpers/crypto.md +117 -0
- package/wiki/references/helpers/env.md +67 -0
- package/wiki/references/helpers/error.md +80 -0
- package/wiki/references/helpers/index.md +21 -0
- package/wiki/references/helpers/inversion.md +141 -0
- package/wiki/references/helpers/logger.md +98 -0
- package/wiki/references/helpers/network.md +143 -0
- package/wiki/references/helpers/queue.md +131 -0
- package/wiki/references/helpers/redis.md +121 -0
- package/wiki/references/helpers/socket-io.md +103 -0
- package/wiki/references/helpers/storage.md +130 -0
- package/wiki/references/helpers/testing.md +115 -0
- package/wiki/references/helpers/worker-thread.md +162 -0
- package/wiki/references/src-details/core.md +249 -0
- package/wiki/references/src-details/dev-configs.md +302 -0
- package/wiki/references/src-details/docs.md +61 -0
- package/wiki/references/src-details/helpers.md +211 -0
- package/wiki/references/src-details/inversion.md +345 -0
- package/wiki/references/src-details/mcp-server.md +726 -0
- package/wiki/references/utilities/crypto.md +39 -0
- package/wiki/references/utilities/date.md +72 -0
- package/wiki/references/utilities/index.md +12 -0
- package/wiki/references/utilities/module.md +40 -0
- package/wiki/references/utilities/parse.md +68 -0
- package/wiki/references/utilities/performance.md +64 -0
- package/wiki/references/utilities/promise.md +83 -0
- package/wiki/references/utilities/request.md +66 -0
- package/wiki/references/utilities/schema.md +88 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Health Check Component
|
|
2
|
+
|
|
3
|
+
Simple endpoint for monitoring application health - essential for microservices and containerized deployments.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
| Component | Purpose |
|
|
8
|
+
|-----------|---------|
|
|
9
|
+
| **HealthCheckComponent** | Registers health check controller |
|
|
10
|
+
| **HealthCheckController** | Provides health check routes |
|
|
11
|
+
|
|
12
|
+
### Default Endpoints
|
|
13
|
+
|
|
14
|
+
| Method | Path | Purpose | Response |
|
|
15
|
+
|--------|------|---------|----------|
|
|
16
|
+
| `GET` | `/health` | Basic health check | `{ "status": "ok" }` |
|
|
17
|
+
| `POST` | `/health/ping` | Echo test | `{ "type": "PONG", "date": "...", "message": "..." }` |
|
|
18
|
+
|
|
19
|
+
### Configuration
|
|
20
|
+
|
|
21
|
+
| Option | Default | Description |
|
|
22
|
+
|--------|---------|-------------|
|
|
23
|
+
| `restOptions.path` | `/health` | Base path for health endpoints |
|
|
24
|
+
|
|
25
|
+
## Architecture Components
|
|
26
|
+
|
|
27
|
+
- **`HealthCheckComponent`**: Registers `HealthCheckController`
|
|
28
|
+
- **`HealthCheckController`**: Uses decorators (`@api`) to define routes
|
|
29
|
+
- **Self-contained**: No external dependencies required
|
|
30
|
+
|
|
31
|
+
## Implementation Details
|
|
32
|
+
|
|
33
|
+
### Tech Stack
|
|
34
|
+
|
|
35
|
+
- **Hono**
|
|
36
|
+
- **`@hono/zod-openapi`**
|
|
37
|
+
|
|
38
|
+
### Configuration
|
|
39
|
+
|
|
40
|
+
The health check endpoint path can be configured by binding a custom `IHealthCheckOptions` object to the `HealthCheckBindingKeys.HEALTH_CHECK_OPTIONS` key in the DI container.
|
|
41
|
+
|
|
42
|
+
**Default options:**
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
const DEFAULT_OPTIONS: IHealthCheckOptions = {
|
|
46
|
+
restOptions: { path: '/health' },
|
|
47
|
+
};
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### Customizing the Health Check Path
|
|
51
|
+
|
|
52
|
+
In your `src/application.ts`, you can bind your custom options:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { HealthCheckBindingKeys, IHealthCheckOptions, HealthCheckComponent } from '@venizia/ignis';
|
|
56
|
+
|
|
57
|
+
// ... in your Application class's preConfigure method
|
|
58
|
+
preConfigure(): ValueOrPromise<void> {
|
|
59
|
+
// ...
|
|
60
|
+
this.bind<IHealthCheckOptions>({
|
|
61
|
+
key: HealthCheckBindingKeys.HEALTH_CHECK_OPTIONS,
|
|
62
|
+
}).toValue({
|
|
63
|
+
restOptions: { path: '/health-check' },
|
|
64
|
+
});
|
|
65
|
+
this.component(HealthCheckComponent);
|
|
66
|
+
// ...
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Code Samples
|
|
71
|
+
|
|
72
|
+
#### Controller Implementation
|
|
73
|
+
|
|
74
|
+
The `HealthCheckController` is a simple controller that uses decorators to define its routes. It now includes a `GET /` for a simple status check and a `POST /ping` that echoes a message.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// packages/core/src/components/health-check/controller.ts
|
|
78
|
+
import { BaseController, IControllerOptions, TRouteContext, api, jsonContent, jsonResponse, HTTP, z } from '@venizia/ignis';
|
|
79
|
+
|
|
80
|
+
const ROUTE_CONFIGS = {
|
|
81
|
+
'/': {
|
|
82
|
+
method: HTTP.Methods.GET,
|
|
83
|
+
path: '/',
|
|
84
|
+
responses: jsonResponse({
|
|
85
|
+
schema: z.object({ status: z.string() }).openapi({
|
|
86
|
+
description: 'HealthCheck Schema',
|
|
87
|
+
examples: [{ status: 'ok' }],
|
|
88
|
+
}),
|
|
89
|
+
description: 'Health check status',
|
|
90
|
+
}),
|
|
91
|
+
},
|
|
92
|
+
'/ping': {
|
|
93
|
+
method: HTTP.Methods.POST,
|
|
94
|
+
path: '/ping',
|
|
95
|
+
request: {
|
|
96
|
+
body: jsonContent({
|
|
97
|
+
description: 'PING | Request body',
|
|
98
|
+
schema: z.object({
|
|
99
|
+
type: z.string().optional().default('PING'),
|
|
100
|
+
message: z.string().min(1).max(255),
|
|
101
|
+
}),
|
|
102
|
+
}),
|
|
103
|
+
},
|
|
104
|
+
responses: jsonResponse({
|
|
105
|
+
schema: z
|
|
106
|
+
.object({
|
|
107
|
+
type: z.string().optional().default('PONG'),
|
|
108
|
+
date: z.iso.datetime(),
|
|
109
|
+
message: z.string(),
|
|
110
|
+
})
|
|
111
|
+
.openapi({
|
|
112
|
+
description: 'HealthCheck PingPong Schema',
|
|
113
|
+
examples: [{ date: new Date().toISOString(), message: 'ok' }],
|
|
114
|
+
}),
|
|
115
|
+
description: 'HealthCheck PingPong Message',
|
|
116
|
+
}),
|
|
117
|
+
},
|
|
118
|
+
} as const;
|
|
119
|
+
|
|
120
|
+
@controller({ path: '/health' }) // Base path is configured by options
|
|
121
|
+
export class HealthCheckController extends BaseController {
|
|
122
|
+
constructor(opts: IControllerOptions) {
|
|
123
|
+
super({ ...opts, scope: HealthCheckController.name });
|
|
124
|
+
// Note: This is optional declare internal controller route definitions
|
|
125
|
+
this.definitions = ROUTE_CONFIGS;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@api({ configs: ROUTE_CONFIGS['/'] })
|
|
129
|
+
checkHealth(c: TRouteContext<typeof ROUTE_CONFIGS['/']>) {
|
|
130
|
+
return c.json({ status: 'ok' });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@api({ configs: ROUTE_CONFIGS['/ping'] })
|
|
134
|
+
pingPong(c: TRouteContext<typeof ROUTE_CONFIGS['/ping']>) {
|
|
135
|
+
// context.req.valid('json') is automatically typed as { type?: string, message: string }
|
|
136
|
+
const { message } = c.req.valid('json');
|
|
137
|
+
|
|
138
|
+
// Return type is automatically validated against the response schema
|
|
139
|
+
return c.json(
|
|
140
|
+
{ type: 'PONG', date: new Date().toISOString(), message },
|
|
141
|
+
HTTP.ResultCodes.RS_2.Ok,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### Registering the Health Check Component
|
|
148
|
+
|
|
149
|
+
In your `src/application.ts`, simply register the `HealthCheckComponent`.
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
// src/application.ts
|
|
153
|
+
import { HealthCheckComponent } from '@venizia/ignis';
|
|
154
|
+
|
|
155
|
+
// ... in your Application class's preConfigure method
|
|
156
|
+
preConfigure(): ValueOrPromise<void> {
|
|
157
|
+
// ...
|
|
158
|
+
this.component(HealthCheckComponent);
|
|
159
|
+
// ...
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## API or Interface Specifications
|
|
164
|
+
|
|
165
|
+
- **Endpoint:** `GET /health` (or the custom path you configured)
|
|
166
|
+
- **Method:** `GET`
|
|
167
|
+
- **Success Response (200 OK):**
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"status": "ok"
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
- **Endpoint:** `POST /health/ping`
|
|
174
|
+
- **Method:** `POST`
|
|
175
|
+
- **Request Body:**
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"message": "Any string here"
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
- **Success Response (200 OK):**
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"type": "PONG",
|
|
185
|
+
"date": "YYYY-MM-DDTHH:mm:ss.sssZ",
|
|
186
|
+
"message": "Any string here"
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
This component provides a simple and effective way to monitor the health of your `Ignis` application.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Components
|
|
2
|
+
|
|
3
|
+
Reusable, pluggable modules that encapsulate specific features in Ignis applications.
|
|
4
|
+
|
|
5
|
+
## Built-in Components
|
|
6
|
+
|
|
7
|
+
| Component | Purpose | Key Features |
|
|
8
|
+
|-----------|---------|--------------|
|
|
9
|
+
| [Authentication](./authentication.md) | JWT-based auth | Token generation, protected routes, user payload |
|
|
10
|
+
| [Health Check](./health-check.md) | Monitoring endpoint | `/health` endpoint, ping/pong functionality |
|
|
11
|
+
| [Swagger](./swagger.md) | API documentation | OpenAPI generation, Swagger UI, Scalar UI |
|
|
12
|
+
| [Socket.IO](./socket-io.md) | Real-time communication | WebSocket support, Redis adapter, event-based |
|
|
13
|
+
|
|
14
|
+
## Creating a Component
|
|
15
|
+
|
|
16
|
+
To create a new component, you need to create a class that extends `BaseComponent`.
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { BaseApplication, BaseComponent, inject, CoreBindings, ValueOrPromise } from '@venizia/ignis';
|
|
20
|
+
|
|
21
|
+
export class MyCustomComponent extends BaseComponent {
|
|
22
|
+
constructor(
|
|
23
|
+
@inject({ key: CoreBindings.APPLICATION_INSTANCE }) private application: BaseApplication,
|
|
24
|
+
) {
|
|
25
|
+
super({ scope: MyCustomComponent.name });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override binding(): ValueOrPromise<void> {
|
|
29
|
+
// This is where you bind your component's resources.
|
|
30
|
+
this.application.service(MyCustomService);
|
|
31
|
+
this.application.controller(MyCustomController);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Component Lifecycle
|
|
37
|
+
|
|
38
|
+
| Phase | When | Purpose |
|
|
39
|
+
|-------|------|---------|
|
|
40
|
+
| **`constructor()`** | Component instantiation | Receive dependencies, define default bindings |
|
|
41
|
+
| **`binding()`** | Application startup | Register controllers, services, repositories with DI container |
|
|
42
|
+
|
|
43
|
+
## Registering a Component
|
|
44
|
+
|
|
45
|
+
To use a component, you need to register it with the application instance, usually in the `preConfigure` method of your `Application` class.
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// in src/application.ts
|
|
49
|
+
import { MyCustomComponent } from './components/my-custom.component';
|
|
50
|
+
|
|
51
|
+
// ... inside your Application class
|
|
52
|
+
|
|
53
|
+
preConfigure(): ValueOrPromise<void> {
|
|
54
|
+
// ...
|
|
55
|
+
this.component(MyCustomComponent);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When the application starts, it will automatically call the `binding()` method of the registered component, setting up all the resources it provides.
|
|
60
|
+
|
|
61
|
+
Using components is a great way to organize your application's features into modular, reusable pieces of code, keeping your main application class clean and focused on high-level configuration.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Request Tracker Component
|
|
2
|
+
|
|
3
|
+
The Request Tracker component logs incoming requests and adds a unique request ID for tracing purposes.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
- **Feature Name:** Request Tracker
|
|
8
|
+
- **Purpose:** To log incoming requests and add a unique request ID for tracing purposes.
|
|
9
|
+
- **Background:** In a production environment, it is crucial to have detailed logs for debugging and monitoring. The Request Tracker component provides a way to automatically log every incoming request with a unique ID, making it easier to trace the entire lifecycle of a request.
|
|
10
|
+
- **Related Features/Modules:** This component is a default middleware that is registered at the application level and integrates with the core logging feature.
|
|
11
|
+
|
|
12
|
+
## Design and Architecture
|
|
13
|
+
|
|
14
|
+
- **`RequestTrackerComponent`:** This component registers the `RequestSpyMiddleware`.
|
|
15
|
+
- **`RequestSpyMiddleware`:** A middleware that intercepts incoming requests, logs them, and adds a request ID to the context. It uses the `requestId` middleware from `hono/request-id` to generate the unique ID.
|
|
16
|
+
|
|
17
|
+
## Implementation Details
|
|
18
|
+
|
|
19
|
+
### Tech Stack
|
|
20
|
+
|
|
21
|
+
- **Hono**
|
|
22
|
+
- **`hono/request-id`**
|
|
23
|
+
|
|
24
|
+
### Configuration
|
|
25
|
+
|
|
26
|
+
The `RequestTrackerComponent` is enabled by default in `BaseApplication` and requires no manual registration or configuration. It is automatically registered as part of the application's default middleware stack during the `initialize()` lifecycle step.
|
|
27
|
+
|
|
28
|
+
When the component is active, it adds the `requestId` and `RequestSpyMiddleware` to the Hono application instance. A sample log output for a request would look like this:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
[spy][<request-id>] START | Handling Request | forwardedIp: 127.0.0.1 | path: /hello | method: GET
|
|
32
|
+
[spy][<request-id>] DONE | Handling Request | forwardedIp: 127.0.0.1 | path: /hello | method: GET | Took: 1.234 (ms)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This feature is essential for building production-ready applications with proper logging and traceability.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Socket.IO Component
|
|
2
|
+
|
|
3
|
+
Real-time, bidirectional, event-based communication using Socket.IO.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
| Component | Purpose |
|
|
8
|
+
|-----------|---------|
|
|
9
|
+
| **SocketIOComponent** | Sets up Socket.IO server and bindings |
|
|
10
|
+
| **SocketIOServerHelper** | Encapsulates Socket.IO server instance |
|
|
11
|
+
| **Redis Adapter** | Enables horizontal scaling with Redis |
|
|
12
|
+
| **Redis Emitter** | Emit events from other processes/services |
|
|
13
|
+
|
|
14
|
+
### Required Bindings
|
|
15
|
+
|
|
16
|
+
| Binding Key | Type | Purpose |
|
|
17
|
+
|-------------|------|---------|
|
|
18
|
+
| `SERVER_OPTIONS` | `ISocketIOOptions` | Socket.IO server configuration (optional) |
|
|
19
|
+
| `REDIS_CONNECTION` | `DefaultRedisHelper` | Redis instance for scaling |
|
|
20
|
+
| `AUTHENTICATE_HANDLER` | `Function` | Authenticate socket connections |
|
|
21
|
+
| `CLIENT_CONNECTED_HANDLER` | `Function` | Handle successful connections (optional) |
|
|
22
|
+
|
|
23
|
+
### Use Cases
|
|
24
|
+
|
|
25
|
+
- Live notifications
|
|
26
|
+
- Real-time chat
|
|
27
|
+
- Collaborative editing
|
|
28
|
+
- Live data streams
|
|
29
|
+
|
|
30
|
+
## Architecture Components
|
|
31
|
+
|
|
32
|
+
- **`SocketIOComponent`**: Sets up Socket.IO server, binds `SocketIOServerHelper` to DI
|
|
33
|
+
- **`SocketIOServerHelper`**: Wraps Socket.IO server, provides interaction methods
|
|
34
|
+
- **`@socket.io/redis-adapter`**: Scales Socket.IO with Redis
|
|
35
|
+
- **`@socket.io/redis-emitter`**: Emits events from external processes
|
|
36
|
+
- **Integration**: Works with HTTP server and authentication system
|
|
37
|
+
|
|
38
|
+
## Implementation Details
|
|
39
|
+
|
|
40
|
+
### Tech Stack
|
|
41
|
+
|
|
42
|
+
- **Socket.IO**
|
|
43
|
+
- **`@socket.io/redis-adapter`**
|
|
44
|
+
- **`@socket.io/redis-emitter`**
|
|
45
|
+
- **`ioredis`** (if using Redis)
|
|
46
|
+
|
|
47
|
+
### Configuration
|
|
48
|
+
|
|
49
|
+
To use the Socket.IO component, you need to provide a few things in your application's DI container:
|
|
50
|
+
|
|
51
|
+
- **`SocketIOBindingKeys.SERVER_OPTIONS`**: (Optional) Custom options for the Socket.IO server.
|
|
52
|
+
- **`SocketIOBindingKeys.REDIS_CONNECTION`**: An instance of `DefaultRedisHelper` (or a compatible class) for the Redis adapter.
|
|
53
|
+
- **`SocketIOBindingKeys.AUTHENTICATE_HANDLER`**: A function to handle the authentication of new socket connections.
|
|
54
|
+
- **`SocketIOBindingKeys.CLIENT_CONNECTED_HANDLER`**: (Optional) A function to be called when a client is successfully connected and authenticated.
|
|
55
|
+
|
|
56
|
+
### Code Samples
|
|
57
|
+
|
|
58
|
+
#### 1. Setting up the Socket.IO Component
|
|
59
|
+
|
|
60
|
+
In your `src/application.ts`:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import {
|
|
64
|
+
SocketIOComponent,
|
|
65
|
+
SocketIOBindingKeys,
|
|
66
|
+
RedisHelper, // Your Redis helper
|
|
67
|
+
BaseApplication,
|
|
68
|
+
ValueOrPromise,
|
|
69
|
+
IHandshake,
|
|
70
|
+
} from '@venizia/ignis';
|
|
71
|
+
|
|
72
|
+
// ...
|
|
73
|
+
|
|
74
|
+
export class Application extends BaseApplication {
|
|
75
|
+
// ...
|
|
76
|
+
|
|
77
|
+
preConfigure(): ValueOrPromise<void> {
|
|
78
|
+
// ...
|
|
79
|
+
|
|
80
|
+
// 1. Bind Redis connection
|
|
81
|
+
const redis = new RedisHelper({
|
|
82
|
+
name: 'redis',
|
|
83
|
+
host: 'localhost',
|
|
84
|
+
port: 6379,
|
|
85
|
+
password: 'password',
|
|
86
|
+
});
|
|
87
|
+
this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION }).toValue(redis);
|
|
88
|
+
|
|
89
|
+
// 2. Bind authentication handler
|
|
90
|
+
const authenticateFn = async (handshake: IHandshake) => {
|
|
91
|
+
const { token } = handshake.auth;
|
|
92
|
+
// Your custom authentication logic here
|
|
93
|
+
// e.g., verify a JWT
|
|
94
|
+
return !!token;
|
|
95
|
+
};
|
|
96
|
+
this.bind({ key: SocketIOBindingKeys.AUTHENTICATE_HANDLER }).toValue(authenticateFn);
|
|
97
|
+
|
|
98
|
+
// 3. Register the component
|
|
99
|
+
this.component(SocketIOComponent);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ...
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### 2. Emitting Events
|
|
107
|
+
|
|
108
|
+
You can get the `SocketIOServerHelper` instance from the container and use it to emit events.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { SocketIOServerHelper, SocketIOBindingKeys, inject } from '@venizia/ignis';
|
|
112
|
+
|
|
113
|
+
// ... in a service or controller
|
|
114
|
+
|
|
115
|
+
@inject({ key: SocketIOBindingKeys.SOCKET_IO_INSTANCE })
|
|
116
|
+
private io: SocketIOServerHelper;
|
|
117
|
+
|
|
118
|
+
sendNotification(userId: string, message: string) {
|
|
119
|
+
this.io.send({
|
|
120
|
+
destination: userId, // Room or socket ID
|
|
121
|
+
payload: {
|
|
122
|
+
topic: 'notification',
|
|
123
|
+
data: { message },
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
```
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Swagger/OpenAPI Component
|
|
2
|
+
|
|
3
|
+
Automatic interactive API documentation generation using OpenAPI specifications.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
| Component | Purpose |
|
|
8
|
+
|-----------|---------|
|
|
9
|
+
| **SwaggerComponent** | Configures documentation UI and routes |
|
|
10
|
+
| **UIProviderFactory** | Manages UI providers (Swagger UI, Scalar) |
|
|
11
|
+
| **Default UI** | Scalar (can be changed to Swagger UI) |
|
|
12
|
+
|
|
13
|
+
### Default Endpoints
|
|
14
|
+
|
|
15
|
+
| Path | Description |
|
|
16
|
+
|------|-------------|
|
|
17
|
+
| `/doc/explorer` | Documentation UI (Scalar by default) |
|
|
18
|
+
| `/doc/openapi.json` | Raw OpenAPI specification |
|
|
19
|
+
|
|
20
|
+
### UI Provider Types
|
|
21
|
+
|
|
22
|
+
| Provider | Value | When to Use |
|
|
23
|
+
|----------|-------|-------------|
|
|
24
|
+
| **Scalar** | `'scalar'` | Modern, clean UI (default) |
|
|
25
|
+
| **Swagger UI** | `'swagger'` | Classic Swagger interface |
|
|
26
|
+
|
|
27
|
+
## Architecture Components
|
|
28
|
+
|
|
29
|
+
- **`SwaggerComponent`**: Configures documentation UI and registers routes
|
|
30
|
+
- **`UIProviderFactory`**: Manages different UI providers
|
|
31
|
+
- **`@hono/zod-openapi`**: Powers OpenAPI generation from Zod schemas
|
|
32
|
+
- **Integration**: Works with controller `defineRoute` methods using Zod schemas
|
|
33
|
+
|
|
34
|
+
## Implementation Details
|
|
35
|
+
|
|
36
|
+
### Tech Stack
|
|
37
|
+
|
|
38
|
+
- **Hono**
|
|
39
|
+
- **`@hono/zod-openapi`**
|
|
40
|
+
- **`@hono/swagger-ui`** (for Swagger UI)
|
|
41
|
+
- **`@scalar/hono-api-reference`** (for Scalar UI)
|
|
42
|
+
- **`zod`**
|
|
43
|
+
|
|
44
|
+
### Configuration
|
|
45
|
+
|
|
46
|
+
The Swagger component can be configured via the `ISwaggerOptions` binding. You can customize the documentation path, OpenAPI version, and the UI provider type.
|
|
47
|
+
|
|
48
|
+
**`ISwaggerOptions` Interface:**
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
export interface ISwaggerOptions {
|
|
52
|
+
restOptions: {
|
|
53
|
+
base: { path: string }; // Base path for all documentation routes
|
|
54
|
+
doc: { path: string }; // Path to the raw openapi.json file
|
|
55
|
+
ui: {
|
|
56
|
+
path: string; // Path to the documentation UI
|
|
57
|
+
type: 'swagger' | 'scalar'; // Type of UI to render
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
explorer: {
|
|
61
|
+
openapi: string;
|
|
62
|
+
info?: { /* ... */ };
|
|
63
|
+
servers?: Array<{ url: string; description?: string; }>;
|
|
64
|
+
};
|
|
65
|
+
uiConfig?: Record<string, any>; // Custom config for the UI provider
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Default Options:**
|
|
70
|
+
|
|
71
|
+
The default UI provider is `scalar`.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
const DEFAULT_SWAGGER_OPTIONS: ISwaggerOptions = {
|
|
75
|
+
restOptions: {
|
|
76
|
+
base: { path: '/doc' },
|
|
77
|
+
doc: { path: '/openapi.json' },
|
|
78
|
+
ui: { path: '/explorer', type: 'scalar' },
|
|
79
|
+
},
|
|
80
|
+
// ...
|
|
81
|
+
};
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Code Samples
|
|
85
|
+
|
|
86
|
+
#### 1. Registering the Swagger Component
|
|
87
|
+
|
|
88
|
+
In your `src/application.ts`, register the `SwaggerComponent`.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// src/application.ts
|
|
92
|
+
import { SwaggerComponent, BaseApplication, ValueOrPromise } from '@venizia/ignis';
|
|
93
|
+
|
|
94
|
+
export class Application extends BaseApplication {
|
|
95
|
+
// ...
|
|
96
|
+
preConfigure(): ValueOrPromise<void> {
|
|
97
|
+
// ...
|
|
98
|
+
this.component(SwaggerComponent);
|
|
99
|
+
// ...
|
|
100
|
+
}
|
|
101
|
+
// ...
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### 2. Customizing the UI Provider
|
|
106
|
+
|
|
107
|
+
To change the UI provider to Swagger UI, you can bind custom options in your application's `preConfigure` method.
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { SwaggerComponent, SwaggerBindingKeys, ISwaggerOptions } from '@venizia/ignis';
|
|
111
|
+
|
|
112
|
+
// ... in your Application class's preConfigure method
|
|
113
|
+
preConfigure(): ValueOrPromise<void> {
|
|
114
|
+
// ...
|
|
115
|
+
this.bind<ISwaggerOptions>({
|
|
116
|
+
key: SwaggerBindingKeys.SWAGGER_OPTIONS,
|
|
117
|
+
}).toValue({
|
|
118
|
+
restOptions: {
|
|
119
|
+
base: { path: '/doc' },
|
|
120
|
+
doc: { path: '/openapi.json' },
|
|
121
|
+
ui: { path: '/explorer', type: 'swagger' }, // Use Swagger UI
|
|
122
|
+
},
|
|
123
|
+
explorer: {
|
|
124
|
+
openapi: '3.0.0',
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
this.component(SwaggerComponent);
|
|
129
|
+
// ...
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### 3. Defining Routes with Zod Schemas
|
|
134
|
+
|
|
135
|
+
To get the most out of the documentation, define your routes with `zod` schemas.
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// src/controllers/hello.controller.ts
|
|
139
|
+
import { z } from '@hono/zod-openapi';
|
|
140
|
+
import { BaseController, controller, HTTP, jsonContent, ValueOrPromise } from '@venizia/ignis';
|
|
141
|
+
|
|
142
|
+
@controller({ path: '/hello' })
|
|
143
|
+
export class HelloController extends BaseController {
|
|
144
|
+
constructor() {
|
|
145
|
+
super({ scope: HelloController.name, path: '/hello' });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
override binding(): ValueOrPromise<void> {
|
|
149
|
+
this.defineRoute({
|
|
150
|
+
configs: {
|
|
151
|
+
path: '/',
|
|
152
|
+
method: 'get',
|
|
153
|
+
responses: {
|
|
154
|
+
[HTTP.ResultCodes.RS_2.Ok]: jsonContent({
|
|
155
|
+
description: 'A simple hello message',
|
|
156
|
+
schema: z.object({ message: z.string() }),
|
|
157
|
+
}),
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
handler: (c) => {
|
|
161
|
+
return c.json({ message: 'Hello, `Ignis`!' });
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## API or Interface Specifications
|
|
169
|
+
|
|
170
|
+
By default, the documentation is available at the following endpoints:
|
|
171
|
+
|
|
172
|
+
- **/doc/explorer**: The documentation UI (`scalar` by default).
|
|
173
|
+
- **/doc/openapi.json**: The raw OpenAPI specification.
|
|
174
|
+
|
|
175
|
+
These paths can be configured by providing custom `ISwaggerOptions`. This feature provides a powerful and flexible way to document your APIs, making them easier to consume and understand.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Cron Helper
|
|
2
|
+
|
|
3
|
+
Schedule and manage recurring tasks (cron jobs) using cron patterns.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
| Option | Type | Description |
|
|
8
|
+
|--------|------|-------------|
|
|
9
|
+
| `cronTime` | `string` | Cron pattern (e.g., `'0 */1 * * * *'` = every minute) |
|
|
10
|
+
| `onTick` | `Function` | Callback executed on schedule |
|
|
11
|
+
| `autoStart` | `boolean` | Start automatically (default: `false`) |
|
|
12
|
+
| `tz` | `string` | Timezone (e.g., `'America/New_York'`) |
|
|
13
|
+
| `errorHandler` | `Function` | Handle errors in `onTick` |
|
|
14
|
+
|
|
15
|
+
### Common Cron Patterns
|
|
16
|
+
|
|
17
|
+
| Pattern | Description |
|
|
18
|
+
|---------|-------------|
|
|
19
|
+
| `'0 */1 * * * *'` | Every minute |
|
|
20
|
+
| `'0 */5 * * * *'` | Every 5 minutes |
|
|
21
|
+
| `'0 0 * * * *'` | Every hour |
|
|
22
|
+
| `'0 0 0 * * *'` | Every day at midnight |
|
|
23
|
+
| `'0 0 0 * * 1'` | Every Monday at midnight |
|
|
24
|
+
|
|
25
|
+
### Key Methods
|
|
26
|
+
|
|
27
|
+
| Method | Purpose |
|
|
28
|
+
|--------|---------|
|
|
29
|
+
| `start()` | Start the cron job manually |
|
|
30
|
+
| `modifyCronTime({ cronTime })` | Change schedule dynamically |
|
|
31
|
+
| `duplicate({ cronTime })` | Create new job with same config |
|
|
32
|
+
|
|
33
|
+
## Creating a Cron Job
|
|
34
|
+
|
|
35
|
+
To create a cron job, you instantiate the `CronHelper` with your desired options.
|
|
36
|
+
|
|
37
|
+
### `ICronHelperOptions`
|
|
38
|
+
|
|
39
|
+
- `cronTime` (string): The cron pattern that defines when the job should run (e.g., `'0 */1 * * * *'` for every minute).
|
|
40
|
+
- `onTick` (() => void | Promise<void>): The function to be executed when the cron job triggers.
|
|
41
|
+
- `onCompleted` (CronOnCompleteCommand | null, optional): A function to be executed when the job stops.
|
|
42
|
+
- `autoStart` (boolean, optional): If `true`, the job will start automatically. Defaults to `false`.
|
|
43
|
+
- `tz` (string, optional): The timezone to use for the schedule.
|
|
44
|
+
- `errorHandler` ((error: unknown) => void | null, optional): A function to handle errors that occur during the `onTick` execution.
|
|
45
|
+
|
|
46
|
+
### Example
|
|
47
|
+
|
|
48
|
+
Here's how to create a simple cron job that logs a message every minute:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { CronHelper } from '@venizia/ignis';
|
|
52
|
+
|
|
53
|
+
const myJob = new CronHelper({
|
|
54
|
+
cronTime: '0 */1 * * * *', // Every minute
|
|
55
|
+
onTick: () => {
|
|
56
|
+
console.log('This message will be logged every minute.');
|
|
57
|
+
},
|
|
58
|
+
autoStart: true,
|
|
59
|
+
tz: 'America/New_York',
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Managing Cron Jobs
|
|
64
|
+
|
|
65
|
+
The `CronHelper` instance provides several methods for managing the cron job:
|
|
66
|
+
|
|
67
|
+
### `start()`
|
|
68
|
+
|
|
69
|
+
Manually starts the cron job if `autoStart` was set to `false`.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
myJob.start();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### `modifyCronTime(opts)`
|
|
76
|
+
|
|
77
|
+
Dynamically changes the schedule of an existing cron job.
|
|
78
|
+
|
|
79
|
+
- `cronTime` (string): The new cron pattern.
|
|
80
|
+
- `shouldFireOnTick` (boolean, optional): If `true`, the `onTick` function will be executed immediately after the time is changed.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// Change the job to run every 5 minutes
|
|
84
|
+
myJob.modifyCronTime({ cronTime: '0 */5 * * * *' });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### `duplicate(opts)`
|
|
88
|
+
|
|
89
|
+
Creates a new `CronHelper` instance with the same configuration but a new `cronTime`.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
const anotherJob = myJob.duplicate({ cronTime: '0 0 * * *' }); // Runs once at midnight
|
|
93
|
+
anotherJob.start();
|
|
94
|
+
```
|