molly-db 1.0.27 → 1.0.30

Sign up to get free protection for your applications and to get access to all the features.
package/main.js CHANGED
@@ -19,6 +19,8 @@ class molly_db{
19
19
  this.pass = opt.pass; this.port = opt.port || 27017;
20
20
  this.path = opt.path.replace( /^\./,process.cwd() );
21
21
  this.threads = opt.threads || 1;
22
+ this.import = opt.import || '';
23
+ this.time = opt.saveTime || .5;
22
24
  return require(`${__dirname}/module/_worker_.js`)(this);
23
25
  }
24
26
  }
@@ -0,0 +1,214 @@
1
+ /* --------------------------------------------------------------------------------------- */
2
+
3
+ function list( _params ){
4
+ try{return parseData( db[_params.db][_params.table].slice(
5
+ _params.offset, Number(_params.offset)+Number(_params.length)
6
+ ).map(x=>JSON.parse(x)));
7
+ } catch(e) { return parseError(e) }
8
+ }
9
+
10
+ function match( _params ){
11
+ try{
12
+
13
+ } catch(e) {
14
+ const result = new Array();
15
+ db[_params.db][_params.table].map((x)=>{
16
+ const reg = crypto.slugify(_params.target);
17
+ const regex = new RegExp(reg,'gi');
18
+ const target = crypto.slugify(x);
19
+ if( regex.test(target) ) result.push(x);
20
+ });
21
+ return parseData( result.map(x=>JSON.parse(x)).slice(
22
+ _params.offset, Number(_params.offset)+Number(_params.length)
23
+ ), result.length);
24
+ }
25
+ }
26
+
27
+ function hash( _params ){
28
+ try{const result = new Array();
29
+ db[_params.db][_params.table].map((x)=>{
30
+ const regex = new RegExp(_params.target,'gi');
31
+ if( regex.test(x) ) result.push(x);
32
+ });
33
+ return parseData( result.map(x=>JSON.parse(x)).slice(
34
+ _params.offset, Number(_params.offset)+Number(_params.length)
35
+ ), result.length);
36
+ } catch(e) { return parseError(e) }
37
+ }
38
+
39
+ /* --------------------------------------------------------------------------------------- */
40
+
41
+ async function unshift( _params ){ db._update_ = true;
42
+ return parseData(db[_params.db][_params.table].unshift(...body))
43
+ }
44
+
45
+ async function push( _params ){ db._update_ = true;
46
+ return parseData(db[_params.db][_params.table].push(...body))
47
+ }
48
+
49
+ async function shift( _params ){ db._update_ = true;
50
+ return parseData(db[_params.db][_params.table].shift())
51
+ }
52
+
53
+ async function pop( _params ){ db._update_ = true;
54
+ return parseData(db[_params.db][_params.table].pop())
55
+ }
56
+
57
+ /* --------------------------------------------------------------------------------------- */
58
+
59
+ async function update( _params ){
60
+ try{db._update_ = true;
61
+ for( var i in db[_params.db][_params.table] ){
62
+
63
+ const regex = new RegExp(_params.target,'gi');
64
+ if( regex.test(db[_params.db][_params.table][i]) )
65
+ return db[_params.db][_params.table].splice(i,1,...body);
66
+
67
+ }
68
+ } catch(e) { return parseError(e) }
69
+ }
70
+
71
+ async function remove( _params ){
72
+ try{db._update_ = true;
73
+ for( var i in db[_params.db][_params.table] ){
74
+
75
+ const regex = new RegExp(_params.target,'gi');
76
+ if( regex.test(db[_params.db][_params.table][i]) )
77
+ return db[_params.db][_params.table].splice(i,1);
78
+
79
+ }
80
+ } catch(e) { return parseError(e) }
81
+ }
82
+
83
+ /* --------------------------------------------------------------------------------------- */
84
+
85
+ async function addTable( _params ){
86
+ try{db._update_ = true;
87
+
88
+ if( db[_params.db][_params.table] ) return {
89
+ status: 'table already exist',
90
+ database: _params.db,
91
+ table: _params.table,
92
+ };
93
+
94
+ for( var i in db._init_.DB ){
95
+ if( db._init_.DB[i].name == _params.db ){
96
+ db[_params.db][_params.table] = new Array();
97
+ db._init_.DB[i].tables.push(_params.table);
98
+ break;
99
+ }
100
+ }
101
+
102
+ /*await save( _params )*/ return [{
103
+ status: 'table added',
104
+ database: _params.db,
105
+ table: _params.table,
106
+ }];
107
+
108
+ } catch(e) { return parseError(e) }
109
+ }
110
+
111
+ async function removeTable( _params ){
112
+ try{db._update_ = true;
113
+
114
+ if( !db[_params.db][_params.table] ) return {
115
+ status: 'table does not exist',
116
+ database: _params.db,
117
+ table: _params.table,
118
+ };
119
+
120
+ for( var i in db._init_.DB ){
121
+ if( db._init_.DB[i].name == _params.db ){
122
+ delete db[_params.db][_params.table];
123
+ db._init_.DB[i].tables.splice(j,1);
124
+ break;
125
+ }
126
+ }
127
+
128
+ /*await save( _params )*/ return [{
129
+ status: 'table removed',
130
+ database: _params.db,
131
+ table: _params.table,
132
+ }];
133
+
134
+ } catch(e) { return parseError(e) }
135
+ }
136
+
137
+ /* --------------------------------------------------------------------------------------- */
138
+
139
+ async function addDB( _params ){
140
+ try{db._update_ = true;
141
+
142
+ if( db[_params.db] ) return {
143
+ status: 'DB already exist',
144
+ database: _params.db,
145
+ table: _params.table,
146
+ };
147
+
148
+ db._init_.DB.push({
149
+ tables: [], name: _params.db,
150
+ }); db[_params.db] = new Array();
151
+
152
+ /*await save( _params )*/ return [{
153
+ database: _params.db,
154
+ status: 'DB added'
155
+ }];
156
+
157
+ } catch(e) { return parseError(e) }
158
+ }
159
+
160
+ async function removeDB( _params ){
161
+ try{
162
+
163
+ if( !db[_params.db] ) return {
164
+ status: 'DB does not exist',
165
+ database: _params.db,
166
+ table: _params.table,
167
+ };
168
+
169
+ for( var i in db._init_.DB ){
170
+ if( db._init_.DB.name == _params.db ){
171
+ db._init_.DB[i].tables.map(x=>{
172
+ const path = `${query.path}/${x}.json`;
173
+ fs.unlinkSync(path);
174
+ }); db._init_.DB.splice(i,1);
175
+ delete db[_params.db];
176
+ break;
177
+ }
178
+ }
179
+
180
+ /*await save( _params )*/ return [{
181
+ database: _params.db,
182
+ table: _params.table,
183
+ status: 'DB deleted'
184
+ }];
185
+
186
+ } catch(e) { return parseError(e) }
187
+ }
188
+
189
+ async function modifyDB( _name, _table ){
190
+ try{
191
+
192
+ const init = `${query.path}/_init_.json`;
193
+ const path = `${query.path}/${_table}.json`;
194
+
195
+ fs.writeFileSync( init,JSON.stringify(db._init_) );
196
+
197
+ try{const length = db[_name][_table].length;
198
+ if( !(length>0) ) fs.writeFileSync(path,'');
199
+ else await encryptDB( _name, _table, path );
200
+ } catch(e) { fs.unlinkSync( path ); }
201
+
202
+ } catch(e) { return parseError(e) }
203
+ }
204
+
205
+ /* --------------------------------------------------------------------------------------- */
206
+
207
+ async function saveAll( _params ){
208
+ try{for( var i in db['_init_'] ){ for( var j in db['_init_'][i] ){
209
+ const {name,tables} = db['_init_'][i][j];
210
+ for( var k in tables )
211
+ await modifyDB(name,tables[k])
212
+ }} return parseData([]);
213
+ } catch(e) { return parseError(e) }
214
+ }
@@ -0,0 +1,188 @@
1
+
2
+ const api = url.parse( req.url,true );
3
+ const query = process.mollyDB;
4
+ let params = api.query;
5
+ let body = undefined;
6
+ let parse = api;
7
+
8
+ /* --------------------------------------------------------------------------------------- */
9
+
10
+ function error( _error ){
11
+ res.writeHead(404,{'contetn-type':'application/json'});
12
+ res.end(JSON.stringify([{ status:'error', message:_error }]));
13
+ console.log( _error,req.url );
14
+ }
15
+
16
+ function json( _data ){
17
+ res.writeHead(200,{'content-type':'application/json'});
18
+ res.end(JSON.stringify(_data));
19
+ }
20
+
21
+ function parseData( _data, _length ){
22
+ const length = _length||db[params.db][params.table].length;
23
+ const pagination = Math.ceil(length/_data.length)||1;
24
+ return {
25
+ pagination: pagination,
26
+ database: params.db,
27
+ table: params.table,
28
+ length: length,
29
+ status: 'OK',
30
+ data: _data,
31
+ }
32
+ }
33
+
34
+ function parseError( _e ){
35
+ return {
36
+ data: _e.message||_e,
37
+ database: params.db,
38
+ table: params.table,
39
+ status: 'error',
40
+ }
41
+ }
42
+
43
+ /* --------------------------------------------------------------------------------------- */
44
+
45
+ function bodyParser( _data ){
46
+ try{
47
+ const date = Date.now(); _data = JSON.parse(_data);
48
+ const result = _data.length ? _data : [_data];
49
+ return result.map(x=>{ if( !x?.hash )
50
+ x.hash = crypto.hash( date,Math.random() );
51
+ return JSON.stringify(x);
52
+ });
53
+ } catch(e) { return false }
54
+ }
55
+
56
+ function getBody(){
57
+ return new Promise((response,reject)=>{
58
+ try{
59
+ if( req.method == 'POST' || (/push|unshift|splice|update/).test(api.pathname) ){
60
+ const data = new Array();
61
+ req.on('data',(chunk)=>{ data.push(chunk); });
62
+ req.on('close',()=>{ try{
63
+ const buff = Buffer.concat(data);
64
+ response( bodyParser(buff) );
65
+ } catch(e) { response(false) } });
66
+ } else { response(true) }
67
+ } catch(e) { response(false) }
68
+ });
69
+ }
70
+
71
+ function encryptDB( _db,_table, _path ){
72
+ return new Promise((response,reject)=>{
73
+ const writable = fs.createWriteStream( _path+'_tmp' );
74
+ for( var i in db[_db][_table] ){
75
+
76
+ const data = db[_db][_table][i];
77
+ const ecrp = crypto.encrypt( data,query.pass );
78
+
79
+ writable.write(`${ecrp}\n`);
80
+ } writable.end();
81
+
82
+ writable.on('close',()=>{
83
+ fs.renameSync( _path+'_tmp', _path );
84
+ response('done');
85
+ });
86
+
87
+ writable.on('error',(e)=>{
88
+ reject(e);
89
+ });
90
+ });
91
+ }
92
+
93
+ function validate( _params ){
94
+ return new Promise((response,reject)=>{
95
+
96
+ let validator = false;
97
+
98
+ const vdb = (key)=>{ return db._init_.DB.some(x=>{ return x.name == key; }) }
99
+ const vtb = (key)=>{ return db._init_.DB.some(x=>{ return x.tables.join().match(key); }) }
100
+
101
+ validator = [
102
+ [ !_params?.offset, '_params.offset = 0' ],
103
+ [ !_params?.target, '_params.target = ""' ],
104
+ [ !_params?.length, '_params.length = 100' ],
105
+ ].every(x=>{ if(x[0]) eval(x[1]); return true; });
106
+
107
+ validator = [
108
+ [!body, {status:'error',message:'invalid data'}],
109
+ [!_params?.db, {status:'error',message:'no db name added'}],
110
+ [!_params?.table, {status:'error',message:'no table name added'}]
111
+ ].some(x=>{ if(x[0]) reject(x[1]); return x[0];}); if(validator) return 0;
112
+
113
+ if( !(/table|db|all/gi).test(parse.pathname) ){
114
+ validator = [
115
+ [!vdb(_params?.db), {status:'error',message:`no db called ${_params.db} exist`}],
116
+ [!vtb(_params?.table), {status:'error',message:`no table called ${_params.table} exist`}]
117
+ ].some(x=>{ if(x[0]) reject(x[1]); return x[0];}); if(validator) return 0;
118
+ }
119
+
120
+ response(_params);
121
+
122
+ });
123
+ }
124
+
125
+ /* --------------------------------------------------------------------------------------- */
126
+
127
+ function refresh( _params ){
128
+ return new Promise((response,reject)=>{
129
+ _init_().then(()=>{ response([{status: 'done'}]) })
130
+ .catch((e)=>{ reject([{status:'error',message:e.message}]) });
131
+ });
132
+ }
133
+
134
+ async function save( _params ){
135
+ await modifyDB( _params.db,_params.table );
136
+ return [{
137
+ database: _params.db,
138
+ table: _params.table,
139
+ status: 'saved'
140
+ }];
141
+ }
142
+
143
+ /* --------------------------------------------------------------------------------------- */
144
+
145
+ (async ()=>{
146
+ try{
147
+
148
+ body = await getBody();
149
+ params = await validate(params);
150
+
151
+ /* Find Api */
152
+ if( api.pathname == '/list' ) json( await list(params) )
153
+ else if( api.pathname == '/hash' ) json( await hash(params) )
154
+ else if( api.pathname == '/match' ) json( await match(params) )
155
+ else if( api.pathname == '/update' ) json( await update(params) )
156
+
157
+ else if( api.pathname == '/index' ) json( await indexOf(params) )
158
+ else if( api.pathname == '/length' ) json( await lengthOf(params) )
159
+
160
+ /* Save Api */
161
+ else if( api.pathname == '/save' ) json( await save(params) )
162
+ else if( api.pathname == '/remove' ) json( await remove(params) )
163
+ else if( api.pathname == '/refresh' ) json( await refresh(params) )
164
+ else if( api.pathname == '/saveAll' ) json( await saveAll(params) )
165
+
166
+ /* Remove Api */
167
+ else if( api.pathname == '/pop' ) json( await pop(params) )
168
+ else if( api.pathname == '/shift' ) json( await shift(params) )
169
+
170
+ /* Modify Api */
171
+ else if( api.pathname == '/push' ) json( await push(params) )
172
+ else if( api.pathname == '/splice' ) json( await splice(params) )
173
+ else if( api.pathname == '/unshift' ) json( await unshift(params) )
174
+
175
+ /* Modify Table Api */
176
+ else if( api.pathname == '/addDB' ) json( await addDB(params) )
177
+ else if( api.pathname == '/removeDB' ) json( await removeDB(params) )
178
+
179
+ /* Modify Table Api */
180
+ else if( api.pathname == '/addTable' ) json( await addTable(params) )
181
+ else if( api.pathname == '/removeTable' ) json( await removeTable(params) )
182
+
183
+ else error(parseError('Oops something went wrong'));
184
+
185
+ } catch(e) { error(parseError(e)); }
186
+ })();
187
+
188
+ /* --------------------------------------------------------------------------------------- */
@@ -1,4 +1,3 @@
1
-
2
1
  const crypto = require('crypto-js');
3
2
  const output = new Object();
4
3
 
@@ -36,7 +35,7 @@ output.slugify = (str)=>{
36
35
  ['u','ú|ù|û|ü'],
37
36
  ['o','ó|ò|ô|õ|ö'],
38
37
  ['a','á|à|ã|â|ä'],
39
- ['' ,/\s+|\W+/,]
38
+ ['' ,/\s+|\W+| /,]
40
39
  ].map(x=>{
41
40
  const regex = new RegExp(x[1],'gi');
42
41
  str = str.replace( regex,x[0] );
@@ -66,4 +65,94 @@ output.decrypt = ( _message,_password )=>{
66
65
 
67
66
  /* -------------------------------------------------------------------------------------------------------- */
68
67
 
68
+ class State {
69
+
70
+ state = new Object();
71
+ events = new Array();
72
+ update = new Array();
73
+ active = true;
74
+
75
+ constructor( state ){
76
+ for( var i in state ){
77
+ this.state[i] = state[i];
78
+ }
79
+ }
80
+
81
+ set( state ){ let newState;
82
+
83
+ const oldState = new Object();
84
+ const keys = Object.keys(this.state);
85
+ keys.map(x=>{ oldState[x]=this.state[x] });
86
+
87
+ if( typeof state == 'function' ){
88
+ newState = state( this.state ); const validator = [
89
+ [!newState,'state is empty, please set a return state'],
90
+ [typeof newState != 'object','state is not an object, please return a valid Object'],
91
+ ]; if( validator.some(x=>{ if(x[0]) console.log(x[1]); return x[0] }) ) return 0;
92
+ } else if( !state || typeof state != 'object' ) {
93
+ return console.log('state is not an object, please return a valid Object')
94
+ } else { newState = state; }
95
+
96
+ this.active = this.shouldUpdate(null,[this.state,newState]);
97
+ for( var i in newState ){ this.state[i] = newState[i];
98
+ this.callback( i, oldState[i], newState[i] );
99
+ }
100
+
101
+ }
102
+
103
+ get( item ){ return this.state[item] }
104
+
105
+ shouldUpdate( callback,attr ){
106
+ if( callback && typeof callback == 'function' )
107
+ return this.update.push(callback);
108
+ else if( callback && callback != 'function' )
109
+ return console.log('callback should be a function');
110
+ if( this.update.length == 0 ) return true;
111
+ return this.update.some( x=>x(...attr) );
112
+ }
113
+
114
+ forceUpdate( item ){
115
+ for( var i in this.events ){
116
+ const field = this.events[i][0]
117
+ this.events[i][1](
118
+ this.state[field],
119
+ this.state[field]
120
+ );
121
+ }
122
+ }
123
+
124
+ callback( item, prev, act ){
125
+ if( !this.active ) return 0;
126
+ for( var i in this.events ){
127
+ if( this.events[i][0] == item )
128
+ this.events[i][1]( prev,act );
129
+ }
130
+ }
131
+
132
+ observeField( field,callback ){
133
+ const id = this.eventID();
134
+ const event = [field,callback,id];
135
+ this.events.push(event); return id;
136
+ }
137
+
138
+ unObserveField( eventID ){
139
+ for( var i in this.events ){
140
+ if( this.events[i][2] == eventID ){
141
+ this.events.splice(i,1);
142
+ return true;
143
+ }
144
+ } return false;
145
+ }
146
+
147
+ eventID(){
148
+ return crypto.SHA256(`
149
+ ${Math.random()}
150
+ ${Date.now()}
151
+ `).toString();
152
+ }
153
+
154
+ }; output.state = State;
155
+
156
+ /* -------------------------------------------------------------------------------------------------------- */
157
+
69
158
  module.exports = output;
package/module/_init_.js CHANGED
@@ -17,7 +17,7 @@ function fillDB( _db, _table, _path ){
17
17
  else { console.log(`error reading ${_path}`); return response(); }
18
18
 
19
19
  _itr.on('line',(line)=>{
20
- db[_db][_table].push(crypto.decrypt( line,query.pass ));
20
+ db[_db][_table].push(crypto.decrypt( line,process.mollyDB.pass ));
21
21
  }); _itr.on('close',()=>{ response() });
22
22
 
23
23
  });
@@ -28,9 +28,10 @@ function fillDB( _db, _table, _path ){
28
28
  (()=>{ return new Promise(async(response,reject)=>{
29
29
  try {
30
30
 
31
- const path = `${query.path}/_init_.json`;
31
+ const path = `${process.mollyDB.path}/_init_.json`;
32
+ db._update_ = true;
32
33
 
33
- if( (/^http/).test(query.path) ){
34
+ if( (/^http/).test(process.mollyDB.path) ){
34
35
  const stream = await fetch(path);
35
36
  db._init_ = stream.data;
36
37
  } else{
@@ -38,7 +39,7 @@ function fillDB( _db, _table, _path ){
38
39
  db._init_ = JSON.parse( db._buff_ );
39
40
  }
40
41
 
41
- db._path_ = query.path;
42
+ db._path_ = process.mollyDB.path;
42
43
  for( var i in db._init_.DB ){
43
44
 
44
45
  const DB = db._init_.DB[i];
@@ -58,8 +59,8 @@ function fillDB( _db, _table, _path ){
58
59
  } catch(e) {
59
60
 
60
61
  db._init_ = { DB:[] };
61
- db._path_ = query.path;
62
- const path = `${query.path}/_init_.json`;
62
+ db._path_ = process.mollyDB.path;
63
+ const path = `${process.mollyDB.path}/_init_.json`;
63
64
  fs.writeFileSync( path,JSON.stringify(db._init_) );
64
65
 
65
66
  } response();
@@ -11,41 +11,52 @@ const fs = require('fs');
11
11
  /* --------------------------------------------------------------------------------------- */
12
12
 
13
13
  const db = new Object();
14
- let query;
14
+ const api_script = fs.readFileSync(`${__dirname}/_api_.js`).toString();
15
+ const app_script = fs.readFileSync(`${__dirname}/_app_.js`).toString();
16
+ const init_script = fs.readFileSync(`${__dirname}/_init_.js`).toString();
17
+ //const importDB_script = fs.readFileSync(`${__dirname}/_importDB.js`).toString();
15
18
 
16
19
  /* --------------------------------------------------------------------------------------- */
17
20
 
18
- function _init_(){
19
- try{ return eval( fs.readFileSync(`${__dirname}/_init_.js`).toString() );
20
- } catch(e){ console.log(e); }
21
- }
21
+ async function _init_(){ await eval(`try{ ${init_script} }catch(e){console.log(e)}`) }
22
+ async function _importDB_(){ await eval(`try{ ${importDB_script} }catch(e){console.log(e)}`) }
23
+ async function app(req,res){ await eval(`try{ ${api_script} \n ${app_script} }catch(e){console.log(e)}`) }
22
24
 
23
25
  /* --------------------------------------------------------------------------------------- */
24
-
25
- function app(req,res){
26
- try{ eval( fs.readFileSync(`${__dirname}/_server_.js`).toString() );
27
- } catch(e) { console.log(e) }
26
+ function saveTimeout(){
27
+ time = process.mollyDB.time * 3600000;
28
+ setTimeout(() => {
29
+ if( db._update_ == true ){
30
+ const api = url.format({
31
+ path: '/saveAll?db=&table=',
32
+ port: process.mollyDB.port,
33
+ host: 'http://127.0.0.1',
34
+ }); fetch(api).then().catch();
35
+ db._update_ = false;
36
+ }
37
+ }, time);
28
38
  }
29
-
30
39
  /* --------------------------------------------------------------------------------------- */
31
40
 
32
- module.exports = (args)=>{ query = args;
41
+ module.exports = (args)=>{ process.mollyDB = args;
33
42
  return new Promise((response,reject)=>{
34
43
 
35
- if ( cluster.isPrimary ) { for ( let i=query.threads; i--; ) {
36
- const worker = cluster.fork();
37
- worker.on('message', (msg)=>{ console.log(msg); response(); });
38
- cluster.on('exit', (worker, code, signal) => { cluster.fork();
39
- console.log(`worker ${worker.process.pid} died`);
40
- }); worker.on('exit', (msg)=>{ reject(msg); });
41
- }} else {
42
- http.createServer( app ).listen( query.port,()=>{
44
+ if( cluster.isPrimary )
45
+ for ( let i=args.threads; i--; ){ const worker = cluster.fork();
46
+ worker.on('message', (msg)=>{ console.log(msg); response(); });
47
+ cluster.on('exit', (worker, code, signal) => { cluster.fork();
48
+ console.log(`worker ${worker.process.pid} died`);
49
+ }); worker.on('exit', (msg)=>{ reject(msg); });
50
+ }
51
+
52
+ else
53
+ http.createServer( app ).listen( process.mollyDB.port,()=>{
43
54
  _init_().then(()=>{ process.send({
44
- workerID: process.pid, port: query.port,
45
- protocol: 'HTTP', status: 'started',
46
- })}).catch(e=>{ console.log(e); });
55
+ protocol: 'HTTP', status: 'started',
56
+ workerID: process.pid, port: process.mollyDB.port,
57
+ }); saveTimeout();
58
+ }).catch(e=>{ console.log(e) });
47
59
  });
48
- }
49
60
 
50
61
  });
51
62
  }
package/package.json CHANGED
@@ -1,18 +1,12 @@
1
1
  {
2
2
  "license": "MIT",
3
3
  "main": "main.js",
4
- "version": "1.0.27",
5
4
  "name": "molly-db",
5
+ "version": "1.0.30",
6
6
  "author": "bececrazy",
7
- "scripts": {
8
- "start": "node main"
9
- },
7
+ "scripts": { "start": "node main" },
10
8
  "repository": "https://github.com/EDBC-REPO-NPM/Molly-db",
11
- "dependencies": {
12
- "crypto-js": "^4.1.1",
13
- "fs": "^0.0.1-security",
14
- "molly-fetch": "^1.0.16"
15
- },
9
+ "dependencies": { "crypto-js": "^4.1.1", "molly-fetch": "^1.0.16" },
16
10
  "description": "Molly-db is a free and open source library for nodejs that allow you create a lightweight encrypted database using Json files",
17
11
  "keywords": [
18
12
  "json",
@@ -1,382 +0,0 @@
1
-
2
- const api = url.parse( req.url,true );
3
- let params = api.query;
4
- let body = undefined;
5
- let parse = api;
6
-
7
- /* --------------------------------------------------------------------------------------- */
8
-
9
- function error( _error ){
10
- res.writeHead(404,{'contetn-type':'application/json'});
11
- res.end(JSON.stringify([{ status:'error', message:_error }]));
12
- console.log( _error,req.url );
13
- }
14
-
15
- function json( _data ){
16
- res.writeHead(200,{'content-type':'application/json'});
17
- res.end(JSON.stringify(_data));
18
- }
19
-
20
- /* --------------------------------------------------------------------------------------- */
21
-
22
- function bodyParser( _data ){
23
-
24
- const date = Date.now(); _data = JSON.parse(_data);
25
- const result = _data.length ? _data : [_data];
26
-
27
- return result.map(x=>{ if( !x?.hash )
28
- x.hash = crypto.hash( date,Math.random() );
29
- return JSON.stringify(x);
30
- });
31
-
32
- }
33
-
34
- function getBody(){
35
- return new Promise((response,reject)=>{
36
- try{
37
- if( req.method == 'POST' || (/push|unshift|splice|update/).test(api.pathname) ){
38
- const data = new Array();
39
- req.on('data',(chunk)=>{ data.push(chunk); });
40
- req.on('close',()=>{ try{
41
- const buff = Buffer.concat(data);
42
- response( bodyParser(buff) );
43
- } catch(e) { response(false) } });
44
- } else { response(true) }
45
- } catch(e) { response(false) }
46
- });
47
- }
48
-
49
- function encryptDB( _db,_table, _path ){
50
- return new Promise((response,reject)=>{
51
- const writable = fs.createWriteStream( _path+'_tmp' );
52
- for( var i in db[_db][_table] ){
53
-
54
- const data = db[_db][_table][i];
55
- const ecrp = crypto.encrypt( data,query.pass );
56
-
57
- writable.write(`${ecrp}\n`);
58
- } writable.end();
59
-
60
- writable.on('close',()=>{
61
- fs.renameSync( _path+'_tmp', _path );
62
- response('done');
63
- });
64
-
65
- writable.on('error',(e)=>{
66
- reject(e);
67
- });
68
- });
69
- }
70
-
71
- function validate( _params ){
72
- return new Promise((response,reject)=>{
73
-
74
- let validator = false;
75
-
76
- const vdb = (key)=>{ return db._init_.DB.some(x=>{ return x.name == key; }) }
77
- const vtb = (key)=>{ return db._init_.DB.some(x=>{ return x.tables.join().match(key); }) }
78
-
79
- validator = [
80
- [ !_params?.offset, '_params.offset = 0' ],
81
- [ !_params?.target, '_params.target = ""' ],
82
- [ !_params?.length, '_params.length = 100' ],
83
- ].every(x=>{ if(x[0]) eval(x[1]); return true; });
84
-
85
- validator = [
86
- [!body, {status:'error',message:'invalid data'}],
87
- [!_params?.db, {status:'error',message:'no db name added'}],
88
- [!_params?.table, {status:'error',message:'no table name added'}]
89
- ].some(x=>{ if(x[0]) reject(x[1]); return x[0];}); if(validator) return 0;
90
-
91
- if( !(/table|db/gi).test(parse.pathname) ){
92
- validator = [
93
- [!vdb(_params?.db), {status:'error',message:`no db called ${_params.db} exist`}],
94
- [!vtb(_params?.table), {status:'error',message:`no table called ${_params.table} exist`}]
95
- ].some(x=>{ if(x[0]) reject(x[1]); return x[0];}); if(validator) return 0;
96
- }
97
-
98
- response(_params);
99
-
100
- });
101
- }
102
-
103
- /* --------------------------------------------------------------------------------------- */
104
-
105
- function list( _params ){
106
- return db[_params.db][_params.table].slice(
107
- _params.offset, Number(_params.offset)+Number(_params.length)
108
- ).map(x=>JSON.parse(x));
109
- }
110
-
111
- function match( _params ){
112
- const result = new Array();
113
- db[_params.db][_params.table].map((x)=>{
114
- const regex = new RegExp(crypto.slugify(_params.target),'gi');
115
- const target = crypto.slugify(x);
116
- if( regex.test(target) ) result.push(x);
117
- });
118
- return result.map(x=>JSON.parse(x)).slice(
119
- _params.offset, Number(_params.offset)+Number(_params.length)
120
- );
121
- }
122
-
123
- function hash( _params ){
124
- const result = new Array();
125
- db[_params.db][_params.table].map((x)=>{
126
- const regex = new RegExp(_params.target,'gi');
127
- if( regex.test(x) ) result.push(x);
128
- });
129
- return result.map(x=>JSON.parse(x)).slice(
130
- _params.offset, Number(_params.offset)+Number(_params.length)
131
- );
132
- }
133
-
134
- /* --------------------------------------------------------------------------------------- */
135
-
136
- async function shift( _params ){
137
- const result = db[_params.db][_params.table].shift(); await save( _params ); return result;
138
- }
139
-
140
- async function pop( _params ){
141
- const result = db[_params.db][_params.table].pop(); await save( _params ); return result;
142
- }
143
-
144
- /* --------------------------------------------------------------------------------------- */
145
-
146
- function lengthOf( _params ){ return db[_params.db][_params.table].length; }
147
- function indexOf( _params ){
148
- return db[_params.db][_params.table].indexOf(x=>{
149
- const regex = new RegExp(_params.target,'gi');
150
- return regex.test(x);
151
- });
152
- }
153
-
154
- /* --------------------------------------------------------------------------------------- */
155
-
156
- async function unshift( _params ){
157
-
158
- db[_params.db][_params.table].unshift( ...body );
159
-
160
- await save( _params ); return [{
161
- database: _params.db,
162
- table: _params.table,
163
- status: 'unshifted'
164
- }];
165
- }
166
-
167
- async function push( _params ){
168
-
169
- db[_params.db][_params.table].push( ...body );
170
- await save( _params ); return [{
171
- database: _params.db,
172
- table: _params.table,
173
- status: 'pushed'
174
- }];
175
-
176
- }
177
-
178
- /* --------------------------------------------------------------------------------------- */
179
-
180
- async function update( _params ){
181
-
182
- const index = db[_params.db][_params.table].findIndex(x=>{
183
- const regex = new RegExp(_params.target,'gi');
184
- return regex.test(x);
185
- });
186
-
187
- if( !(index<0) )
188
- db[_params.db][_params.table].splice( index,1,...body );
189
-
190
- await save( _params ); return [{
191
- database: _params.db,
192
- table: _params.table,
193
- status: 'udated'
194
- }];
195
- }
196
-
197
- async function remove( _params ){
198
-
199
- const index = db[_params.db][_params.table].findIndex(x=>{
200
- const regex = new RegExp(_params.target,'gi');
201
- return regex.test(x);
202
- });
203
-
204
- if( !(index<0) )
205
- db[_params.db][_params.table].splice( index,1 );
206
-
207
- await save( _params ); return [{
208
- database: _params.db,
209
- table: _params.table,
210
- status: 'removed'
211
- }];
212
- }
213
-
214
- /* --------------------------------------------------------------------------------------- */
215
-
216
- async function addDB( _params ){
217
- try{
218
-
219
- db._init_.DB.push({
220
- tables: [],
221
- name: _params.db,
222
- }); db[_params.db] = new Array();
223
-
224
- await save( _params ); return [{
225
- database: _params.db,
226
- status: 'DB added'
227
- }];
228
-
229
- } catch(e) { }
230
- }
231
-
232
- async function removeDB( _params ){
233
- try{
234
-
235
- const i = db._init_.DB.findIndex(x=>{
236
- return x.name == _params.db
237
- });
238
-
239
- db._init_.DB[i].tables.forEach(x=>{
240
- const path = `${query.path}/${x}.json`;
241
- fs.unlinkSync(path);
242
- }); db._init_.DB.splice(i,1);
243
- db[_params.db] = new Array();
244
-
245
- await save( _params ); return [{
246
- database: _params.db,
247
- table: _params.table,
248
- status: 'DB deleted'
249
- }];
250
-
251
- } catch(e) { }
252
- }
253
-
254
- async function modifyDB( _name, _table ){
255
- try{
256
-
257
- const init = `${query.path}/_init_.json`;
258
- const path = `${query.path}/${_table}.json`;
259
- fs.writeFileSync( init,JSON.stringify(db._init_) );
260
-
261
- try {
262
- const length = db[_name][_table].length;
263
- if( length>0 )
264
- await encryptDB( _name, _table, path );
265
- else
266
- fs.writeFileSync( path,'' );
267
- } catch(e) {
268
- fs.unlinkSync( path );
269
- }
270
-
271
- } catch(e) { }
272
- }
273
-
274
- /* --------------------------------------------------------------------------------------- */
275
-
276
- async function addTable( _params ){
277
-
278
- if( db[_params.db][_params.table] )
279
- return {
280
- database: _params.db,
281
- table: _params.table,
282
- status: 'table exist'
283
- };
284
-
285
- const i = db._init_.DB.findIndex(x=>{
286
- return x.name == _params.db;
287
- }); db._init_.DB[i].tables.push(_params.table);
288
-
289
- db[_params.db][_params.table] = new Array();
290
-
291
- await save( _params ); return [{
292
- database: _params.db,
293
- table: _params.table,
294
- status: 'table added'
295
- }];
296
-
297
- }
298
-
299
- async function removeTable( _params ){
300
-
301
- const i = db._init_.DB.findIndex(x=>{
302
- return x.name == _params.db;
303
- });
304
-
305
- const j = db._init_.DB[i].tables.findIndex(x=>{
306
- return x == _params.table;
307
- });
308
-
309
- db._init_.DB[i].tables.splice(j,1);
310
- delete db[_params.db][_params.table];
311
-
312
- await save( _params ); return [{
313
- database: _params.db,
314
- table: _params.table,
315
- status: 'table removed'
316
- }];
317
-
318
- }
319
-
320
- /* --------------------------------------------------------------------------------------- */
321
-
322
- function refresh( _params ){
323
- return new Promise((response,reject)=>{
324
- _init_().then(()=>{ response([{status: 'done'}]) })
325
- .catch((e)=>{ reject([{status:'error',message:e.message}]) });
326
- });
327
- }
328
-
329
- async function save( _params ){
330
- await modifyDB( _params.db,_params.table );
331
- return [{
332
- database: _params.db,
333
- table: _params.table,
334
- status: 'saved'
335
- }];
336
- }
337
-
338
- /* --------------------------------------------------------------------------------------- */
339
-
340
- (async ()=>{
341
- try{
342
-
343
- body = await getBody();
344
- params = await validate(params);
345
-
346
- /* Find Api */
347
- if( api.pathname == '/list' ) json( await list(params) )
348
- else if( api.pathname == '/hash' ) json( await hash(params) )
349
- else if( api.pathname == '/match' ) json( await match(params) )
350
- else if( api.pathname == '/update' ) json( await update(params) )
351
-
352
- else if( api.pathname == '/index' ) json( await indexOf(params) )
353
- else if( api.pathname == '/lengt' ) json( await lengthOf(params) )
354
-
355
- /* Save Api */
356
- else if( api.pathname == '/save' ) json( await save(params) )
357
- else if( api.pathname == '/remove' ) json( await remove(params) )
358
- else if( api.pathname == '/refresh' ) json( await refresh(params) )
359
-
360
- /* Remove Api */
361
- else if( api.pathname == '/pop' ) json( await pop(params) )
362
- else if( api.pathname == '/shift' ) json( await shift(params) )
363
-
364
- /* Modify Api */
365
- else if( api.pathname == '/push' ) json( await push(params) )
366
- else if( api.pathname == '/splice' ) json( await splice(params) )
367
- else if( api.pathname == '/unshift' ) json( await unshift(params) )
368
-
369
- /* Modify Table Api */
370
- else if( api.pathname == '/addDB' ) json( await addDB(params) )
371
- else if( api.pathname == '/removeDB' ) json( await removeDB(params) )
372
-
373
- /* Modify Table Api */
374
- else if( api.pathname == '/addTable' ) json( await addTable(params) )
375
- else if( api.pathname == '/removeTable' ) json( await removeTable(params) )
376
-
377
- else error('Oops something went wrong');
378
-
379
- } catch(e) { error(e?.message||e); }
380
- })();
381
-
382
- /* --------------------------------------------------------------------------------------- */