@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,131 @@
|
|
|
1
|
+
# Queue Helpers
|
|
2
|
+
|
|
3
|
+
Message queuing and asynchronous task management with BullMQ, MQTT, and in-memory solutions.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
| Helper | Type | Use Case | Backed By |
|
|
8
|
+
|--------|------|----------|-----------|
|
|
9
|
+
| **BullMQHelper** | Redis-backed job queue | Background job processing, task queue | BullMQ + Redis |
|
|
10
|
+
| **MQTTClientHelper** | Message broker | Real-time messaging, IoT | MQTT broker |
|
|
11
|
+
| **QueueHelper** | In-memory queue | Sequential tasks, single process | Memory |
|
|
12
|
+
|
|
13
|
+
### BullMQHelper Roles
|
|
14
|
+
|
|
15
|
+
| Role | Purpose | Key Property |
|
|
16
|
+
|------|---------|--------------|
|
|
17
|
+
| `worker` | Process jobs (consumer) | `onWorkerData`, `onWorkerDataCompleted` |
|
|
18
|
+
| `queue` | Add jobs (producer) | `queue.add(name, data)` |
|
|
19
|
+
|
|
20
|
+
### Common Operations
|
|
21
|
+
|
|
22
|
+
| Helper | Subscribe/Consume | Publish/Produce |
|
|
23
|
+
|--------|-------------------|-----------------|
|
|
24
|
+
| **BullMQ** | Create worker role | `queue.add()` |
|
|
25
|
+
| **MQTT** | `subscribe({ topics })` | `publish({ topic, message })` |
|
|
26
|
+
| **In-Memory** | `new QueueHelper({ onMessage })` | `enqueue(payload)` |
|
|
27
|
+
|
|
28
|
+
## BullMQ Helper
|
|
29
|
+
|
|
30
|
+
The `BullMQHelper` provides a robust, Redis-backed message queuing system using the [BullMQ](https://docs.bullmq.io/) library. It's ideal for background job processing and can be configured to act as a job producer (queue) or a job consumer (worker).
|
|
31
|
+
|
|
32
|
+
### Creating a BullMQ Worker
|
|
33
|
+
|
|
34
|
+
To process jobs, you create a `BullMQHelper` with the `worker` role.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { BullMQHelper, RedisHelper } from '@venizia/ignis';
|
|
38
|
+
|
|
39
|
+
const redisConnection = new RedisHelper({
|
|
40
|
+
name: 'redis-queue',
|
|
41
|
+
host: 'localhost',
|
|
42
|
+
port: 6379,
|
|
43
|
+
password: 'password',
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const myWorker = new BullMQHelper({
|
|
47
|
+
queueName: 'my-email-queue',
|
|
48
|
+
identifier: 'email-worker',
|
|
49
|
+
role: 'worker',
|
|
50
|
+
connection: redisConnection.getClient(),
|
|
51
|
+
onWorkerData: async (job) => {
|
|
52
|
+
console.log(`Sending email to ${job.data.email}`);
|
|
53
|
+
// ... email sending logic
|
|
54
|
+
return { status: 'ok' };
|
|
55
|
+
},
|
|
56
|
+
onWorkerDataCompleted: async (job, result) => {
|
|
57
|
+
console.log(`Job ${job.id} completed with result:`, result);
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Creating a BullMQ Queue (Producer)
|
|
63
|
+
|
|
64
|
+
To add jobs to the queue, you create a `BullMQHelper` with the `queue` role.
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { BullMQHelper, RedisHelper } from '@venizia/ignis';
|
|
68
|
+
|
|
69
|
+
const redisConnection = new RedisHelper({
|
|
70
|
+
name: 'redis-queue',
|
|
71
|
+
host: 'localhost',
|
|
72
|
+
port: 6379,
|
|
73
|
+
password: 'password',
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const myQueue = new BullMQHelper({
|
|
77
|
+
queueName: 'my-email-queue',
|
|
78
|
+
identifier: 'email-queue',
|
|
79
|
+
role: 'queue',
|
|
80
|
+
connection: redisConnection.getClient(),
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Add a job to the queue
|
|
84
|
+
myQueue.queue.add('send-welcome-email', { email: 'test@example.com' });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## MQTT Helper
|
|
88
|
+
|
|
89
|
+
The `MQTTClientHelper` provides an interface for interacting with an MQTT broker, allowing you to publish and subscribe to topics for real-time messaging.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { MQTTClientHelper } from '@venizia/ignis';
|
|
93
|
+
|
|
94
|
+
const mqttClient = new MQTTClientHelper({
|
|
95
|
+
identifier: 'my-mqtt-client',
|
|
96
|
+
url: 'mqtt://localhost:1883',
|
|
97
|
+
options: {
|
|
98
|
+
username: 'user',
|
|
99
|
+
password: 'password',
|
|
100
|
+
},
|
|
101
|
+
onMessage: ({ topic, message }) => {
|
|
102
|
+
console.log(`Received message on topic ${topic}:`, message.toString());
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Subscribe to a topic
|
|
107
|
+
mqttClient.subscribe({ topics: ['my-topic'] });
|
|
108
|
+
|
|
109
|
+
// Publish a message
|
|
110
|
+
mqttClient.publish({ topic: 'my-topic', message: 'Hello, MQTT!' });
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## In-Memory Queue Helper
|
|
114
|
+
|
|
115
|
+
The `QueueHelper` provides a simple, in-memory queue for managing sequential tasks within a single application instance. It's useful when you don't need the overhead of an external message broker.
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { QueueHelper } from '@venizia/ignis';
|
|
119
|
+
|
|
120
|
+
const myQueue = new QueueHelper<string>({
|
|
121
|
+
identifier: 'my-in-memory-queue',
|
|
122
|
+
onMessage: async ({ queueElement }) => {
|
|
123
|
+
console.log('Processing message:', queueElement.payload);
|
|
124
|
+
// Simulate some work
|
|
125
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
myQueue.enqueue('message 1');
|
|
130
|
+
myQueue.enqueue('message 2');
|
|
131
|
+
```
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Redis Helper
|
|
2
|
+
|
|
3
|
+
Powerful Redis abstraction supporting single instances and clusters via `ioredis`.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
| Helper Class | Use Case |
|
|
8
|
+
|--------------|----------|
|
|
9
|
+
| **RedisHelper** | Single Redis instance |
|
|
10
|
+
| **RedisClusterHelper** | Redis cluster |
|
|
11
|
+
| **DefaultRedisHelper** | Base class with unified API |
|
|
12
|
+
|
|
13
|
+
### Supported Operations
|
|
14
|
+
|
|
15
|
+
| Operation | Methods |
|
|
16
|
+
|-----------|---------|
|
|
17
|
+
| **Key-Value** | `set()`, `get()`, `getObject()`, `del()` |
|
|
18
|
+
| **Hashes** | `hset()`, `hget()`, `hgetall()` |
|
|
19
|
+
| **JSON** (RedisJSON) | `jSet()`, `jGet()` (requires RedisJSON module) |
|
|
20
|
+
| **Pub/Sub** | `subscribe()`, `publish()`, `unsubscribe()` |
|
|
21
|
+
| **TTL** | Set expiration on keys |
|
|
22
|
+
|
|
23
|
+
## Creating a Redis Client
|
|
24
|
+
|
|
25
|
+
### Single Instance
|
|
26
|
+
|
|
27
|
+
Use the `RedisHelper` for connecting to a single Redis instance.
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { RedisHelper } from '@venizia/ignis';
|
|
31
|
+
|
|
32
|
+
const redisClient = new RedisHelper({
|
|
33
|
+
name: 'my-redis-client',
|
|
34
|
+
host: 'localhost',
|
|
35
|
+
port: 6379,
|
|
36
|
+
password: 'password',
|
|
37
|
+
autoConnect: true,
|
|
38
|
+
maxRetry: 5,
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Redis Cluster
|
|
43
|
+
|
|
44
|
+
Use the `RedisClusterHelper` for connecting to a Redis cluster.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { RedisClusterHelper } from '@venizia/ignis';
|
|
48
|
+
|
|
49
|
+
const redisClusterClient = new RedisClusterHelper({
|
|
50
|
+
name: 'my-redis-cluster',
|
|
51
|
+
nodes: [
|
|
52
|
+
{ host: 'localhost', port: 7000 },
|
|
53
|
+
{ host: 'localhost', port: 7001 },
|
|
54
|
+
// ... other nodes
|
|
55
|
+
],
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Basic Operations
|
|
60
|
+
|
|
61
|
+
The helper provides methods for common Redis commands.
|
|
62
|
+
|
|
63
|
+
### Key-Value
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
// Set a value
|
|
67
|
+
await redisClient.set({ key: 'mykey', value: { a: 1, b: 2 } });
|
|
68
|
+
|
|
69
|
+
// Get a value
|
|
70
|
+
const value = await redisClient.getObject({ key: 'mykey' });
|
|
71
|
+
// => { a: 1, b: 2 }
|
|
72
|
+
|
|
73
|
+
// Delete a key
|
|
74
|
+
await redisClient.del({ keys: ['mykey'] });
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Hashes
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// Set hash fields
|
|
81
|
+
await redisClient.hset({ key: 'myhash', value: { field1: 'hello', field2: 'world' } });
|
|
82
|
+
|
|
83
|
+
// Get all hash fields
|
|
84
|
+
const hash = await redisClient.hgetall({ key: 'myhash' });
|
|
85
|
+
// => { field1: 'hello', field2: 'world' }
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## RedisJSON
|
|
89
|
+
|
|
90
|
+
If your Redis server has the RedisJSON module installed, you can use the `j*` methods to work with JSON documents.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// Set a JSON document
|
|
94
|
+
await redisClient.jSet({ key: 'mydoc', path: '$', value: { a: { b: 1 } } });
|
|
95
|
+
|
|
96
|
+
// Get a part of the document
|
|
97
|
+
const result = await redisClient.jGet({ key: 'mydoc', path: '$.a.b' });
|
|
98
|
+
// => [1]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Pub/Sub
|
|
102
|
+
|
|
103
|
+
The helper also supports Redis Pub/Sub for real-time messaging.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// Subscribe to a topic
|
|
107
|
+
redisClient.subscribe({ topic: 'my-channel' });
|
|
108
|
+
|
|
109
|
+
// Listen for messages (in a separate part of your app)
|
|
110
|
+
redisClient.getClient().on('message', (channel, message) => {
|
|
111
|
+
if (channel === 'my-channel') {
|
|
112
|
+
console.log('Received message:', JSON.parse(message));
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Publish a message
|
|
117
|
+
await redisClient.publish({
|
|
118
|
+
topics: ['my-channel'],
|
|
119
|
+
payload: { data: 'some important update' },
|
|
120
|
+
});
|
|
121
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Socket.IO Helper
|
|
2
|
+
|
|
3
|
+
Structured Socket.IO client and server management for real-time bidirectional communication.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
| Helper | Type | Features |
|
|
8
|
+
|--------|------|----------|
|
|
9
|
+
| **SocketIOServerHelper** | Server | Auth flow, room management, Redis scaling |
|
|
10
|
+
| **SocketIOClientHelper** | Client | Structured API, event subscription |
|
|
11
|
+
|
|
12
|
+
### SocketIOServerHelper Features
|
|
13
|
+
|
|
14
|
+
| Feature | Description |
|
|
15
|
+
|---------|-------------|
|
|
16
|
+
| **Redis Integration** | `@socket.io/redis-adapter` (scaling), `@socket.io/redis-emitter` (broadcasting) |
|
|
17
|
+
| **Authentication** | Built-in flow - clients emit `authenticate` event |
|
|
18
|
+
| **Client Management** | Track connections and auth state |
|
|
19
|
+
| **Room Management** | Group clients for targeted messaging |
|
|
20
|
+
|
|
21
|
+
### Common Operations
|
|
22
|
+
|
|
23
|
+
| Helper | Method | Purpose |
|
|
24
|
+
|--------|--------|---------|
|
|
25
|
+
| **Server** | `send({ destination, payload })` | Send message to room/socket |
|
|
26
|
+
| **Server** | `broadcast({ payload })` | Broadcast to all clients |
|
|
27
|
+
| **Client** | `connect()` | Connect to server |
|
|
28
|
+
| **Client** | `emit({ topic, ...data })` | Emit event |
|
|
29
|
+
| **Client** | `subscribe({ events })` | Subscribe to events |
|
|
30
|
+
|
|
31
|
+
### Usage
|
|
32
|
+
|
|
33
|
+
The `SocketIOServerHelper` is typically instantiated and managed by the `SocketIOComponent`. To use it, you need to provide the necessary configurations and handlers when you register the component. See the [Socket.IO Component documentation](../components/socket-io.md) for details on how to set it up.
|
|
34
|
+
|
|
35
|
+
Once configured, you can inject the `SocketIOServerHelper` instance into your services or controllers to emit events.
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { SocketIOServerHelper, SocketIOBindingKeys, inject } from '@venizia/ignis';
|
|
39
|
+
|
|
40
|
+
// ... in a service or controller
|
|
41
|
+
|
|
42
|
+
@inject({ key: SocketIOBindingKeys.SOCKET_IO_INSTANCE })
|
|
43
|
+
private io: SocketIOServerHelper;
|
|
44
|
+
|
|
45
|
+
sendNotification(userId: string, message: string) {
|
|
46
|
+
this.io.send({
|
|
47
|
+
destination: userId, // Room or socket ID
|
|
48
|
+
payload: {
|
|
49
|
+
topic: 'notification',
|
|
50
|
+
data: { message },
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## `SocketIOClientHelper`
|
|
57
|
+
|
|
58
|
+
The `SocketIOClientHelper` provides a structured API for managing client-side Socket.IO connections.
|
|
59
|
+
|
|
60
|
+
### Creating a Socket.IO Client
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { SocketIOClientHelper } from '@venizia/ignis';
|
|
64
|
+
|
|
65
|
+
const socketClient = new SocketIOClientHelper({
|
|
66
|
+
identifier: 'my-socket-client',
|
|
67
|
+
host: 'http://localhost:3000',
|
|
68
|
+
options: {
|
|
69
|
+
path: '/io', // Path to the Socket.IO server
|
|
70
|
+
extraHeaders: {
|
|
71
|
+
Authorization: 'Bearer my-jwt-token',
|
|
72
|
+
},
|
|
73
|
+
auth: {
|
|
74
|
+
token: 'my-jwt-token',
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
socketClient.connect();
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Subscribing to Events
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
socketClient.subscribe({
|
|
86
|
+
events: {
|
|
87
|
+
connect: () => {
|
|
88
|
+
console.log('Connected to Socket.IO server!');
|
|
89
|
+
// Authenticate with the server
|
|
90
|
+
socketClient.emit({ topic: 'authenticate' });
|
|
91
|
+
},
|
|
92
|
+
authenticated: (data) => {
|
|
93
|
+
console.log('Successfully authenticated:', data);
|
|
94
|
+
},
|
|
95
|
+
notification: (data) => {
|
|
96
|
+
console.log('Received notification:', data);
|
|
97
|
+
},
|
|
98
|
+
disconnect: () => {
|
|
99
|
+
console.log('Disconnected from server.');
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
```
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Storage Helpers
|
|
2
|
+
|
|
3
|
+
In-memory and external object storage solutions.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
| Helper | Type | Use Case |
|
|
8
|
+
|--------|------|----------|
|
|
9
|
+
| **MemoryStorageHelper** | In-memory key-value | Caching, temporary state, single-process data |
|
|
10
|
+
| **MinioHelper** | S3-compatible object storage | File uploads, persistent storage, MinIO/S3 |
|
|
11
|
+
|
|
12
|
+
### MemoryStorageHelper Methods
|
|
13
|
+
|
|
14
|
+
| Method | Purpose |
|
|
15
|
+
|--------|---------|
|
|
16
|
+
| `set(key, value)` | Store value |
|
|
17
|
+
| `get<T>(key)` | Retrieve value |
|
|
18
|
+
| `isBound(key)` | Check if key exists |
|
|
19
|
+
| `keys()` | Get all keys |
|
|
20
|
+
| `clear()` | Clear all data |
|
|
21
|
+
|
|
22
|
+
### MinioHelper Operations
|
|
23
|
+
|
|
24
|
+
| Operation | Methods |
|
|
25
|
+
|-----------|---------|
|
|
26
|
+
| **Bucket** | `createBucket()`, `isBucketExists()`, `removeBucket()` |
|
|
27
|
+
| **Upload** | `upload({ bucket, files })` |
|
|
28
|
+
| **Download** | `getFile({ bucket, name })` |
|
|
29
|
+
| **Delete** | `removeObject()`, `removeObjects()` |
|
|
30
|
+
|
|
31
|
+
## `MemoryStorageHelper`
|
|
32
|
+
|
|
33
|
+
The `MemoryStorageHelper` is a simple in-memory key-value store. It's useful for caching, storing temporary application state, or passing data between loosely coupled parts of your application within a single process.
|
|
34
|
+
|
|
35
|
+
### Creating an Instance
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { MemoryStorageHelper } from '@venizia/ignis';
|
|
39
|
+
|
|
40
|
+
const memoryStore = new MemoryStorageHelper();
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Usage
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// Set a value
|
|
47
|
+
memoryStore.set('my-key', { a: 1, b: 2 });
|
|
48
|
+
|
|
49
|
+
// Get a value
|
|
50
|
+
const value = memoryStore.get<{ a: number; b: number }>('my-key');
|
|
51
|
+
// => { a: 1, b: 2 }
|
|
52
|
+
|
|
53
|
+
// Check if a key exists
|
|
54
|
+
const hasKey = memoryStore.isBound('my-key');
|
|
55
|
+
// => true
|
|
56
|
+
|
|
57
|
+
// Get all keys
|
|
58
|
+
const allKeys = memoryStore.keys();
|
|
59
|
+
// => ['my-key']
|
|
60
|
+
|
|
61
|
+
// Clear the storage
|
|
62
|
+
memoryStore.clear();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## `MinioHelper`
|
|
66
|
+
|
|
67
|
+
The `MinioHelper` is a comprehensive client for interacting with MinIO or any S3-compatible object storage service.
|
|
68
|
+
|
|
69
|
+
### Creating a MinIO Client
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { MinioHelper } from '@venizia/ignis';
|
|
73
|
+
|
|
74
|
+
const minioClient = new MinioHelper({
|
|
75
|
+
endPoint: 'localhost',
|
|
76
|
+
port: 9000,
|
|
77
|
+
useSSL: false,
|
|
78
|
+
accessKey: 'minioadmin',
|
|
79
|
+
secretKey: 'minioadmin',
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Bucket Operations
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// Create a bucket if it doesn't exist
|
|
87
|
+
const bucketName = 'my-bucket';
|
|
88
|
+
const bucketExists = await minioClient.isBucketExists({ name: bucketName });
|
|
89
|
+
if (!bucketExists) {
|
|
90
|
+
await minioClient.createBucket({ name: bucketName });
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Object Operations
|
|
95
|
+
|
|
96
|
+
#### Uploading a File
|
|
97
|
+
|
|
98
|
+
The `upload` method takes an array of file objects, typically from a multipart form data request.
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// Assuming `files` is an array of IUploadFile objects from a request
|
|
102
|
+
const uploadResult = await minioClient.upload({
|
|
103
|
+
bucket: 'my-bucket',
|
|
104
|
+
files: files,
|
|
105
|
+
});
|
|
106
|
+
// => [{ bucket: 'my-bucket', fileName: '...', link: '...' }]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### Getting an Object
|
|
110
|
+
|
|
111
|
+
The `getFile` method returns a `Readable` stream for an object.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
const fileStream = await minioClient.getFile({
|
|
115
|
+
bucket: 'my-bucket',
|
|
116
|
+
name: 'my-file.txt',
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
fileStream.pipe(process.stdout);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### Removing Objects
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// Remove a single object
|
|
126
|
+
await minioClient.removeObject({ bucket: 'my-bucket', name: 'my-file.txt' });
|
|
127
|
+
|
|
128
|
+
// Remove multiple objects
|
|
129
|
+
await minioClient.removeObjects({ bucket: 'my-bucket', names: ['file1.txt', 'file2.txt'] });
|
|
130
|
+
```
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Testing Helper
|
|
2
|
+
|
|
3
|
+
Structured test framework integrating with Node.js's native `node:test` module.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
| Component | Purpose |
|
|
8
|
+
|-----------|---------|
|
|
9
|
+
| **TestPlan** | Organizes test suite with lifecycle hooks and shared context |
|
|
10
|
+
| **TestCase** | Single runnable test unit with metadata |
|
|
11
|
+
| **TestCaseHandler** | Encapsulates test execution and validation logic |
|
|
12
|
+
| **TestDescribe** | Runs test plans |
|
|
13
|
+
|
|
14
|
+
### Test Lifecycle Hooks
|
|
15
|
+
|
|
16
|
+
| Hook | When | Purpose |
|
|
17
|
+
|------|------|---------|
|
|
18
|
+
| `before` | Before all tests | Setup (e.g., start server, seed DB) |
|
|
19
|
+
| `after` | After all tests | Cleanup (e.g., close connections) |
|
|
20
|
+
| `beforeEach` | Before each test | Reset state |
|
|
21
|
+
| `afterEach` | After each test | Cleanup per test |
|
|
22
|
+
|
|
23
|
+
### TestCaseDecisions
|
|
24
|
+
|
|
25
|
+
| Decision | Meaning |
|
|
26
|
+
|----------|---------|
|
|
27
|
+
| `SUCCESS` | Test passed |
|
|
28
|
+
| `FAIL` | Test failed |
|
|
29
|
+
| `SKIP` | Test skipped |
|
|
30
|
+
|
|
31
|
+
## Creating a Test Plan
|
|
32
|
+
|
|
33
|
+
A test plan is the main entry point for a test suite. You define the scope, hooks, and test cases within the plan.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// __tests__/my-feature.test.ts
|
|
37
|
+
import { TestPlan, TestDescribe, TestCase, TestCaseHandler, TestCaseDecisions } from '@venizia/ignis';
|
|
38
|
+
|
|
39
|
+
// 1. Define a Test Case Handler
|
|
40
|
+
class MyTestHandler extends TestCaseHandler {
|
|
41
|
+
async execute() {
|
|
42
|
+
// Perform the action to be tested
|
|
43
|
+
return { result: 'some-value' };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getValidator() {
|
|
47
|
+
return (opts: { result: string }) => {
|
|
48
|
+
if (opts.result === 'some-value') {
|
|
49
|
+
return TestCaseDecisions.SUCCESS;
|
|
50
|
+
}
|
|
51
|
+
return TestCaseDecisions.FAIL;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 2. Create a Test Plan
|
|
57
|
+
const myTestPlan = TestPlan.newInstance({
|
|
58
|
+
scope: 'My Feature',
|
|
59
|
+
hooks: {
|
|
60
|
+
before: async () => console.log('Starting My Feature tests...'),
|
|
61
|
+
after: async () => console.log('Finished My Feature tests.'),
|
|
62
|
+
},
|
|
63
|
+
testCases: [
|
|
64
|
+
TestCase.withOptions({
|
|
65
|
+
code: 'MY-FEATURE-001',
|
|
66
|
+
description: 'It should return the correct value',
|
|
67
|
+
expectation: 'The result should be "some-value"',
|
|
68
|
+
handler: new MyTestHandler({ context: {} as any }), // Context is provided by the plan
|
|
69
|
+
}),
|
|
70
|
+
],
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// 3. Run the Test Plan
|
|
74
|
+
TestDescribe.withTestPlan({ testPlan: myTestPlan }).run();
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Shared Context
|
|
78
|
+
|
|
79
|
+
The `TestPlan` provides a `context` that can be used to share data between test cases and hooks. This is useful for setup tasks like creating a JWT token or seeding a database.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// __tests__/auth.test.ts
|
|
83
|
+
import { TestPlan, TestDescribe, TestCase, TestCaseHandler, ITestContext } from '@venizia/ignis';
|
|
84
|
+
|
|
85
|
+
// A handler that uses the context
|
|
86
|
+
class SecureApiHandler extends TestCaseHandler<{ token: string }> {
|
|
87
|
+
async execute() {
|
|
88
|
+
const token = this.context.getSync<{ token: string }>({ key: 'token' });
|
|
89
|
+
const response = await app.request('/api/secure-data', {
|
|
90
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
91
|
+
});
|
|
92
|
+
return { status: response.status };
|
|
93
|
+
}
|
|
94
|
+
// ... validator
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const authTestPlan = TestPlan.newInstance({
|
|
98
|
+
scope: 'Authentication',
|
|
99
|
+
hooks: {
|
|
100
|
+
before: async (context: ITestContext<{ token: string }>) => {
|
|
101
|
+
// Generate a token and bind it to the context
|
|
102
|
+
const token = await generateTestToken();
|
|
103
|
+
context.bind({ key: 'token', value: token });
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
testCases: [
|
|
107
|
+
TestCase.withOptions({
|
|
108
|
+
// ...
|
|
109
|
+
handler: new SecureApiHandler({ context: {} as any }),
|
|
110
|
+
}),
|
|
111
|
+
],
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
TestDescribe.withTestPlan({ testPlan: authTestPlan }).run();
|
|
115
|
+
```
|