molly-db 1.0.4 → 1.0.5
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/main.js +45 -5
- package/module/_crypto_.js +65 -0
- package/module/_init_.js +68 -0
- package/module/_server_.js +281 -0
- package/module/_worker_.js +42 -0
- package/package.json +21 -4
- package/module/localDB.js +0 -415
- package/module/readline.js +0 -208
- package/module/streamDB.js +0 -200
- package/module/webDB.js +0 -377
package/main.js
CHANGED
@@ -1,7 +1,47 @@
|
|
1
|
-
const
|
1
|
+
const worker = require('worker_threads');
|
2
|
+
const fetch = require('axios');
|
3
|
+
const url = require('url');
|
4
|
+
const fs = require('fs');
|
2
5
|
|
3
|
-
|
4
|
-
try{ output.localDB = require('./module/localDB'); } catch(e) { /*console.log(e)*/ }
|
5
|
-
try{ output.webDB = require('./module/webDB'); } catch(e) { /*console.log(e)*/ }
|
6
|
+
/* --------------------------------------------------------------------------------------- */
|
6
7
|
|
7
|
-
|
8
|
+
function config( _config ) {
|
9
|
+
const _default = { offset:0, length:100 };
|
10
|
+
if( !_config ) return _default;
|
11
|
+
Object.keys(_config).map(x=>{
|
12
|
+
_default[x] = _config[x];
|
13
|
+
});
|
14
|
+
}
|
15
|
+
|
16
|
+
/* --------------------------------------------------------------------------------------- */
|
17
|
+
|
18
|
+
class molly_db{
|
19
|
+
|
20
|
+
constructor( opt ){
|
21
|
+
return new Promise((response,reject)=>{
|
22
|
+
if( opt.pass )
|
23
|
+
this.pass = opt.pass;
|
24
|
+
this.port = opt.port || 27017;
|
25
|
+
this.type = opt.type || 'local';
|
26
|
+
this.path = opt.path.replace(/^\./,process.cwd());
|
27
|
+
|
28
|
+
if( this.worker ) return console.log(`server is running`);
|
29
|
+
|
30
|
+
this.worker = new worker.Worker(
|
31
|
+
`${__dirname}/module/_worker_`,{
|
32
|
+
env: worker.SHARE_ENV,
|
33
|
+
workerData: this
|
34
|
+
}
|
35
|
+
);
|
36
|
+
|
37
|
+
this.worker.on('exit',(err)=>{ });
|
38
|
+
this.worker.on('error',(err)=>{ });
|
39
|
+
this.worker.on('message',(msg)=>{ console.log(msg); response(); });
|
40
|
+
});
|
41
|
+
}
|
42
|
+
|
43
|
+
}
|
44
|
+
|
45
|
+
/* --------------------------------------------------------------------------------------- */
|
46
|
+
|
47
|
+
module.exports = molly_db;
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
const crypto = require('crypto-js');
|
3
|
+
const output = new Object();
|
4
|
+
|
5
|
+
/* -------------------------------------------------------------------------------------------------------- */
|
6
|
+
|
7
|
+
const JsonFormatter = {
|
8
|
+
|
9
|
+
'stringify': function(cipherParams) {
|
10
|
+
var jsonObj = { ct: cipherParams.ciphertext.toString(crypto.enc.Base64) };
|
11
|
+
if (cipherParams.salt) jsonObj.s = cipherParams.salt.toString();
|
12
|
+
if (cipherParams.iv) jsonObj.iv = cipherParams.iv.toString();
|
13
|
+
return new Buffer.from(JSON.stringify(jsonObj)).toString('base64');
|
14
|
+
},
|
15
|
+
|
16
|
+
'parse': function(jsonStr) {
|
17
|
+
var jsonObj = JSON.parse( new Buffer.from(jsonStr,'base64').toString());
|
18
|
+
var cipherParams = crypto.lib.CipherParams.create({
|
19
|
+
ciphertext: crypto.enc.Base64.parse(jsonObj.ct)
|
20
|
+
});
|
21
|
+
if (jsonObj.iv) cipherParams.iv = crypto.enc.Hex.parse(jsonObj.iv);
|
22
|
+
if (jsonObj.s) cipherParams.salt = crypto.enc.Hex.parse(jsonObj.s);
|
23
|
+
return cipherParams;
|
24
|
+
}
|
25
|
+
|
26
|
+
};
|
27
|
+
|
28
|
+
/* --------------------------------------------------------------------------------------- */
|
29
|
+
|
30
|
+
output.slugify = (str)=>{
|
31
|
+
const map = {
|
32
|
+
'c' : 'ç',
|
33
|
+
'n' : 'ñ',
|
34
|
+
'e' : 'é|è|ê|ë',
|
35
|
+
'i' : 'í|ì|î|ï',
|
36
|
+
'u' : 'ú|ù|û|ü',
|
37
|
+
'o' : 'ó|ò|ô|õ|ö',
|
38
|
+
'a' : 'á|à|ã|â|ä',
|
39
|
+
'' : /\s+|\W+/,
|
40
|
+
};
|
41
|
+
for (var pattern in map) {
|
42
|
+
str=str.replace( new RegExp(map[pattern],'gi' ), pattern);
|
43
|
+
} return str.toLowerCase();
|
44
|
+
}
|
45
|
+
|
46
|
+
output.encrypt = ( _message,_password )=>{
|
47
|
+
try{if( _password )
|
48
|
+
return crypto.AES.encrypt( _message,_password,{
|
49
|
+
format: JsonFormatter
|
50
|
+
}).toString(); return _message;
|
51
|
+
} catch(e) { return _message; }
|
52
|
+
}
|
53
|
+
|
54
|
+
output.decrypt = ( _message,_password )=>{
|
55
|
+
try{if( _password )
|
56
|
+
return crypto.AES.decrypt( _message,_password,{
|
57
|
+
format: JsonFormatter
|
58
|
+
}).toString( crypto.enc.Utf8 );
|
59
|
+
return _message;
|
60
|
+
} catch(e) { return _message; }
|
61
|
+
}
|
62
|
+
|
63
|
+
/* -------------------------------------------------------------------------------------------------------- */
|
64
|
+
|
65
|
+
module.exports = output;
|
package/module/_init_.js
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
function fillDB( _db, _table, _path ){
|
3
|
+
return new Promise(async(response,reject)=>{
|
4
|
+
|
5
|
+
let _itr = undefined;
|
6
|
+
|
7
|
+
if( (/^http/).test(_path) ){
|
8
|
+
const stream = await fetch.get(_path,{responseType:'stream'});
|
9
|
+
_itr = readline.createInterface({
|
10
|
+
input: stream.data
|
11
|
+
});
|
12
|
+
|
13
|
+
} else
|
14
|
+
_itr = readline.createInterface({
|
15
|
+
input: fs.createReadStream(_path)
|
16
|
+
});
|
17
|
+
|
18
|
+
_itr.on('close',()=>{ response() });
|
19
|
+
_itr.on('line',(line)=>{
|
20
|
+
db[_db][_table].push(crypto.decrypt( line,query.pass ));
|
21
|
+
});
|
22
|
+
|
23
|
+
});
|
24
|
+
}
|
25
|
+
|
26
|
+
/* --------------------------------------------------------------------------------------- */
|
27
|
+
|
28
|
+
(async()=>{
|
29
|
+
try {
|
30
|
+
|
31
|
+
const path = `${query.path}/_init_.json`;
|
32
|
+
|
33
|
+
if( (/^http/).test(query.path) ){
|
34
|
+
const stream = await fetch.get(path);
|
35
|
+
db._init_ = stream.data;
|
36
|
+
} else{
|
37
|
+
db._buff_ = fs.readFileSync( path );
|
38
|
+
db._init_ = JSON.parse( db._buff_ );
|
39
|
+
}
|
40
|
+
|
41
|
+
db._path_ = query.path;
|
42
|
+
for( var i in db._init_.DB ){
|
43
|
+
|
44
|
+
const DB = db._init_.DB[i];
|
45
|
+
const name = DB.name;
|
46
|
+
|
47
|
+
db[name] = new Object();
|
48
|
+
|
49
|
+
for( var j in DB.tables ){
|
50
|
+
const table = DB.tables[j];
|
51
|
+
const path = `${db._path_}/${table}.json`;
|
52
|
+
db[name][table] = new Array();
|
53
|
+
await fillDB( name,table,path );
|
54
|
+
}
|
55
|
+
|
56
|
+
}
|
57
|
+
|
58
|
+
} catch(e) {
|
59
|
+
|
60
|
+
const path = `${query.path}/_init_.json`;
|
61
|
+
db._buff_ = fs.readFileSync( path );
|
62
|
+
db._path_ = query.path;
|
63
|
+
db._init_ = { DB:[] }
|
64
|
+
|
65
|
+
fs.writeFileSync( path,db._init_ );
|
66
|
+
|
67
|
+
} response();
|
68
|
+
})();
|
@@ -0,0 +1,281 @@
|
|
1
|
+
|
2
|
+
function text( _data ){
|
3
|
+
res.writeHead(200,{'contetn-type':'text/plain'});
|
4
|
+
res.end( _data );
|
5
|
+
}
|
6
|
+
|
7
|
+
function error( _error ){
|
8
|
+
res.writeHead(200,{'contetn-type':'text/plain'});
|
9
|
+
res.end(`error: ${_error.message}`);
|
10
|
+
console.log(_error);
|
11
|
+
}
|
12
|
+
|
13
|
+
function json( _data ){
|
14
|
+
res.writeHead(200,{'content-type':'application/json'});
|
15
|
+
res.end(JSON.stringify(_data));
|
16
|
+
}
|
17
|
+
|
18
|
+
/* --------------------------------------------------------------------------------------- */
|
19
|
+
|
20
|
+
function getBody(){
|
21
|
+
return new Promise((response,reject)=>{
|
22
|
+
if( req.method == 'POST' ){
|
23
|
+
const data = new Array();
|
24
|
+
req.on('data',(chunk)=>{ data.push(chunk); });
|
25
|
+
req.on('close',()=>{ response( Buffer.concat(data).toString() ); });
|
26
|
+
} else { reject() }
|
27
|
+
});
|
28
|
+
}
|
29
|
+
|
30
|
+
function encryptDB( _db,_table, _path ){
|
31
|
+
return new Promise((response,reject)=>{
|
32
|
+
const writable = fs.createWriteStream( _path+'_tmp' );
|
33
|
+
for( var i in db[_db][_table] ){
|
34
|
+
|
35
|
+
const data = db[_db][_table][i];
|
36
|
+
const ecrp = crypto.encrypt( data,query.pass );
|
37
|
+
|
38
|
+
writable.write(`${ecrp}\n`);
|
39
|
+
} writable.end();
|
40
|
+
|
41
|
+
writable.on('close',()=>{
|
42
|
+
fs.renameSync( _path+'_tmp', _path );
|
43
|
+
response('done');
|
44
|
+
});
|
45
|
+
|
46
|
+
writable.on('error',(e)=>{
|
47
|
+
reject(e);
|
48
|
+
});
|
49
|
+
});
|
50
|
+
}
|
51
|
+
|
52
|
+
/* --------------------------------------------------------------------------------------- */
|
53
|
+
|
54
|
+
function list( _params ){
|
55
|
+
return db[_params.db][_params.table].slice(
|
56
|
+
_params.offset, Number(_params.offset)+Number(_params.length)
|
57
|
+
).map(x=>JSON.parse(x));
|
58
|
+
}
|
59
|
+
|
60
|
+
function match( _params ){
|
61
|
+
const result = new Array();
|
62
|
+
db[_params.db][_params.table].map((x)=>{
|
63
|
+
const regex = new RegExp(crypto.slugify(_params.target),'gi');
|
64
|
+
const target = crypto.slugify(x);
|
65
|
+
if( regex.test(target) ) result.push(x);
|
66
|
+
}).slice(
|
67
|
+
_params.offset, Number(_params.offset)+Number(_params.length)
|
68
|
+
); return result.map(x=>JSON.parse(x));
|
69
|
+
}
|
70
|
+
|
71
|
+
function hash( _params ){
|
72
|
+
const result = new Array();
|
73
|
+
db[_params.db][_params.table].map((x)=>{
|
74
|
+
const regex = new RegExp(_params.target,'gi');
|
75
|
+
if( regex.test(x) ) result.push(x);
|
76
|
+
}).slice(
|
77
|
+
_params.offset, Number(_params.offset)+Number(_params.length)
|
78
|
+
); return result.map(x=>JSON.parse(x));
|
79
|
+
}
|
80
|
+
|
81
|
+
/* --------------------------------------------------------------------------------------- */
|
82
|
+
|
83
|
+
function shift( _params ){
|
84
|
+
const result = db[_params.db][_params.table].shift();
|
85
|
+
modifyDB( _params.db,_params.table ); return result;
|
86
|
+
}
|
87
|
+
|
88
|
+
function pop( _params ){
|
89
|
+
const result = db[_params.db][_params.table].pop();
|
90
|
+
modifyDB( _params.db,_params.table ); return result; return result;
|
91
|
+
}
|
92
|
+
|
93
|
+
/* --------------------------------------------------------------------------------------- */
|
94
|
+
|
95
|
+
async function push( _params ){
|
96
|
+
|
97
|
+
const body = await getBody();
|
98
|
+
db[_params.db][_params.table].push( body );
|
99
|
+
|
100
|
+
modifyDB( _params.db,_params.table );
|
101
|
+
return {
|
102
|
+
database: _params.db,
|
103
|
+
table: _params.table,
|
104
|
+
status: 'pushed'
|
105
|
+
};
|
106
|
+
|
107
|
+
}
|
108
|
+
|
109
|
+
async function splice( _params ){
|
110
|
+
|
111
|
+
const body = await getBody();
|
112
|
+
db[_params.db][_params.table].splice(
|
113
|
+
_params.offset,_params.length,body
|
114
|
+
);
|
115
|
+
|
116
|
+
modifyDB( _params.db,_params.table );
|
117
|
+
return {
|
118
|
+
database: _params.db,
|
119
|
+
table: _params.table,
|
120
|
+
status: 'spliced'
|
121
|
+
};
|
122
|
+
}
|
123
|
+
|
124
|
+
async function unshift( _params ){
|
125
|
+
|
126
|
+
const body = await getBody();
|
127
|
+
db[_params.db][_params.table].unshift( body );
|
128
|
+
|
129
|
+
modifyDB( _params.db,_params.table );
|
130
|
+
return {
|
131
|
+
database: _params.db,
|
132
|
+
table: _params.table,
|
133
|
+
status: 'unshifted'
|
134
|
+
};
|
135
|
+
}
|
136
|
+
|
137
|
+
/* --------------------------------------------------------------------------------------- */
|
138
|
+
|
139
|
+
function addDB( _params ){
|
140
|
+
|
141
|
+
const init = `${query.path}/_init_.json`;
|
142
|
+
|
143
|
+
db._init_.DB.push({
|
144
|
+
name: _params.db,
|
145
|
+
tables: []
|
146
|
+
});
|
147
|
+
|
148
|
+
db[_params.db] = new Array();
|
149
|
+
fs.writeFileSync( init,JSON.stringify(db._init_) );
|
150
|
+
|
151
|
+
return {
|
152
|
+
database: _params.db,
|
153
|
+
status: 'DB added'
|
154
|
+
};
|
155
|
+
|
156
|
+
}
|
157
|
+
|
158
|
+
function removeDB( _params ){
|
159
|
+
|
160
|
+
const init = `${query.path}/_init_.json`;
|
161
|
+
const i = db._init_.DB.findIndex(x=>{
|
162
|
+
return x.name == _params.db
|
163
|
+
});
|
164
|
+
|
165
|
+
db._init_.DB[i].tables.forEach(x=>{
|
166
|
+
const path = `${query.path}/${x}.json`;
|
167
|
+
fs.unlinkSync(path);
|
168
|
+
}); db._init_.DB.splice(i,1);
|
169
|
+
|
170
|
+
db[_params.db] = new Array();
|
171
|
+
fs.writeFileSync( init,JSON.stringify(db._init_) );
|
172
|
+
|
173
|
+
return {
|
174
|
+
database: _params.db,
|
175
|
+
table: _params.table,
|
176
|
+
status: 'DB deleted'
|
177
|
+
};
|
178
|
+
|
179
|
+
}
|
180
|
+
|
181
|
+
function modifyDB( _name, _table ){
|
182
|
+
|
183
|
+
const init = `${query.path}/_init_.json`;
|
184
|
+
const path = `${query.path}/${_table}.json`;
|
185
|
+
|
186
|
+
fs.writeFileSync( init,JSON.stringify(db._init_) );
|
187
|
+
|
188
|
+
try {
|
189
|
+
const length = db[_name][_table].length;
|
190
|
+
if( length>0 ) encryptDB( _name, _table, path );
|
191
|
+
else fs.writeFileSync( path,'' );
|
192
|
+
} catch(e) {
|
193
|
+
fs.unlinkSync( path );
|
194
|
+
}
|
195
|
+
|
196
|
+
}
|
197
|
+
|
198
|
+
/* --------------------------------------------------------------------------------------- */
|
199
|
+
|
200
|
+
function addTable( _params ){
|
201
|
+
|
202
|
+
if( db[_params.db][_params.table] )
|
203
|
+
return {
|
204
|
+
database: _params.db,
|
205
|
+
table: _params.table,
|
206
|
+
status: 'table exist'
|
207
|
+
};
|
208
|
+
|
209
|
+
const i = db._init_.DB.findIndex(x=>{
|
210
|
+
return x.name == _params.db;
|
211
|
+
}); db._init_.DB[i].tables.push(_params.table);
|
212
|
+
|
213
|
+
db[_params.db][_params.table] = new Array();
|
214
|
+
modifyDB( _params.db,_params.table );
|
215
|
+
|
216
|
+
return {
|
217
|
+
database: _params.db,
|
218
|
+
table: _params.table,
|
219
|
+
status: 'table added'
|
220
|
+
};
|
221
|
+
|
222
|
+
}
|
223
|
+
|
224
|
+
function removeTable( _params ){
|
225
|
+
|
226
|
+
const i = db._init_.DB.findIndex(x=>{
|
227
|
+
return x.name == _params.db;
|
228
|
+
});
|
229
|
+
|
230
|
+
const j = db._init_.DB[i].tables.findIndex(x=>{
|
231
|
+
return x == _params.table;
|
232
|
+
});
|
233
|
+
|
234
|
+
db._init_.DB[i].tables.splice(j,1);
|
235
|
+
delete db[_params.db][_params.table];
|
236
|
+
modifyDB( _params.db,_params.table );
|
237
|
+
|
238
|
+
return {
|
239
|
+
database: _params.db,
|
240
|
+
table: _params.table,
|
241
|
+
status: 'table removed'
|
242
|
+
};
|
243
|
+
|
244
|
+
}
|
245
|
+
|
246
|
+
/* --------------------------------------------------------------------------------------- */
|
247
|
+
|
248
|
+
(async()=>{
|
249
|
+
try{
|
250
|
+
|
251
|
+
const api = url.parse( req.url,true );
|
252
|
+
const params = api.query;
|
253
|
+
|
254
|
+
/* Find Api */
|
255
|
+
if( api.pathname == '/list' ) json( await list(params) )
|
256
|
+
else if( api.pathname == '/hash' ) json( await hash(params) )
|
257
|
+
else if( api.pathname == '/match' ) json( await match(params) )
|
258
|
+
|
259
|
+
/* Remove Api */
|
260
|
+
else if( api.pathname == '/pop' ) json( await pop(params) )
|
261
|
+
else if( api.pathname == '/shift' ) json( await shift(params) )
|
262
|
+
|
263
|
+
/* Modify Api */
|
264
|
+
else if( api.pathname == '/push' ) json( await push(params) )
|
265
|
+
else if( api.pathname == '/splice' ) json( await splice(params) )
|
266
|
+
else if( api.pathname == '/unshift' ) json( await unshift(params) )
|
267
|
+
|
268
|
+
/* Modify Table Api */
|
269
|
+
else if( api.pathname == '/addDB' ) json( await addDB(params) )
|
270
|
+
else if( api.pathname == '/removeDB' ) json( await removeDB(params) )
|
271
|
+
|
272
|
+
/* Modify Table Api */
|
273
|
+
else if( api.pathname == '/addTable' ) json( await addTable(params) )
|
274
|
+
else if( api.pathname == '/removeTable' ) json( await removeTable(params) )
|
275
|
+
|
276
|
+
else error('Oops something went wrong');
|
277
|
+
|
278
|
+
} catch(e) { error(e); }
|
279
|
+
})();
|
280
|
+
|
281
|
+
/* --------------------------------------------------------------------------------------- */
|
@@ -0,0 +1,42 @@
|
|
1
|
+
const worker = require('worker_threads');
|
2
|
+
const readline = require('readline');
|
3
|
+
const crypto = require('./_crypto_');
|
4
|
+
const {Buffer} = require('buffer');
|
5
|
+
const fetch = require('axios');
|
6
|
+
const http = require('http');
|
7
|
+
const url = require('url');
|
8
|
+
const fs = require('fs');
|
9
|
+
|
10
|
+
const query = worker.workerData;
|
11
|
+
const db = new Object();
|
12
|
+
|
13
|
+
/* --------------------------------------------------------------------------------------- */
|
14
|
+
|
15
|
+
function app(req,res){
|
16
|
+
eval( fs.readFileSync(`${__dirname}/_server_.js`).toString() );
|
17
|
+
}
|
18
|
+
|
19
|
+
/* --------------------------------------------------------------------------------------- */
|
20
|
+
|
21
|
+
function _init_(){
|
22
|
+
return new Promise((response,reject)=>{
|
23
|
+
eval( fs.readFileSync(`${__dirname}/_init_.js`).toString() );
|
24
|
+
});
|
25
|
+
}
|
26
|
+
|
27
|
+
/* --------------------------------------------------------------------------------------- */
|
28
|
+
|
29
|
+
(()=>{
|
30
|
+
try{
|
31
|
+
console.log('molly-db is running, please wait');
|
32
|
+
http.createServer( app ).listen( query.port,()=>{
|
33
|
+
_init_().then(()=>{
|
34
|
+
worker.parentPort.postMessage(
|
35
|
+
`server started -> http://localhost:${query.port}`
|
36
|
+
);
|
37
|
+
}).catch(e=>{ process.exit(1); });
|
38
|
+
});
|
39
|
+
} catch(e) { process.exit(1); }
|
40
|
+
})();
|
41
|
+
|
42
|
+
/* --------------------------------------------------------------------------------------- */
|
package/package.json
CHANGED
@@ -1,12 +1,29 @@
|
|
1
1
|
{
|
2
2
|
"license": "MIT",
|
3
3
|
"main": "main.js",
|
4
|
-
"version": "1.0.
|
4
|
+
"version": "1.0.5",
|
5
5
|
"name": "molly-db",
|
6
6
|
"author": "bececrazy",
|
7
|
-
"scripts": {
|
7
|
+
"scripts": {
|
8
|
+
"start": "node main"
|
9
|
+
},
|
8
10
|
"repository": "https://github.com/EDBC-REPO-NPM/Molly-db",
|
9
|
-
"dependencies": {
|
11
|
+
"dependencies": {
|
12
|
+
"axios": "^0.27.2",
|
13
|
+
"crypto-js": "^4.1.1",
|
14
|
+
"fs": "^0.0.1-security"
|
15
|
+
},
|
10
16
|
"description": "Molly-db is a free and open source library for nodejs that allow you create a lightweight encrypted database using Json files",
|
11
|
-
"keywords": [
|
17
|
+
"keywords": [
|
18
|
+
"json",
|
19
|
+
"storage",
|
20
|
+
"database",
|
21
|
+
"datastorage",
|
22
|
+
"web-database",
|
23
|
+
"json-database",
|
24
|
+
"encrypted-data",
|
25
|
+
"web-local-storage",
|
26
|
+
"encrypted-database",
|
27
|
+
"web-encrypted-database"
|
28
|
+
]
|
12
29
|
}
|