UNPKG

actionhero

Version:

actionhero.js is a multi-transport API Server with integrated cluster capabilities and delayed tasks

162 lines (161 loc) 5.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Server = void 0; const events_1 = require("events"); const connection_1 = require("./connection"); const actionProcessor_1 = require("./actionProcessor"); const index_1 = require("../index"); const log_1 = require("../modules/log"); /** * Create a new Actionhero Server. The required properties of an server. These can be defined statically (this.name) or as methods which return a value. */ class Server extends events_1.EventEmitter { constructor() { super(); this.options = {}; this.attributes = {}; this.config = {}; // will be applied by the initializer this.connectionCustomMethods = {}; const defaultAttributes = this.defaultAttributes(); for (const key in defaultAttributes) { if (!this.attributes[key]) { this.attributes[key] = defaultAttributes[key]; } if (typeof this.attributes[key] === "function") { this.attributes[key] = this[key](); } } } defaultAttributes() { return { type: null, canChat: true, logConnections: true, logExits: true, sendWelcomeMessage: true, verbs: [], }; } validate() { if (!this.type) { throw new Error("type is required for this server"); } [ "start", "stop", "sendFile", "sendMessage", "goodbye", ].forEach((method) => { if (!this[method] || typeof this[method] !== "function") { throw new Error(`${method} is a required method for the server \`${this.type}\``); } }); } /** * * Build a the Actionhero.Connection from the raw parts provided by the server. * ```js *this.buildConnection({ * rawConnection: { * req: req, * res: res, * params: {}, * method: method, * cookies: cookies, * responseHeaders: responseHeaders, * responseHttpCode: responseHttpCode, * parsedURL: parsedURL * }, * id: fingerprint + '-' + uuid.v4(), * fingerprint: fingerprint, * remoteAddress: remoteIP, * remotePort: remotePort *}) * ``` */ async buildConnection(data) { const details = { type: this.type, id: data.id, remotePort: data.remotePort, remoteIP: data.remoteAddress, rawConnection: data.rawConnection, messageId: data.messageId, canChat: null, fingerprint: null, }; if (this.attributes.canChat === true) { details.canChat = true; } if (data.fingerprint) { details.fingerprint = data.fingerprint; } const connection = await connection_1.Connection.createAsync(details); connection.sendMessage = async (message) => { this.sendMessage(connection, message); }; connection.sendFile = async (path) => { connection.params.file = path; this.processFile(connection); }; this.emit("connection", connection); if (this.attributes.logConnections === true) { this.log("new connection", "info", { to: connection.remoteIP }); } if (this.attributes.sendWelcomeMessage === true) { connection.sendMessage({ welcome: connection.localize("actionhero.welcomeMessage"), context: "api", }); } if (typeof this.attributes.sendWelcomeMessage === "number") { setTimeout(() => { try { connection.sendMessage({ welcome: connection.localize("actionhero.welcomeMessage"), context: "api", }); } catch (e) { this.log(e, "error"); } }, this.attributes.sendWelcomeMessage); } } /** * When a connection has called an Action command, and all properties are set. Connection should have `params.action` set at least. * on(event: 'actionComplete', cb: (data: object) => void): this; */ async processAction(connection) { const actionProcessor = new actionProcessor_1.ActionProcessor(connection); const data = await actionProcessor.processAction(); this.emit("actionComplete", data); } /** * When a connection has called an File command, and all properties are set. Connection should have `params.file` set at least. Will eventually call Actionhero.Server#sendFile. */ async processFile(connection) { const results = await index_1.api.staticFile.get(connection); this.sendFile(results.connection, results.error, results.fileStream, results.mime, results.length, results.lastModified); } /** * Enumerate the connections for this server type on this server. */ connections() { const connections = []; for (const i in index_1.api.connections.connections) { const connection = index_1.api.connections.connections[i]; if (connection.type === this.type) { connections.push(connection); } } return connections; } /** * Log a message from this server type. A wrapper around log() with a server prefix. */ log(message, severity, data) { log_1.log(`[server: ${this.type}] ${message}`, severity, data); } } exports.Server = Server;