molly-db 1.0.27 → 1.0.30

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 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
- /* --------------------------------------------------------------------------------------- */