UNPKG

cloudworker-proxy

Version:
136 lines (116 loc) 3.83 kB
'use strict'; /** * Connection */ const WebSocket = require('ws'); class Connection { constructor(sdk) { this.sdk = sdk; this.connection = null; this.context = {}; } isConnected() { return !!this.connection; } /** * Connects to websockets and returns the connection with event handlers .on('open', 'message', 'error') */ async connect(options) { if (options.orgUid) { this.sdk.context.orgUid = options.orgUid; } // Validate org if (!this.sdk.context.orgUid) { throw new Error('You must specify an "orgUid" to connect'); } // Sanitize filter options.filter = options.filter || {}; options.filter.stageName = options.filter.stageName ? options.filter.stageName.trim() : null; options.filter.appName = options.filter.appName ? options.filter.appName.trim() : null; options.filter.instanceName = options.filter.instanceName ? options.filter.instanceName.trim() : null; // Connect let queryParams = `?accessKey=${this.sdk.accessKey}&orgUid=${this.sdk.context.orgUid}&`; queryParams += `filter=${encodeURIComponent(JSON.stringify(options.filter))}`; const domain = this.sdk.getDomain('events-streaming') + queryParams; this.connection = new WebSocket(domain); // Handle message event if (options.onEvent) { this.connection.on('message', (message) => { const decodedMessage = Buffer.from(message, 'base64').toString(); const data = JSON.parse(decodedMessage); return options.onEvent(data); }); } // Handle disconnect event if (options.onDisconnect) { this.connection.on('close', (code, reason) => { return options.onDisconnect(code, reason); }); } return new Promise((resolve, reject) => { // Error handler for errors that don't have an unexpected response this.connection.on('error', (error) => { const e = new Error(`Unexpected Serverless Platform Streaming Error: ${error.message}`); e.detail = error; return reject(e); }); this.connection.on('open', () => { return resolve(); }); }); } /** * Terminates the websockets connection */ disconnect() { if (this.connection) { this.connection.close(); this.connection = null; } } /** * Sends a message via the websockets connection. Validation should be handled in sdk.publish() * event format: * { * orgUid, * accessKey, * data * } */ send(event) { // Validate if (!event) { throw new Error('An "event" is required'); } if (typeof event !== 'object') { throw new Error('The "event" argument must be an object'); } if (!event.event || typeof event.event !== 'string') { throw new Error( 'The "event" property containing the event type is required and must be a string' ); } // Convert to a safe Serverless Platform Event const safeEvent = {}; safeEvent.accessKey = this.sdk.accessKey; safeEvent.event = event.event.trim(); safeEvent.orgUid = event.orgUid || this.sdk.context.orgUid; safeEvent.stageName = this.sdk.context.stageName; safeEvent.appName = this.sdk.context.appName; safeEvent.instanceName = this.sdk.context.instanceName; safeEvent.componentName = this.sdk.context.componentName; safeEvent.componentVersion = this.sdk.context.componentVersion; safeEvent.data = event.data || {}; // Store createdAt date safeEvent.data.createdAt = Date.now(); // Validate if (!safeEvent.orgUid) { throw new Error('event must have an "orgUid"'); } const encodedData = Buffer.from(JSON.stringify(safeEvent)).toString('base64'); this.connection.send(encodedData); } } module.exports = Connection;