@onlineapps/conn-orch-registry 1.1.4

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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 ONLINE APPS s.r.o.; info@onlineapps.cz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # @onlineapps/connector-registry-client
2
+
3
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/onlineapps/connector-registry-client/nodejs.yml?branch=main)](https://github.com/onlineapps/connector-registry-client/actions)
4
+ [![Coverage Status](https://codecov.io/gh/onlineapps/connector-registry-client/branch/main/graph/badge.svg)](https://codecov.io/gh/onlineapps/connector-registry-client)
5
+ [![npm version](https://img.shields.io/npm/v/@onlineapps/connector-registry-client)](https://www.npmjs.com/package/@onlineapps/connector-registry-client)
6
+
7
+ > A lightweight client for microservice registration, heartbeat, and API description exchange via RabbitMQ.
8
+
9
+ ## 🚀 Features
10
+
11
+ * Automatic queue management (`workflow`, `<serviceName>.registry`, `api_services_queuer`, `registry_office`)
12
+ * Periodic heartbeat messages with metadata
13
+ * API description request/response flow
14
+ * Event-driven API using `EventEmitter`
15
+ * Fully configurable via environment variables or constructor options
16
+
17
+ ## 📦 Installation
18
+
19
+ ```bash
20
+ npm install @onlineapps/connector-registry-client
21
+ # or
22
+ yarn add @onlineapps/connector-registry-client
23
+ ```
24
+
25
+ ## 🔧 Quick Start
26
+
27
+ ```js
28
+ // Load environment, if using .env
29
+ require('dotenv').config();
30
+
31
+ const { ServiceRegistryClient, EVENTS } = require('@onlineapps/connector-registry-client');
32
+
33
+ const client = new ServiceRegistryClient({
34
+ amqpUrl: process.env.AMQP_URL,
35
+ serviceName: 'invoicing',
36
+ version: '1.0.0'
37
+ });
38
+
39
+ // Listen for API description requests
40
+ client.on(EVENTS.API_DESCRIPTION_REQUEST, async () => {
41
+ const apiSpec = await loadOpenApiSpec();
42
+ await client.sendApiDescription(apiSpec);
43
+ });
44
+
45
+ // Initialize and start heartbeats
46
+ await client.init();
47
+ client.startHeartbeat();
48
+
49
+ // Graceful shutdown
50
+ process.on('SIGINT', async () => {
51
+ await client.close();
52
+ process.exit(0);
53
+ });
54
+ ```
55
+
56
+ ## 📄 Configuration
57
+
58
+ Configuration can be provided via environment variables or constructor options:
59
+
60
+ | Variable | Description | Default |
61
+ | -------------------- | --------------------------------------------- | -------------------- |
62
+ | `AMQP_URL` | RabbitMQ connection string (required) | — |
63
+ | `SERVICE_NAME` | Logical name of your service (required) | — |
64
+ | `SERVICE_VERSION` | Service version in SemVer format (required) | — |
65
+ | `HEARTBEAT_INTERVAL` | Interval in ms between heartbeats | `10000` |
66
+ | `API_QUEUE` | Queue name for heartbeat/API messages | `api_services_queuer` |
67
+ | `REGISTRY_QUEUE` | Queue name for registry requests/descriptions | `registry_office` |
68
+
69
+ ## 📨 Message Formats
70
+
71
+ ### Register Request
72
+ ```javascript
73
+ {
74
+ type: "register",
75
+ serviceName: "hello-service",
76
+ version: "1.0.0",
77
+ token: "pre-validation-token",
78
+ endpoints: [...],
79
+ timestamp: "ISO-8601"
80
+ }
81
+ ```
82
+
83
+ ### Register Confirmed
84
+ ```javascript
85
+ {
86
+ type: "register.confirmed",
87
+ serviceName: "hello-service",
88
+ success: true,
89
+ certificate: {
90
+ id: "cert-uuid",
91
+ signature: "cryptographic-signature",
92
+ validUntil: "ISO-8601"
93
+ },
94
+ cached: false
95
+ }
96
+ ```
97
+
98
+ ### Heartbeat
99
+ ```javascript
100
+ {
101
+ type: "heartbeat",
102
+ serviceName: "hello-service",
103
+ status: "UP",
104
+ timestamp: "ISO-8601"
105
+ }
106
+ ```
107
+
108
+ ## 🛠️ API Reference
109
+
110
+ See [docs/api.md](https://github.com/onlineapps/connector-registry-client/blob/main/docs/api.md) for full details on classes, methods, and events.
111
+
112
+ ## 📖 Documentation
113
+
114
+ * Architecture overview: [docs/architecture.md](https://github.com/onlineapps/connector-registry-client/blob/main/docs/architecture.md)
115
+ * API reference: [docs/api.md](https://github.com/onlineapps/connector-registry-client/blob/main/docs/api.md)
116
+ * Examples: [examples/basicUsage.js](https://github.com/onlineapps/agent-registry-client/blob/main/examples/basicUsage.js)
117
+
118
+ ## 🔗 Related Documentation
119
+
120
+ - **[⭐ Complete Two-Tier Validation System](/docs/modules/validator.md)** - Full validation architecture and flow
121
+ - [Registry Module Overview](/docs/modules/registry.md) - High-level registry system architecture
122
+ - [api_services_registry](/api/api_services_registry/README.md) - Registry service implementation
123
+
124
+ ## ✅ Testing
125
+
126
+ ```bash
127
+ # Run unit and integration tests
128
+ yarn test
129
+ # or
130
+ npm test
131
+ ```
132
+
133
+ ## 🎨 Coding Standards
134
+
135
+ * **Linting**: ESLint (Airbnb style)
136
+ * **Formatting**: Prettier
137
+ * **Testing**: Jest
138
+
139
+ ## 🤝 Contributing
140
+
141
+ Please read [CONTRIBUTING.md](https://github.com/onlineapps/agent-registry-client/blob/main/CONTRIBUTING.md) for details on submitting issues and pull requests.
142
+
143
+ ## 📜 License
144
+
145
+ This project is licensed under the MIT License. See [LICENSE](https://github.com/onlineapps/agent-registry-client/blob/main/LICENSE) for details.
146
+
147
+ ## 📚 Documentation
148
+
149
+ - [Complete Connectors Documentation](../../../docs/modules/connector.md)
150
+ - [Testing Standards](../../../docs/modules/connector.md#testing-standards)
151
+
@@ -0,0 +1,240 @@
1
+ # Registry Client Guide
2
+
3
+ ## Overview
4
+
5
+ The `ServiceRegistryClient` is a connector library that enables microservices to communicate with the API Services Registry. It handles service registration, validation, heartbeats, and specification sharing.
6
+
7
+ ## Registration Flow
8
+
9
+ ### New Registration Process (v1.1+)
10
+
11
+ The registration flow has been updated to include validation before activation:
12
+
13
+ ```
14
+ Microservice Registry Backend
15
+ | | |
16
+ |-- init() --------------->| |
17
+ | (setup connection) | |
18
+ | | |
19
+ |-- register() ----------->| |
20
+ | (send service info) | |
21
+ | |-- validate() --------->|
22
+ | | (check if tested) |
23
+ | |<-- validation result --|
24
+ | | |
25
+ |<-- registration result --| |
26
+ | | |
27
+ |-- startHeartbeat() ----->| |
28
+ | (if validated OK) | |
29
+ | | |
30
+ |-- sendApiDescription() ->| |
31
+ | (on request) | |
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ### 1. Basic Setup
37
+
38
+ ```javascript
39
+ const { ServiceRegistryClient } = require('@onlineapps/connector-registry-client');
40
+
41
+ const registryClient = new ServiceRegistryClient({
42
+ amqpUrl: 'amqp://localhost:5672',
43
+ serviceName: 'my-service',
44
+ version: '1.0.0',
45
+ specificationEndpoint: '/api/v1/specification',
46
+ heartbeatInterval: 10000
47
+ });
48
+ ```
49
+
50
+ ### 2. Service Initialization and Registration
51
+
52
+ ```javascript
53
+ async function initializeService() {
54
+ // Step 1: Initialize connection
55
+ await registryClient.init();
56
+
57
+ // Step 2: Register service with registry
58
+ const registrationResult = await registryClient.register({
59
+ endpoints: [
60
+ { path: '/api/users', method: 'GET' },
61
+ { path: '/api/users', method: 'POST' },
62
+ { path: '/api/users/:id', method: 'GET' },
63
+ { path: '/api/users/:id', method: 'PUT' },
64
+ { path: '/api/users/:id', method: 'DELETE' }
65
+ ],
66
+ metadata: {
67
+ description: 'User management service',
68
+ author: 'Development Team',
69
+ documentation: 'https://docs.example.com/users'
70
+ },
71
+ health: '/health',
72
+ spec: openApiSpec // Optional: OpenAPI specification object
73
+ });
74
+
75
+ // Step 3: If registration successful, start heartbeat
76
+ if (registrationResult.success) {
77
+ registryClient.startHeartbeat();
78
+ console.log('Service registered and activated');
79
+ } else {
80
+ console.error('Registration failed:', registrationResult.message);
81
+ // Handle registration failure (service not tested, invalid config, etc.)
82
+ }
83
+ }
84
+ ```
85
+
86
+ ### 3. Handling API Description Requests
87
+
88
+ ```javascript
89
+ // Listen for requests to send API specification
90
+ registryClient.on('apiDescriptionRequest', async (request) => {
91
+ const apiSpec = await loadApiSpecification();
92
+ await registryClient.sendApiDescription(apiSpec);
93
+ });
94
+ ```
95
+
96
+ ### 4. Event Subscription (Optional)
97
+
98
+ For services that need to be notified about registry changes:
99
+
100
+ ```javascript
101
+ await registryClient.subscribeToChanges();
102
+
103
+ // Will receive events when services are added/removed/updated
104
+ ```
105
+
106
+ ### 5. Cleanup
107
+
108
+ ```javascript
109
+ async function shutdown() {
110
+ registryClient.stopHeartbeat();
111
+ await registryClient.close();
112
+ }
113
+ ```
114
+
115
+ ## API Reference
116
+
117
+ ### Constructor Options
118
+
119
+ | Option | Type | Default | Description |
120
+ |--------|------|---------|-------------|
121
+ | `amqpUrl` | string | required | AMQP connection URL |
122
+ | `serviceName` | string | required | Unique service identifier |
123
+ | `version` | string | required | Service version (semver) |
124
+ | `specificationEndpoint` | string | '/api/v1/specification' | Endpoint for API spec |
125
+ | `heartbeatInterval` | number | 10000 | Heartbeat interval in ms |
126
+ | `apiQueue` | string | 'api_services_queuer' | Queue for API traffic |
127
+ | `registryQueue` | string | 'registry_office' | Registry queue name |
128
+
129
+ ### Methods
130
+
131
+ #### `async init()`
132
+ Initializes the connection to RabbitMQ and sets up queues.
133
+
134
+ #### `async register(serviceInfo)`
135
+ Registers the service with the registry. The registry will validate that the service is properly tested and approved before activation.
136
+
137
+ **Parameters:**
138
+ - `serviceInfo.endpoints` - Array of API endpoints
139
+ - `serviceInfo.metadata` - Service metadata object
140
+ - `serviceInfo.health` - Health check endpoint
141
+ - `serviceInfo.spec` - OpenAPI specification (optional)
142
+
143
+ **Returns:** Registration result object with `success` status
144
+
145
+ #### `startHeartbeat()`
146
+ Starts sending periodic heartbeat messages. Should only be called after successful registration.
147
+
148
+ #### `stopHeartbeat()`
149
+ Stops the heartbeat timer.
150
+
151
+ #### `async sendApiDescription(description)`
152
+ Sends the API specification to the registry when requested.
153
+
154
+ #### `async subscribeToChanges()`
155
+ Subscribes to registry change events (optional).
156
+
157
+ #### `async close()`
158
+ Closes all connections and cleans up resources.
159
+
160
+ ### Events
161
+
162
+ | Event | Payload | Description |
163
+ |-------|---------|-------------|
164
+ | `registerSent` | Registration message | Emitted when registration is sent |
165
+ | `heartbeatSent` | Heartbeat message | Emitted on each heartbeat |
166
+ | `apiDescriptionRequest` | Request details | Registry requests API spec |
167
+ | `apiDescriptionSent` | Description message | API spec was sent |
168
+ | `error` | Error object | Error occurred |
169
+
170
+ ## Registration Validation
171
+
172
+ The registry performs several validation checks during registration:
173
+
174
+ 1. **Service Testing Status** - Verifies the service has passed required tests
175
+ 2. **Version Compatibility** - Checks version against registry requirements
176
+ 3. **Endpoint Validation** - Ensures endpoints follow API standards
177
+ 4. **Dependencies Check** - Validates required services are available
178
+
179
+ Only after passing all validation checks will the service be activated and allowed to send heartbeats.
180
+
181
+ ## Migration from v1.0
182
+
183
+ If you're upgrading from v1.0 where services immediately started heartbeats:
184
+
185
+ **Old flow (v1.0):**
186
+ ```javascript
187
+ await registryClient.init();
188
+ registryClient.startHeartbeat(); // Started immediately
189
+ ```
190
+
191
+ **New flow (v1.1+):**
192
+ ```javascript
193
+ await registryClient.init();
194
+ const result = await registryClient.register(serviceInfo); // NEW: Registration required
195
+ if (result.success) {
196
+ registryClient.startHeartbeat(); // Only after validation
197
+ }
198
+ ```
199
+
200
+ ## Troubleshooting
201
+
202
+ ### Registration Fails
203
+
204
+ If registration fails, check:
205
+ - Service has passed all required tests
206
+ - Version number is correctly formatted
207
+ - All required endpoints are documented
208
+ - Service metadata is complete
209
+
210
+ ### No Heartbeats Sent
211
+
212
+ Ensure:
213
+ - Registration was successful before starting heartbeats
214
+ - RabbitMQ connection is stable
215
+ - Correct queue names are configured
216
+
217
+ ### API Description Not Received
218
+
219
+ Verify:
220
+ - Event listener is properly set up
221
+ - Service name and version match exactly
222
+ - Queue consumption is active
223
+
224
+ ## Testing
225
+
226
+ ### Unit Tests
227
+ ```bash
228
+ npm test:unit
229
+ ```
230
+
231
+ ### Integration Tests
232
+ ```bash
233
+ # Requires RabbitMQ and MinIO running
234
+ npm test:integration
235
+ ```
236
+
237
+ ### Full Test Suite
238
+ ```bash
239
+ npm test
240
+ ```
@@ -0,0 +1,85 @@
1
+ /**
2
+ * basicUsage.js
3
+ *
4
+ * Example demonstrating full lifecycle of ServiceRegistryClient:
5
+ * 1. Load environment variables
6
+ * 2. Instantiate client
7
+ * 3. Initialize (setup queues and start listening for requests)
8
+ * 4. Register event listeners (apiDescriptionRequest, heartbeatSent, apiDescriptionSent, error)
9
+ * 5. Start heartbeat loop
10
+ * 6. Graceful shutdown on process signals
11
+ */
12
+
13
+ // Load environment variables from .env file
14
+ require('dotenv').config();
15
+
16
+ const { ServiceRegistryClient, EVENTS } = require('@onlineapps/connector-registry-client');
17
+
18
+ // Step 1: Create a new ServiceRegistryClient instance
19
+ const registryClient = new ServiceRegistryClient({
20
+ amqpUrl: process.env.AMQP_URL,
21
+ serviceName: process.env.SERVICE_NAME || 'invoicing',
22
+ version: process.env.SERVICE_VERSION || '1.0.0',
23
+ specificationEndpoint: process.env.SPECIFICATION_ENDPOINT || '/api/v1/specification',
24
+ heartbeatInterval: parseInt(process.env.HEARTBEAT_INTERVAL, 10) || 10000,
25
+ apiQueue: process.env.API_QUEUE,
26
+ registryQueue: process.env.REGISTRY_QUEUE
27
+ });
28
+
29
+ // Step 2: Register event listeners
30
+ registryClient.on(EVENTS.HEARTBEAT_SENT, (msg) => {
31
+ console.log(`[Heartbeat] Sent at ${msg.timestamp} for ${msg.serviceName}@${msg.version}`);
32
+ });
33
+
34
+ registryClient.on(EVENTS.API_DESCRIPTION_REQUEST, async (payload) => {
35
+ console.log(`[API Description Request] for ${payload.serviceName}@${payload.version}`);
36
+ // Load local API description (from file or in-memory)
37
+ const apiDesc = await loadLocalApiDescription();
38
+ await registryClient.sendApiDescription(apiDesc);
39
+ });
40
+
41
+ registryClient.on(EVENTS.API_DESCRIPTION_SENT, (msg) => {
42
+ console.log(`[API Description Sent] at ${msg.timestamp} for ${msg.serviceName}@${msg.version}`);
43
+ });
44
+
45
+ registryClient.on(EVENTS.ERROR, (err) => {
46
+ console.error('[RegistryClient Error]', err);
47
+ });
48
+
49
+ (async () => {
50
+ try {
51
+ // Step 3: Initialize client (setup queues and listeners)
52
+ await registryClient.init();
53
+ console.log('RegistryClient initialized: queues are ready.');
54
+
55
+ // Step 4: Start heartbeat loop
56
+ registryClient.startHeartbeat();
57
+ console.log('Heartbeat loop started.');
58
+
59
+ // Step 5: Graceful shutdown on SIGINT/SIGTERM
60
+ const shutdown = async () => {
61
+ console.log('Shutting down RegistryClient...');
62
+ await registryClient.close();
63
+ process.exit(0);
64
+ };
65
+ process.on('SIGINT', shutdown);
66
+ process.on('SIGTERM', shutdown);
67
+ } catch (err) {
68
+ console.error('Failed to initialize RegistryClient', err);
69
+ process.exit(1);
70
+ }
71
+ })();
72
+
73
+ /**
74
+ * Helper: Load local API description
75
+ * In a real application, this could read from a JSON file,
76
+ * introspect OpenAPI spec, or build dynamically.
77
+ */
78
+ async function loadLocalApiDescription() {
79
+ return {
80
+ endpoints: [
81
+ { path: '/invoices', method: 'POST', description: 'Create a new invoice' },
82
+ { path: '/invoices/:id', method: 'GET', description: 'Retrieve invoice by ID' }
83
+ ]
84
+ };
85
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Example: Using ServiceRegistryClient with event consumption
3
+ *
4
+ * Demonstrates opt-in subscription to registry change events
5
+ */
6
+
7
+ const { ServiceRegistryClient } = require('../src/index');
8
+ const Redis = require('ioredis');
9
+
10
+ async function main() {
11
+ // Optional Redis for index persistence
12
+ const redis = new Redis({
13
+ host: process.env.REDIS_HOST || 'localhost',
14
+ port: process.env.REDIS_PORT || 6379
15
+ });
16
+
17
+ // Initialize client with storage configuration
18
+ const client = new ServiceRegistryClient({
19
+ amqpUrl: process.env.AMQP_URL || 'amqp://localhost',
20
+ serviceName: 'example-service',
21
+ version: '1.0.0',
22
+ redis: redis,
23
+ storageConfig: {
24
+ endPoint: process.env.MINIO_ENDPOINT || 'localhost',
25
+ port: parseInt(process.env.MINIO_PORT || 9000),
26
+ useSSL: process.env.MINIO_USE_SSL === 'true',
27
+ accessKey: process.env.MINIO_ACCESS_KEY || 'minioadmin',
28
+ secretKey: process.env.MINIO_SECRET_KEY || 'minioadmin'
29
+ }
30
+ });
31
+
32
+ // Initialize connection
33
+ await client.init();
34
+
35
+ // Register ourselves with registry
36
+ await client.sendApiDescription({
37
+ openapi: '3.0.0',
38
+ info: {
39
+ title: 'Example Service',
40
+ version: '1.0.0'
41
+ },
42
+ paths: {
43
+ '/hello': {
44
+ get: {
45
+ summary: 'Say hello',
46
+ responses: {
47
+ '200': {
48
+ description: 'Success'
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }
54
+ });
55
+
56
+ // Start heartbeat
57
+ client.startHeartbeat();
58
+
59
+ // OPT-IN: Subscribe to registry changes
60
+ console.log('Subscribing to registry changes...');
61
+ await client.subscribeToChanges();
62
+
63
+ // Listen for events
64
+ client.on('serviceUpdated', ({ service, fingerprint, version }) => {
65
+ console.log(`Service updated: ${service} v${version} (${fingerprint})`);
66
+ });
67
+
68
+ client.on('statusChanged', ({ service, status }) => {
69
+ console.log(`Service status changed: ${service} -> ${status}`);
70
+ });
71
+
72
+ client.on('snapshotReceived', ({ count }) => {
73
+ console.log(`Received snapshot with ${count} services`);
74
+
75
+ // Show active services
76
+ const activeServices = client.getActiveServices();
77
+ console.log('Active services:', activeServices);
78
+ });
79
+
80
+ // Example: Check if another service is active
81
+ setTimeout(() => {
82
+ if (client.isServiceActive('invoicing')) {
83
+ console.log('Invoicing service is active');
84
+
85
+ // Load its spec
86
+ client.getServiceSpec('invoicing')
87
+ .then(spec => {
88
+ console.log('Invoicing API:', spec.info?.title);
89
+ })
90
+ .catch(err => {
91
+ console.error('Failed to load invoicing spec:', err.message);
92
+ });
93
+ } else {
94
+ console.log('Invoicing service is not active');
95
+ }
96
+ }, 5000);
97
+
98
+ // Graceful shutdown
99
+ process.on('SIGINT', async () => {
100
+ console.log('\nShutting down...');
101
+ await client.close();
102
+ await redis.quit();
103
+ process.exit(0);
104
+ });
105
+ }
106
+
107
+ // Run example
108
+ main().catch(console.error);
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@onlineapps/conn-orch-registry",
3
+ "version": "1.1.4",
4
+ "license": "MIT",
5
+ "description": "Connector-registry-client provides the core communication mechanism for microservices in this environment. It enables them to interact with a services_registry to receive and fulfill tasks by submitting heartbeats or their API descriptions.",
6
+ "keywords": [
7
+ "microservice",
8
+ "connector",
9
+ "registry",
10
+ "rabbitmq",
11
+ "heartbeat",
12
+ "api",
13
+ "environment",
14
+ "nodejs"
15
+ ],
16
+ "files": [
17
+ "src/",
18
+ "docs/",
19
+ "examples/",
20
+ "README.md",
21
+ "LICENSE",
22
+ "CONTRIBUTING.md"
23
+ ],
24
+ "main": "src/index.js",
25
+ "scripts": {
26
+ "test": "jest --coverage",
27
+ "test:unit": "jest --testPathPattern=unit --coverage",
28
+ "test:component": "jest --testPathPattern=component --coverage",
29
+ "test:integration": "jest --config=jest.integration.config.js",
30
+ "test:integration:required": "REQUIRE_SERVICES=true jest --config=jest.integration.config.js",
31
+ "test:watch": "jest --watch",
32
+ "test:coverage": "jest --coverage --coverageReporters=text-lcov html",
33
+ "semantic-release": "semantic-release",
34
+ "lint": "eslint src test examples --ext .js --cache --cache-location .eslintcache",
35
+ "docs": "jsdoc2md --files src/**/*.js > API.md"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "dependencies": {
41
+ "@onlineapps/conn-base-storage": "file:../conn-base-storage",
42
+ "amqplib": "^0.10.3",
43
+ "axios": "^1.5.0",
44
+ "dotenv": "^16.1.4",
45
+ "ioredis": "^5.3.2",
46
+ "joi": "^17.9.2",
47
+ "uuid": "^9.0.0"
48
+ },
49
+ "devDependencies": {
50
+ "@semantic-release/changelog": "^6.0.3",
51
+ "@semantic-release/commit-analyzer": "^11.1.0",
52
+ "@semantic-release/git": "^10.0.1",
53
+ "@semantic-release/npm": "^11.0.3",
54
+ "@semantic-release/release-notes-generator": "^12.1.0",
55
+ "eslint": "^8.44.0",
56
+ "eslint-config-airbnb-base": "^15.0.0",
57
+ "eslint-config-prettier": "^10.1.5",
58
+ "eslint-plugin-import": "^2.30.1",
59
+ "eslint-plugin-prettier": "^5.4.0",
60
+ "jest": "^29.6.1",
61
+ "semantic-release": "^22.0.12"
62
+ },
63
+ "engines": {
64
+ "node": ">=18"
65
+ }
66
+ }