123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- import WebSocket from 'ws';
-
- /**
- * Uses the webhook proxy service to proxy events to the testing clients.
- */
- export default class WebhookProxy {
- private url;
- private secret;
- private ws: WebSocket | undefined;
- private cache = new Map();
- private listeners = new Map();
- private consumers = new Map();
-
- /**
- * Initializes the webhook proxy.
- * @param url
- * @param secret
- */
- constructor(url: string, secret: string) {
- this.url = url;
- this.secret = secret;
- }
-
- /**
- * Connects.
- */
- connect() {
- this.ws = new WebSocket(this.url, {
- headers: {
- Authorization: this.secret
- }
- });
-
- this.ws.on('error', console.error);
-
- this.ws.on('open', function open() {
- console.log('WebhookProxy connected');
- });
-
- this.ws.on('message', (data: any) => {
- const msg = JSON.parse(data.toString());
-
- if (msg.eventType) {
- if (this.consumers.has(msg.eventType)) {
- this.consumers.get(msg.eventType)(msg);
- this.consumers.delete(msg.eventType);
- } else {
- this.cache.set(msg.eventType, msg);
- }
-
- if (this.listeners.has(msg.eventType)) {
- this.listeners.get(msg.eventType)(msg);
- }
- }
- });
- }
-
- /**
- * Adds event consumer. Consumers receive the event single time and we remove them from the list of consumers.
- * @param eventType
- * @param callback
- */
- addConsumer(eventType: string, callback: (deventata: any) => void) {
- if (this.cache.has(eventType)) {
- callback(this.cache.get(eventType));
- this.cache.delete(eventType);
-
- return;
- }
-
- this.consumers.set(eventType, callback);
- }
-
- /**
- * Clear any stored event.
- */
- clearCache() {
- this.cache.clear();
- }
-
- /**
- * Waits for the event to be received.
- * @param eventType
- * @param timeout
- */
- async waitForEvent(eventType: string, timeout = 4000): Promise<any> {
- // we create the error here so we have a meaningful stack trace
- const error = new Error(`Timeout waiting for event:${eventType}`);
-
- return new Promise((resolve, reject) => {
- const waiter = setTimeout(() => reject(error), timeout);
-
- this.addConsumer(eventType, event => {
- clearTimeout(waiter);
-
- resolve(event);
- });
-
- });
- }
-
- /**
- * Adds a listener for the event type.
- * @param eventType
- * @param callback
- */
- addListener(eventType: string, callback: (data: any) => void) {
- this.listeners.set(eventType, callback);
- }
-
- /**
- * Adds a listener for the event type.
- * @param eventType
- */
- removeListener(eventType: string) {
- this.listeners.delete(eventType);
- }
-
- /**
- * Disconnects the webhook proxy.
- */
- disconnect() {
- if (this.ws) {
- this.ws.close();
- console.log('WebhookProxy disconnected');
- this.ws = undefined;
- }
- }
- }
|