cadenlane-cli-2 1.0.0
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/CHANGELOG.md +6 -0
- package/LICENSE +21 -0
- package/README.md +333 -0
- package/bin.js +2 -0
- package/dist/application/config/config.manager.d.ts +62 -0
- package/dist/application/config/config.manager.d.ts.map +1 -0
- package/dist/application/config/config.manager.js +146 -0
- package/dist/application/config/config.manager.js.map +1 -0
- package/dist/application/services/application.service.d.ts +35 -0
- package/dist/application/services/application.service.d.ts.map +1 -0
- package/dist/application/services/application.service.js +174 -0
- package/dist/application/services/application.service.js.map +1 -0
- package/dist/application/services/download.service.d.ts +27 -0
- package/dist/application/services/download.service.d.ts.map +1 -0
- package/dist/application/services/download.service.js +197 -0
- package/dist/application/services/download.service.js.map +1 -0
- package/dist/application/services/file-naming.service.d.ts +34 -0
- package/dist/application/services/file-naming.service.d.ts.map +1 -0
- package/dist/application/services/file-naming.service.js +142 -0
- package/dist/application/services/file-naming.service.js.map +1 -0
- package/dist/application/services/queue.service.d.ts +53 -0
- package/dist/application/services/queue.service.d.ts.map +1 -0
- package/dist/application/services/queue.service.js +82 -0
- package/dist/application/services/queue.service.js.map +1 -0
- package/dist/cli/commands/start.command.d.ts +39 -0
- package/dist/cli/commands/start.command.d.ts.map +1 -0
- package/dist/cli/commands/start.command.js +196 -0
- package/dist/cli/commands/start.command.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +86 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/domain/constants/config.constants.d.ts +54 -0
- package/dist/domain/constants/config.constants.d.ts.map +1 -0
- package/dist/domain/constants/config.constants.js +142 -0
- package/dist/domain/constants/config.constants.js.map +1 -0
- package/dist/domain/dtos/index.d.ts +4 -0
- package/dist/domain/dtos/index.d.ts.map +1 -0
- package/dist/domain/dtos/index.js +10 -0
- package/dist/domain/dtos/index.js.map +1 -0
- package/dist/domain/dtos/log-entry.dto.d.ts +15 -0
- package/dist/domain/dtos/log-entry.dto.d.ts.map +1 -0
- package/dist/domain/dtos/log-entry.dto.js +64 -0
- package/dist/domain/dtos/log-entry.dto.js.map +1 -0
- package/dist/domain/dtos/message.dto.d.ts +27 -0
- package/dist/domain/dtos/message.dto.d.ts.map +1 -0
- package/dist/domain/dtos/message.dto.js +140 -0
- package/dist/domain/dtos/message.dto.js.map +1 -0
- package/dist/domain/dtos/queue-message.dto.d.ts +10 -0
- package/dist/domain/dtos/queue-message.dto.d.ts.map +1 -0
- package/dist/domain/dtos/queue-message.dto.js +39 -0
- package/dist/domain/dtos/queue-message.dto.js.map +1 -0
- package/dist/domain/entities/cli-instance.entity.d.ts +55 -0
- package/dist/domain/entities/cli-instance.entity.d.ts.map +1 -0
- package/dist/domain/entities/cli-instance.entity.js +132 -0
- package/dist/domain/entities/cli-instance.entity.js.map +1 -0
- package/dist/domain/entities/index.d.ts +3 -0
- package/dist/domain/entities/index.d.ts.map +1 -0
- package/dist/domain/entities/index.js +8 -0
- package/dist/domain/entities/index.js.map +1 -0
- package/dist/domain/entities/log-entry.entity.d.ts +60 -0
- package/dist/domain/entities/log-entry.entity.d.ts.map +1 -0
- package/dist/domain/entities/log-entry.entity.js +101 -0
- package/dist/domain/entities/log-entry.entity.js.map +1 -0
- package/dist/domain/entities/message.entity.d.ts +64 -0
- package/dist/domain/entities/message.entity.d.ts.map +1 -0
- package/dist/domain/entities/message.entity.js +110 -0
- package/dist/domain/entities/message.entity.js.map +1 -0
- package/dist/domain/enums/error-category.enum.d.ts +11 -0
- package/dist/domain/enums/error-category.enum.d.ts.map +1 -0
- package/dist/domain/enums/error-category.enum.js +15 -0
- package/dist/domain/enums/error-category.enum.js.map +1 -0
- package/dist/domain/enums/index.d.ts +4 -0
- package/dist/domain/enums/index.d.ts.map +1 -0
- package/dist/domain/enums/index.js +10 -0
- package/dist/domain/enums/index.js.map +1 -0
- package/dist/domain/enums/log-level.enum.d.ts +11 -0
- package/dist/domain/enums/log-level.enum.d.ts.map +1 -0
- package/dist/domain/enums/log-level.enum.js +15 -0
- package/dist/domain/enums/log-level.enum.js.map +1 -0
- package/dist/domain/enums/message-status.enum.d.ts +11 -0
- package/dist/domain/enums/message-status.enum.d.ts.map +1 -0
- package/dist/domain/enums/message-status.enum.js +15 -0
- package/dist/domain/enums/message-status.enum.js.map +1 -0
- package/dist/domain/interfaces/adapters/ifilesystem.adapter.d.ts +34 -0
- package/dist/domain/interfaces/adapters/ifilesystem.adapter.d.ts.map +1 -0
- package/dist/domain/interfaces/adapters/ifilesystem.adapter.js +3 -0
- package/dist/domain/interfaces/adapters/ifilesystem.adapter.js.map +1 -0
- package/dist/domain/interfaces/adapters/ihttp.adapter.d.ts +22 -0
- package/dist/domain/interfaces/adapters/ihttp.adapter.d.ts.map +1 -0
- package/dist/domain/interfaces/adapters/ihttp.adapter.js +3 -0
- package/dist/domain/interfaces/adapters/ihttp.adapter.js.map +1 -0
- package/dist/domain/interfaces/adapters/index.d.ts +4 -0
- package/dist/domain/interfaces/adapters/index.d.ts.map +1 -0
- package/dist/domain/interfaces/adapters/index.js +3 -0
- package/dist/domain/interfaces/adapters/index.js.map +1 -0
- package/dist/domain/interfaces/adapters/isupabase.adapter.d.ts +27 -0
- package/dist/domain/interfaces/adapters/isupabase.adapter.d.ts.map +1 -0
- package/dist/domain/interfaces/adapters/isupabase.adapter.js +3 -0
- package/dist/domain/interfaces/adapters/isupabase.adapter.js.map +1 -0
- package/dist/domain/interfaces/repositories/ilog.repository.d.ts +32 -0
- package/dist/domain/interfaces/repositories/ilog.repository.d.ts.map +1 -0
- package/dist/domain/interfaces/repositories/ilog.repository.js +3 -0
- package/dist/domain/interfaces/repositories/ilog.repository.js.map +1 -0
- package/dist/domain/interfaces/repositories/imessage.repository.d.ts +39 -0
- package/dist/domain/interfaces/repositories/imessage.repository.d.ts.map +1 -0
- package/dist/domain/interfaces/repositories/imessage.repository.js +3 -0
- package/dist/domain/interfaces/repositories/imessage.repository.js.map +1 -0
- package/dist/domain/interfaces/repositories/index.d.ts +4 -0
- package/dist/domain/interfaces/repositories/index.d.ts.map +1 -0
- package/dist/domain/interfaces/repositories/index.js +3 -0
- package/dist/domain/interfaces/repositories/index.js.map +1 -0
- package/dist/domain/interfaces/repositories/iqueue.repository.d.ts +75 -0
- package/dist/domain/interfaces/repositories/iqueue.repository.d.ts.map +1 -0
- package/dist/domain/interfaces/repositories/iqueue.repository.js +3 -0
- package/dist/domain/interfaces/repositories/iqueue.repository.js.map +1 -0
- package/dist/domain/interfaces/services/idownload.service.d.ts +28 -0
- package/dist/domain/interfaces/services/idownload.service.d.ts.map +1 -0
- package/dist/domain/interfaces/services/idownload.service.js +3 -0
- package/dist/domain/interfaces/services/idownload.service.js.map +1 -0
- package/dist/domain/interfaces/services/iqueue.service.d.ts +35 -0
- package/dist/domain/interfaces/services/iqueue.service.d.ts.map +1 -0
- package/dist/domain/interfaces/services/iqueue.service.js +3 -0
- package/dist/domain/interfaces/services/iqueue.service.js.map +1 -0
- package/dist/domain/services/path-resolver.service.d.ts +94 -0
- package/dist/domain/services/path-resolver.service.d.ts.map +1 -0
- package/dist/domain/services/path-resolver.service.js +332 -0
- package/dist/domain/services/path-resolver.service.js.map +1 -0
- package/dist/domain/validators/index.d.ts +4 -0
- package/dist/domain/validators/index.d.ts.map +1 -0
- package/dist/domain/validators/index.js +10 -0
- package/dist/domain/validators/index.js.map +1 -0
- package/dist/domain/validators/message.validator.d.ts +20 -0
- package/dist/domain/validators/message.validator.d.ts.map +1 -0
- package/dist/domain/validators/message.validator.js +31 -0
- package/dist/domain/validators/message.validator.js.map +1 -0
- package/dist/domain/validators/path.validator.d.ts +44 -0
- package/dist/domain/validators/path.validator.d.ts.map +1 -0
- package/dist/domain/validators/path.validator.js +156 -0
- package/dist/domain/validators/path.validator.js.map +1 -0
- package/dist/domain/validators/url.validator.d.ts +19 -0
- package/dist/domain/validators/url.validator.d.ts.map +1 -0
- package/dist/domain/validators/url.validator.js +46 -0
- package/dist/domain/validators/url.validator.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/adapters/filesystem.adapter.d.ts +35 -0
- package/dist/infrastructure/adapters/filesystem.adapter.d.ts.map +1 -0
- package/dist/infrastructure/adapters/filesystem.adapter.js +103 -0
- package/dist/infrastructure/adapters/filesystem.adapter.js.map +1 -0
- package/dist/infrastructure/adapters/http.adapter.d.ts +15 -0
- package/dist/infrastructure/adapters/http.adapter.d.ts.map +1 -0
- package/dist/infrastructure/adapters/http.adapter.js +80 -0
- package/dist/infrastructure/adapters/http.adapter.js.map +1 -0
- package/dist/infrastructure/adapters/index.d.ts +4 -0
- package/dist/infrastructure/adapters/index.d.ts.map +1 -0
- package/dist/infrastructure/adapters/index.js +10 -0
- package/dist/infrastructure/adapters/index.js.map +1 -0
- package/dist/infrastructure/adapters/pgmq.adapter.d.ts +29 -0
- package/dist/infrastructure/adapters/pgmq.adapter.d.ts.map +1 -0
- package/dist/infrastructure/adapters/pgmq.adapter.js +84 -0
- package/dist/infrastructure/adapters/pgmq.adapter.js.map +1 -0
- package/dist/infrastructure/adapters/supabase.adapter.d.ts +79 -0
- package/dist/infrastructure/adapters/supabase.adapter.d.ts.map +1 -0
- package/dist/infrastructure/adapters/supabase.adapter.js +97 -0
- package/dist/infrastructure/adapters/supabase.adapter.js.map +1 -0
- package/dist/infrastructure/database/supabase.client.d.ts +20 -0
- package/dist/infrastructure/database/supabase.client.d.ts.map +1 -0
- package/dist/infrastructure/database/supabase.client.js +36 -0
- package/dist/infrastructure/database/supabase.client.js.map +1 -0
- package/dist/infrastructure/di/container.d.ts +18 -0
- package/dist/infrastructure/di/container.d.ts.map +1 -0
- package/dist/infrastructure/di/container.js +103 -0
- package/dist/infrastructure/di/container.js.map +1 -0
- package/dist/infrastructure/repositories/cli-instance.repository.d.ts +64 -0
- package/dist/infrastructure/repositories/cli-instance.repository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/cli-instance.repository.js +154 -0
- package/dist/infrastructure/repositories/cli-instance.repository.js.map +1 -0
- package/dist/infrastructure/repositories/config.repository.d.ts +52 -0
- package/dist/infrastructure/repositories/config.repository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/config.repository.js +130 -0
- package/dist/infrastructure/repositories/config.repository.js.map +1 -0
- package/dist/infrastructure/repositories/index.d.ts +4 -0
- package/dist/infrastructure/repositories/index.d.ts.map +1 -0
- package/dist/infrastructure/repositories/index.js +10 -0
- package/dist/infrastructure/repositories/index.js.map +1 -0
- package/dist/infrastructure/repositories/log.repository.d.ts +44 -0
- package/dist/infrastructure/repositories/log.repository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/log.repository.js +108 -0
- package/dist/infrastructure/repositories/log.repository.js.map +1 -0
- package/dist/infrastructure/repositories/message.repository.d.ts +51 -0
- package/dist/infrastructure/repositories/message.repository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/message.repository.js +161 -0
- package/dist/infrastructure/repositories/message.repository.js.map +1 -0
- package/dist/infrastructure/repositories/queue.repository.d.ts +69 -0
- package/dist/infrastructure/repositories/queue.repository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/queue.repository.js +130 -0
- package/dist/infrastructure/repositories/queue.repository.js.map +1 -0
- package/dist/infrastructure/utils/connection-health.util.d.ts +23 -0
- package/dist/infrastructure/utils/connection-health.util.d.ts.map +1 -0
- package/dist/infrastructure/utils/connection-health.util.js +64 -0
- package/dist/infrastructure/utils/connection-health.util.js.map +1 -0
- package/package.json +105 -0
- package/pm2.config.js +104 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.QueueRepository = void 0;
|
|
16
|
+
const tsyringe_1 = require("tsyringe");
|
|
17
|
+
const pgmq_adapter_1 = require("../adapters/pgmq.adapter");
|
|
18
|
+
/**
|
|
19
|
+
* Queue Repository
|
|
20
|
+
* Handles PGMQ queue operations using direct PostgreSQL connection
|
|
21
|
+
*/
|
|
22
|
+
let QueueRepository = class QueueRepository {
|
|
23
|
+
adapter;
|
|
24
|
+
constructor(adapter) {
|
|
25
|
+
this.adapter = adapter;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Reads a message from the queue (non-blocking)
|
|
29
|
+
* @param queueName - Name of the queue
|
|
30
|
+
* @param visibilityTimeoutSeconds - Visibility timeout in seconds
|
|
31
|
+
* @returns PGMQ message or null if queue is empty
|
|
32
|
+
*/
|
|
33
|
+
async readMessage(queueName, visibilityTimeoutSeconds) {
|
|
34
|
+
try {
|
|
35
|
+
const messages = await this.adapter.readMessage(queueName, visibilityTimeoutSeconds, 1);
|
|
36
|
+
return messages.length > 0 ? messages[0] : null;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new Error('Failed to read message from queue: ' + (error instanceof Error ? error.message : String(error)));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Reads a message from the queue with blocking poll (event-driven)
|
|
44
|
+
* Note: Not implemented with direct PG adapter - use readMessage instead
|
|
45
|
+
* @param queueName - Name of the queue
|
|
46
|
+
* @param visibilityTimeoutSeconds - Visibility timeout in seconds
|
|
47
|
+
* @param pollTimeoutSeconds - How long to wait for a message (default: 5s)
|
|
48
|
+
* @param pollIntervalMs - Internal polling interval (default: 250ms)
|
|
49
|
+
* @returns PGMQ message or null if timeout reached
|
|
50
|
+
*/
|
|
51
|
+
async readMessageWithPoll(queueName, visibilityTimeoutSeconds, _pollTimeoutSeconds = 5, _pollIntervalMs = 250) {
|
|
52
|
+
// Use simple read instead of blocking poll
|
|
53
|
+
return this.readMessage(queueName, visibilityTimeoutSeconds);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Deletes a message from the queue
|
|
57
|
+
* @param queueName - Name of the queue
|
|
58
|
+
* @param messageId - PGMQ message ID
|
|
59
|
+
* @returns true if deleted, false otherwise
|
|
60
|
+
*/
|
|
61
|
+
async deleteMessage(queueName, messageId) {
|
|
62
|
+
try {
|
|
63
|
+
return await this.adapter.deleteMessage(queueName, messageId);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw new Error('Failed to delete message from queue: ' + (error instanceof Error ? error.message : String(error)));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Sends a message to the queue
|
|
71
|
+
* @param queueName - Name of the queue
|
|
72
|
+
* @param message - Message to send
|
|
73
|
+
* @returns PGMQ message ID
|
|
74
|
+
*/
|
|
75
|
+
async sendMessage(queueName, message) {
|
|
76
|
+
try {
|
|
77
|
+
return await this.adapter.sendMessage(queueName, message);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
throw new Error('Failed to send message to queue: ' + (error instanceof Error ? error.message : String(error)));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Gets queue metrics
|
|
85
|
+
* @param queueName - Name of the queue
|
|
86
|
+
* @returns Queue metrics
|
|
87
|
+
*/
|
|
88
|
+
async getMetrics(_queueName) {
|
|
89
|
+
// Not implemented with direct PG adapter
|
|
90
|
+
throw new Error('getMetrics not implemented with direct PostgreSQL adapter');
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Creates a new queue (idempotent - safe to call if queue exists)
|
|
94
|
+
* @param queueName - Name of the queue to create
|
|
95
|
+
* @returns true if created or already exists
|
|
96
|
+
*/
|
|
97
|
+
async createQueue(queueName) {
|
|
98
|
+
try {
|
|
99
|
+
await this.adapter.createQueue(queueName);
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
104
|
+
// Queue already exists - this is OK (idempotent operation)
|
|
105
|
+
if (errorMessage.includes('already a member of extension') ||
|
|
106
|
+
errorMessage.includes('already exists')) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
throw new Error('Failed to create queue: ' + errorMessage);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Sends a message to a specific CLI instance queue
|
|
114
|
+
* @param baseQueueName - Base queue name (e.g., 'image_downloads')
|
|
115
|
+
* @param targetInstanceId - Target CLI instance ID
|
|
116
|
+
* @param message - Message to send
|
|
117
|
+
* @returns PGMQ message ID
|
|
118
|
+
*/
|
|
119
|
+
async sendMessageToInstance(baseQueueName, targetInstanceId, message) {
|
|
120
|
+
const instanceQueueName = `${baseQueueName}_${targetInstanceId}`;
|
|
121
|
+
return await this.sendMessage(instanceQueueName, message);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
exports.QueueRepository = QueueRepository;
|
|
125
|
+
exports.QueueRepository = QueueRepository = __decorate([
|
|
126
|
+
(0, tsyringe_1.injectable)(),
|
|
127
|
+
__param(0, (0, tsyringe_1.inject)(pgmq_adapter_1.PgmqAdapter)),
|
|
128
|
+
__metadata("design:paramtypes", [pgmq_adapter_1.PgmqAdapter])
|
|
129
|
+
], QueueRepository);
|
|
130
|
+
//# sourceMappingURL=queue.repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.repository.js","sourceRoot":"","sources":["../../../src/infrastructure/repositories/queue.repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
+
/**
|
|
3
|
+
* Connection Health Utility
|
|
4
|
+
* Validates database connectivity with timeout
|
|
5
|
+
*/
|
|
6
|
+
export declare class ConnectionHealthUtil {
|
|
7
|
+
/**
|
|
8
|
+
* Checks if Supabase connection is healthy
|
|
9
|
+
* @param client - Supabase client to test
|
|
10
|
+
* @param timeoutMs - Timeout in milliseconds (default: 5000)
|
|
11
|
+
* @returns true if connection is healthy, false otherwise
|
|
12
|
+
*/
|
|
13
|
+
static isHealthy(client: SupabaseClient, timeoutMs?: number): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Waits for connection to become healthy
|
|
16
|
+
* @param client - Supabase client to test
|
|
17
|
+
* @param maxRetries - Maximum number of retries (default: 3)
|
|
18
|
+
* @param retryDelayMs - Delay between retries in milliseconds (default: 1000)
|
|
19
|
+
* @returns true if connection became healthy, false otherwise
|
|
20
|
+
*/
|
|
21
|
+
static waitForHealthy(client: SupabaseClient, maxRetries?: number, retryDelayMs?: number): Promise<boolean>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=connection-health.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-health.util.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/utils/connection-health.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;;GAGG;AACH,qBAAa,oBAAoB;IAC/B;;;;;OAKG;WACU,SAAS,CACpB,MAAM,EAAE,cAAc,EACtB,SAAS,GAAE,MAAa,GACvB,OAAO,CAAC,OAAO,CAAC;IA+BnB;;;;;;OAMG;WACU,cAAc,CACzB,MAAM,EAAE,cAAc,EACtB,UAAU,GAAE,MAAU,EACtB,YAAY,GAAE,MAAa,GAC1B,OAAO,CAAC,OAAO,CAAC;CAepB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConnectionHealthUtil = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Connection Health Utility
|
|
6
|
+
* Validates database connectivity with timeout
|
|
7
|
+
*/
|
|
8
|
+
class ConnectionHealthUtil {
|
|
9
|
+
/**
|
|
10
|
+
* Checks if Supabase connection is healthy
|
|
11
|
+
* @param client - Supabase client to test
|
|
12
|
+
* @param timeoutMs - Timeout in milliseconds (default: 5000)
|
|
13
|
+
* @returns true if connection is healthy, false otherwise
|
|
14
|
+
*/
|
|
15
|
+
static async isHealthy(client, timeoutMs = 5000) {
|
|
16
|
+
try {
|
|
17
|
+
// Create timeout promise
|
|
18
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
19
|
+
setTimeout(() => {
|
|
20
|
+
resolve({ data: null, error: new Error('Connection timeout') });
|
|
21
|
+
}, timeoutMs);
|
|
22
|
+
});
|
|
23
|
+
// Create query promise
|
|
24
|
+
const queryPromise = client
|
|
25
|
+
.from('app_config')
|
|
26
|
+
.select('id')
|
|
27
|
+
.limit(1);
|
|
28
|
+
// Race between query and timeout
|
|
29
|
+
const result = await Promise.race([queryPromise, timeoutPromise]);
|
|
30
|
+
if (result.error) {
|
|
31
|
+
console.warn(`[ConnectionHealth] Database query failed: ${result.error.message}`);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
38
|
+
console.warn(`[ConnectionHealth] Connection check failed: ${message}`);
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Waits for connection to become healthy
|
|
44
|
+
* @param client - Supabase client to test
|
|
45
|
+
* @param maxRetries - Maximum number of retries (default: 3)
|
|
46
|
+
* @param retryDelayMs - Delay between retries in milliseconds (default: 1000)
|
|
47
|
+
* @returns true if connection became healthy, false otherwise
|
|
48
|
+
*/
|
|
49
|
+
static async waitForHealthy(client, maxRetries = 3, retryDelayMs = 1000) {
|
|
50
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
51
|
+
const healthy = await this.isHealthy(client);
|
|
52
|
+
if (healthy) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
if (i < maxRetries - 1) {
|
|
56
|
+
console.log(`[ConnectionHealth] Retry ${i + 1}/${maxRetries} in ${retryDelayMs}ms...`);
|
|
57
|
+
await new Promise(resolve => setTimeout(resolve, retryDelayMs));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.ConnectionHealthUtil = ConnectionHealthUtil;
|
|
64
|
+
//# sourceMappingURL=connection-health.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-health.util.js","sourceRoot":"","sources":["../../../src/infrastructure/utils/connection-health.util.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACH,MAAa,oBAAoB;IAC/B;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,SAAS,CACpB,MAAsB,EACtB,YAAoB,IAAI;QAExB,IAAI,CAAC;YACH,yBAAyB;YACzB,MAAM,cAAc,GAAG,IAAI,OAAO,CAA+B,CAAC,OAAO,EAAE,EAAE;gBAC3E,UAAU,CAAC,GAAG,EAAE;oBACd,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;gBAClE,CAAC,EAAE,SAAS,CAAC,CAAC;YAChB,CAAC,CAAC,CAAC;YAEH,uBAAuB;YACvB,MAAM,YAAY,GAAG,MAAM;iBACxB,IAAI,CAAC,YAAY,CAAC;iBAClB,MAAM,CAAC,IAAI,CAAC;iBACZ,KAAK,CAAC,CAAC,CAAC,CAAC;YAEZ,iCAAiC;YACjC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;YAElE,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC,6CAA6C,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAClF,OAAO,KAAK,CAAC;YACf,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACzE,OAAO,CAAC,IAAI,CAAC,+CAA+C,OAAO,EAAE,CAAC,CAAC;YACvE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,cAAc,CACzB,MAAsB,EACtB,aAAqB,CAAC,EACtB,eAAuB,IAAI;QAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,IAAI,CAAC;YACd,CAAC;YAED,IAAI,CAAC,GAAG,UAAU,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,GAAG,CAAC,IAAI,UAAU,OAAO,YAAY,OAAO,CAAC,CAAC;gBACvF,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAnED,oDAmEC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cadenlane-cli-2",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Production-ready, cross-platform TypeScript CLI for processing image downloads from Supabase PGMQ queue with multi-instance support",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"cadenlane-cli-2": "./bin.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/**/*",
|
|
12
|
+
"bin.js",
|
|
13
|
+
"pm2.config.js",
|
|
14
|
+
"README.md",
|
|
15
|
+
"CHANGELOG.md",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/Shiphero-Yolo/cadenlane-cli-2.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/Shiphero-Yolo/cadenlane-cli-2/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/Shiphero-Yolo/cadenlane-cli-2#readme",
|
|
26
|
+
"scripts": {
|
|
27
|
+
"dev": "ts-node -r tsconfig-paths/register src/index.ts start",
|
|
28
|
+
"build": "npm run clean && tsc && tsc-alias",
|
|
29
|
+
"clean": "rimraf dist",
|
|
30
|
+
"prepublishOnly": "npm run test && npm run build",
|
|
31
|
+
"start": "node dist/index.js start",
|
|
32
|
+
"start:build": "npm run build && node dist/index.js start",
|
|
33
|
+
"test": "jest",
|
|
34
|
+
"test:unit": "jest --testPathPattern=tests/unit",
|
|
35
|
+
"test:unit:coverage": "jest --testPathPattern=tests/unit --coverage",
|
|
36
|
+
"test:integration": "jest --testPathPattern=tests/integration",
|
|
37
|
+
"test:e2e": "jest --config jest.e2e.config.ts --runInBand",
|
|
38
|
+
"test:watch": "jest --watch",
|
|
39
|
+
"test:coverage": "jest --coverage",
|
|
40
|
+
"coverage:check": "jest --coverage --coverageThreshold='{\"global\":{\"statements\":90,\"branches\":85,\"functions\":90,\"lines\":90}}'",
|
|
41
|
+
"lint": "eslint src tests --ext .ts",
|
|
42
|
+
"lint:fix": "eslint src tests --ext .ts --fix",
|
|
43
|
+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
44
|
+
"type-check": "tsc --noEmit",
|
|
45
|
+
"pm2:start": "npm run build && pm2 start ecosystem.config.js",
|
|
46
|
+
"pm2:stop": "pm2 stop ecosystem.config.js",
|
|
47
|
+
"pm2:restart": "pm2 restart ecosystem.config.js",
|
|
48
|
+
"pm2:reload": "pm2 reload ecosystem.config.js",
|
|
49
|
+
"pm2:delete": "pm2 delete ecosystem.config.js",
|
|
50
|
+
"pm2:logs": "pm2 logs cli-base-worker",
|
|
51
|
+
"pm2:monit": "pm2 monit",
|
|
52
|
+
"pm2:status": "pm2 status"
|
|
53
|
+
},
|
|
54
|
+
"keywords": [
|
|
55
|
+
"cli",
|
|
56
|
+
"image-download",
|
|
57
|
+
"supabase",
|
|
58
|
+
"pgmq",
|
|
59
|
+
"queue",
|
|
60
|
+
"typescript",
|
|
61
|
+
"cross-platform",
|
|
62
|
+
"multi-instance",
|
|
63
|
+
"event-driven",
|
|
64
|
+
"automation",
|
|
65
|
+
"worker",
|
|
66
|
+
"distributed"
|
|
67
|
+
],
|
|
68
|
+
"author": "Caden Lane",
|
|
69
|
+
"license": "MIT",
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"@automapper/classes": "^8.8.1",
|
|
72
|
+
"@automapper/core": "^8.8.1",
|
|
73
|
+
"@supabase/supabase-js": "^2.55.0",
|
|
74
|
+
"@types/pg": "^8.15.6",
|
|
75
|
+
"axios": "^1.12.2",
|
|
76
|
+
"class-transformer": "^0.5.1",
|
|
77
|
+
"class-validator": "^0.14.0",
|
|
78
|
+
"commander": "^11.0.0",
|
|
79
|
+
"dotenv": "^17.2.1",
|
|
80
|
+
"pg": "^8.16.3",
|
|
81
|
+
"reflect-metadata": "^0.1.14",
|
|
82
|
+
"tsyringe": "^4.8.0"
|
|
83
|
+
},
|
|
84
|
+
"devDependencies": {
|
|
85
|
+
"@jest/globals": "^29.7.0",
|
|
86
|
+
"@types/jest": "^29.5.0",
|
|
87
|
+
"@types/node": "^20.0.0",
|
|
88
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
89
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
90
|
+
"eslint": "^9.39.2",
|
|
91
|
+
"jest": "^29.7.0",
|
|
92
|
+
"jest-mock-extended": "^3.0.5",
|
|
93
|
+
"pm2": "^6.0.13",
|
|
94
|
+
"prettier": "^3.0.0",
|
|
95
|
+
"rimraf": "^6.0.1",
|
|
96
|
+
"ts-jest": "^29.1.0",
|
|
97
|
+
"ts-node": "^10.9.0",
|
|
98
|
+
"tsc-alias": "^1.8.16",
|
|
99
|
+
"tsconfig-paths": "^4.2.0",
|
|
100
|
+
"typescript": "^5.0.0"
|
|
101
|
+
},
|
|
102
|
+
"engines": {
|
|
103
|
+
"node": ">=18.0.0"
|
|
104
|
+
}
|
|
105
|
+
}
|
package/pm2.config.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PM2 Ecosystem Configuration for cadenlane CLI
|
|
3
|
+
*
|
|
4
|
+
* This configuration is designed for global npm installations.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* pm2 start pm2.config.js
|
|
8
|
+
* pm2 save
|
|
9
|
+
* pm2 startup
|
|
10
|
+
*
|
|
11
|
+
* For custom configuration, copy this file and modify as needed:
|
|
12
|
+
* cp $(npm root -g)/cadenlane-cli-2/pm2.config.js ~/cadenlane-cli-2-pm2.config.js
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const os = require('os');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
|
|
18
|
+
// Get home directory for cross-platform compatibility
|
|
19
|
+
const homeDir = os.homedir();
|
|
20
|
+
const logsDir = path.join(homeDir, '.cadenlane-cli-2', 'logs');
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
apps: [{
|
|
24
|
+
name: 'cadenlane-worker',
|
|
25
|
+
// Use the compiled JS file directly for better Windows compatibility
|
|
26
|
+
script: path.join(__dirname, 'dist', 'cli', 'index.js'),
|
|
27
|
+
args: 'start',
|
|
28
|
+
|
|
29
|
+
// Process configuration
|
|
30
|
+
instances: 1,
|
|
31
|
+
exec_mode: 'fork',
|
|
32
|
+
autorestart: true,
|
|
33
|
+
watch: false,
|
|
34
|
+
max_memory_restart: '500M',
|
|
35
|
+
|
|
36
|
+
// Environment
|
|
37
|
+
env: {
|
|
38
|
+
NODE_ENV: 'production',
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
// Logging configuration
|
|
42
|
+
error_file: path.join(logsDir, 'pm2-error.log'),
|
|
43
|
+
out_file: path.join(logsDir, 'pm2-out.log'),
|
|
44
|
+
log_file: path.join(logsDir, 'pm2-combined.log'),
|
|
45
|
+
time: true,
|
|
46
|
+
merge_logs: true,
|
|
47
|
+
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
|
48
|
+
|
|
49
|
+
// Restart configuration
|
|
50
|
+
min_uptime: '10s',
|
|
51
|
+
max_restarts: 10,
|
|
52
|
+
|
|
53
|
+
// Advanced features
|
|
54
|
+
kill_timeout: 5000,
|
|
55
|
+
wait_ready: false,
|
|
56
|
+
listen_timeout: 3000,
|
|
57
|
+
|
|
58
|
+
// Custom actions for PM2.io dashboard
|
|
59
|
+
actions: [
|
|
60
|
+
{
|
|
61
|
+
action_name: 'stop-worker',
|
|
62
|
+
action_type: 'internal',
|
|
63
|
+
description: 'Stop the worker process',
|
|
64
|
+
command: 'pm2',
|
|
65
|
+
args: ['stop', 'cadenlane-worker']
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
action_name: 'restart-worker',
|
|
69
|
+
action_type: 'internal',
|
|
70
|
+
description: 'Restart the worker process',
|
|
71
|
+
command: 'pm2',
|
|
72
|
+
args: ['restart', 'cadenlane-worker']
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
action_name: 'view-logs',
|
|
76
|
+
action_type: 'internal',
|
|
77
|
+
description: 'View last 50 lines of logs',
|
|
78
|
+
command: 'pm2',
|
|
79
|
+
args: ['logs', 'cadenlane-worker', '--lines', '50']
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
action_name: 'flush-logs',
|
|
83
|
+
action_type: 'internal',
|
|
84
|
+
description: 'Clear all PM2 logs',
|
|
85
|
+
command: 'pm2',
|
|
86
|
+
args: ['flush', 'cadenlane-worker']
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
action_name: 'reload-env',
|
|
90
|
+
action_type: 'internal',
|
|
91
|
+
description: 'Reload environment variables',
|
|
92
|
+
command: 'pm2',
|
|
93
|
+
args: ['restart', 'cadenlane-worker', '--update-env']
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
action_name: 'update-package',
|
|
97
|
+
action_type: 'internal',
|
|
98
|
+
description: 'Update to latest npm package version',
|
|
99
|
+
command: 'npm',
|
|
100
|
+
args: ['install', '-g', 'cadenlane-cli-2@latest']
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
}],
|
|
104
|
+
};
|