help-me-respond
Advanced tools
Comparing version 1.2.1 to 2.0.0
170
index.js
@@ -1,10 +0,47 @@ | ||
const CONFIG = require("config") | ||
const TOOLS = require('./tools') | ||
const I18N = require('i18n-nodejs')(CONFIG.lang, CONFIG.langFile); | ||
const MESSAGES = require('./messages') | ||
let CONFIG = {}; | ||
let USER_DEFINED_MESSAGES = {}; | ||
let I18N = null; | ||
try { | ||
CONFIG = require("../../config/default"); | ||
} catch (e) { | ||
CONFIG = require('./_default'); | ||
} | ||
try { | ||
USER_DEFINED_MESSAGES = require('../../config/messages'); | ||
} catch (e) { | ||
USER_DEFINED_MESSAGES = require('./_messages'); | ||
} | ||
if (CONFIG && CONFIG.lang && CONFIG.langFile) { | ||
I18N = require('i18n-nodejs')(CONFIG.lang, CONFIG.langFile); | ||
} | ||
const TOOLS = require('./tools'); | ||
const MESSAGES = require('./messages'); | ||
function checkMessage(msg, code) { | ||
if (!msg) { | ||
switch (code) { | ||
case 400: | ||
msg = MESSAGES.BAD_REQUEST; | ||
break; | ||
case 401: | ||
msg = MESSAGES.UNAUTHORIZED; | ||
break; | ||
case 403: | ||
msg = MESSAGES.FORBIDDEN; | ||
break; | ||
case 404: | ||
msg = MESSAGES.NOT_FOUND; | ||
break; | ||
} | ||
} | ||
return msg; | ||
} | ||
function http400(res, msg, headers) { | ||
if (!msg || msg == undefined) { | ||
msg = MESSAGES.BAD_REQUEST; | ||
} | ||
msg = checkMessage(msg, 400); | ||
return rCode(400, res, msg, headers); | ||
@@ -14,5 +51,3 @@ } | ||
function http404(res, msg, headers) { | ||
if (!msg || msg == undefined) { | ||
msg = MESSAGES.NOT_FOUND; | ||
} | ||
msg = checkMessage(msg, 404); | ||
return rCode(404, res, msg, headers); | ||
@@ -22,5 +57,3 @@ } | ||
function http403(res, msg, headers) { | ||
if (!msg || msg == undefined) { | ||
msg = MESSAGES.FORBIDDEN; | ||
} | ||
msg = checkMessage(msg, 403); | ||
return rCode(403, res, msg, headers); | ||
@@ -30,26 +63,11 @@ } | ||
function http401(res, msg, headers) { | ||
if (!msg || msg == undefined) { | ||
msg = MESSAGES.UNAUTHENTICATED; | ||
} | ||
msg = checkMessage(msg, 401); | ||
return rCode(401, res, msg, headers); | ||
} | ||
function http502(res, resp, body) { | ||
let code = 502; | ||
let headers = ''; | ||
if (resp !== undefined && resp !== null) { | ||
code = resp.statusCode; | ||
headers = resp.headers; | ||
} | ||
return rCode( | ||
502, | ||
res, { | ||
statusCode: code, | ||
message: body | ||
}, | ||
headers | ||
); | ||
function httpSuccess(res, msg, headers) { | ||
return rCode(200, res, msg, headers); | ||
} | ||
function httpSuccess(res, msg, headers) { | ||
function http200(res, msg, headers) { | ||
return rCode(200, res, msg, headers); | ||
@@ -62,2 +80,6 @@ } | ||
function http204(res, msg, headers) { | ||
return rCode(204, res, msg, headers); | ||
} | ||
function rCode(code, res, msg, headers) { | ||
@@ -69,30 +91,14 @@ let args = null | ||
code = code ? code : 400; | ||
// empty message is ok | ||
msg = msg ? msg : ''; | ||
res.status(code); | ||
res = res.status(code); | ||
// if user set some headers | ||
if (headers && headers !== undefined) { | ||
if (!CONFIG.disableJsonHeader) { | ||
headers['content-type'] = 'application/json'; | ||
} | ||
res = res.header(headers); | ||
} else { | ||
if (!CONFIG.disableJsonHeader) { | ||
let headers = {} | ||
headers['content-type'] = 'application/json'; | ||
res = res.header(headers); | ||
} | ||
} | ||
setHeaders(headers, res); | ||
//// RETRIEVE THE MESSAGE FROM ERR OBJECT | ||
if (code >= 400 && msg instanceof Error) { | ||
stack = msg.stack.split('\n'); | ||
stack.splice(0, 1); | ||
stack.splice(0, 1) | ||
msg = msg.message.toString(); | ||
} | ||
if (code == 502 && msg.message && msg.statusCode && msg.message instanceof Error) { | ||
msg.message = msg.message.message.toString() | ||
} | ||
// DECODE JSON STRING -> placeholders for localizaiton only | ||
if (TOOLS.isJsonString(msg)) { | ||
@@ -108,8 +114,9 @@ let jsonObj = JSON.parse(msg) | ||
// friendly messages for users | ||
// USER friendly message | ||
if (checkFriendly(msg)) { | ||
msg = { | ||
friendlyMessage: I18N.__(msg, args) | ||
friendlyMessage: getMessage(msg, args) | ||
} | ||
} else if (msg && msg instanceof Object) { | ||
// DATA message | ||
if (CONFIG && !CONFIG.prefixNone) { | ||
@@ -120,12 +127,5 @@ msg = { | ||
} | ||
} else if (code == 502) { | ||
if (checkFriendly(msg.message)) { | ||
msg.friendlyMessage = I18N.__(msg.message, args) | ||
delete msg.message | ||
} else { | ||
msg.message = I18N.__(msg.message, args) | ||
} | ||
} else { | ||
msg = { | ||
message: I18N.__(msg, args), | ||
message: getMessage(msg, args), | ||
stack: stack | ||
@@ -136,18 +136,34 @@ } | ||
if (code >= 400) { | ||
if (!msg) { | ||
msg = {}; | ||
} | ||
msg = { | ||
code: code, | ||
error: msg | ||
error: msg, | ||
} | ||
} | ||
if (msg.message == '') { | ||
return res.send(); | ||
} else { | ||
return CONFIG.disableJsonHeader ? res.send(msg) : res.json(msg); | ||
return (CONFIG && CONFIG.disableJsonHeader) ? res.send(msg) : res.json(msg); | ||
} | ||
} | ||
/** | ||
* Does on of | ||
* 1. uses localization lib to translate the messages | ||
* 2. finds the message in user defined messages file | ||
* 3. returns messages as it is | ||
*/ | ||
function getMessage(msg, args) { | ||
let result = null; | ||
if (I18N) { | ||
result = I18N.__(msg, args); | ||
} | ||
// we found translation for this msg in locales file | ||
if (result !== msg) { | ||
return result; | ||
} | ||
if (USER_DEFINED_MESSAGES[msg]) { | ||
return USER_DEFINED_MESSAGES[msg]; | ||
} | ||
return msg; | ||
} | ||
function checkFriendly(msg) { | ||
@@ -157,5 +173,13 @@ if (CONFIG && CONFIG.friendlyMessages) { | ||
} | ||
return false | ||
return false; | ||
} | ||
function setHeaders(headers, res) { | ||
headers = headers ? headers : {}; | ||
if (CONFIG && !CONFIG.disableJsonHeader) { | ||
headers['content-type'] = 'application/json'; | ||
} | ||
res.header(headers); | ||
} | ||
module.exports = { | ||
@@ -166,5 +190,7 @@ http400, | ||
http401, | ||
http502, | ||
http200, | ||
http201, | ||
http204, | ||
httpSuccess, | ||
rCode | ||
} |
module.exports = { | ||
FORBIDDEN: 'FORBIDDEN', | ||
NOT_FOUND: 'NOT FOUND', | ||
UNAUTHENTICATED: 'UNAUTHENTICATED', | ||
BAD_REQUEST: 'BAD_REQUEST' | ||
UNAUTHORIZED: 'UNAUTHORIZED', | ||
BAD_REQUEST: 'BAD REQUEST' | ||
} |
{ | ||
"name": "help-me-respond", | ||
"version": "1.2.1", | ||
"description": "Simple nodejs response helper", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"keywords": [ | ||
"node response", | ||
"nodejs response", | ||
"response helper", | ||
"symphonyno9", | ||
"express response" | ||
], | ||
"author": "Daria Mikhailova <drmikhailova@gmail.com>", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/Symphony9/help-me-respond" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/Symphony9/help-me-respond/issues" | ||
}, | ||
"license": "ISC", | ||
"dependencies": { | ||
"config": "^1.25.1", | ||
"i18n-nodejs": "^2.0.0" | ||
} | ||
"name": "help-me-respond", | ||
"version": "2.0.0", | ||
"description": "Simple nodejs Express http response helper", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"keywords": [ | ||
"http response", | ||
"node http response", | ||
"node response", | ||
"nodejs response", | ||
"nodejs http response", | ||
"response helper", | ||
"http response helper", | ||
"symphonyno9", | ||
"express response", | ||
"express http response" | ||
], | ||
"author": "Daria Mikhailova <drmikhailova@gmail.com>", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/Symphony9/help-me-respond" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/Symphony9/help-me-respond/issues" | ||
}, | ||
"license": "ISC", | ||
"dependencies": { | ||
"i18n-nodejs": "^2.0.0", | ||
"mocha": "^4.1.0" | ||
} | ||
} |
122
README.md
## Help me respond | ||
This is a simple response helper which should make you life a bit easier. It supports localization and friendly messages for users. | ||
Help-me-respond preconfigures HTTP responses for you by setting up the status code, processing the message and setting headers. You only need to call one of the API functions and pass the message in a form of a string or an object to it. | ||
This is a simple response helper which should make your life a bit easier. It supports localization and friendly messages for users. | ||
Help-me-respond preconfigures HTTP responses for you by setting the status code, processing the message and setting headers. You only need to call one of the API functions and pass the message in a form of a string or an object to it. | ||
## UPDATES | ||
08.01.2018 | ||
The library became lighter! :) I removed config library dependency in order to minimize dependencies, however you can still use it since the config folder structure I am following here is the same as for the [node-config](https://github.com/lorenwest/node-config); | ||
The library is easier to configure. No need to configure anything :) Just start using it! | ||
Localization became optional. | ||
**BREAKING CHANGES**: | ||
Removed *code* key from the error response message object. If u were using this, please use the code in the Express HTTP Response object. | ||
Removed `http502`. | ||
## Prerequisites for usage | ||
Your project is a nodejs server based on Express or something similar. Help-me-respond uses the res object from Express, which represents the HTTP response that an Express app sends when it gets an HTTP request. | ||
Your project is a nodejs server based on Express or something similar. Help-me-respond uses the res object from Express, which represents an HTTP response. | ||
@@ -15,12 +32,44 @@ ## Setup | ||
npm i help-me-respond --save | ||
```` | ||
*OPTIONAL*: Create *config/messages.json* file. We don't want our messages to be hardcoded in the code, so we will keep them in a separate file. | ||
``` | ||
{ | ||
"MESSAGE_NAME1": "Very long and important message text.", | ||
"MESSAGE_NAME2": "Very long and important message text2." | ||
} | ||
``` | ||
### Config setup | ||
## Configuration | ||
Create a config folder and put **default.json** in it. (more cool config setup at https://github.com/lorenwest/node-config). | ||
All the configurations are put in **config/** folder in the root of your project. | ||
You will need to add the following to your **default.json** file. File naming is up to you :) This is a basic setup for the i18n-nodejs - https://github.com/eslam-mahmoud/i18n-nodejs | ||
### User friendly messages | ||
Some messages returned from the server are too technical for users. So we would like to differentiate between those messages and user friendly messages. See example below. You can use it for messages in *messages.json* or *locales.json* | ||
**config/messages.json** | ||
{ | ||
"messageOne": "This is the first message", | ||
"messageTwo": "This is the second message" | ||
} | ||
**config/default.json** | ||
{ | ||
"friendlyMessages": ["messageOne", "messageTwo"] | ||
} | ||
Once the message name is in the above array, the response will have a key **friendlyMessage** which makes it easy for front-end to differentiate between messages. | ||
### Localization | ||
You will need to add the following to your **config/default.json** file. This is a basic setup for the i18n-nodejs - https://github.com/eslam-mahmoud/i18n-nodejs | ||
{ | ||
"lang": "en", | ||
@@ -36,7 +85,7 @@ "langFile": "../../config/locales.json" | ||
{ | ||
"NO_SHARING_WITH_YOURSELF": { | ||
"en": "You cannot share the link with yourslef" | ||
"SHARING_ERROR": { | ||
"en": "You cannot share the link with yourself." | ||
}, | ||
"NOT_OWNER": { | ||
"en": "You are not the owner" | ||
"en": "You are not the owner." | ||
} | ||
@@ -46,15 +95,21 @@ } | ||
* Setup friendly messages. | ||
### Pass arguments to your messages | ||
Some messages returned from the server are too technical for the user. So we would like to differentiate between those messages and user friendly messages. Simply add the following to your **default.json** configuration file. Now you can add message names in the friendlyMessages array. | ||
This works only if you are using localization. | ||
**config/locales.json** | ||
{ | ||
"friendlyMessages": [] | ||
"welcome": "Welcome dear {{name}}", | ||
} | ||
**somewhere in the code** | ||
Once the message name is in the above array, the response will have a key **friendlyMessage** which makes it easy for front-end to differentiate between messages. | ||
http200(res, JSON.stringify({ | ||
msg: 'welcome', | ||
args: { | ||
name: 'Mike' | ||
} | ||
})); | ||
## Configuration | ||
### Turn off data prefix | ||
@@ -99,18 +154,14 @@ When you server returns any data, a prefix **data** is added to response. | ||
#### http200(res, msg, headers) | ||
returns HTTP response with 201 success code | ||
#### http502(res, response, headers) | ||
response - an Express response object | ||
returns HTTP response with 502 error code | ||
This can be used when you are quering third party API. E.g. You will receive an error reponse for you request. You can call this function with the original response object. This way you will differentiate between you own server errors and third party API problems | ||
#### http201(res, msg, headers) | ||
returns HTTP response with 201 success code | ||
#### httpSuccess(res, msg, headers) | ||
returns HTTP response with 200 success code | ||
#### http204(res, msg, headers) | ||
returns HTTP response with 204 code | ||
#### http201(res, msg, headers) | ||
returns HTTP response with 201 success code | ||
#### rCode(code, res, msg, headers) | ||
@@ -138,3 +189,2 @@ general function to return any HTTP code you want | ||
{ | ||
"code": 400, | ||
"error": { | ||
@@ -150,5 +200,23 @@ "friendlyMessage": "I am a friendly error message" | ||
"error": { | ||
"message": "I am a very technical error message that users do not want to see" | ||
"message": "I am a very technical error message that users do not want to see", | ||
"stack": [ | ||
'at /Users/XX/Projects/help-me-respond/test/responseErrorTest.js:28:9', | ||
'at DUMMY_ERROR_OBJECT (/Users/Dasha/Projects/help-me-respond/test/responseErrorTest.js:27:9)', | ||
'at Context.<anonymous> (/Users/Dasha/Projects/help-me-respond/test/responseErrorTest.js:72:3)', | ||
'at callFn (/usr/local/Cellar/node/0.12.7/libexec/npm/lib/node_modules/mocha/lib/runnable.js:334:21)' | ||
] | ||
} | ||
} | ||
``` | ||
### Data response | ||
``` | ||
{ | ||
"data": { | ||
"item1": "name", | ||
"item2": "name" | ||
} | ||
} | ||
``` |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
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
16400
8
374
217
2
1
+ Addedmocha@^4.1.0
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedbrowser-stdout@1.3.0(transitive)
+ Addedcommander@2.11.0(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addeddebug@3.1.0(transitive)
+ Addeddiff@3.3.1(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.1.2(transitive)
+ Addedgrowl@1.10.3(transitive)
+ Addedhas-flag@2.0.0(transitive)
+ Addedhe@1.1.1(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedminimist@0.0.8(transitive)
+ Addedmkdirp@0.5.1(transitive)
+ Addedmocha@4.1.0(transitive)
+ Addedms@2.0.0(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedsupports-color@4.4.0(transitive)
+ Addedwrappy@1.0.2(transitive)
- Removedconfig@^1.25.1
- Removedconfig@1.31.0(transitive)
- Removedjson5@1.0.2(transitive)
- Removedminimist@1.2.8(transitive)