@wooch-tickets/wookster-cli 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/README.md +15 -0
- package/dist/cli/base-command.js +29 -0
- package/dist/cli/commands/base-command.js +29 -0
- package/dist/cli/commands/listener/base-command.js +100 -0
- package/dist/cli/commands/listener/base-request-handler-command.js +106 -0
- package/dist/cli/commands/listener/proxy-executor.js +130 -0
- package/dist/cli/commands/listener/script-executor.js +285 -0
- package/dist/cli/commands/script-executor.js +31 -0
- package/dist/cli/env.js +28 -0
- package/dist/cli/global-option-applier.js +36 -0
- package/dist/cli/global-option-parsing.js +70 -0
- package/dist/cli/index.js +36 -0
- package/dist/cli/rx-event-counter.js +12 -0
- package/dist/client/handlers/base.request-handler.js +12 -0
- package/dist/client/handlers/method.request-handler.js +27 -0
- package/dist/client/handlers/multi.request-handler.js +19 -0
- package/dist/client/handlers/subject.request-handler.js +21 -0
- package/dist/client/logger/global-logger.js +29 -0
- package/dist/client/logger/json.logger.js +29 -0
- package/dist/client/logger/log.js +2 -0
- package/dist/client/logger/logger-service.js +90 -0
- package/dist/client/logger/logger.decorator.js +29 -0
- package/dist/client/logger/noop.logger.js +9 -0
- package/dist/client/logger/pretty.logger.js +56 -0
- package/dist/client/models/handler-models.js +21 -0
- package/dist/client/models/webhook-request.js +23 -0
- package/dist/client/services/request-handler.service.js +226 -0
- package/dist/index.js +28 -0
- package/package.json +43 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LogService = void 0;
|
|
4
|
+
exports.allowSeverity = allowSeverity;
|
|
5
|
+
exports.disallowSeverity = disallowSeverity;
|
|
6
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
|
+
const global_logger_1 = require("./global-logger");
|
|
8
|
+
const allowedSeverities = ['info', 'warn', 'error'];
|
|
9
|
+
function allowSeverity(severity) {
|
|
10
|
+
if (!allowedSeverities.includes(severity)) {
|
|
11
|
+
allowedSeverities.push(severity);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function disallowSeverity(severity) {
|
|
15
|
+
const index = allowedSeverities.indexOf(severity);
|
|
16
|
+
if (index !== -1) {
|
|
17
|
+
allowedSeverities.splice(index, 1);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
class LogService {
|
|
21
|
+
logger;
|
|
22
|
+
source;
|
|
23
|
+
messageQueue = [];
|
|
24
|
+
constructor(logger, source) {
|
|
25
|
+
this.logger = logger;
|
|
26
|
+
this.source = source;
|
|
27
|
+
}
|
|
28
|
+
info(message, context = {}) {
|
|
29
|
+
this.sendToLogger('info', message, context);
|
|
30
|
+
}
|
|
31
|
+
warn(message, context = {}) {
|
|
32
|
+
this.sendToLogger('warn', message, context);
|
|
33
|
+
}
|
|
34
|
+
error(message, context = {}) {
|
|
35
|
+
this.sendToLogger('error', message, context);
|
|
36
|
+
}
|
|
37
|
+
debug(message, context = {}) {
|
|
38
|
+
this.sendToLogger('debug', message, context);
|
|
39
|
+
}
|
|
40
|
+
sendToLogger(severity, message, context) {
|
|
41
|
+
const log = {
|
|
42
|
+
severity: severity,
|
|
43
|
+
source: this.source || 'unknown',
|
|
44
|
+
message: this.tryReplace(message, context),
|
|
45
|
+
timestamp: new Date(),
|
|
46
|
+
context
|
|
47
|
+
};
|
|
48
|
+
this.ensureLoggerState(log);
|
|
49
|
+
this.log(log);
|
|
50
|
+
}
|
|
51
|
+
log(log) {
|
|
52
|
+
if (allowedSeverities.includes(log.severity)) {
|
|
53
|
+
this.logger.log(log);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
tryReplace(message, context) {
|
|
57
|
+
for (const key in context) {
|
|
58
|
+
const placeholder = `{${key}}`;
|
|
59
|
+
if (message.includes(placeholder)) {
|
|
60
|
+
message = message.replace(placeholder, String(context[key]));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return message;
|
|
64
|
+
}
|
|
65
|
+
ensureLoggerState(log = null) {
|
|
66
|
+
if (this.logger) {
|
|
67
|
+
if (this.messageQueue.length) {
|
|
68
|
+
for (const queuedLog of this.messageQueue) {
|
|
69
|
+
this.log(queuedLog);
|
|
70
|
+
}
|
|
71
|
+
this.messageQueue = [];
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const globalLogger = (0, global_logger_1.getGlobalLogger)();
|
|
76
|
+
if (!globalLogger) {
|
|
77
|
+
if (log) {
|
|
78
|
+
this.messageQueue.push(log);
|
|
79
|
+
if (this.messageQueue.length > 5) {
|
|
80
|
+
console.error(`Please set a global logger, you are losing log messages in ${this.source}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
this.logger = globalLogger;
|
|
85
|
+
}
|
|
86
|
+
flushQueue() {
|
|
87
|
+
this.ensureLoggerState();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.LogService = LogService;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WithLogger = void 0;
|
|
4
|
+
exports.Log = Log;
|
|
5
|
+
const global_logger_1 = require("./global-logger");
|
|
6
|
+
const logger_service_1 = require("./logger-service");
|
|
7
|
+
/*
|
|
8
|
+
* Add a logger to the class, accessible in this.log
|
|
9
|
+
*/
|
|
10
|
+
function Log(loggerName) {
|
|
11
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
12
|
+
return function (constructor) {
|
|
13
|
+
const name = loggerName ?? constructor.name;
|
|
14
|
+
const service = new logger_service_1.LogService((0, global_logger_1.getGlobalLogger)(), name);
|
|
15
|
+
service.debug(`Logger for ${name} created successfully`);
|
|
16
|
+
return class extends constructor {
|
|
17
|
+
log = service;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/*
|
|
22
|
+
* Structure for logger type
|
|
23
|
+
*/
|
|
24
|
+
class WithLogger {
|
|
25
|
+
log;
|
|
26
|
+
constructor() {
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.WithLogger = WithLogger;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PrettyLogger = void 0;
|
|
4
|
+
const LOG_TEMPLATE = '{timestamp} {severity} -- {source} : {message} {context}';
|
|
5
|
+
class PrettyLogger {
|
|
6
|
+
color;
|
|
7
|
+
template;
|
|
8
|
+
constructor(color = true, template = LOG_TEMPLATE) {
|
|
9
|
+
this.color = color;
|
|
10
|
+
this.template = template;
|
|
11
|
+
}
|
|
12
|
+
log(log) {
|
|
13
|
+
const timestamp = log.timestamp.toISOString();
|
|
14
|
+
let severity = this.prettySeverity(log.severity);
|
|
15
|
+
const source = this.prettySource(log.source);
|
|
16
|
+
const message = log.message;
|
|
17
|
+
const context = Object.keys(log.context).length ? JSON.stringify(log.context) : '';
|
|
18
|
+
if (this.color) {
|
|
19
|
+
switch (log.severity) {
|
|
20
|
+
case 'info':
|
|
21
|
+
severity = `\x1b[32m${severity}\x1b[0m`; // Green
|
|
22
|
+
break;
|
|
23
|
+
case 'warn':
|
|
24
|
+
severity = `\x1b[33m${severity}\x1b[0m`; // Yellow
|
|
25
|
+
break;
|
|
26
|
+
case 'error':
|
|
27
|
+
severity = `\x1b[31m${severity}\x1b[0m`; // Red
|
|
28
|
+
break;
|
|
29
|
+
case 'debug':
|
|
30
|
+
severity = `\x1b[34m${severity}\x1b[0m`; // Blue
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const formattedLog = this.template
|
|
35
|
+
.replace('{timestamp}', timestamp)
|
|
36
|
+
.replace('{severity}', severity)
|
|
37
|
+
.replace('{source}', source)
|
|
38
|
+
.replace('{message}', message)
|
|
39
|
+
.replace('{context}', context);
|
|
40
|
+
console.log(formattedLog);
|
|
41
|
+
}
|
|
42
|
+
prettySource(source) {
|
|
43
|
+
const maxLength = 30;
|
|
44
|
+
if (source.length > maxLength) {
|
|
45
|
+
return source.substring(source.length - maxLength);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return source.padEnd(maxLength, ' ');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//severity with fixed width (max 5 chars)
|
|
52
|
+
prettySeverity(severity) {
|
|
53
|
+
return severity.toUpperCase().padStart(5, ' ');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.PrettyLogger = PrettyLogger;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebhookResult = void 0;
|
|
4
|
+
class WebhookResult {
|
|
5
|
+
code;
|
|
6
|
+
message;
|
|
7
|
+
state = 'success';
|
|
8
|
+
executionTime;
|
|
9
|
+
constructor(state, code, message) {
|
|
10
|
+
this.state = state;
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.message = message;
|
|
13
|
+
}
|
|
14
|
+
static success(message = 'OK', code = 200) {
|
|
15
|
+
return new WebhookResult('success', code, message);
|
|
16
|
+
}
|
|
17
|
+
static failure(message = 'Error', code = 500) {
|
|
18
|
+
return new WebhookResult('failure', code, message);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.WebhookResult = WebhookResult;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebhookRequest = void 0;
|
|
4
|
+
/*
|
|
5
|
+
Model for a webhook request
|
|
6
|
+
*/
|
|
7
|
+
class WebhookRequest {
|
|
8
|
+
id;
|
|
9
|
+
method;
|
|
10
|
+
body;
|
|
11
|
+
headers;
|
|
12
|
+
type;
|
|
13
|
+
signature;
|
|
14
|
+
constructor(data) {
|
|
15
|
+
this.id = data.id;
|
|
16
|
+
this.method = data.method;
|
|
17
|
+
this.body = data.body;
|
|
18
|
+
this.headers = data.headers;
|
|
19
|
+
this.type = data.type;
|
|
20
|
+
this.signature = data.signature;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.WebhookRequest = WebhookRequest;
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.RequestHandlerService = void 0;
|
|
41
|
+
const rx_stomp_1 = require("@stomp/rx-stomp");
|
|
42
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
43
|
+
const logger_decorator_1 = require("../logger/logger.decorator");
|
|
44
|
+
const handler_models_1 = require("../models/handler-models");
|
|
45
|
+
const webhook_request_1 = require("../models/webhook-request");
|
|
46
|
+
function assertExists(object, key) {
|
|
47
|
+
const value = object[key];
|
|
48
|
+
(0, node_assert_1.default)(value !== undefined && value !== null, `Missing required property: ${String(key)}`);
|
|
49
|
+
if (typeof value === 'string') {
|
|
50
|
+
(0, node_assert_1.default)(value.trim().length > 0, `Property ${String(key)} cannot be an empty string`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const WEBHOOK_QUEUE = '/queue/worker/webhook_request';
|
|
54
|
+
const WEBHOOK_RESPONSE_CHANNEL = '/messages/worker/webhook-request/{requestId}';
|
|
55
|
+
let RequestHandlerService = (() => {
|
|
56
|
+
let _classDecorators = [(0, logger_decorator_1.Log)()];
|
|
57
|
+
let _classDescriptor;
|
|
58
|
+
let _classExtraInitializers = [];
|
|
59
|
+
let _classThis;
|
|
60
|
+
let _classSuper = logger_decorator_1.WithLogger;
|
|
61
|
+
var RequestHandlerService = class extends _classSuper {
|
|
62
|
+
static { _classThis = this; }
|
|
63
|
+
static {
|
|
64
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
65
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
66
|
+
RequestHandlerService = _classThis = _classDescriptor.value;
|
|
67
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
68
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
69
|
+
}
|
|
70
|
+
options;
|
|
71
|
+
handler;
|
|
72
|
+
client;
|
|
73
|
+
tunnelSub;
|
|
74
|
+
listenerSub;
|
|
75
|
+
intervalHandle;
|
|
76
|
+
constructor(options) {
|
|
77
|
+
super();
|
|
78
|
+
(0, node_assert_1.default)(options, 'RequestHandlerService requires options');
|
|
79
|
+
assertExists(options, 'worker');
|
|
80
|
+
assertExists(options, 'apiKey');
|
|
81
|
+
assertExists(options, 'serverUrl');
|
|
82
|
+
this.options = options;
|
|
83
|
+
this.handler = options.handler;
|
|
84
|
+
this.client = new rx_stomp_1.RxStomp();
|
|
85
|
+
const connectHeaders = {
|
|
86
|
+
'api-key': this.options.apiKey
|
|
87
|
+
};
|
|
88
|
+
if (options.worker) {
|
|
89
|
+
connectHeaders['worker'] = options.worker;
|
|
90
|
+
}
|
|
91
|
+
this.client.configure({
|
|
92
|
+
reconnectTimeMode: rx_stomp_1.ReconnectionTimeMode.LINEAR,
|
|
93
|
+
maxReconnectDelay: 10000,
|
|
94
|
+
brokerURL: this.options.serverUrl,
|
|
95
|
+
connectHeaders: connectHeaders,
|
|
96
|
+
reconnectDelay: 1000,
|
|
97
|
+
beforeConnect: () => {
|
|
98
|
+
this.log.info('Connecting to server...');
|
|
99
|
+
return Promise.resolve();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
setHandler(handler) {
|
|
104
|
+
this.handler = handler;
|
|
105
|
+
}
|
|
106
|
+
start() {
|
|
107
|
+
if (!this.handler) {
|
|
108
|
+
throw new Error('Cannot start RequestHandlerService without a handler set');
|
|
109
|
+
}
|
|
110
|
+
this.tunnelSub = this.client.connected$.subscribe({
|
|
111
|
+
next: async (state) => {
|
|
112
|
+
this.log.debug(`Connection state changed: ${rx_stomp_1.RxStompState[state]}`);
|
|
113
|
+
switch (state) {
|
|
114
|
+
case rx_stomp_1.RxStompState.OPEN:
|
|
115
|
+
this.log.info('Connected to server');
|
|
116
|
+
await this.handler.connected();
|
|
117
|
+
break;
|
|
118
|
+
case rx_stomp_1.RxStompState.CLOSED:
|
|
119
|
+
await this.handler.disconnected();
|
|
120
|
+
this.log.info('Disconnected from server');
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
this.client.webSocketErrors$.subscribe({
|
|
126
|
+
next: (error) => {
|
|
127
|
+
//try to reconnect on websocket errors
|
|
128
|
+
this.log.error(`Tunnel error, client disconnected ....${error}`);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
this.client.stompErrors$.subscribe({
|
|
132
|
+
next: (frame) => {
|
|
133
|
+
if (frame.headers['message']) {
|
|
134
|
+
if (frame.headers['message'].includes('Failed to send message')) {
|
|
135
|
+
//forbidden, likely bad api key
|
|
136
|
+
this.log.error(`Error, forbidden access to the ressource. Please check your API key and worker ID.`);
|
|
137
|
+
this.reportError({ type: 'connection', level: 'fatal', message: 'Forbidden access to the resource, likely due to invalid API key or worker ID' });
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
this.log.error(`STOMP Error: ${frame.body}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
this.listenerSub = this.client.watch(`${WEBHOOK_QUEUE}/${this.options.worker}`).subscribe(async (message) => {
|
|
147
|
+
if (!this.handler) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
let payload;
|
|
151
|
+
try {
|
|
152
|
+
payload = JSON.parse(message.body);
|
|
153
|
+
payload = new webhook_request_1.WebhookRequest(payload);
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
this.sendState('unknown', handler_models_1.WebhookResult.failure('Invalid request payload'));
|
|
157
|
+
this.log.error(`Received invalid request payload: ${error.message}`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const startTime = Date.now();
|
|
161
|
+
try {
|
|
162
|
+
this.log.debug('Processing request ' + payload.id);
|
|
163
|
+
this.ackMessage(payload.id);
|
|
164
|
+
const result = await this.handler.handle(payload);
|
|
165
|
+
result.executionTime = Date.now() - startTime;
|
|
166
|
+
this.sendState(payload.id, result);
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
this.log.error(`Error processing request ${payload.id}: ${error.message}`);
|
|
170
|
+
const result = handler_models_1.WebhookResult.failure(error.message);
|
|
171
|
+
result.executionTime = Date.now() - startTime;
|
|
172
|
+
this.sendState(payload.id, result);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
this.log.info('Starting Outbound tunnel...');
|
|
176
|
+
this.client.activate();
|
|
177
|
+
this.intervalHandle = setInterval(async () => {
|
|
178
|
+
if (this.client.connected()) {
|
|
179
|
+
this.log.debug('Connection is healthy');
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
this.log.warn('Connection is not healthy, attempting to reconnect...');
|
|
183
|
+
await this.client.deactivate({ force: true });
|
|
184
|
+
this.client.activate();
|
|
185
|
+
this.log.info("Reconnection attempt initiated");
|
|
186
|
+
}
|
|
187
|
+
}, 5000);
|
|
188
|
+
}
|
|
189
|
+
async destroy(force = false) {
|
|
190
|
+
this.tunnelSub?.unsubscribe();
|
|
191
|
+
await this.client.deactivate({ force: force });
|
|
192
|
+
this.intervalHandle?.close();
|
|
193
|
+
}
|
|
194
|
+
ackMessage(requestId) {
|
|
195
|
+
this.log.debug('Sending ack for request ' + requestId);
|
|
196
|
+
this.client.publish({ destination: WEBHOOK_RESPONSE_CHANNEL.replace('{requestId}', requestId), body: JSON.stringify({ type: 'ack' }) });
|
|
197
|
+
}
|
|
198
|
+
sendState(requestId, result) {
|
|
199
|
+
this.log.debug('Sending result for request ' + requestId + ': ' + result.state, result);
|
|
200
|
+
const destination = WEBHOOK_RESPONSE_CHANNEL.replace('{requestId}', requestId);
|
|
201
|
+
this.client.publish({
|
|
202
|
+
destination, body: JSON.stringify({
|
|
203
|
+
type: 'response',
|
|
204
|
+
data: {
|
|
205
|
+
state: result.state,
|
|
206
|
+
message: result.message,
|
|
207
|
+
code: result.code,
|
|
208
|
+
executionTime: result.executionTime
|
|
209
|
+
}
|
|
210
|
+
})
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
//error
|
|
214
|
+
errorHandler;
|
|
215
|
+
setErrorHandler(handler) {
|
|
216
|
+
this.errorHandler = handler;
|
|
217
|
+
}
|
|
218
|
+
reportError(error) {
|
|
219
|
+
if (this.errorHandler) {
|
|
220
|
+
this.errorHandler(error);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
return RequestHandlerService = _classThis;
|
|
225
|
+
})();
|
|
226
|
+
exports.RequestHandlerService = RequestHandlerService;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const node_timers_1 = require("node:timers");
|
|
4
|
+
const fromEvent_1 = require("rxjs/internal/observable/fromEvent");
|
|
5
|
+
const method_request_handler_1 = require("./client/handlers/method.request-handler");
|
|
6
|
+
const global_logger_1 = require("./client/logger/global-logger");
|
|
7
|
+
const pretty_logger_1 = require("./client/logger/pretty.logger");
|
|
8
|
+
const handler_models_1 = require("./client/models/handler-models");
|
|
9
|
+
const request_handler_service_1 = require("./client/services/request-handler.service");
|
|
10
|
+
(0, global_logger_1.setGlobalLogger)(pretty_logger_1.PrettyLogger);
|
|
11
|
+
const mainLogger = (0, global_logger_1.generateLogService)('main');
|
|
12
|
+
mainLogger.info(`Starting client at ${new Date().toISOString()}`);
|
|
13
|
+
const service = new request_handler_service_1.RequestHandlerService({
|
|
14
|
+
worker: 'worker-f35a23c047df44b29d7d7d316a5a4aa7',
|
|
15
|
+
apiKey: '6g5ZE0CH.ZjTnaGKAp0Vg8It6DrKmdfceziPwx8Sy',
|
|
16
|
+
serverUrl: 'ws://localhost:8080/virtual-hooks',
|
|
17
|
+
});
|
|
18
|
+
service.
|
|
19
|
+
(new method_request_handler_1.MethodRequestHandler((request) => {
|
|
20
|
+
mainLogger.info('Received request:', request);
|
|
21
|
+
return Promise.resolve(handler_models_1.WebhookResult.success());
|
|
22
|
+
}));
|
|
23
|
+
(0, fromEvent_1.fromEvent)(process, 'SIGINT').subscribe(async () => {
|
|
24
|
+
mainLogger.info('Received SIGINT, shutting down...');
|
|
25
|
+
await service.destroy();
|
|
26
|
+
process.exit(0);
|
|
27
|
+
});
|
|
28
|
+
(0, node_timers_1.setInterval)(() => { }, 5000);
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wooch-tickets/wookster-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A TypeScript cli library for connecting to Wookster's services",
|
|
5
|
+
"peerDependencies": {
|
|
6
|
+
"typescript": "^5"
|
|
7
|
+
},
|
|
8
|
+
"type": "commonjs",
|
|
9
|
+
"bin": {
|
|
10
|
+
"wookster": "./dist/cli/index.js"
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/cli/index.js",
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsc --watch",
|
|
16
|
+
"start:dev": "concurrently \"npm run dev\" \"nodemon --watch 'dist/**/*.js' --exec 'node' dist/cli/index.js\"",
|
|
17
|
+
"lint": "eslint src/**/*.ts --fix",
|
|
18
|
+
"prepublishOnly": "npm run lint && npm run build"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@sindresorhus/tsconfig": "^8.1.0",
|
|
22
|
+
"@stomp/rx-stomp": "^2.3.0",
|
|
23
|
+
"commander": "^14.0.2",
|
|
24
|
+
"prettier": "^3.7.4",
|
|
25
|
+
"rxjs": "^7.8.2",
|
|
26
|
+
"ws": "^8.18.3"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@eslint/js": "^9.39.2",
|
|
30
|
+
"@types/eslint": "^9.6.1",
|
|
31
|
+
"@types/node": "^25.0.3",
|
|
32
|
+
"@types/ws": "^8.5.4",
|
|
33
|
+
"concurrently": "^9.2.1",
|
|
34
|
+
"eslint": "^8.57.1",
|
|
35
|
+
"globals": "^16.5.0",
|
|
36
|
+
"nodemon": "^3.1.11",
|
|
37
|
+
"typescript": "^5.9.3",
|
|
38
|
+
"typescript-eslint": "^8.51.0"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist"
|
|
42
|
+
]
|
|
43
|
+
}
|