UNPKG

sgapps-server

Version:
928 lines (829 loc) • 33.5 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>prototypes/server.js - SGApps Server - Framework</title> <meta name="description" content="SGApps Server for high performance results" /> <meta name="keywords" content="javascript, js, application-prototype, prototype" /> <meta name="keyword" content="javascript, js, application-prototype, prototype" /> <meta property="og:title" content="SGApps Server - Framework"/> <meta property="og:type" content="website"/> <meta property="og:image" content=""/> <meta property="og:url" content="https://labs.sgapps.io/open-source/sgapps-server"/> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc.css"> <script src="scripts/nav.js" defer></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav class="wrap"> <input type="text" id="nav-search" placeholder="Search" /> <h2><a href="index.html">Home</a></h2><h2><a href="https://labs.sgapps.io/open-source/sgapps-server" target="_blank" class="menu-item" id="website_link" >Project Page ( Git Lab )</a></h2><h2><a href="http://gordienco.net/" target="_blank" class="menu-item" id="website_link" >About Me</a></h2><h2><a href="https://labs.sgapps.io/open-source/sgapps-server" target="_blank" class="menu-item" id="github_link" >GitHub</a></h2><h3>Classes</h3><ul><li><a href="AccessLogger.html">AccessLogger</a><ul class='methods'><li data-type='method' style='display: none;'><a href="AccessLogger.html#formattedDate">formattedDate</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getProtocol">getProtocol</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getReferer">getReferer</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getRemoteIp">getRemoteIp</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getSize">getSize</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getUsername">getUsername</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#logRequest">logRequest</a></li></ul></li><li><a href="FaceboxTemplate.html">FaceboxTemplate</a><ul class='methods'><li data-type='method' style='display: none;'><a href="FaceboxTemplate.html#render">render</a></li><li data-type='method' style='display: none;'><a href="FaceboxTemplate.html#renderCode">renderCode</a></li><li data-type='method' style='display: none;'><a href="FaceboxTemplate.html#renderFile">renderFile</a></li></ul></li><li><a href="FSLibrary.html">FSLibrary</a></li><li><a href="LoggerBuilder.html">LoggerBuilder</a><ul class='methods'><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#decorateGlobalLogger">decorateGlobalLogger</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#error">error</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#info">info</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#log">log</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#prettyCli">prettyCli</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#prompt">prompt</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#warn">warn</a></li></ul></li><li><a href="SGAppsServer.html">SGAppsServer</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServer.html#all">all</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#connect">connect</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#delete">delete</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#Email">Email</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#finalHandler">finalHandler</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#get">get</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handle">handle</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handleErrorRequest">handleErrorRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handlePostData">handlePostData</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handleRequest">handleRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handleStaticRequest">handleStaticRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#head">head</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#options">options</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#patch">patch</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#post">post</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#put">put</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#server">server</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#trace">trace</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#use">use</a></li></ul></li><li><a href="SGAppsServer.NodeJsMvc.html">NodeJsMvc</a></li><li class="level-hide"><a href="SGAppsServer.NodeJsMvc.Controller.html">Controller</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#actionExists">actionExists</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#addAction">addAction</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#addView">addView</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#getAction">getAction</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#getView">getView</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#removeAction">removeAction</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#removeView">removeView</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#render">render</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#viewExists">viewExists</a></li></ul></li><li class="level-hide"><a href="SGAppsServer.NodeJsMvc.Controller.Action.html">Action</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.Action.html#run">run</a></li></ul></li><li><a href="SGAppsServerDecoratorsLibrary.html">SGAppsServerDecoratorsLibrary</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerDecoratorsLibrary.html#.AccessLoggerDecorator">AccessLoggerDecorator</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerDecoratorsLibrary.html#.NodeJsMvcDecorator">NodeJsMvcDecorator</a></li></ul></li><li><a href="SGAppsServerDictionary.html">SGAppsServerDictionary</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerDictionary.html#generatePathKey">generatePathKey</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerDictionary.html#push">push</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerDictionary.html#run">run</a></li></ul></li><li><a href="SGAppsServerEmail.html">SGAppsServerEmail</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#.from">from</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#.isValidAddress">isValidAddress</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#.timeout">timeout</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#send">send</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#valid">valid</a></li></ul></li><li><a href="SGAppsServerRequest.html">SGAppsServerRequest</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerRequest.html#_parseDeepFieldName">_parseDeepFieldName</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerRequest.html#getMountUpdatedUrl">getMountUpdatedUrl</a></li></ul></li><li><a href="SGAppsServerRequestCookie.html">SGAppsServerRequestCookie</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerRequestCookie.html#get">get</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerRequestCookie.html#set">set</a></li></ul></li><li><a href="SGAppsServerRequestSession.html">SGAppsServerRequestSession</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerRequestSession.html#destroy">destroy</a></li></ul></li><li><a href="SGAppsServerResponse.html">SGAppsServerResponse</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#pipeFile">pipeFile</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#pipeFileStatic">pipeFileStatic</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#redirect">redirect</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#send">send</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#sendError">sendError</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#sendStatusCode">sendStatusCode</a></li></ul></li><li><a href="SGAppsServerShared.html">SGAppsServerShared</a></li><li><a href="SGAppsSessionManager.html">SGAppsSessionManager</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsSessionManager.html#handleRequest">handleRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsSessionManager.html#removeExpiredSessions">removeExpiredSessions</a></li></ul></li><li><a href="TemplateManager.html">TemplateManager</a><ul class='methods'><li data-type='method' style='display: none;'><a href="TemplateManager.html#add">add</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#addList">addList</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#get">get</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#remove">remove</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#render">render</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#templateExists">templateExists</a></li></ul></li><li><a href="TemplateManagerViewer.html">TemplateManagerViewer</a><ul class='methods'><li data-type='method' style='display: none;'><a href="TemplateManagerViewer.html#render">render</a></li><li data-type='method' style='display: none;'><a href="TemplateManagerViewer.html#renderCode">renderCode</a></li></ul></li></ul><h3>Global</h3><ul><li><a href="global.html#LoggerBuilderPrompt">LoggerBuilderPrompt</a></li><li><a href="global.html#MountUpdatedURL">MountUpdatedURL</a></li><li><a href="global.html#RequestHandler">RequestHandler</a></li><li><a href="global.html#RequestPathStructure">RequestPathStructure</a></li><li><a href="global.html#RequestPathStructureMap">RequestPathStructureMap</a></li><li><a href="global.html#RequestSessionDecorator">RequestSessionDecorator</a></li><li><a href="global.html#ResourcesExtensions">ResourcesExtensions</a></li><li><a href="global.html#routeMatch">routeMatch</a></li><li><a href="global.html#SGAppsServerDecorator">SGAppsServerDecorator</a></li><li><a href="global.html#SGAppsServerDictionaryRunCallBack">SGAppsServerDictionaryRunCallBack</a></li><li><a href="global.html#SGAppsServerErrorCallBack">SGAppsServerErrorCallBack</a></li><li><a href="global.html#SGAppsServerErrorOnlyCallback">SGAppsServerErrorOnlyCallback</a></li><li><a href="global.html#SGAppsServerHandlerPostData">SGAppsServerHandlerPostData</a></li><li><a href="global.html#SGAppsServerOptions">SGAppsServerOptions</a></li><li><a href="global.html#SGAppsServerRequestFile">SGAppsServerRequestFile</a></li><li><a href="global.html#SGAppsServerRequestPostDataItem">SGAppsServerRequestPostDataItem</a></li><li><a href="global.html#SGAppsServerRequestSessionCache">SGAppsServerRequestSessionCache</a></li><li><a href="global.html#SGAppsSessionManagerOptions">SGAppsSessionManagerOptions</a></li><li><a href="global.html#TemplateManagerRenderOptions">TemplateManagerRenderOptions</a></li><li><a href="global.html#TemplateManagerTemplate">TemplateManagerTemplate</a></li></ul> </nav> <div id="main"> <h1 class="page-title">prototypes/server.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>const FSLibrary = require('fs'); const _Extensions = require('./../resources/extensions'); const { Server, IncomingMessage, ServerResponse } = require('http'); const { Duplex } = require('stream'); const LoggerBuilder = require('./logger'); const _EmailBuilder = require('./email'); const SGAppsServerRequest = require('./server/request'); const SGAppsServerResponse = require('./server/response'); const SGAppsServerDictionary = require('./dictionary'); /** * @class * @name SGAppsServerDecoratorsLibrary */ /** * @callback SGAppsServerErrorCallBack * @param {Error} err * @param {SGAppsServerRequest} request * @param {SGAppsServerResponse} response * @param {SGAppsServer} server */ /** * @callback SGAppsServerErrorOnlyCallback * @param {Error} err */ /** * @class * @name FSLibrary * @mixes FSLibraryModule */ /** * @class * @name SGAppsServerShared */; /** * @callback SGAppsServerDecorator * @param {SGAppsServerRequest} request * @param {SGAppsServerResponse} response * @param {SGAppsServer} server * @param {function} callback */; const _decorators = [ require('./server/extend/request-url'), require('./server/extend/response-send'), require('./server/extend/response-error'), require('./server/extend/response-redirect'), require('./server/extend/response-pipe-file'), require('./server/extend/response-template'), require('./server/extend/request-postdata'), require('./server/extend/request-cookie'), require('./server/extend/request-session'), require('./server/extend/response-pipe-file-static'), ]; /** * @typedef {string|RegExp} RequestPathStructure */ /** * @callback RequestHandler * @param {SGAppsServerRequest} request * @param {SGAppsServerResponse} response * @param {function} next */ /** * @typedef {object} SGAppsServerOptions * @property {Server} [server] * @property {boolean} [strictRouting=false] * @property {number} [_DEBUG_MAX_HANDLER_EXECUTION_TIME=500] * @property {boolean} [_DEBUG_REQUEST_HANDLERS_STATS=false] * @property {boolean} [_REQUEST_FORM_PARAMS_DEEP_PARSE=true] parse formData field names to create deep object request.body */ /** * @example * // ================================ * // Start your 🚀 Web-Server app * // ================================ * * const { SGAppsServer } = require('@sgapps.io/server'); * const app = new SGAppsServer(); * * app.get('/', function (req, res) { * res.send('hello world') * }) * * app.server().listen(8080, () => { * app.logger.log('Server is running on port 8080'); * }) * * @example * // ======================================== * // Start your 🚀 Web-Server app Extended * // ======================================== * * const { SGAppsServer } = require('@sgapps.io/server'); * const app = new SGAppsServer(); * * app.get('/', function (req, res) { * res.send('hello world') * }) * * app.whenReady.then(() => { * app.SessionManager.cookie = 'ssid'; * app.SessionManager.SESSION_LIFE = 120; // seconds * * app.server().listen(8080, () => { * app.logger.log('Server is running on port 8080'); * }) * }, app.logger.error); * * @class * @description HTTP Server for high performance results * @name SGAppsServer * @param {object} [options] * @param {Server} [options.server] * @param {boolean} [options.strictRouting=true] * @param {boolean} [options.debug=true] * @param {object} [options._DEBUG_MAX_HANDLER_EXECUTION_TIME=500] console shows an warn if handler is executed more than ( works in debug mode ) * @param {object} [options._DEBUG_REQUEST_HANDLERS_STATS=false] console shows an warn if handler is executed more than ( works in debug mode ) * @param {boolean} [options._REQUEST_FORM_PARAMS_DEEP_PARSE=true] parse formData field names to create deep object request.body * @param {SGAppsServerDecorator[]} [options.decorators] */ function SGAppsServer(options) { options = Object.assign( { server: null, strictRouting: true, decorators: [], debug: true, _DEBUG_MAX_HANDLER_EXECUTION_TIME: 500, _DEBUG_REQUEST_HANDLERS_STATS: false, _REQUEST_FORM_PARAMS_DEEP_PARSE: true }, options || {} ); /** * @memberof SGAppsServer# * @name _server * @type {Server} */ //@ts-ignore this._server = options.server ? options.server : require("http").createServer(); /** * @memberof SGAppsServer# * @name _decorators * @type {SGAppsServerDecorator[]} */; let _decoratorsComputed = [ ..._decorators, ...(options.decorators || []) ]; Object.defineProperty( this, '_decorators', { get: () => _decoratorsComputed, set: (decorators) => { _decoratorsComputed = [ ..._decorators, ...decorators ]; }, enumerable: true, configurable: false } ); /** * @memberof SGAppsServer# * @name _options * @type {SGAppsServerOptions} */ this._options = Object.assign( { strictRouting: true }, (options || {}) ); /** * @memberof SGAppsServer# * @name STATUS_CODES * @type {Object&lt;number,string>} */ this.STATUS_CODES = require('http').STATUS_CODES; /** * @memberof SGAppsServer# * @name shared * @type {SGAppsServerShared} */ this.shared = {}; /** * @memberof SGAppsServer# * @name logger * @type {LoggerBuilder} */ this.logger = new LoggerBuilder(); this.logger._debug = options.debug; /** * @memberof SGAppsServer# * @method Email * @param {SGAppsServerEmail.Config} config * @returns {SGAppsServerEmail} */ //@ts-ignore this.Email = _EmailBuilder; /** * @memberof SGAppsServer# * @name mountPath * @type {string} */ let _mountPath = ''; Object.defineProperty( this, 'mountPath', { get: () => _mountPath, set: (path) => { _mountPath = path; }, enumerable: true, configurable: true } ); /** * @memberof SGAppsServer# * @name _fs * @type {object} */; this._fs = require('fs'); /** * @memberof SGAppsServer# * @name _path * @type {object} */; this._path = require('path'); /** * @memberof SGAppsServer# * @name EXTENSIONS * @type {ResourcesExtensions} */ this.EXTENSIONS = _Extensions; /** * @memberof SGAppsServer# * @name _requestListeners * @type {Object&lt;string,SGAppsServerDictionary>} */ this._requestListeners = { "use" : new SGAppsServerDictionary({ name: "use" }), "post" : new SGAppsServerDictionary({ name: "post" }), "get" : new SGAppsServerDictionary({ name: "get" }), "head" : new SGAppsServerDictionary({ name: "head" }), "put" : new SGAppsServerDictionary({ name: "put" }), "trace" : new SGAppsServerDictionary({ name: "trace" }), "delete" : new SGAppsServerDictionary({ name: "delete" }), "options" : new SGAppsServerDictionary({ name: "options" }), "connect" : new SGAppsServerDictionary({ name: "connect" }), "patch" : new SGAppsServerDictionary({ name: "patch" }), "_finalHandler" : new SGAppsServerDictionary({ name: "_finalHandler", reverse: true }) }; this._server.on( 'request', ( /** * @param {IncomingMessage} request * @param {ServerResponse} response * @this {SGAppsServer} */ function (request, response) { this.handle( request, response ); } ).bind(this) ); this._server.on( 'upgrade', /** * * @param {IncomingMessage} request * @param {Duplex} socket * @param {Buffer} data */ function (request, socket, data) { } ); /** * default value is `16 Kb` » `16 * 1024` * @memberof SGAppsServer# * @name MAX_POST_SIZE * @type {number} */ var MAX_POST_SIZE = 16 * 1024; Object.defineProperty(this, 'MAX_POST_SIZE', { get: function () { return MAX_POST_SIZE; }, set: (value) => { if (typeof(value) === "number") { MAX_POST_SIZE = value; } else { this.logger.error('MAX_POST_SIZE should be a number'); } } }); /** * @memberof SGAppsServer# * @name whenReady * @type {Promise&lt;SGAppsServer>} */ this.whenReady = new Promise((resolve, reject) => { let index = 0; // @ts-ignore const _decorators = this._decorators; const loadDecorator = () => { if (_decorators[index]) { if (this.logger._debug) { process.stderr.write( `\n\t» \x1b[36m[Server.Decorator] ${ _decorators[index].name || _decorators[index].toString() }\x1b[0m` ); } _decorators[index]( null, null, this, (err) => { if (err) { process.stderr.write( ' \x1b[32;1mError\x1b[0m\n' + err.message + '\n' ); reject(err); } else { index++; if (this.logger._debug) { process.stderr.write(' \x1b[32;1mDone\x1b[0m'); } loadDecorator(); } } ); } else { if (this.logger._debug) { process.stderr.write('\n\n\t\t\x1b[32;1mDecorators Loaded\x1b[0m\n'); } resolve(this); } }; loadDecorator(); }); return this; } /** * @memberof SGAppsServer * @param {SGAppsServerRequest} request * @param {SGAppsServerResponse} response * @param {SGAppsServerDictionaryRunCallBack} callback */ SGAppsServer.prototype.handleRequest = function (request, response, callback) { const method = (request.request.method || 'get').toLocaleLowerCase(); if ( method &amp;&amp; method[0] !== "_" &amp;&amp; ( method in this._requestListeners ) ) { this._requestListeners.use.run( request, response, //@ts-ignore this, (request, response, server) => { this._requestListeners[method].run( request, response, //@ts-ignore this, (request, response, server) => { server._requestListeners._finalHandler.run( request, response, server, () => { if (callback) { callback(request, response, server); } else if ( !response._flags.finished ) { response.sendError( Error(`Unable to handle path ${request.request ? request.request.url : ''}`), { statusCode: 404 } ); } } ); } ); } ); } else { response.sendError(Error(`[Request.method] is unknown; ${method}`)); } }; /** * @memberof SGAppsServer * @param {SGAppsServerRequest} request * @param {SGAppsServerResponse} response * @param {Error} [err] */ SGAppsServer.prototype.handleErrorRequest = function (request, response, err) { response.sendError(err || Error('unknown error'), { statusCode: 500 }); }; /** * @memberof SGAppsServer * @param {SGAppsServerRequest} request * @param {SGAppsServerResponse} response * @param {string} path * @param {SGAppsServerErrorCallBack} callback * @param {object} [options] * @param {number} [options.timeout=0] * @param {string[]} [options.autoIndex] list of auto-index files, ex: ['index.html', 'index.htm', 'default.html'] */ SGAppsServer.prototype.handleStaticRequest = function (request, response, path, callback, options = { timeout: 0, autoIndex: [] }) { if (response.response) { response.pipeFileStatic( this._path.join( this._path.resolve(path), this._path.resolve( request.mountPath || './', this._path.resolve( '/', request.urlInfo.pathname ) ) ), (request.urlInfo.pathname || '').replace( /^.*\//, '' ) || 'index.html', (err) => { if (callback) { callback( err || null, request, response, //@ts-ignore this ); } else { if (err) { response.sendError( Error(`404 ${this.STATUS_CODES[404]}; ${err.message}`), { statusCode: 404 } ); } } }, options ); } else { if (callback) { callback( Error('[Response] is already finished'), request, response, //@ts-ignore this ); } } }; /** * @memberof SGAppsServer * @param {IncomingMessage} request * @param {ServerResponse} response * @param {SGAppsServerDictionaryRunCallBack} [callback] */ SGAppsServer.prototype.handle = function (request, response, callback) { /** * @private * @type {SGAppsServerRequest} */ //@ts-ignore const _request = new SGAppsServerRequest(request, this); /** * @private * @type {SGAppsServerResponse} */ //@ts-ignore const _response = new SGAppsServerResponse(response, this); let index = 0; const loadDecorator = () => { //@ts-ignore const _decorators = this._decorators; if (_decorators[index]) { _decorators[index]( _request, _response, // @ts-ignore this, (err) => { if (err) { _response.sendError( Error( `Unable to load [Request.Decorator]: ${_decorators[index].name} ; ${err.message}` ) ); } else { index++; loadDecorator(); } } ); } else { this.handleRequest( _request, _response, function () { if (callback) { callback(_request, _response, this); } else { _response.sendError( Error(`Unable to handle path ${request.url}`), { statusCode: 404 } ); } } ); } }; loadDecorator(); // // Improve garbage collector // _response._destroy.push(function () { // delete _request.request; // delete _response.response; // }); }; /** * @memberof SGAppsServer * @returns {Server} */ SGAppsServer.prototype.server = function () { return this._server; }; /** * @memberof SGAppsServer * @param {string|RequestHandler} path * @param {...RequestHandler} [handlers] * @returns {SGAppsServer} */ SGAppsServer.prototype.use = function (path, ...handlers) { this._requestListeners.use.push( (typeof(path) === "string" || (path instanceof RegExp)) ? path : '', //@ts-ignore typeof(path) === "function" ? [path, ...handlers] : handlers ); return this; }; /** * The `POST` method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server. * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.post = function (path, ...handlers) { this._requestListeners.post.push( path, handlers ); return this; }; /** * The `GET` method requests a representation of the specified resource. Requests using GET should only retrieve data. * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.get = function (path, ...handlers) { this._requestListeners.get.push( path, handlers ); return this; }; /** * The `HEAD` method asks for a response identical to that of a GET request, but without the response body. * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.head = function (path, ...handlers) { this._requestListeners.head.push( path, handlers ); return this; }; /** * The `PUT` method replaces all current representations of the target resource with the request payload. * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.put = function (path, ...handlers) { this._requestListeners.put.push( path, handlers ); return this; }; /** * The `TRACE` method performs a message loop-back test along the path to the target resource. * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.trace = function (path, ...handlers) { this._requestListeners.trace.push( path, handlers ); return this; }; /** * The `DELETE` method deletes the specified resource. * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.delete = function (path, ...handlers) { this._requestListeners.delete.push( path, handlers ); return this; }; /** * The `OPTIONS` method is used to describe the communication options for the target resource. * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.options = function (path, ...handlers) { this._requestListeners.options.push( path, handlers ); return this; }; /** * The `CONNECT` method establishes a tunnel to the server identified by the target resource. * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.connect = function (path, ...handlers) { this._requestListeners.connect.push( path, handlers ); return this; }; /** * The `PATCH` method is used to apply partial modifications to a resource. * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.patch = function (path, ...handlers) { this._requestListeners.patch.push( path, handlers ); return this; }; /** * add handler to all methods * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.all = function (path, ...handlers) { Object.keys( this._requestListeners ).forEach((method) => { if (method !== "use" &amp;&amp; method[0] !== '_' &amp;&amp; method[0] !== 'finalHandler') { this._requestListeners[method].push( path, handlers ); } }); return this; }; /** * add final handler to all methods, last added is first * * @memberof SGAppsServer * @param {RequestPathStructure} path * @param {...RequestHandler} handlers * @returns {SGAppsServer} */ SGAppsServer.prototype.finalHandler = function (path, ...handlers) { this._requestListeners._finalHandler.push( path, handlers ); return this; }; /** * @callback SGAppsServerHandlerPostData * @param {SGAppsServerRequest} request * @param {SGAppsServerResponse} response * @param {function} next */ /** * @memberof SGAppsServer * @param {object} [options] * @param {number} [options.MAX_POST_SIZE] * @param {object} [options.error] * @param {number} options.error.statusCode * @param {string} [options.error.message] * @returns {SGAppsServerHandlerPostData} */ SGAppsServer.prototype.handlePostData = function (options) { return (request, response, next) => { options = Object.assign( { error: { statusCode: 500 } }, options ); if ("MAX_POST_SIZE" in options) { request.MAX_POST_SIZE = options.MAX_POST_SIZE; } request.postData.then( () => { next(); }, (err) => { response.sendError( Error( options.error.message || this.STATUS_CODES[options.error.statusCode] || err.message || 'Unexpected Error' ), { statusCode: options.error.statusCode } ); } ); }; }; module.exports = SGAppsServer;</code></pre> </article> </section> </div> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.5</a> using the <a href="https://github.com/clenemt/docdash">docdash</a> theme. </footer> <script>prettyPrint();</script> <script src="scripts/polyfill.js"></script> <script src="scripts/linenumber.js"></script> <script src="scripts/search.js" defer></script> <script src="scripts/collapse.js" defer></script> <script src="https://sgapps.io/components/sgapps-labs-examples/toolbar/loader.js"></script> </body> </html>