UNPKG

actionhero

Version:

The reusable, scalable, and quick node.js API server for stateless and stateful applications

144 lines (143 loc) 5.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Server = void 0; const events_1 = require("events"); const index_1 = require("../index"); const log_1 = require("../modules/log"); const actionProcessor_1 = require("./actionProcessor"); const connection_1 = require("./connection"); /** * 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() { var _a, _b, _c, _d, _e; super(); this.options = {}; this.attributes = {}; this.config = {}; // will be applied by the initializer this.connectionCustomMethods = {}; this.canChat = (_a = this.canChat) !== null && _a !== void 0 ? _a : true; this.logExits = (_b = this.logExits) !== null && _b !== void 0 ? _b : true; this.sendWelcomeMessage = (_c = this.sendWelcomeMessage) !== null && _c !== void 0 ? _c : true; this.logConnections = (_d = this.logConnections) !== null && _d !== void 0 ? _d : true; this.verbs = (_e = this.verbs) !== null && _e !== void 0 ? _e : []; } validate() { if (!this.type) { throw new Error("type is required for this server"); } [ "start", "stop", "sendFile", // connection, error, fileStream, mime, length, lastModified "sendMessage", // connection, message "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) { var _a, _b; const details = { type: this.type, id: data.id, remotePort: data.remotePort, remoteIP: data.remoteAddress, rawConnection: data.rawConnection, messageId: data.messageId, canChat: (_a = this.attributes.canChat) !== null && _a !== void 0 ? _a : null, fingerprint: (_b = data.fingerprint) !== null && _b !== void 0 ? _b : null, }; 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: index_1.config.general.welcomeMessage, context: "api", }); } if (typeof this.attributes.sendWelcomeMessage === "number") { setTimeout(() => { try { connection.sendMessage({ welcome: index_1.config.general.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) { (0, log_1.log)(`[server: ${this.type}] ${message}`, severity, data); } } exports.Server = Server;