-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
120 lines (93 loc) · 3.01 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* @module status-codes/index
* @desc
* It exports the ecosystem-level response codes and statuses to use it as the quick-read human-friendly response of
* any API or the public method of the neighbour module.
*
* The idea is based on the JSON-RPC protocol spec.
*
* As a part of HTTP-API response it is better than http 1**-5** statuses (but the of them 418 is still unsurpassed),
* cause we can describe our business-logic as pizdato as we can using as much this codes as we need.
*
* ABSTRACT
* Client sends an http-api req.
* Server sends a JSON response with {status: {code: 106, message: 'WRONG_ARGS'}}.
* Client has the same statuses .js module (this module) as the server.
* Handling the response client calls codes.statusEqual(res.status, codes.WRONG_ARGS)
* and gets a bool value into the server's response handler code.
*
* Goals:
* - human-readability
* - one style of errors handling for all project ecosystem
* - one style of server response for all HTTP/WS apis
*/
/**
* A collection of statuses
*/
const statuses = require('./statuses')
/**
* It calls native Object.freeze() for the object
* and for all embed objects recursively
* @param obj {Object}
* @void
*/
function freezeObjectDeep (obj) {
Object.values(obj).forEach(val => {
if (typeof val === 'object' && !Array.isArray(val)) {
freezeObjectDeep(val)
}
})
Object.freeze(obj)
}
/**
* It is needed to make the statuses more human-friendly
* For e.x.
* input >>>
* {
* OK: 100,
* FAIL: 101,
* accounts: {
* EMAIL_EXISTS: 201
* }
* }
* ... magic ...
*
* output >>>
* {
* OK: { code: 100, message: OK },
* FAIL: { code: 101, message: 101 },
* accounts: {
* EMAIL_EXISTS: { code: 201, message: 201}
* }
* }
* @param values {Object}
* @returns {Object}
*/
function addMessagesToValues (values) {
Object.entries(values).forEach(([status, numeric_value]) => {
/** when we have a real <status-name>: <numeric-code> pair on the top level */
if (typeof values[status] === 'number') {
values[status] = {code: numeric_value, message: status}
/** if it is an object instead of the pair, we'll make a recursive call */
} else {
values[status] = addMessagesToValues(values[status])
}
})
return values
}
const codes = addMessagesToValues(statuses)
/** simply public comparison method which can short your RPC code ten times
* @function codes.statusEqual
* @param status1 {{code: Number, message: String}}
* @param status2 {{code: Number, message: String}}
* @returns boolean
* */
codes.statusEqual = (status1, status2) => {
if (!status1 || !status2 ||
!status1.code || !status2.code ||
!status1.message || !status2.message) return false
return (status1.code === status2.code && status1.message === status2.message)
}
/** Deep freezing the codes before export to prevent the accidental changes */
freezeObjectDeep(codes)
module.exports = {codes}