Comparing version 0.1.4 to 0.1.5
@@ -16,3 +16,3 @@ Guide | ||
``` | ||
Above configs can used before elet initialisation. | ||
Above configs can used before elet initialisation. | ||
@@ -34,2 +34,5 @@ ### Accessing request parameters | ||
**request.params.data** Form data can be accessed through this property. We can use this property to access | ||
Form data in POST/PUT/DELETE methods as well as querystring in GET method. | ||
**request.params.pass** The passed argument are accessed. For ex "/articles/view/1", here 1 will be accesed by this property. | ||
@@ -113,3 +116,3 @@ | ||
},_add = function(req, res) { | ||
}, _add = function(req, res) { | ||
var locals = { | ||
@@ -122,2 +125,11 @@ title: 'A JSON format data returned, Normally used in AJAX response data', | ||
res.json(locals); | ||
}, _swigtojade = function(req, res) { | ||
var controllerData = { | ||
title: 'Test', | ||
pagename: 'awesome peoplexz', | ||
authors: ['Paul', 'Jim', 'Jane'], | ||
params: req.params | ||
}; | ||
/* Override default template engine to another */ | ||
res.render('home', controllerData, 'jade'); | ||
}, _contact = function(req, res) { | ||
@@ -137,2 +149,3 @@ var locals = { | ||
add: _add, | ||
swigtojade: _swigtojade, | ||
contact: _contact | ||
@@ -139,0 +152,0 @@ } |
var http = require('http'); | ||
var elet = require('../lib/elet'); | ||
var elet = require('elet'); | ||
@@ -5,0 +5,0 @@ elet.config({ |
@@ -28,3 +28,12 @@ module.exports = (function () { | ||
}; | ||
}, _contact = function(req, res) { | ||
}, _swigtojade = function(req, res) { | ||
var controllerData = { | ||
title: 'Test', | ||
pagename: 'awesome peoplexz', | ||
authors: ['Paul', 'Jim', 'Jane'], | ||
params: req.params | ||
}; | ||
/* Override default template engine to another */ | ||
res.render('home', controllerData, 'jade'); | ||
}, _contact = function(req, res) { | ||
var locals = { | ||
@@ -44,4 +53,5 @@ title: 'Contact', | ||
test: _test, | ||
swigtojade: _swigtojade, | ||
contact: _contact | ||
} | ||
})(); |
{ | ||
"name": "lite", | ||
"description": "A demo app in lite framework.", | ||
"description": "A demo app in elet web framework.", | ||
"main": "app.js", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"private": true, | ||
@@ -12,2 +12,3 @@ "author": { "name": "Justin John Mathews", "email": "justinjohnmathews@gmail.com" }, | ||
, "jade": "*" | ||
, "elet": "*" | ||
}, | ||
@@ -14,0 +15,0 @@ "devDependencies": {}, |
@@ -6,3 +6,3 @@ Set up basic Elet Application | ||
* Install Node.js | ||
* Extract the `examples` directory from `node_modules/elet` and move `examples` directory out of node_modules directory or Copy `examples` directory from Elet [Download Master](https://github.com/justin-john/elet/archive/master.zip). | ||
* Move the `examples` directory from `node_modules/elet` and keep this examples directory to root directory that is out of node_modules directory or Extract `examples` directory from Elet [Download Master](https://github.com/justin-john/elet/archive/master.zip). | ||
* Go to `examples` root directory in cmd. | ||
@@ -22,1 +22,11 @@ * Install dependencies before starting the application using `npm install` in cmd. | ||
Go to http://localhost:3000 | ||
### FAQ: | ||
1. `Error: Cannot find module 'swig'`. This error happens even after `npm install` or swig is installed. | ||
Please move the examples folder out of node_modules. | ||
``` | ||
└── node_modules/ To └── node_modules | ||
└── examples └── examples | ||
``` |
288
lib/elet.js
@@ -22,4 +22,14 @@ /** | ||
} | ||
var _get = function (request, response, reqDetail, reqMethod, params) { | ||
/** | ||
* Return a function call to controller methods on request | ||
* | ||
* @param {Object} request | ||
* @param {Object} response | ||
* @param {Object} reqDetail | ||
* @param {Object} params | ||
* @return {Function|null} | ||
* @private | ||
*/ | ||
var _get = function (request, response, reqDetail, params) { | ||
dbg.log('Triggered _get Method: '); | ||
@@ -36,3 +46,4 @@ if (!reqDetail.reqParam.ext) { | ||
url : UTIL.urlParams(reqDetail.url), | ||
query : UTIL.queryParams | ||
query : UTIL.queryParams, | ||
data : params | ||
} | ||
@@ -49,3 +60,12 @@ return reqDetail.reqParam.moduleController[reqDetail.reqParam.actionMethod](request, response); | ||
var _fetchParsedBody = function (reqDetail, request) { | ||
/** | ||
* Return a object on GET request used to parse data | ||
* | ||
* @param {Object} reqDetail | ||
* @param {Object} request | ||
* @param {Object} response | ||
* @return {Object|null} | ||
* @private | ||
*/ | ||
var _fetchParsedBody = function (reqDetail, request, response) { | ||
dbg.log('Triggered _fetchParsedBody Method: ', reqDetail.path); | ||
@@ -57,37 +77,51 @@ var querystring = require('querystring'); | ||
var _fetchDecodedBody = function (reqDetail, request) { | ||
/** | ||
* Return a function call on POST request, this method is used to parse form data | ||
* | ||
* @param {Object} reqDetail | ||
* @param {Object} request | ||
* @param {Object} response | ||
* @return {Function} | ||
* @private | ||
*/ | ||
var _fetchDecodedBody = function (reqDetail, request, response) { | ||
dbg.log('Triggered _fetchDecodedBody Method: ', reqDetail.path); | ||
var querystring = require('querystring'); | ||
var chunkedData = ''; | ||
request.isStreamEmitOnData = true; | ||
request.on('data', function(chunk) { | ||
chunkedData += chunk.toString(); | ||
}).on('end', function() { | ||
return _get(request, response, reqDetail, querystring.parse(chunkedData)); | ||
}); | ||
return querystring.parse(chunkedData); | ||
}; | ||
/** | ||
* Return a function | ||
* | ||
* @param {Object} reqDetail | ||
* @param {Object} contentType | ||
* @param {Object} request | ||
* @param {Object} response | ||
* @return {Function} | ||
* @private | ||
*/ | ||
var _fetch = function(reqDetail, contentType, request, response) { | ||
dbg.log('Triggered _fetch Method: ', reqDetail, contentType); | ||
if (contentType.ext == '.html') { | ||
var _fetchBodyParams; | ||
if (request && request.method === 'GET') { | ||
_fetchBodyParams = _fetchParsedBody(reqDetail, request); | ||
} else if (request && request.method === 'POST') { | ||
_fetchBodyParams = _fetchDecodedBody(reqDetail, request); | ||
} | ||
return _get(request, response, reqDetail, request.method, _fetchBodyParams); | ||
} else if (request && request.method === 'GET') { | ||
return _get(request, response, reqDetail, request.method, _fetchParsedBody(reqDetail, request)); | ||
if (request && request.method === 'GET') { | ||
return _get(request, response, reqDetail, _fetchParsedBody(reqDetail, request, response)); | ||
} else if (request && request.method === 'POST') { | ||
return _get(request, response, reqDetail, request.method, _fetchDecodedBody(reqDetail, request)); | ||
} else { | ||
return {}; | ||
return _fetchDecodedBody(reqDetail, request, response); | ||
} else { | ||
/* HTTP PUT and DELETE methods will be handle here */ | ||
return _fetchDecodedBody(reqDetail, request, response); | ||
} | ||
}; | ||
/* | ||
* Initialize the router | ||
* | ||
* @param {Object} request | ||
* @param {Object} response | ||
* */ | ||
/** | ||
* Initialize the router | ||
* | ||
* @param {Object} request | ||
* @param {Object} response | ||
*/ | ||
var _init = function(request, response) { | ||
@@ -103,12 +137,26 @@ dbg.log('---------------------------------------'); | ||
, typeModule = require('./type') | ||
/* | ||
* Set file path | ||
* */ | ||
/** | ||
* Set file path | ||
* @param {String} url | ||
*/ | ||
, getRequestDetail = function(url) { | ||
var fPath | ||
, fviewChangePath | ||
, controller | ||
, actionMethod | ||
, isNameNotValid | ||
, ext = path.extname(url); | ||
dbg.log('Triggered filePath Method', url, ext, CONF.viewsMap); | ||
var controller = url.split('/')[1]; | ||
var actionMethod = url.split('/')[2]; | ||
controller = url.split('/')[1]; | ||
/** | ||
* Check controller name has `?`, `#`, `=`, `&` chars, split name upto corresponding first matched character | ||
* as controller name, otherwise give controller name without any check. | ||
**/ | ||
isNameNotValid = /(\?|#|=|&)/.exec(controller); | ||
controller = isNameNotValid ? controller.split(isNameNotValid[0])[0] : controller; | ||
/* If controller name is not valid/have matched `?`, `#`, `=`, `&` char, then set action name to null */ | ||
actionMethod = isNameNotValid ? null : url.split('/')[2]; | ||
/* Action name check same as above controller name check */ | ||
isNameNotValid = /(\?|#|=|&)/.exec(actionMethod); | ||
actionMethod = isNameNotValid ? actionMethod.split(isNameNotValid[0])[0] : actionMethod; | ||
if (!ext && url) { | ||
@@ -138,8 +186,20 @@ controller = controller || 'index'; | ||
return typeModule.getType(extname); | ||
}, | ||
/* | ||
* Set the template engine, defaults to swig. | ||
* */ | ||
setTemplateRenderedView = function (path, controllerFetch, content) { | ||
} | ||
/** | ||
* Get template content parsed with controller fetched data. | ||
* This method is exposed to public as `response.getParsedFileData`. | ||
* | ||
* Examples: | ||
* res.getParsedFileData('view/index/index.html', { name: 'Elet' }); | ||
* res.getParsedFileData('view/index/index.html', { name: 'Elet' }, '', 'jade'); | ||
* | ||
* @param {String} path | ||
* @param {Object} controllerFetch | ||
* @param {String} content | ||
* @param {String} templateEngine | ||
* @public | ||
**/ | ||
, setTemplateRenderedView = function (path, controllerFetch, content, templateEngine) { | ||
var renderContent; | ||
CONF.templateEngine = templateEngine || CONF.templateEngine; | ||
switch (CONF.templateEngine) { | ||
@@ -163,23 +223,60 @@ case 'swig': | ||
return renderContent; | ||
}, | ||
/* | ||
* Write response. | ||
* */ | ||
resWrite = function (statusCode, contentType, data, encode) { | ||
} | ||
/** | ||
* Write a response, a wrapper to node response's `writeHead` method. | ||
* This method is exposed to public as `response.resWrite`. | ||
* | ||
* Examples: | ||
* res.resWrite(200, 'text/html', data, 'utf8'); | ||
* res.resWrite(200, 'application/json', data, 'utf8'); | ||
* | ||
* @param {Number} statusCode | ||
* @param {Object} contentType | ||
* @param {Object} data | ||
* @param {String} encode | ||
* @public | ||
**/ | ||
, resWrite = function (statusCode, contentType, data, encode) { | ||
response.writeHead(statusCode, { 'Content-Type': contentType }); | ||
response.end(data, encode || CONST.UTF_8); | ||
}, | ||
/* | ||
* Render the JSON to response. | ||
* */ | ||
triggerJSON = function (renderResultObj) { | ||
} | ||
/** | ||
* Render the JSON to response. This method is exposed to public as `response.json`. | ||
* | ||
* Examples: | ||
* res.json({ name: 'Justin' }) | ||
* | ||
* @param {Object} renderResultObj | ||
* @public | ||
**/ | ||
, triggerJSON = function (renderResultObj) { | ||
resWrite(CONST.ST_CODE_OK, CONST.MIME_JSON, JSON.stringify(renderResultObj), CONST.UTF_8); | ||
}, | ||
/* | ||
* Render the content to response. | ||
* */ | ||
triggerRender = function (viewTemplate, renderResultObj) { | ||
dbg.log('Trigger render method: ', viewTemplate, renderResultObj); | ||
} | ||
/** | ||
* Render the template content to response. This method is exposed to public as `response.render`. | ||
* Method accepts `view file name without file extension`, `controller fetched data`, and | ||
* `template engine name for override`. | ||
* | ||
* Examples: | ||
* res.render('index', { name: 'Angeline' }) | ||
* res.render('index') | ||
* // Call default template same as action name with object passed | ||
* res.render({ name: 'Angeline' }) | ||
* // Call default template same as action name | ||
* res.render() | ||
* // Render with different template engine than config defined template engine. | ||
* // Here swig is default template engine overridden to jade template engine only for corresponding request. | ||
* res.render('index', { name: 'Angeline' }, 'jade') | ||
* | ||
* @param {String} viewTemplate | ||
* @param {Object} renderResultObj | ||
* @param {Object} templateEngine | ||
* @public | ||
**/ | ||
, triggerRender = function (viewTemplate, renderResultObj, templateEngine) { | ||
dbg.log('Trigger render method: ', viewTemplate, renderResultObj, templateEngine); | ||
var readViewFilePath = reqDetail.path; | ||
dbg.log('LOG:: readViewFilePath On Call:: ', readViewFilePath); | ||
renderResultObj = renderResultObj || {}; | ||
/* If first argument is object, set it to renderResultObj` and `viewTemplate` to empty */ | ||
if ('object' === typeof viewTemplate) { | ||
@@ -189,2 +286,4 @@ renderResultObj = viewTemplate; | ||
} | ||
/* If templateEngine is present, override default view extension of view file. */ | ||
CONF.viewExtension = templateEngine || CONF.viewExtension; | ||
if (viewTemplate) { | ||
@@ -205,9 +304,9 @@ readViewFilePath = viewTemplate.indexOf('/') > -1 | ||
} else { | ||
data = setTemplateRenderedView(readViewFilePath, renderResultObj, data); | ||
data = setTemplateRenderedView(readViewFilePath, renderResultObj, data, templateEngine); | ||
resWrite(CONST.ST_CODE_OK, contentType.contentType, data, contentType.encoding || CONST.UTF_8); | ||
} | ||
}); | ||
} else if(!exists && contentType.ext !== '.js'&& contentType.ext !== '.css') { | ||
dbg.log('LOG:: On Render Method File Not Exists JSON format RETURN'); | ||
if (renderResultObj) { | ||
} else { | ||
dbg.log('LOG:: On Render Method File Not Exists data return on JSON format'); | ||
if (renderResultObj && 'object' === typeof renderResultObj) { | ||
resWrite(CONST.ST_CODE_OK, CONST.MIME_JSON, JSON.stringify(renderResultObj), CONST.UTF_8); | ||
@@ -218,6 +317,2 @@ } else { | ||
} | ||
} else { | ||
dbg.log('LOG:: On Render Method File Not Exist 404 Error'); | ||
response.writeHead(CONST.ST_CODE_NOT_FOUND); | ||
response.end(); | ||
} | ||
@@ -229,5 +324,5 @@ }); | ||
/* | ||
* Request and Response Methods | ||
* */ | ||
/** | ||
* Request and Response Public API Methods | ||
*/ | ||
response.render = triggerRender; | ||
@@ -244,2 +339,8 @@ response.json = triggerJSON; | ||
/** | ||
* Check the request accesses controller file and action method by using request url have extension and | ||
* require `ModuleController` and set `hasModuleController` and `hasActionMethod` variable to know the request | ||
* have valid hit point in controller file, otherwise set `ModuleController` and `ActionMethod` to `undefined`. | ||
* This `undefined` leads to request to "Page Not Found". | ||
**/ | ||
if (!reqDetail.reqParam.ext) { | ||
@@ -256,5 +357,13 @@ try { | ||
dbg.log('LOG:: Read file reqParam: ', reqDetail.reqParam); | ||
/** | ||
* Check the request have extension in url OR not have module controller OR not have action method in | ||
* controller. | ||
**/ | ||
if (reqDetail.reqParam.ext || !reqDetail.reqParam.hasModuleController || !reqDetail.reqParam.hasActionMethod) { | ||
fs.exists(reqDetail.path, function(exists) { | ||
if (exists && reqDetail.reqParam.ext) { | ||
/** | ||
* IF Case: File exists on any type of file. | ||
**/ | ||
dbg.log('LOG:: File Exist'); | ||
@@ -266,13 +375,30 @@ fs.readFile(reqDetail.path, contentType.encoding || CONST.UTF_8, function(error, data) { | ||
} else { | ||
if (contentType.ext == '.html') { | ||
controllerFetch = _fetch(reqDetail, contentType, request, response); | ||
data = setTemplateRenderedView(reqDetail.path, controllerFetch, data); | ||
/** | ||
* Check the request have readable stream emit on `data` event and send response only on | ||
* readable stream emit on `end` event, otherwise send response without in events callbacks | ||
*/ | ||
if (request.isStreamEmitOnData) { | ||
request.on('end', function() { | ||
resWrite(CONST.ST_CODE_OK, contentType.contentType, data, contentType.encoding || CONST.UTF_8); | ||
}); | ||
} else { | ||
resWrite(CONST.ST_CODE_OK, contentType.contentType, data, contentType.encoding || CONST.UTF_8); | ||
} | ||
resWrite(CONST.ST_CODE_OK, contentType.contentType, data, contentType.encoding || CONST.UTF_8); | ||
} | ||
}); | ||
} else if(exists && !reqDetail.reqParam.ext && (!reqDetail.reqParam.hasModuleController || !reqDetail.reqParam.hasActionMethod)) { | ||
var contentError = CONF.errorFilePath ? setTemplateRenderedView(CONF.errorFilePath) : TEMPLATE.errorContent; | ||
/** | ||
* ELSE IF Case: View file exists for request in view folder, but no module controller OR | ||
* action method. If this case excluded, the current request will fallback to 404 error instead of | ||
* "Page Not Found Exception". | ||
**/ | ||
dbg.log('LOG:: File Exists but no controller/action method'); | ||
var contentError = CONF.errorFilePath ? setTemplateRenderedView(CONF.errorFilePath) : TEMPLATE.errorContent; | ||
resWrite(CONST.ST_CODE_OK, CONST.MIME_HTML, contentError, CONST.UTF_8); | ||
} else if(!exists && contentType.ext !== '.js'&& contentType.ext !== '.css') { | ||
} else if(!exists && !reqDetail.reqParam.ext) { | ||
/** | ||
* ELSE IF Case: File not exist and no extension in request url. Check any controller data is | ||
* fetched in request, then set response to json mime type with controller data, | ||
* otherwise set an error content to response | ||
**/ | ||
dbg.log('LOG:: File Not Exists JSON format RETURN'); | ||
@@ -282,6 +408,18 @@ var fetchedResponse = _fetch(reqDetail, contentType, request, response); | ||
if (fetchedResponse) { | ||
resWrite(CONST.ST_CODE_OK, CONST.MIME_JSON, JSON.stringify(fetchedResponse), CONST.UTF_8); | ||
if (request.isStreamEmitOnData) { | ||
request.on('end', function() { | ||
resWrite(CONST.ST_CODE_OK, CONST.MIME_JSON, JSON.stringify(fetchedResponse), CONST.UTF_8); | ||
}); | ||
} else { | ||
resWrite(CONST.ST_CODE_OK, CONST.MIME_JSON, JSON.stringify(fetchedResponse), CONST.UTF_8); | ||
} | ||
} else { | ||
var contentError = CONF.errorFilePath ? setTemplateRenderedView(CONF.errorFilePath) : TEMPLATE.errorContent; | ||
resWrite(CONST.ST_CODE_OK, CONST.MIME_HTML, contentError, CONST.UTF_8); | ||
if (request.isStreamEmitOnData) { | ||
request.on('end', function() { | ||
resWrite(CONST.ST_CODE_OK, CONST.MIME_HTML, contentError, CONST.UTF_8); | ||
}); | ||
} else { | ||
resWrite(CONST.ST_CODE_OK, CONST.MIME_HTML, contentError, CONST.UTF_8); | ||
} | ||
} | ||
@@ -299,7 +437,7 @@ } else { | ||
}, | ||
/* | ||
* Set config method | ||
* | ||
* @param {Object} config | ||
* */ | ||
/** | ||
* Set config method | ||
* | ||
* @param {Object} config | ||
*/ | ||
_config = function (config) { | ||
@@ -306,0 +444,0 @@ config = config || {}; |
@@ -12,3 +12,3 @@ { | ||
"homepage": "https://github.com/justin-john/elet", | ||
"version": "0.1.4", | ||
"version": "0.1.5", | ||
"author": { | ||
@@ -15,0 +15,0 @@ "name": "Justin John Mathews", |
@@ -66,6 +66,2 @@ Elet | ||
### Guide | ||
Visit [docs](https://github.com/justin-john/elet/blob/master/docs/home.md). | ||
### Working of elet | ||
@@ -86,3 +82,3 @@ | ||
##### response.render(view, [locals object]) | ||
##### response.render(view, [locals object], templateEngine) | ||
Renders a view and sends the rendered HTML string to the client. | ||
@@ -95,4 +91,9 @@ Parameters: | ||
If both parameters are omitted. The method will look in view directory with action named file is present and automatically render the template. | ||
templateEngine, a string used render with different template engine than config defined default template engine. If swig is | ||
default template engine in application then this property to override to jade/ejs template engine only for | ||
corresponding request. If templateEngine is given, then we must give all other arguments that is view string and locals | ||
object in response.render method. Remember, this templateEngine given must be required before using in application. | ||
If all arguments are omitted, the method will look in view directory with action named file is present and automatically render the template. | ||
#####response.json([locals object]) | ||
@@ -120,7 +121,13 @@ Sends a JSON response | ||
### Relases Notes | ||
### Additional Documentation | ||
Want to improve the elet, please don’t hesitate to fork and make a [Pull Request](https://github.com/justin-john/elet/pulls). If you have any questions, thoughts, concerns or feedback, please don't hesitate to create an [issue](https://github.com/justin-john/elet/issues). | ||
Your suggestions are always welcome! | ||
Visit additional documentation [here](https://github.com/justin-john/elet/blob/master/docs/home.md). | ||
### Contributing | ||
Please have look in Elet and let me know how I can improve it. Your suggestion will be highly appreciated. If any one of you like to contribute with your ideas, please do not hesitate to | ||
create an [issue](https://github.com/justin-john/elet/issues) or make a [pull request](https://github.com/justin-john/elet/pulls) in repository. | ||
If you like to contact me, please come at <justinjohnmathews@gmail.com>. | ||
## License | ||
@@ -127,0 +134,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
87172
32
681
134