@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,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
19
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
20
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
21
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
22
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
23
|
+
var _, done = false;
|
|
24
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
25
|
+
var context = {};
|
|
26
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
27
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
28
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
29
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
30
|
+
if (kind === "accessor") {
|
|
31
|
+
if (result === void 0) continue;
|
|
32
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
33
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
34
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
35
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
36
|
+
}
|
|
37
|
+
else if (_ = accept(result)) {
|
|
38
|
+
if (kind === "field") initializers.unshift(_);
|
|
39
|
+
else descriptor[key] = _;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
43
|
+
done = true;
|
|
44
|
+
};
|
|
45
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
46
|
+
var useValue = arguments.length > 2;
|
|
47
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
48
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
49
|
+
}
|
|
50
|
+
return useValue ? value : void 0;
|
|
51
|
+
};
|
|
52
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
53
|
+
var ownKeys = function(o) {
|
|
54
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
55
|
+
var ar = [];
|
|
56
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
57
|
+
return ar;
|
|
58
|
+
};
|
|
59
|
+
return ownKeys(o);
|
|
60
|
+
};
|
|
61
|
+
return function (mod) {
|
|
62
|
+
if (mod && mod.__esModule) return mod;
|
|
63
|
+
var result = {};
|
|
64
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
65
|
+
__setModuleDefault(result, mod);
|
|
66
|
+
return result;
|
|
67
|
+
};
|
|
68
|
+
})();
|
|
69
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
70
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
71
|
+
};
|
|
72
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
73
|
+
exports.ScriptExecutor = void 0;
|
|
74
|
+
const fs = __importStar(require("node:fs"));
|
|
75
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
76
|
+
const vm = __importStar(require("node:vm"));
|
|
77
|
+
const global_logger_1 = require("../../../client/logger/global-logger");
|
|
78
|
+
const logger_decorator_1 = require("../../../client/logger/logger.decorator");
|
|
79
|
+
const handler_models_1 = require("../../../client/models/handler-models");
|
|
80
|
+
const base_request_handler_command_1 = require("./base-request-handler-command");
|
|
81
|
+
let ScriptExecutor = (() => {
|
|
82
|
+
let _classDecorators = [(0, logger_decorator_1.Log)()];
|
|
83
|
+
let _classDescriptor;
|
|
84
|
+
let _classExtraInitializers = [];
|
|
85
|
+
let _classThis;
|
|
86
|
+
let _classSuper = base_request_handler_command_1.BaseRequestHandlerCommand;
|
|
87
|
+
var ScriptExecutor = class extends _classSuper {
|
|
88
|
+
static { _classThis = this; }
|
|
89
|
+
static {
|
|
90
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
91
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
92
|
+
ScriptExecutor = _classThis = _classDescriptor.value;
|
|
93
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
94
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
95
|
+
}
|
|
96
|
+
constructor() {
|
|
97
|
+
super();
|
|
98
|
+
}
|
|
99
|
+
init(opts) {
|
|
100
|
+
super.init(opts);
|
|
101
|
+
const path = opts.script;
|
|
102
|
+
if (!path) {
|
|
103
|
+
throw new Error('Script path is required');
|
|
104
|
+
}
|
|
105
|
+
this.log.info(`Loading script from: ${path}`);
|
|
106
|
+
try {
|
|
107
|
+
const handler = new ScriptHandler(path);
|
|
108
|
+
this.setHandler(handler);
|
|
109
|
+
this.log.info(`Script ${handler.handlerType} loaded successfully !`);
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
this.log.error(`Failed to load script: ${e.message}`);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
return ScriptExecutor = _classThis;
|
|
118
|
+
})();
|
|
119
|
+
exports.ScriptExecutor = ScriptExecutor;
|
|
120
|
+
class ScriptHandler {
|
|
121
|
+
path;
|
|
122
|
+
method;
|
|
123
|
+
handlerType = 'method';
|
|
124
|
+
constructor(path) {
|
|
125
|
+
this.path = path;
|
|
126
|
+
this.loadScript(this.path);
|
|
127
|
+
}
|
|
128
|
+
connected() {
|
|
129
|
+
return Promise.resolve();
|
|
130
|
+
}
|
|
131
|
+
disconnected() {
|
|
132
|
+
return Promise.resolve();
|
|
133
|
+
}
|
|
134
|
+
handle(request) {
|
|
135
|
+
return new Promise((resolve, reject) => {
|
|
136
|
+
if (!this.method) {
|
|
137
|
+
return reject(new Error('Method not loaded'));
|
|
138
|
+
}
|
|
139
|
+
const responseFactory = {
|
|
140
|
+
ok: (message, code = 200) => {
|
|
141
|
+
return handler_models_1.WebhookResult.success(message, code);
|
|
142
|
+
},
|
|
143
|
+
error: (message, code = 500) => {
|
|
144
|
+
return handler_models_1.WebhookResult.failure(message, code);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
try {
|
|
148
|
+
const result = this.method(request, responseFactory);
|
|
149
|
+
if (result instanceof Promise) {
|
|
150
|
+
result.then(resolve).catch(reject);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
resolve(result);
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
reject(e);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
loadScript(path) {
|
|
161
|
+
const basePath = process.cwd() + '/' + path;
|
|
162
|
+
if (!fs.existsSync(basePath)) {
|
|
163
|
+
throw new Error(`Script file not found at path: ${basePath}`);
|
|
164
|
+
}
|
|
165
|
+
const scriptContent = fs.readFileSync(basePath, 'utf-8');
|
|
166
|
+
const scriptHeaderRegex = /^\/\/@wookster\/(\w+):?(\w+)?$/m;
|
|
167
|
+
const headerMatch = scriptContent.match(scriptHeaderRegex);
|
|
168
|
+
if (!headerMatch) {
|
|
169
|
+
throw new Error(SCRIPT_MISSING_ERROR);
|
|
170
|
+
}
|
|
171
|
+
const scriptType = headerMatch[1];
|
|
172
|
+
const scriptOption = headerMatch[2] || '';
|
|
173
|
+
if (scriptType !== 'method' && scriptType !== 'file') {
|
|
174
|
+
throw new Error(`Unsupported script type: ${scriptType}. Supported types are 'method' and 'file',\n\n${SCRIPT_MISSING_ERROR}`);
|
|
175
|
+
}
|
|
176
|
+
this.handlerType = scriptType;
|
|
177
|
+
if (scriptType === 'method') {
|
|
178
|
+
this.loadMethodScript(scriptContent, basePath, scriptOption);
|
|
179
|
+
}
|
|
180
|
+
else if (scriptType === 'file') {
|
|
181
|
+
this.loadFileScript(scriptContent, basePath);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
getConsoleProxy(name) {
|
|
185
|
+
const logger = (0, global_logger_1.generateLogService)(name);
|
|
186
|
+
function argsToString(args) {
|
|
187
|
+
return args.map(arg => {
|
|
188
|
+
if (typeof arg === 'string') {
|
|
189
|
+
return arg;
|
|
190
|
+
}
|
|
191
|
+
else if (typeof arg === 'object') {
|
|
192
|
+
try {
|
|
193
|
+
return JSON.stringify(arg);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return String(arg);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
return String(arg);
|
|
201
|
+
}
|
|
202
|
+
}).join(' ');
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
log: (...args) => logger.info(argsToString(args)),
|
|
206
|
+
info: (...args) => logger.info(argsToString(args)),
|
|
207
|
+
warn: (...args) => logger.warn(argsToString(args)),
|
|
208
|
+
error: (...args) => logger.error(argsToString(args)),
|
|
209
|
+
debug: (...args) => logger.debug(argsToString(args)),
|
|
210
|
+
trace: (...args) => logger.debug(argsToString(args)),
|
|
211
|
+
dir: (obj) => logger.debug(JSON.stringify(obj, null, 2)),
|
|
212
|
+
assert: (condition, ...args) => {
|
|
213
|
+
if (!condition) {
|
|
214
|
+
logger.error('Assertion failed: ' + args.join(' '));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
loadMethodScript(scriptContent, basePath, methodName) {
|
|
220
|
+
if (!methodName || methodName.trim() === '') {
|
|
221
|
+
methodName = 'handle';
|
|
222
|
+
}
|
|
223
|
+
const script = new vm.Script(scriptContent, { filename: basePath });
|
|
224
|
+
const filename = node_path_1.default.basename(basePath);
|
|
225
|
+
const console = this.getConsoleProxy(filename);
|
|
226
|
+
const context = vm.createContext({ console: console, exports: {}, require, module: {} });
|
|
227
|
+
script.runInContext(context);
|
|
228
|
+
const exported = context.exports;
|
|
229
|
+
if (exported && typeof exported[methodName] === 'function') {
|
|
230
|
+
console.debug(`Loaded method from exports: ${methodName}`);
|
|
231
|
+
this.method = exported[methodName];
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
else if (typeof context[methodName] === 'function') {
|
|
235
|
+
console.debug(`Loaded method from context: ${methodName}`);
|
|
236
|
+
this.method = context[methodName];
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
throw new Error(`Method ${methodName} not found in script`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
loadFileScript(scriptContent, basePath) {
|
|
244
|
+
// for file scripts, we expect the script to export a function named 'handle'
|
|
245
|
+
const script = new vm.Script(scriptContent, { filename: basePath });
|
|
246
|
+
const filename = node_path_1.default.basename(basePath);
|
|
247
|
+
this.method = (request) => {
|
|
248
|
+
let result;
|
|
249
|
+
const middlewareFactory = {
|
|
250
|
+
ok: (message, code = 200) => {
|
|
251
|
+
if (!result) {
|
|
252
|
+
result = handler_models_1.WebhookResult.success(message, code);
|
|
253
|
+
}
|
|
254
|
+
return result;
|
|
255
|
+
},
|
|
256
|
+
error: (message, code = 500) => {
|
|
257
|
+
if (!result) {
|
|
258
|
+
result = handler_models_1.WebhookResult.failure(message, code);
|
|
259
|
+
}
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
const context = vm.createContext({ console: this.getConsoleProxy(filename), require, request: request, response: middlewareFactory });
|
|
264
|
+
script.runInContext(context);
|
|
265
|
+
if (!result) {
|
|
266
|
+
throw new Error('Script did not return a response. Please use response.ok() or response.error() to return a response.');
|
|
267
|
+
}
|
|
268
|
+
return result;
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const SCRIPT_MISSING_ERROR = `Script file is missing required header.
|
|
273
|
+
Please add a header in the following format at the top of your script file:
|
|
274
|
+
//@wookster/method:<function_name>
|
|
275
|
+
or
|
|
276
|
+
//@wookster/file
|
|
277
|
+
|
|
278
|
+
Ex:
|
|
279
|
+
//@wookster/method:handle
|
|
280
|
+
|
|
281
|
+
function handle(request, response) {
|
|
282
|
+
// your code here
|
|
283
|
+
return response.ok('Request handled successfully');
|
|
284
|
+
}
|
|
285
|
+
`;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.execute = execute;
|
|
4
|
+
const node_timers_1 = require("node:timers");
|
|
5
|
+
const fromEvent_1 = require("rxjs/internal/observable/fromEvent");
|
|
6
|
+
const method_request_handler_1 = require("../../client/handlers/method.request-handler");
|
|
7
|
+
const global_logger_1 = require("../../client/logger/global-logger");
|
|
8
|
+
const noop_logger_1 = require("../../client/logger/noop.logger");
|
|
9
|
+
const handler_models_1 = require("../../client/models/handler-models");
|
|
10
|
+
const request_handler_service_1 = require("../../client/services/request-handler.service");
|
|
11
|
+
async function execute() {
|
|
12
|
+
(0, global_logger_1.setGlobalLogger)(noop_logger_1.NoopLogger);
|
|
13
|
+
const mainLogger = (0, global_logger_1.generateLogService)('main');
|
|
14
|
+
mainLogger.info(`Starting client at ${new Date().toISOString()}`);
|
|
15
|
+
const service = new request_handler_service_1.RequestHandlerService({
|
|
16
|
+
worker: 'worker-f35a23c047df44b29d7d7d316a5a4aa7',
|
|
17
|
+
apiKey: '6g5ZE0CH.ZjTnaGKAp0Vg8It6DrKmdfceziPwx8Sy',
|
|
18
|
+
serverUrl: 'ws://localhost:8080/virtual-hooks',
|
|
19
|
+
});
|
|
20
|
+
service.setHandler(new method_request_handler_1.MethodRequestHandler((request) => {
|
|
21
|
+
mainLogger.info('Received request:', request);
|
|
22
|
+
return Promise.resolve(handler_models_1.WebhookResult.success());
|
|
23
|
+
}));
|
|
24
|
+
(0, fromEvent_1.fromEvent)(process, 'SIGINT').subscribe(async () => {
|
|
25
|
+
mainLogger.info('Received SIGINT, shutting down...');
|
|
26
|
+
await service.destroy();
|
|
27
|
+
process.exit(0);
|
|
28
|
+
});
|
|
29
|
+
service.start();
|
|
30
|
+
(0, node_timers_1.setInterval)(() => { }, 5000);
|
|
31
|
+
}
|
package/dist/cli/env.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getEnvVarNames = getEnvVarNames;
|
|
4
|
+
exports.getEnvVar = getEnvVar;
|
|
5
|
+
exports.saveAsEnv = saveAsEnv;
|
|
6
|
+
exports.getEnv = getEnv;
|
|
7
|
+
const ENV_AVAILABLE_VARS = ['WOOKSTER_URL', 'WOOKSTER_API_KEY', 'WOOKSTER_WORKER_ID', 'WOOKSTER_LOGGER', 'WOOKSTER_VERBOSE'];
|
|
8
|
+
const globalSavedEnv = {};
|
|
9
|
+
function getEnvVarNames() {
|
|
10
|
+
return ENV_AVAILABLE_VARS;
|
|
11
|
+
}
|
|
12
|
+
function getEnvVar(key) {
|
|
13
|
+
const savedData = globalSavedEnv[key];
|
|
14
|
+
if (savedData) {
|
|
15
|
+
return savedData;
|
|
16
|
+
}
|
|
17
|
+
return process.env[key];
|
|
18
|
+
}
|
|
19
|
+
function saveAsEnv(key, value) {
|
|
20
|
+
globalSavedEnv[key] = value;
|
|
21
|
+
}
|
|
22
|
+
function getEnv() {
|
|
23
|
+
const env = {};
|
|
24
|
+
for (const key of ENV_AVAILABLE_VARS) {
|
|
25
|
+
env[key] = process.env[key];
|
|
26
|
+
}
|
|
27
|
+
return env;
|
|
28
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.globalOptionApplier = globalOptionApplier;
|
|
4
|
+
const global_logger_1 = require("../client/logger/global-logger");
|
|
5
|
+
const json_logger_1 = require("../client/logger/json.logger");
|
|
6
|
+
const logger_service_1 = require("../client/logger/logger-service");
|
|
7
|
+
const noop_logger_1 = require("../client/logger/noop.logger");
|
|
8
|
+
const pretty_logger_1 = require("../client/logger/pretty.logger");
|
|
9
|
+
const env_1 = require("./env");
|
|
10
|
+
function setLoggerFromType(logger) {
|
|
11
|
+
if (!logger) {
|
|
12
|
+
logger = (0, env_1.getEnvVar)('WOOKSTER_LOGGER') ?? 'pretty';
|
|
13
|
+
}
|
|
14
|
+
switch (logger) {
|
|
15
|
+
case 'json':
|
|
16
|
+
(0, global_logger_1.setGlobalLogger)(json_logger_1.JsonLogger);
|
|
17
|
+
break;
|
|
18
|
+
case 'pretty':
|
|
19
|
+
(0, global_logger_1.setGlobalLogger)(pretty_logger_1.PrettyLogger);
|
|
20
|
+
break;
|
|
21
|
+
case 'noop':
|
|
22
|
+
(0, global_logger_1.setGlobalLogger)(noop_logger_1.NoopLogger);
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
throw new Error(`Unknown logger type: ${logger}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function globalOptionApplier(command) {
|
|
29
|
+
const opts = command.opts();
|
|
30
|
+
if (opts.verbose) {
|
|
31
|
+
(0, logger_service_1.allowSeverity)('debug');
|
|
32
|
+
}
|
|
33
|
+
setLoggerFromType(opts.logger);
|
|
34
|
+
(0, env_1.saveAsEnv)('WOOKSTER_API_KEY', opts.apiKey);
|
|
35
|
+
(0, env_1.saveAsEnv)('WOOKSTER_URL', opts.serverUrl);
|
|
36
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.globalOptionApplier = globalOptionApplier;
|
|
37
|
+
function setLoggerFromType(logger) {
|
|
38
|
+
switch (logger) {
|
|
39
|
+
case 'json':
|
|
40
|
+
Promise.resolve().then(() => __importStar(require('../client/logger/json.logger'))).then(module => {
|
|
41
|
+
const { setGlobalLogger } = require('../client/logger/global-logger');
|
|
42
|
+
setGlobalLogger(module.JsonLogger);
|
|
43
|
+
});
|
|
44
|
+
break;
|
|
45
|
+
case 'pretty':
|
|
46
|
+
Promise.resolve().then(() => __importStar(require('../client/logger/pretty.logger'))).then(module => {
|
|
47
|
+
const { setGlobalLogger } = require('../client/logger/global-logger');
|
|
48
|
+
setGlobalLogger(module.PrettyLogger);
|
|
49
|
+
});
|
|
50
|
+
break;
|
|
51
|
+
case 'noop':
|
|
52
|
+
Promise.resolve().then(() => __importStar(require('../client/logger/noop.logger'))).then(module => {
|
|
53
|
+
const { setGlobalLogger } = require('../client/logger/global-logger');
|
|
54
|
+
setGlobalLogger(module.NoopLogger);
|
|
55
|
+
});
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
throw new Error(`Unknown logger type: ${logger}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function globalOptionApplier(command) {
|
|
62
|
+
const opts = command.opts();
|
|
63
|
+
if (opts.verbose) {
|
|
64
|
+
const { allowSeverity } = require('../client/logger/logger-service');
|
|
65
|
+
allowSeverity('debug');
|
|
66
|
+
}
|
|
67
|
+
if (opts.logger) {
|
|
68
|
+
setLoggerFromType(opts.logger);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const base_request_handler_command_1 = require("./commands/listener/base-request-handler-command");
|
|
6
|
+
const proxy_executor_1 = require("./commands/listener/proxy-executor");
|
|
7
|
+
const script_executor_1 = require("./commands/listener/script-executor");
|
|
8
|
+
const global_option_applier_1 = require("./global-option-applier");
|
|
9
|
+
const program = new commander_1.Command();
|
|
10
|
+
program
|
|
11
|
+
.name('wookster')
|
|
12
|
+
.description('CLI for Wookster Virtual Hooks')
|
|
13
|
+
.version('0.0.1');
|
|
14
|
+
program.hook('preAction', global_option_applier_1.globalOptionApplier);
|
|
15
|
+
//global actions:
|
|
16
|
+
program.addOption(new commander_1.Option('--verbose').default(false, 'Enable verbose logging'));
|
|
17
|
+
program.addOption(new commander_1.Option('--logger <type>', "Specify logger type").choices(['json', 'pretty', 'noop']));
|
|
18
|
+
program.addOption(new commander_1.Option('-k, --api-key <apiKey>', "Api key for authentication"));
|
|
19
|
+
program.addOption(new commander_1.Option('-u, --server-url <serverUrl>', 'Server URL to connect to'));
|
|
20
|
+
program
|
|
21
|
+
.command('execute')
|
|
22
|
+
.description('Start a virtual hook client and execute a provided script for each request')
|
|
23
|
+
.requiredOption("-w, --worker <worker>", 'Worker identifier to process requests')
|
|
24
|
+
.requiredOption('-s, --script <script>', 'Path to the script to execute for each request')
|
|
25
|
+
.action(async (options) => {
|
|
26
|
+
(0, base_request_handler_command_1.runCommand)(script_executor_1.ScriptExecutor, options);
|
|
27
|
+
});
|
|
28
|
+
program
|
|
29
|
+
.command('proxy')
|
|
30
|
+
.description('Start a virtual hook client and proxy request to another server')
|
|
31
|
+
.requiredOption('-w, --worker <worker>', 'Worker identifier to process requests')
|
|
32
|
+
.requiredOption('-t, --target <target>', 'Target url to proxy webhook request (http.s)')
|
|
33
|
+
.action(async (argument) => {
|
|
34
|
+
(0, base_request_handler_command_1.runCommand)(proxy_executor_1.ProxyExecutor, argument);
|
|
35
|
+
});
|
|
36
|
+
program.parseAsync();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rxEventCounter = rxEventCounter;
|
|
4
|
+
const of_1 = require("rxjs/internal/observable/of");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
function rxEventCounter(counts, timeSpan) {
|
|
7
|
+
return (0, operators_1.switchMap)((source) => {
|
|
8
|
+
return (0, of_1.of)(source).pipe((0, operators_1.map)(() => new Date().getTime()), (0, operators_1.bufferCount)(counts, 1), (0, operators_1.filter)((timestamps) => {
|
|
9
|
+
return timestamps[0] > new Date().getTime() - timeSpan;
|
|
10
|
+
}));
|
|
11
|
+
});
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseRequestHandler = void 0;
|
|
4
|
+
class BaseRequestHandler {
|
|
5
|
+
connected() {
|
|
6
|
+
return Promise.resolve();
|
|
7
|
+
}
|
|
8
|
+
disconnected() {
|
|
9
|
+
return Promise.resolve();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.BaseRequestHandler = BaseRequestHandler;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MethodRequestHandler = void 0;
|
|
4
|
+
const base_request_handler_1 = require("./base.request-handler");
|
|
5
|
+
class MethodRequestHandler extends base_request_handler_1.BaseRequestHandler {
|
|
6
|
+
method;
|
|
7
|
+
constructor(method) {
|
|
8
|
+
super();
|
|
9
|
+
this.method = method;
|
|
10
|
+
}
|
|
11
|
+
handle(request) {
|
|
12
|
+
return this.method(request);
|
|
13
|
+
}
|
|
14
|
+
static from(method) {
|
|
15
|
+
return new MethodRequestHandler(method);
|
|
16
|
+
}
|
|
17
|
+
static forObject(object, methodName) {
|
|
18
|
+
const method = object[methodName];
|
|
19
|
+
if (typeof method !== 'function') {
|
|
20
|
+
throw new Error(`Property ${String(methodName)} is not a function on the provided object`);
|
|
21
|
+
}
|
|
22
|
+
return new MethodRequestHandler((request) => {
|
|
23
|
+
return method.call(object, request);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.MethodRequestHandler = MethodRequestHandler;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MultiRequestHandler = void 0;
|
|
4
|
+
const handler_models_1 = require("../models/handler-models");
|
|
5
|
+
const base_request_handler_1 = require("./base.request-handler");
|
|
6
|
+
class MultiRequestHandler extends base_request_handler_1.BaseRequestHandler {
|
|
7
|
+
handlers;
|
|
8
|
+
constructor(handlers) {
|
|
9
|
+
super();
|
|
10
|
+
this.handlers = handlers;
|
|
11
|
+
}
|
|
12
|
+
async handle(request) {
|
|
13
|
+
for (const handler of this.handlers) {
|
|
14
|
+
await handler.handle(request);
|
|
15
|
+
}
|
|
16
|
+
return handler_models_1.WebhookResult.success();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.MultiRequestHandler = MultiRequestHandler;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MethodRequestHandler = void 0;
|
|
4
|
+
const base_request_handler_1 = require("./base.request-handler");
|
|
5
|
+
const handler_models_1 = require("../models/handler-models");
|
|
6
|
+
/**
|
|
7
|
+
* A request handler that converts incoming requests into events on an RxJS Subject.
|
|
8
|
+
* /!\ Note that the handler always returns a successful WebhookResult, regardless of whether there are subscribers to the Subject or not.
|
|
9
|
+
*/
|
|
10
|
+
class MethodRequestHandler extends base_request_handler_1.BaseRequestHandler {
|
|
11
|
+
subject;
|
|
12
|
+
constructor(subject) {
|
|
13
|
+
super();
|
|
14
|
+
this.subject = subject;
|
|
15
|
+
}
|
|
16
|
+
handle(request) {
|
|
17
|
+
this.subject.next(request);
|
|
18
|
+
return Promise.resolve(handler_models_1.WebhookResult.success());
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.MethodRequestHandler = MethodRequestHandler;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.globalLogger = void 0;
|
|
4
|
+
exports.getGlobalLogger = getGlobalLogger;
|
|
5
|
+
exports.setGlobalLogger = setGlobalLogger;
|
|
6
|
+
exports.generateLogService = generateLogService;
|
|
7
|
+
const logger_service_1 = require("./logger-service");
|
|
8
|
+
let __globalLogger;
|
|
9
|
+
let __globalLoggerService;
|
|
10
|
+
function getGlobalLogger() {
|
|
11
|
+
return __globalLogger;
|
|
12
|
+
}
|
|
13
|
+
function setGlobalLogger(logger) {
|
|
14
|
+
if (typeof logger === 'function') {
|
|
15
|
+
logger = new logger();
|
|
16
|
+
}
|
|
17
|
+
__globalLogger = logger;
|
|
18
|
+
__globalLoggerService = generateLogService();
|
|
19
|
+
}
|
|
20
|
+
function generateLogService(source) {
|
|
21
|
+
return new logger_service_1.LogService(getGlobalLogger(), source || 'global');
|
|
22
|
+
}
|
|
23
|
+
const globalLogger = () => {
|
|
24
|
+
if (!__globalLoggerService) {
|
|
25
|
+
__globalLoggerService = generateLogService();
|
|
26
|
+
}
|
|
27
|
+
return Object.freeze(__globalLoggerService);
|
|
28
|
+
};
|
|
29
|
+
exports.globalLogger = globalLogger;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JsonLogger = void 0;
|
|
4
|
+
class JsonLogger {
|
|
5
|
+
mapping = {
|
|
6
|
+
timestamp: 'timestamp',
|
|
7
|
+
severity: 'level',
|
|
8
|
+
source: 'source',
|
|
9
|
+
message: 'message',
|
|
10
|
+
context: 'context'
|
|
11
|
+
};
|
|
12
|
+
constructor(mapping) {
|
|
13
|
+
if (mapping) {
|
|
14
|
+
this.mapping = { ...this.mapping, ...mapping };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
log(log) {
|
|
18
|
+
const result = {};
|
|
19
|
+
result[this.mapping.timestamp] = log.timestamp.toISOString();
|
|
20
|
+
result[this.mapping.severity] = log.severity;
|
|
21
|
+
result[this.mapping.source] = log.source;
|
|
22
|
+
result[this.mapping.message] = log.message;
|
|
23
|
+
if (Object.keys(log.context).length) {
|
|
24
|
+
result[this.mapping.context] = log.context;
|
|
25
|
+
}
|
|
26
|
+
console.log(JSON.stringify(result));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.JsonLogger = JsonLogger;
|