molly-db 1.0.3 → 1.0.6
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 -4
- package/module/_crypto_.js +65 -0
- package/module/_init_.js +68 -0
- package/module/_server_.js +283 -0
- package/module/_worker_.js +42 -0
- package/package.json +21 -4
- package/module/localDB.js +0 -241
- package/module/readline.js +0 -208
- package/module/streamDB.js +0 -80
package/main.js
CHANGED
@@ -1,6 +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)*/ }
|
6
|
+
/* --------------------------------------------------------------------------------------- */
|
5
7
|
|
6
|
-
|
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,283 @@
|
|
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
|
+
});
|
67
|
+
return result.map(x=>JSON.parse(x)).slice(
|
68
|
+
_params.offset, Number(_params.offset)+Number(_params.length)
|
69
|
+
);
|
70
|
+
}
|
71
|
+
|
72
|
+
function hash( _params ){
|
73
|
+
const result = new Array();
|
74
|
+
db[_params.db][_params.table].map((x)=>{
|
75
|
+
const regex = new RegExp(_params.target,'gi');
|
76
|
+
if( regex.test(x) ) result.push(x);
|
77
|
+
});
|
78
|
+
return result.map(x=>JSON.parse(x)).slice(
|
79
|
+
_params.offset, Number(_params.offset)+Number(_params.length)
|
80
|
+
);
|
81
|
+
}
|
82
|
+
|
83
|
+
/* --------------------------------------------------------------------------------------- */
|
84
|
+
|
85
|
+
function shift( _params ){
|
86
|
+
const result = db[_params.db][_params.table].shift();
|
87
|
+
modifyDB( _params.db,_params.table ); return result;
|
88
|
+
}
|
89
|
+
|
90
|
+
function pop( _params ){
|
91
|
+
const result = db[_params.db][_params.table].pop();
|
92
|
+
modifyDB( _params.db,_params.table ); return result; return result;
|
93
|
+
}
|
94
|
+
|
95
|
+
/* --------------------------------------------------------------------------------------- */
|
96
|
+
|
97
|
+
async function push( _params ){
|
98
|
+
|
99
|
+
const body = await getBody();
|
100
|
+
db[_params.db][_params.table].push( body );
|
101
|
+
|
102
|
+
modifyDB( _params.db,_params.table );
|
103
|
+
return {
|
104
|
+
database: _params.db,
|
105
|
+
table: _params.table,
|
106
|
+
status: 'pushed'
|
107
|
+
};
|
108
|
+
|
109
|
+
}
|
110
|
+
|
111
|
+
async function splice( _params ){
|
112
|
+
|
113
|
+
const body = await getBody();
|
114
|
+
db[_params.db][_params.table].splice(
|
115
|
+
_params.offset,_params.length,body
|
116
|
+
);
|
117
|
+
|
118
|
+
modifyDB( _params.db,_params.table );
|
119
|
+
return {
|
120
|
+
database: _params.db,
|
121
|
+
table: _params.table,
|
122
|
+
status: 'spliced'
|
123
|
+
};
|
124
|
+
}
|
125
|
+
|
126
|
+
async function unshift( _params ){
|
127
|
+
|
128
|
+
const body = await getBody();
|
129
|
+
db[_params.db][_params.table].unshift( body );
|
130
|
+
|
131
|
+
modifyDB( _params.db,_params.table );
|
132
|
+
return {
|
133
|
+
database: _params.db,
|
134
|
+
table: _params.table,
|
135
|
+
status: 'unshifted'
|
136
|
+
};
|
137
|
+
}
|
138
|
+
|
139
|
+
/* --------------------------------------------------------------------------------------- */
|
140
|
+
|
141
|
+
function addDB( _params ){
|
142
|
+
|
143
|
+
const init = `${query.path}/_init_.json`;
|
144
|
+
|
145
|
+
db._init_.DB.push({
|
146
|
+
name: _params.db,
|
147
|
+
tables: []
|
148
|
+
});
|
149
|
+
|
150
|
+
db[_params.db] = new Array();
|
151
|
+
fs.writeFileSync( init,JSON.stringify(db._init_) );
|
152
|
+
|
153
|
+
return {
|
154
|
+
database: _params.db,
|
155
|
+
status: 'DB added'
|
156
|
+
};
|
157
|
+
|
158
|
+
}
|
159
|
+
|
160
|
+
function removeDB( _params ){
|
161
|
+
|
162
|
+
const init = `${query.path}/_init_.json`;
|
163
|
+
const i = db._init_.DB.findIndex(x=>{
|
164
|
+
return x.name == _params.db
|
165
|
+
});
|
166
|
+
|
167
|
+
db._init_.DB[i].tables.forEach(x=>{
|
168
|
+
const path = `${query.path}/${x}.json`;
|
169
|
+
fs.unlinkSync(path);
|
170
|
+
}); db._init_.DB.splice(i,1);
|
171
|
+
|
172
|
+
db[_params.db] = new Array();
|
173
|
+
fs.writeFileSync( init,JSON.stringify(db._init_) );
|
174
|
+
|
175
|
+
return {
|
176
|
+
database: _params.db,
|
177
|
+
table: _params.table,
|
178
|
+
status: 'DB deleted'
|
179
|
+
};
|
180
|
+
|
181
|
+
}
|
182
|
+
|
183
|
+
function modifyDB( _name, _table ){
|
184
|
+
|
185
|
+
const init = `${query.path}/_init_.json`;
|
186
|
+
const path = `${query.path}/${_table}.json`;
|
187
|
+
|
188
|
+
fs.writeFileSync( init,JSON.stringify(db._init_) );
|
189
|
+
|
190
|
+
try {
|
191
|
+
const length = db[_name][_table].length;
|
192
|
+
if( length>0 ) encryptDB( _name, _table, path );
|
193
|
+
else fs.writeFileSync( path,'' );
|
194
|
+
} catch(e) {
|
195
|
+
fs.unlinkSync( path );
|
196
|
+
}
|
197
|
+
|
198
|
+
}
|
199
|
+
|
200
|
+
/* --------------------------------------------------------------------------------------- */
|
201
|
+
|
202
|
+
function addTable( _params ){
|
203
|
+
|
204
|
+
if( db[_params.db][_params.table] )
|
205
|
+
return {
|
206
|
+
database: _params.db,
|
207
|
+
table: _params.table,
|
208
|
+
status: 'table exist'
|
209
|
+
};
|
210
|
+
|
211
|
+
const i = db._init_.DB.findIndex(x=>{
|
212
|
+
return x.name == _params.db;
|
213
|
+
}); db._init_.DB[i].tables.push(_params.table);
|
214
|
+
|
215
|
+
db[_params.db][_params.table] = new Array();
|
216
|
+
modifyDB( _params.db,_params.table );
|
217
|
+
|
218
|
+
return {
|
219
|
+
database: _params.db,
|
220
|
+
table: _params.table,
|
221
|
+
status: 'table added'
|
222
|
+
};
|
223
|
+
|
224
|
+
}
|
225
|
+
|
226
|
+
function removeTable( _params ){
|
227
|
+
|
228
|
+
const i = db._init_.DB.findIndex(x=>{
|
229
|
+
return x.name == _params.db;
|
230
|
+
});
|
231
|
+
|
232
|
+
const j = db._init_.DB[i].tables.findIndex(x=>{
|
233
|
+
return x == _params.table;
|
234
|
+
});
|
235
|
+
|
236
|
+
db._init_.DB[i].tables.splice(j,1);
|
237
|
+
delete db[_params.db][_params.table];
|
238
|
+
modifyDB( _params.db,_params.table );
|
239
|
+
|
240
|
+
return {
|
241
|
+
database: _params.db,
|
242
|
+
table: _params.table,
|
243
|
+
status: 'table removed'
|
244
|
+
};
|
245
|
+
|
246
|
+
}
|
247
|
+
|
248
|
+
/* --------------------------------------------------------------------------------------- */
|
249
|
+
|
250
|
+
(async()=>{
|
251
|
+
try{
|
252
|
+
|
253
|
+
const api = url.parse( req.url,true );
|
254
|
+
const params = api.query;
|
255
|
+
|
256
|
+
/* Find Api */
|
257
|
+
if( api.pathname == '/list' ) json( await list(params) )
|
258
|
+
else if( api.pathname == '/hash' ) json( await hash(params) )
|
259
|
+
else if( api.pathname == '/match' ) json( await match(params) )
|
260
|
+
|
261
|
+
/* Remove Api */
|
262
|
+
else if( api.pathname == '/pop' ) json( await pop(params) )
|
263
|
+
else if( api.pathname == '/shift' ) json( await shift(params) )
|
264
|
+
|
265
|
+
/* Modify Api */
|
266
|
+
else if( api.pathname == '/push' ) json( await push(params) )
|
267
|
+
else if( api.pathname == '/splice' ) json( await splice(params) )
|
268
|
+
else if( api.pathname == '/unshift' ) json( await unshift(params) )
|
269
|
+
|
270
|
+
/* Modify Table Api */
|
271
|
+
else if( api.pathname == '/addDB' ) json( await addDB(params) )
|
272
|
+
else if( api.pathname == '/removeDB' ) json( await removeDB(params) )
|
273
|
+
|
274
|
+
/* Modify Table Api */
|
275
|
+
else if( api.pathname == '/addTable' ) json( await addTable(params) )
|
276
|
+
else if( api.pathname == '/removeTable' ) json( await removeTable(params) )
|
277
|
+
|
278
|
+
else error('Oops something went wrong');
|
279
|
+
|
280
|
+
} catch(e) { error(e); }
|
281
|
+
})();
|
282
|
+
|
283
|
+
/* --------------------------------------------------------------------------------------- */
|
@@ -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
|
+
http.createServer( app ).listen( query.port,()=>{
|
32
|
+
console.log('molly-db is running, please wait');
|
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.6",
|
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
|
}
|
package/module/localDB.js
DELETED
@@ -1,241 +0,0 @@
|
|
1
|
-
const readline = require('./readline');
|
2
|
-
const fs = require('fs');
|
3
|
-
|
4
|
-
//TODO: Optimization FUnctions -------------------------------------------------------------------//
|
5
|
-
|
6
|
-
const _default = { offset: 0, length: 100 };
|
7
|
-
const init = function( _table,_config,_self ){
|
8
|
-
return {
|
9
|
-
_tbl: createNewTable( `${_self.path}/${_table}.json` ),
|
10
|
-
_tmp: `${_self.path}/${_table}_tmp.json`,
|
11
|
-
_path: `${_self.path}/${_table}.json`,
|
12
|
-
_cfg: config(_config),
|
13
|
-
}
|
14
|
-
};
|
15
|
-
|
16
|
-
const createNewTable = function( _path ){
|
17
|
-
if( !fs.existsSync( _path ) ) fs.writeFileSync( _path,"" );
|
18
|
-
const table = fs.createReadStream( _path );
|
19
|
-
return table;
|
20
|
-
}
|
21
|
-
|
22
|
-
const createNewHash = function( _object ){
|
23
|
-
_object['_stamp'] = Date.now();
|
24
|
-
const _base = JSON.stringify( _object );
|
25
|
-
if( !_object.hash )
|
26
|
-
_object.hash = crypto.SHA256( _base ).toString();
|
27
|
-
return _object;
|
28
|
-
}
|
29
|
-
|
30
|
-
function config(_config){
|
31
|
-
Object.keys(_config).map((x)=>{
|
32
|
-
_default[x] = _config[x];
|
33
|
-
}); return _default;
|
34
|
-
}
|
35
|
-
|
36
|
-
//TODO: localDB Class ----------------------------------------------------------------------------//
|
37
|
-
|
38
|
-
class localDB {
|
39
|
-
|
40
|
-
default = { offset: 0, length: 100 }
|
41
|
-
|
42
|
-
constructor( _object ){
|
43
|
-
if( _object.pass ){
|
44
|
-
this.password = _object.pass;
|
45
|
-
} this.path = _object.path;
|
46
|
-
}
|
47
|
-
|
48
|
-
// TODO: Searching functions --------------------------------------------------- //
|
49
|
-
list( _table, _config ){
|
50
|
-
return new Promise( async(response,reject)=>{ try{
|
51
|
-
const { _cfg,_tbl,_tmp,_path } = init( _table,_config,this );
|
52
|
-
let data = await readline.list( this,_tbl,_cfg );
|
53
|
-
data = data.map(x=>{ return JSON.parse(x) });
|
54
|
-
response({ data:data, table:_table });
|
55
|
-
} catch(e) { reject(e); }});
|
56
|
-
}
|
57
|
-
|
58
|
-
find( _table, _target, _config ){
|
59
|
-
return new Promise( async(response,reject)=>{ try{
|
60
|
-
const { _cfg,_tbl,_tmp,_path } = init( _table,_config,this );
|
61
|
-
let data = await readline.find( this,_tbl,_target,_cfg );
|
62
|
-
data = data.map(x=>{ return JSON.parse(x) });
|
63
|
-
response({ data:data, table:_table });
|
64
|
-
} catch(e) { reject(e); }});
|
65
|
-
}
|
66
|
-
|
67
|
-
match( _table,_match,_config ){
|
68
|
-
return new Promise( async(response,reject)=>{ try{
|
69
|
-
const { _cfg,_tbl,_tmp,_path } = init( _table,_config,this );
|
70
|
-
let data = await readline.match( this,_tbl,_match );
|
71
|
-
data = data.map(x=>{ return JSON.parse(x) });
|
72
|
-
response({ data:data, table:_table });
|
73
|
-
} catch(e) { reject(e); }});
|
74
|
-
}
|
75
|
-
|
76
|
-
hash( _table, _hash ){
|
77
|
-
return new Promise( async(response,reject)=>{ try{
|
78
|
-
const { _cfg,_tbl,_tmp,_path } = init( _table,null,this );
|
79
|
-
let data = await readline.hash( this,_tbl,_hash,_cfg );
|
80
|
-
data = data.map(x=>{ return JSON.parse(x) });
|
81
|
-
response({ data:data, table:_table });
|
82
|
-
} catch(e) { reject(e); }});
|
83
|
-
}
|
84
|
-
|
85
|
-
// TODO: Saving functions ------------------------------------------------- //
|
86
|
-
push( _table, ..._object ){
|
87
|
-
return new Promise( (response,reject)=>{ try{
|
88
|
-
|
89
|
-
let { _i,_cfg,_itr,_res,_tmp,_path } = init( _table,null,this );
|
90
|
-
const writable = fs.createWriteStream( _tmp );
|
91
|
-
|
92
|
-
_itr.on( 'line',( line )=>{ writable.write(`${line}\n`); });
|
93
|
-
|
94
|
-
_itr.on( 'close',()=>{
|
95
|
-
_object.flat().forEach( item=>{
|
96
|
-
item = createNewHash( item );
|
97
|
-
const encryptedData = this.encrypt( JSON.stringify( item ) );
|
98
|
-
writable.write( `${encryptedData}\n` );
|
99
|
-
}); writable.end();
|
100
|
-
});
|
101
|
-
|
102
|
-
writable.on( 'finish',()=>{ fs.renameSync( _tmp, _path ); res({
|
103
|
-
table: _table,
|
104
|
-
}); });
|
105
|
-
|
106
|
-
} catch(e) { reject(e); }
|
107
|
-
}); }
|
108
|
-
|
109
|
-
unshift( _table, ..._object ){
|
110
|
-
return new Promise( (response,reject)=>{ try{
|
111
|
-
|
112
|
-
let { _i,_cfg,_itr,_res,_tmp,_path } = init( _table,null,this );
|
113
|
-
const writable = fs.createWriteStream( _tmp );
|
114
|
-
|
115
|
-
_itr.on( 'line',( line )=>{
|
116
|
-
if( _i == 0 ){
|
117
|
-
_object.flat().forEach( item=>{
|
118
|
-
item = createNewHash( item );
|
119
|
-
const encryptedData = this.encrypt( JSON.stringify( item ) );
|
120
|
-
writable.write( `${encryptedData}\n` );
|
121
|
-
});
|
122
|
-
} writable.write( `${line}\n` );
|
123
|
-
_i++;});
|
124
|
-
|
125
|
-
_itr.on( 'close',()=>{ writable.end(); });
|
126
|
-
|
127
|
-
writable.on( 'finish',()=>{ fs.renameSync( _tmp, _path ); res({
|
128
|
-
table: _table,
|
129
|
-
}); });
|
130
|
-
|
131
|
-
} catch(e) { reject(e) }
|
132
|
-
}); }
|
133
|
-
|
134
|
-
place( _table, _line, ..._object ){
|
135
|
-
return new Promise( (response,reject)=>{ try{
|
136
|
-
|
137
|
-
let { _i,_cfg,_itr,_res,_tmp,_path } = init( _table,null,this );
|
138
|
-
const writable = fs.createWriteStream( _tmp );
|
139
|
-
|
140
|
-
_itr.on( 'line',( line )=>{
|
141
|
-
if( _i == _line ){
|
142
|
-
_object.flat().forEach( item=>{
|
143
|
-
item = createNewHash( item );
|
144
|
-
const encryptedData = this.encrypt( JSON.stringify( item ) );
|
145
|
-
writable.write( `${encryptedData}\n` );
|
146
|
-
});
|
147
|
-
} writable.write( `${line}\n` );
|
148
|
-
_i++;});
|
149
|
-
|
150
|
-
_itr.on( 'close',()=>{ writable.end(); });
|
151
|
-
|
152
|
-
writable.on( 'finish',()=>{ fs.renameSync( _tmp, _path ); res({
|
153
|
-
table: _table,
|
154
|
-
}); });
|
155
|
-
|
156
|
-
} catch(e) { reject(e) }
|
157
|
-
}); }
|
158
|
-
|
159
|
-
update( _table, _hash, ..._object ){
|
160
|
-
return new Promise( (response,reject)=>{ try{
|
161
|
-
|
162
|
-
let { _i,_cfg,_itr,_res,_tmp,_path } = init( _table,null,this );
|
163
|
-
const writable = fs.createWriteStream( _tmp );
|
164
|
-
|
165
|
-
_itr.on( 'line',( encryptedLine )=>{ try{
|
166
|
-
const line = this.decrypt( encryptedLine );
|
167
|
-
const data = JSON.parse( line );
|
168
|
-
if( data.hash == _hash ){
|
169
|
-
_object.flat().forEach( item=>{
|
170
|
-
item = createNewHash( item );
|
171
|
-
const encryptedData = this.encrypt( JSON.stringify( item ) );
|
172
|
-
writable.write( `${encryptedData}\n` );
|
173
|
-
});
|
174
|
-
} else
|
175
|
-
writable.write( `${encryptedLine}\n` );
|
176
|
-
} catch(e) { reject(`the db can be decripted: ${e}`) }
|
177
|
-
});
|
178
|
-
|
179
|
-
_itr.on( 'close',()=>{ writable.end(); });
|
180
|
-
|
181
|
-
writable.on( 'finish',()=>{ fs.renameSync( _tmp, _path ); res({
|
182
|
-
table: _table,
|
183
|
-
}); });
|
184
|
-
|
185
|
-
} catch(e) { reject(e) }
|
186
|
-
}); }
|
187
|
-
|
188
|
-
// TODO: Removing functions //
|
189
|
-
remove( _table, _hash ){
|
190
|
-
return new Promise( (response,reject)=>{ try{
|
191
|
-
|
192
|
-
let { _i,_cfg,_itr,_res,_tmp,_path } = init( _table,null,this );
|
193
|
-
const writable = fs.createWriteStream( _tmp );
|
194
|
-
|
195
|
-
_itr.on( 'line',( encryptedLine )=>{
|
196
|
-
const line = this.decrypt( encryptedLine );
|
197
|
-
const data = JSON.parse( line );
|
198
|
-
if( data.hash != _hash )
|
199
|
-
writable.write( `${encryptedLine}\n` );
|
200
|
-
});
|
201
|
-
|
202
|
-
_itr.on( 'close',()=>{ writable.end(); });
|
203
|
-
|
204
|
-
writable.on( 'finish',()=>{ fs.renameSync( _tmp, _path ); res({
|
205
|
-
table: _table,
|
206
|
-
}); });
|
207
|
-
|
208
|
-
} catch(e) { reject(e) }
|
209
|
-
}); }
|
210
|
-
|
211
|
-
removeTable( _table ){
|
212
|
-
return new Promise( (response,reject)=>{
|
213
|
-
const _path = `${this.path}/${_table}`;
|
214
|
-
fs.unlink( _path,( err,data )=>{
|
215
|
-
if(err) reject( err );
|
216
|
-
res({ table: _table });
|
217
|
-
});
|
218
|
-
})
|
219
|
-
}
|
220
|
-
|
221
|
-
shift( _table ){
|
222
|
-
return new Promise( (response,reject)=>{ try{
|
223
|
-
|
224
|
-
let { _i,_cfg,_itr,_res,_tmp,_path } = init( _table,null,this );
|
225
|
-
const writable = fs.createWriteStream( _tmp );
|
226
|
-
|
227
|
-
_itr.on( 'line',( line )=>{ if( _i != 0 ) writable.write( `${line}\n` ); _i++;});
|
228
|
-
|
229
|
-
_itr.on( 'close',()=>{ writable.end(); });
|
230
|
-
|
231
|
-
writable.on( 'finish',()=>{ fs.renameSync( _tmp, _path ); res({
|
232
|
-
table: _table,
|
233
|
-
}); });
|
234
|
-
|
235
|
-
} catch(e) { reject(e) }
|
236
|
-
}); }
|
237
|
-
|
238
|
-
}
|
239
|
-
|
240
|
-
//TODO: localDB Class ----------------------------------------------------------------------------//
|
241
|
-
module.exports = localDB;
|
package/module/readline.js
DELETED
@@ -1,208 +0,0 @@
|
|
1
|
-
const crypto = require('crypto-js');
|
2
|
-
const {Buffer} = require('buffer');
|
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
|
-
function 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
|
-
function 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
|
-
function 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
|
-
function processData( _chunk ){
|
64
|
-
for( var i=_chunk.length; i--; ){
|
65
|
-
if( _chunk[i]==10 || _chunk[i]==13 )
|
66
|
-
return [
|
67
|
-
_chunk.slice(0,i),
|
68
|
-
_chunk.slice(i),
|
69
|
-
];
|
70
|
-
} return [ null, _chunk ];
|
71
|
-
}
|
72
|
-
|
73
|
-
/* -------------------------------------------------------------------------------------------------------- */
|
74
|
-
|
75
|
-
function dbDecrypt( _list,_self ){ return _list.map((x)=>{ return decrypt(x,_self?.password) }); }
|
76
|
-
|
77
|
-
function dbEncrypt( _list,_self ){ return _list.map((x)=>{ return encrypt(x,_self?.password) }); }
|
78
|
-
|
79
|
-
/* -------------------------------------------------------------------------------------------------------- */
|
80
|
-
|
81
|
-
output.readLine = ( _self,_stream,_config,_data )=>{
|
82
|
-
return new Promise((response,reject)=>{
|
83
|
-
|
84
|
-
let offset = 0;
|
85
|
-
const db = new Array();
|
86
|
-
let prcd = new Array();
|
87
|
-
let data = new Buffer(0);
|
88
|
-
|
89
|
-
_stream.on('data',async(chunk)=>{
|
90
|
-
|
91
|
-
data = Buffer.concat([ data,chunk ]);
|
92
|
-
prcd = processData( data );
|
93
|
-
data = prcd[1];
|
94
|
-
|
95
|
-
if( prcd[0] ){
|
96
|
-
|
97
|
-
const encrypted = prcd[0].toString().split('\n');
|
98
|
-
const decrypted = dbDecrypt(encrypted,_self);
|
99
|
-
|
100
|
-
const done = await _data( db,decrypted,_config );
|
101
|
-
offset += done.length;
|
102
|
-
|
103
|
-
if( db.length >= _config.length )
|
104
|
-
_stream.destroy();
|
105
|
-
else if ( offset > _config.offset && db.length != 0 )
|
106
|
-
db.push( ...done );
|
107
|
-
else if ( offset > _config.offset && db.length == 0 )
|
108
|
-
db.push( ...done.slice( offset - done.length - _config.offset - 1 ) );
|
109
|
-
|
110
|
-
}
|
111
|
-
|
112
|
-
});
|
113
|
-
|
114
|
-
_stream.on('close',async()=>{ response( db.slice( 0,_config.length ) ); });
|
115
|
-
|
116
|
-
});
|
117
|
-
}
|
118
|
-
|
119
|
-
output.list = ( _self,_stream,_config )=>{
|
120
|
-
|
121
|
-
const onData = ( db,data,_config )=>{
|
122
|
-
return new Promise((response,reject)=>{
|
123
|
-
try{
|
124
|
-
const index = data.findIndex((x)=>x=='');
|
125
|
-
data.splice( index,1 );
|
126
|
-
} catch(e) {} response(data);
|
127
|
-
});
|
128
|
-
}
|
129
|
-
|
130
|
-
return new Promise((response,reject)=>{
|
131
|
-
response( output.readLine( _self,_stream,_config,onData ));
|
132
|
-
});
|
133
|
-
|
134
|
-
}
|
135
|
-
|
136
|
-
output.match = ( _self,_stream,_target,_config )=>{
|
137
|
-
|
138
|
-
const onData = ( db,data,_config )=>{
|
139
|
-
return new Promise((response,reject)=>{
|
140
|
-
const done = new Array();
|
141
|
-
data.map(x=>{
|
142
|
-
try{
|
143
|
-
if( (new RegExp(slugify(_target),'gi')).test(slugify(x)) )
|
144
|
-
done.push(x);
|
145
|
-
} catch(e) {} });
|
146
|
-
response(done);
|
147
|
-
});
|
148
|
-
}
|
149
|
-
|
150
|
-
return new Promise((response,reject)=>{
|
151
|
-
response(output.readLine( _self,_stream,_config,onData ));
|
152
|
-
});
|
153
|
-
|
154
|
-
}
|
155
|
-
|
156
|
-
output.find = ( _self,_stream,_target,_config )=>{
|
157
|
-
|
158
|
-
const onData = ( db,data,_config )=>{
|
159
|
-
return new Promise((response,reject)=>{
|
160
|
-
const done = new Array();
|
161
|
-
data.map(x=>{
|
162
|
-
try{
|
163
|
-
const data = JSON.parse(x);
|
164
|
-
const cond = Object.keys(_target)
|
165
|
-
.every(y=>{
|
166
|
-
return (_target[y]).test(data[y]);
|
167
|
-
}); if( cond ) done.push(x);
|
168
|
-
} catch(e) {}
|
169
|
-
}); response(done);
|
170
|
-
});
|
171
|
-
}
|
172
|
-
|
173
|
-
return new Promise((response,reject)=>{
|
174
|
-
response(output.readLine( _self,_stream,_config,onData ));
|
175
|
-
});
|
176
|
-
|
177
|
-
}
|
178
|
-
|
179
|
-
output.hash = ( _self,_stream,_target )=>{
|
180
|
-
|
181
|
-
const onData = ( db,data,_config )=>{
|
182
|
-
return new Promise((response,reject)=>{
|
183
|
-
data.some((x)=>{
|
184
|
-
try{
|
185
|
-
const y = JSON.parse(x);
|
186
|
-
if( y.hash == _target )
|
187
|
-
response([x]);
|
188
|
-
} catch(e) {}
|
189
|
-
});
|
190
|
-
});
|
191
|
-
}
|
192
|
-
|
193
|
-
const _config = { offset:0, length:1 };
|
194
|
-
return new Promise((response,reject)=>{
|
195
|
-
response(output.readLine( _self,_stream,_config,onData ));
|
196
|
-
});
|
197
|
-
|
198
|
-
}
|
199
|
-
|
200
|
-
output.stream = ( _self,_stream,_config,_onData )=>{
|
201
|
-
return new Promise((response,reject)=>{
|
202
|
-
response(output.readLine( _self,_stream,_config,_onData ));
|
203
|
-
});
|
204
|
-
}
|
205
|
-
|
206
|
-
/* -------------------------------------------------------------------------------------------------------- */
|
207
|
-
|
208
|
-
module.exports = output;
|
package/module/streamDB.js
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
const readline = require('./readline');
|
2
|
-
const fetch = require('axios');
|
3
|
-
const fs = require('fs');
|
4
|
-
|
5
|
-
//TODO: Optimization FUnctions -------------------------------------------------------------------//
|
6
|
-
|
7
|
-
const _default = { offset: 0, length: 100 };
|
8
|
-
|
9
|
-
const init = function( _table,_config,_self ){
|
10
|
-
return new Promise( (response,reject)=>{
|
11
|
-
const path = `${_self.path}/${_table}.json`;
|
12
|
-
fetch.get(path,{responseType:'stream'}).then(({data})=>{
|
13
|
-
response({
|
14
|
-
_cfg: config(_config),
|
15
|
-
_path: null,
|
16
|
-
_tmp: null,
|
17
|
-
_tbl: data,
|
18
|
-
});
|
19
|
-
});
|
20
|
-
});
|
21
|
-
};
|
22
|
-
|
23
|
-
function config(_config){
|
24
|
-
if( !_config ) return _default;
|
25
|
-
Object.keys(_config).map((x)=>{
|
26
|
-
_default[x] = _config[x];
|
27
|
-
}); return _default;
|
28
|
-
}
|
29
|
-
|
30
|
-
//TODO: localDB Class ----------------------------------------------------------------------------//
|
31
|
-
|
32
|
-
class streamDB{
|
33
|
-
|
34
|
-
constructor( _object ){
|
35
|
-
if( _object.pass ){
|
36
|
-
this.password = _object.pass;
|
37
|
-
} this.path = _object.path;
|
38
|
-
}
|
39
|
-
|
40
|
-
// TODO: Searching functions --------------------------------------------------- //
|
41
|
-
list( _table, _config ){
|
42
|
-
return new Promise( async(response,reject)=>{ try{
|
43
|
-
const { _cfg,_tbl,_tmp,_path } = await init( _table,_config,this );
|
44
|
-
let data = await readline.list( this,_tbl,_cfg );
|
45
|
-
data = data.map(x=>{ return JSON.parse(x) });
|
46
|
-
response({ data:data, table:_table });
|
47
|
-
} catch(e) { reject(e); }});
|
48
|
-
}
|
49
|
-
|
50
|
-
find( _table, _target, _config ){
|
51
|
-
return new Promise( async(response,reject)=>{ try{
|
52
|
-
const { _cfg,_tbl,_tmp,_path } = await init( _table,_config,this );
|
53
|
-
let data = await readline.find( this,_tbl,_target,_cfg );
|
54
|
-
data = data.map(x=>{ return JSON.parse(x) });
|
55
|
-
response({ data:data, table:_table });
|
56
|
-
} catch(e) { reject(e); }});
|
57
|
-
}
|
58
|
-
|
59
|
-
match( _table,_match,_config ){
|
60
|
-
return new Promise( async(response,reject)=>{ try{
|
61
|
-
const { _cfg,_tbl,_tmp,_path } = await init( _table,_config,this );
|
62
|
-
let data = await readline.match( this,_tbl,_match,_cfg );
|
63
|
-
data = data.map(x=>{ return JSON.parse(x) });
|
64
|
-
response({ data:data, table:_table });
|
65
|
-
} catch(e) { reject(e); }});
|
66
|
-
}
|
67
|
-
|
68
|
-
hash( _table, _hash ){
|
69
|
-
return new Promise( async(response,reject)=>{ try{
|
70
|
-
const { _cfg,_tbl,_tmp,_path } = await init( _table,null,this );
|
71
|
-
let data = await readline.hash( this,_tbl,_hash );
|
72
|
-
data = data.map(x=>{ return JSON.parse(x) });
|
73
|
-
response({ data:data, table:_table });
|
74
|
-
} catch(e) { reject(e); }});
|
75
|
-
}
|
76
|
-
|
77
|
-
}
|
78
|
-
|
79
|
-
//TODO: localDB Class ----------------------------------------------------------------------------//
|
80
|
-
module.exports = streamDB;
|