binhend 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # binhend
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ const { Binh } = require('../src/binh');
4
+
5
+ new Binh()
6
+ .id()
7
+ .rootpath(__dirname)
8
+ .config(function(loader) {
9
+ loader.object({ PORT: 1400 });
10
+ })
11
+ .api('routes')
12
+ .cluster.fork(-100)
13
+ .port(binh.config('PORT'))
14
+ .start(function(server, configs) {
15
+ console.log('### START >>> configs:', configs);
16
+ });
@@ -0,0 +1,15 @@
1
+ const { router, get, post } = binh().Router();
2
+
3
+ get('/', function(req, res) {
4
+ res.json({ path:'/', dir: __dirname, file: __filename });
5
+ });
6
+
7
+ get('/sub', function(req, res) {
8
+ res.json({ path:'/sub', dir: __dirname, file: __filename });
9
+ });
10
+
11
+ get('/goo', function(req, res) {
12
+ res.json({ path:'/goo', dir: __dirname, file: __filename });
13
+ });
14
+
15
+ module.exports = router;
@@ -0,0 +1,11 @@
1
+ const { router, get, post } = binh().Router();
2
+
3
+ get('/', function(req, res) {
4
+ res.json({ path:'/', dir: __dirname, file: __filename });
5
+ });
6
+
7
+ get('/sub', function(req, res) {
8
+ res.json({ path:'/sub', dir: __dirname, file: __filename });
9
+ });
10
+
11
+ module.exports = router;
@@ -0,0 +1,15 @@
1
+ const { router, get, post } = binh().Router();
2
+
3
+ get('/', function(req, res) {
4
+ res.json({ path:'/', dir: __dirname, file: __filename });
5
+ });
6
+
7
+ get('/sub', function(req, res) {
8
+ res.json({ path:'/sub', dir: __dirname, file: __filename });
9
+ });
10
+
11
+ get('/gaa', function(req, res) {
12
+ res.json({ path:'/gaa', dir: __dirname, file: __filename });
13
+ });
14
+
15
+ module.exports = router;
package/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /*
2
+ * anodejs
3
+ * Copyright(c) 2023 Nguyen Duc Binh
4
+ *
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ module.exports = require('./src/binh');
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "binhend",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "author": "Nguyen Duc Binh",
7
+ "license": "UNLICENSED",
8
+ "scripts": {
9
+ "test": "echo \"Error: no test specified\" && exit 1",
10
+ "example": "node example"
11
+ },
12
+ "dependencies": {
13
+ "express": "^4.17.1"
14
+ },
15
+ "devDependencies": {
16
+ },
17
+ "engines": {
18
+ "node": ">= 16.17.1"
19
+ }
20
+ }
package/src/api.js ADDED
@@ -0,0 +1,74 @@
1
+ const { readdir, statSync } = require('fs');
2
+ const { join, parse } = require('path');
3
+ // const { Router } = require('./router');
4
+ const express = require('express');
5
+
6
+ function mapAPIs(dirpath, router) {
7
+ readdir(dirpath, function(error, item_names) {
8
+ if (error) {
9
+ console.log('Error scanning items in directory:', dirpath, '. Error:', error);
10
+ return;
11
+ }
12
+
13
+ item_names.forEach(function(item) {
14
+ var path = join(dirpath, item),
15
+ route = parse(item).name;
16
+
17
+ try {
18
+ var stat = statSync(path);
19
+ var child_router;
20
+
21
+ if (stat.isFile()) {
22
+ child_router = require(path);
23
+ }
24
+
25
+ if (stat.isDirectory()) {
26
+ try {
27
+ child_router = require(path);
28
+ }
29
+ catch (error) {
30
+ child_router = Router().router;
31
+ }
32
+
33
+ mapAPIs(path, child_router);
34
+ }
35
+
36
+ router.use(`/${route}`, child_router);
37
+ console.log('[NODE] Mapping Restful APIs from:', path);
38
+ }
39
+ catch (error) {
40
+ console.log('Error check status of file path:', path, '. Error:', error);
41
+ }
42
+ });
43
+ });
44
+ }
45
+
46
+ function APIs(rootpath) {
47
+ const router = express.Router();
48
+ router.use(express.urlencoded({ extended: false }));
49
+ router.use(express.json());
50
+
51
+ rootpath = rootpath || join(__dirname, 'routes');
52
+
53
+ mapAPIs(rootpath, router);
54
+
55
+ return router;
56
+ }
57
+
58
+ function Router() {
59
+ var router = express.Router();
60
+
61
+ var output = { router };
62
+
63
+ for (var key in router) {
64
+ if (router[key] instanceof Function) {
65
+ output[key] = router[key].bind(router);
66
+ }
67
+ }
68
+
69
+ return output;
70
+ }
71
+
72
+ module.exports = {
73
+ APIs, Router
74
+ };
package/src/binh.js ADDED
@@ -0,0 +1,115 @@
1
+ const crypto = require('crypto');
2
+ const cluster = require('cluster');
3
+ const os = require('os');
4
+
5
+ const { ConfigLoader } = require('./configuration');
6
+ const { HTTPS } = require('./https');
7
+ const { Server } = require('./server');
8
+ const { APIs, Router } = require('./api');
9
+
10
+ const Crypto = require('./cryptography');
11
+
12
+ const maxcpus = os.cpus().length;
13
+
14
+ function generateId() {
15
+ crypto.randomUUID({ disableEntropyCache: true });
16
+ }
17
+
18
+ function Binh() {
19
+ var _this = this,
20
+ forkcount = 0,
21
+ rootpath = '';
22
+
23
+ var binh = function(module_path) {
24
+ return module_path == undefined ? module.exports : require(`${rootpath}/${module_path}`);
25
+ };
26
+
27
+ var config = {}, loadConfigs = null, configloader = new ConfigLoader(config);
28
+
29
+ binh.config = function(key) {
30
+ return typeof key === 'string' ? config[key] : config;
31
+ };
32
+
33
+ binh.config.reload = function() {
34
+ return new Promise(function(resolve) {
35
+ if (loadConfigs instanceof Function) {
36
+ var loader = new ConfigLoader(config);
37
+ loadConfigs(loader);
38
+ loader.done(resolve);
39
+ }
40
+ else resolve(config);
41
+ });
42
+ };
43
+
44
+ binh.config.loader = function() {
45
+ return new ConfigLoader(config);
46
+ };
47
+
48
+ global.binh = binh;
49
+
50
+ this.rootpath = function(path) {
51
+ rootpath = typeof path === 'string' ? path : '';
52
+ return this;
53
+ };
54
+
55
+ this.id = function(id) {
56
+ binh.id = id == undefined ? generateId() : JSON.stringify(id);
57
+ return this;
58
+ }
59
+
60
+ this.config = function(callback) {
61
+ if (callback instanceof Function) {
62
+ loadConfigs = callback;
63
+ callback(configloader);
64
+ }
65
+ return this;
66
+ }
67
+
68
+ this.cluster = {
69
+ fork: function(number) {
70
+ forkcount = Math.max(0, number >= 0 ? number : maxcpus + number);
71
+ return _this;
72
+ },
73
+ max: function() {
74
+ forkcount = maxcpus;
75
+ return _this;
76
+ }
77
+ };
78
+
79
+ this.api = function(api_path) {
80
+ this.api.value = new APIs(`${rootpath}/${api_path}`);
81
+ return this;
82
+ };
83
+
84
+ this.port = function(port) {
85
+ this.port.value = port;
86
+ return this;
87
+ };
88
+
89
+ this.start = function(callback) {
90
+ if (forkcount > 0 && cluster.isMaster) {
91
+ for (var i = 0; i < forkcount; i++) {
92
+ cluster.fork();
93
+ }
94
+ }
95
+ else {
96
+ launch(callback);
97
+ }
98
+ };
99
+
100
+ function launch(callback) {
101
+ configloader.done(function(configs) {
102
+ var server = new Server({
103
+ port: _this.port.value,
104
+ api: _this.api.value
105
+ });
106
+
107
+ if (callback instanceof Function) {
108
+ callback(server, configs);
109
+ }
110
+ });
111
+ }
112
+
113
+ }
114
+
115
+ module.exports = { Binh, HTTPS, ConfigLoader, Crypto, Router };
@@ -0,0 +1,145 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+
5
+ function ConfigLoader(config_object) {
6
+ const configs = config_object || {};
7
+
8
+ this.getConfigs = function() {
9
+ return configs;
10
+ };
11
+
12
+ function getConfigPosition(key) {
13
+ return key == undefined ? configs : (configs[key] = configs[key] || {});
14
+ };
15
+
16
+ this.object = function(object, key) {
17
+ try {
18
+ var config = getConfigPosition(key);
19
+ Object.assign(config, JSON.parse(JSON.stringify(object)));
20
+ }
21
+ catch(e) {
22
+ return failed(e, object);
23
+ }
24
+ return this;
25
+ };
26
+
27
+ this.json = function(filepath, key) {
28
+ return this.object(json(filepath), key);
29
+ };
30
+
31
+ this.cli = function(key) {
32
+ return this.object(cli(), key);
33
+ };
34
+
35
+ this.file = function(path, encoding, key) {
36
+ return this.object(file(path, encoding), key);
37
+ };
38
+
39
+ var deferred = [];
40
+
41
+ this.loadAsync = function(callback, key) {
42
+ var _this = this;
43
+ var promise = loadAsync(callback).then(function(loaded_config) {
44
+ _this.object(loaded_config, key);
45
+ });
46
+ deferred.push(promise);
47
+ return this;
48
+ };
49
+
50
+ this.done = function(callback) {
51
+ var _this = this;
52
+
53
+ setTimeout(function() {
54
+ Promise.all(deferred).then(function() {
55
+ deferred = [];
56
+ callback(_this.getConfigs());
57
+ });
58
+ });
59
+
60
+ return this;
61
+ };
62
+
63
+ this.target = function(config_object) {
64
+ return new ConfigLoader(config_object);
65
+ };
66
+ }
67
+
68
+ function json(filepath) {
69
+ try {
70
+ return require.main.require(filepath);
71
+ }
72
+ catch(e) {
73
+ return failed(e, filepath);
74
+ }
75
+ }
76
+
77
+ function cli() {
78
+ return processKeyValueStrings(process.argv);
79
+ }
80
+
81
+ function file(path, encoding) {
82
+ encoding = encoding || 'utf8';
83
+ try {
84
+ var source = fs.readFileSync(path, { encoding });
85
+ source = source.replace(/\r\n?/mg, '\n');
86
+ var lines = source.split('\n');
87
+
88
+ return processKeyValueStrings(lines);
89
+ }
90
+ catch(e) {
91
+ return failed(e, path);
92
+ }
93
+ }
94
+
95
+ function processKeyValueStrings(strings) {
96
+ var output = {};
97
+
98
+ if (strings == undefined || !strings.length) {
99
+ return output;
100
+ }
101
+
102
+ var regex_is_comment = /^#/;
103
+
104
+ strings.forEach(function(string) {
105
+ if (regex_is_comment.test(string.trim())) return;
106
+
107
+ var parsed = parseKeyValue(string);
108
+ if (parsed.success) {
109
+ output[parsed.key] = parsed.value;
110
+ }
111
+ });
112
+
113
+ return output;
114
+ }
115
+
116
+ function parseKeyValue(string) {
117
+ var delimiter = '=';
118
+
119
+ var parts = string.split(delimiter);
120
+ if (parts.length < 2) return { success: false };
121
+
122
+ var key = parts[0];
123
+ var value = parts.splice(1).join(delimiter);
124
+
125
+ return { key, value, success: true };
126
+ }
127
+
128
+ function loadAsync(callback) {
129
+ return new Promise(callback);
130
+ }
131
+
132
+ function config(config_object) {
133
+ return new ConfigLoader(config_object);
134
+ }
135
+
136
+ function failed(error, source) {
137
+ console.log(`Failed loading config from: ${source}`);
138
+ console.log('Details:', error);
139
+ return {};
140
+ };
141
+
142
+ module.exports = {
143
+ ConfigLoader, config,
144
+ json, cli, file, loadAsync
145
+ };
@@ -0,0 +1,49 @@
1
+
2
+ const crypto = require('crypto');
3
+ const algorithm = 'aes-256-cbc';
4
+ const lenght_iv = 16;
5
+ const lenght_key = 32;
6
+
7
+ function generateSecurityKey() {
8
+ return crypto.randomBytes(lenght_key).toString('hex');
9
+ }
10
+
11
+ function generateInitialVector() {
12
+ return crypto.randomBytes(lenght_iv).toString('hex');
13
+ }
14
+
15
+ function encrypt(text, key, iv) {
16
+ key = Buffer.from(key, 'hex');
17
+ iv = Buffer.from(iv, 'hex');
18
+ var cipher = crypto.createCipheriv(algorithm, key, iv);
19
+ var encrypted = cipher.update(text, 'utf-8', 'hex');
20
+ encrypted += cipher.final('hex');
21
+ return encrypted;
22
+ }
23
+
24
+ function decrypt(encrypted, key, iv) {
25
+ key = Buffer.from(key, 'hex');
26
+ iv = Buffer.from(iv, 'hex');
27
+ var decipher = crypto.createDecipheriv(algorithm, key, iv);
28
+ var decrypted = decipher.update(encrypted, 'hex', 'utf-8');
29
+ decrypted += decipher.final('utf8');
30
+ return decrypted;
31
+ }
32
+
33
+ function hash(text, encoding = 'hex', length = 256) {
34
+ return new Promise(function(resolve, reject) {
35
+ var salt = crypto.randomBytes(32).toString('hex'),
36
+ options = { N: 16, r: 8, p: 1 };
37
+
38
+ crypto.scrypt(text, salt, length, options, (err, derivedKey) => {
39
+ if (err) return reject(err);
40
+ resolve(derivedKey.toString(encoding));
41
+ });
42
+ });
43
+ }
44
+
45
+ module.exports = {
46
+ encrypt, decrypt, hash,
47
+ generateSecurityKey,
48
+ generateInitialVector
49
+ };
package/src/https.js ADDED
@@ -0,0 +1,93 @@
1
+
2
+ const https = require('https');
3
+
4
+ function HTTPS(url) {
5
+ this.url = url;
6
+ this.parameters = [];
7
+ };
8
+
9
+ var prototype = HTTPS.prototype;
10
+
11
+ prototype.get = function(callback) {
12
+ return this.request('GET', callback);
13
+ }
14
+
15
+ prototype.post = function(callback) {
16
+ return this.request('POST', callback);
17
+ }
18
+
19
+ prototype.request = function(method, callback) {
20
+
21
+ var URL = this.url + this.parameters.join('/') + (this.queries || '');
22
+
23
+ var options = {
24
+ method,
25
+ headers: this.headers
26
+ };
27
+
28
+ var req = https.request(URL, options, function(res) {
29
+ res.setEncoding('utf8');
30
+
31
+ var data = '';
32
+
33
+ res.on('data', (chunk) => {
34
+ data += chunk;
35
+ });
36
+
37
+ res.on('end', () => {
38
+ var response;
39
+
40
+ try {
41
+ response = JSON.parse(data);
42
+ }
43
+ catch(error) {
44
+ response = data;
45
+ }
46
+
47
+ if (callback instanceof Function) {
48
+ callback(response);
49
+ }
50
+ });
51
+ });
52
+
53
+ req.on("error", (err) => {
54
+ console.log("HTTPS request encounters error:" + err.message);
55
+ });
56
+
57
+ if (this.payload) {
58
+ req.write(JSON.stringify(this.payload));
59
+ }
60
+
61
+ req.end();
62
+
63
+ return this;
64
+ }
65
+
66
+ prototype.header = function(map) {
67
+ this.headers = map;
68
+ return this;
69
+ }
70
+
71
+ prototype.body = function(map) {
72
+ this.payload = JSON.stringify(map);
73
+ return this;
74
+ }
75
+
76
+ prototype.parameter = function(array) {
77
+ if (array instanceof Array) {
78
+ var last_char = this.url[this.url.length - 1];
79
+ this.parameters = (last_char === '/' ? [] : ['']).concat(array);
80
+ }
81
+ return this;
82
+ }
83
+
84
+ prototype.query = function(map) {
85
+ var query_string = '';
86
+ for (var key in map) {
87
+ query_string += key + '=' + map[key] + '&';
88
+ }
89
+ this.queries = '?' + query_string;
90
+ return this;
91
+ }
92
+
93
+ module.exports = { HTTPS };
package/src/server.js ADDED
@@ -0,0 +1,18 @@
1
+ const express = require('express');
2
+
3
+ function Server(options) {
4
+ const server = express();
5
+ const PORT = options.port || 1300;
6
+
7
+ if (options.api) {
8
+ server.use(options.api);
9
+ }
10
+
11
+ server.listen(PORT, function() {
12
+ console.log(`[NODE] Server is listening on http://localhost:${PORT}/`);
13
+ });
14
+
15
+ return server;
16
+ }
17
+
18
+ module.exports = { Server };
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "palindrome",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "directories": {
7
+ "test": "test"
8
+ },
9
+ "scripts": {
10
+ "test": "istanbul cover node_modules/mocha/bin/_mocha"
11
+ },
12
+ "author": "",
13
+ "license": "ISC",
14
+ "devDependencies": {
15
+ "chai": "^3.5.0",
16
+ "istanbul": "^0.4.4",
17
+ "mocha": "^3.0.1"
18
+ }
19
+ }