yodata 0.0.7 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -48
- package/index.js +6 -0
- package/lib/bson.js +269 -0
- package/lib/connection.js +81 -0
- package/lib/database.js +337 -0
- package/lib/model.js +53 -0
- package/package.json +24 -25
- package/ex.js +0 -4
- package/server.js +0 -176
- package/system.js +0 -21
package/README.md
CHANGED
|
@@ -1,90 +1,101 @@
|
|
|
1
1
|
# Y0data services #
|
|
2
2
|
|
|
3
|
-
**
|
|
4
|
-
**To get database id go to https://data.y0host.net/**
|
|
3
|
+
**MongoDB-style client for connecting to Y0Data worker server**
|
|
5
4
|
**Your data will save in servers y0data, so no disk will take from your server**
|
|
6
5
|
|
|
7
6
|
# install y0data
|
|
8
7
|
|
|
9
8
|
``` js
|
|
10
|
-
npm install
|
|
9
|
+
npm install y0data
|
|
11
10
|
```
|
|
12
11
|
|
|
13
12
|
# Connect Database
|
|
14
13
|
|
|
15
14
|
``` js
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const Database = require('y0data');
|
|
16
|
+
|
|
17
|
+
// Create connection with host, port, databaseId, username, password
|
|
18
|
+
const db = new Database(
|
|
19
|
+
'localhost', // host
|
|
20
|
+
5001, // port
|
|
21
|
+
'f9b07fbe-7c8d-4f9d-9028-ebec6b3b2eea', // databaseId
|
|
22
|
+
'yousuf', // username
|
|
23
|
+
'41371755aa' // password
|
|
24
|
+
);
|
|
19
25
|
```
|
|
20
26
|
|
|
21
27
|
# events
|
|
22
28
|
|
|
23
29
|
```js
|
|
24
|
-
db.
|
|
30
|
+
db.on('authenticated', async ()=>{
|
|
25
31
|
console.log(`DataBase Ready`)
|
|
32
|
+
// Now you can use database methods
|
|
26
33
|
})
|
|
27
34
|
|
|
28
35
|
db.on('error', (err)=>{
|
|
29
36
|
console.log(`Error: ` + err)
|
|
30
37
|
})
|
|
38
|
+
|
|
39
|
+
db.on('connected', ()=>{
|
|
40
|
+
console.log(`Connected to server`)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
db.on('disconnected', ()=>{
|
|
44
|
+
console.log(`Disconnected from server`)
|
|
45
|
+
})
|
|
31
46
|
```
|
|
32
47
|
|
|
33
48
|
# setup collection
|
|
34
49
|
|
|
35
50
|
```js
|
|
36
|
-
let customersDB = db.
|
|
51
|
+
let customersDB = db.model('Customer', {}, 'customers')
|
|
52
|
+
// Now you can use customersDB methods
|
|
37
53
|
```
|
|
38
54
|
|
|
39
55
|
# functions
|
|
40
56
|
|
|
41
57
|
## Create
|
|
42
58
|
```js
|
|
43
|
-
let data = await customersDB.
|
|
44
|
-
let data = await customersDB.
|
|
59
|
+
let data = await customersDB.insertOne({"money": 51}) // example output → '[Accepted Data]'
|
|
60
|
+
let data = await customersDB.insertOne({"_id": "123", "money": 5}) // example output → '{Accepted Data} / null'
|
|
61
|
+
let data = await customersDB.insertMany([{"money": 51}, {"money": 9}]) // example output → '[Accepted Data]'
|
|
45
62
|
/*
|
|
46
|
-
|
|
47
|
-
For Shared Plan 100 Array max in same time
|
|
48
|
-
For Server Plan 500 Array max in same time
|
|
63
|
+
Data will be serialized to BSON format automatically
|
|
49
64
|
*/
|
|
50
65
|
```
|
|
51
66
|
|
|
52
67
|
## find data
|
|
53
68
|
```js
|
|
54
69
|
let options = {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
$in: {_id: ['123', '1234']} // get Users have in same _id
|
|
70
|
+
money: {$gte: 10}, // Get Users have money greater than or equal to 10
|
|
71
|
+
age: {$gt: 50} // get Users have age greater than 50
|
|
58
72
|
}
|
|
59
73
|
|
|
60
|
-
let data = await customersDB.find(options)
|
|
61
|
-
let data = await customersDB.find(options
|
|
62
|
-
let data = await customersDB.find(options
|
|
63
|
-
let data = await customersDB.find(options
|
|
64
|
-
let data = await customersDB.find(options).select({money: 0}).exec(); // (Will hide money) example output → 'Array'
|
|
74
|
+
let data = await customersDB.find(options) // example output → 'Array'
|
|
75
|
+
let data = await customersDB.find(options, {limit: 20}) // (Get Only 20 data) example output → 'Array'
|
|
76
|
+
let data = await customersDB.find(options, {skip: 20}) // (Skip first 20) example output → 'Array'
|
|
77
|
+
let data = await customersDB.find(options, {limit: 20, skip: 10}) // (Skip 10 and limit 20) example output → 'Array'
|
|
65
78
|
|
|
66
|
-
let data = await customersDB.findOne(options)
|
|
67
|
-
let data = await customersDB.findOne(options
|
|
68
|
-
let data = await customersDB.
|
|
69
|
-
let data = await customersDB.findOne(options).select({money: 0}).exec(); // (Will hide money) example output → 'Object/Null'
|
|
79
|
+
let data = await customersDB.findOne(options) // example output → 'Object/Null'
|
|
80
|
+
let data = await customersDB.findOne(options, {skip: 20}) // (Skip first 20) example output → 'Object/Null'
|
|
81
|
+
let data = await customersDB.findById('123') // (Find by ID) example output → 'Object/Null'
|
|
70
82
|
```
|
|
71
83
|
|
|
72
84
|
## Update Data
|
|
73
85
|
```js
|
|
74
86
|
let options = {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
$in: {_id: ['123', '1234']} // get Users have in same _id
|
|
87
|
+
money: {$gte: 10}, // Get Users have money greater than or equal to 10
|
|
88
|
+
_id: {$in: ['123', '1234']} // get Users with IDs in array
|
|
78
89
|
}
|
|
79
90
|
|
|
80
91
|
let new_values = {
|
|
81
|
-
$inc: {money: 50}, // Add money you can also do -50 to remove
|
|
92
|
+
$inc: {money: 50}, // Add money you can also do -50 to remove
|
|
82
93
|
|
|
83
|
-
$push: {arr: ["1"]}, // add in array items
|
|
84
|
-
$push: {arr: "1"}, // add in array item
|
|
94
|
+
$push: {arr: ["1"]}, // add in array items
|
|
95
|
+
$push: {arr: "1"}, // add in array item
|
|
85
96
|
|
|
86
|
-
$pull: {arr: ["1"]}, // delete from array items
|
|
87
|
-
$pull: {arr: "1"} // delete from array item
|
|
97
|
+
$pull: {arr: ["1"]}, // delete from array items
|
|
98
|
+
$pull: {arr: "1"} // delete from array item
|
|
88
99
|
}
|
|
89
100
|
|
|
90
101
|
let data = await customersDB.updateOne(options, new_values) // example output → 'true/false'
|
|
@@ -95,9 +106,8 @@ let data = await customersDB.updateMany(options, new_values); // example output
|
|
|
95
106
|
## Delete Data
|
|
96
107
|
```js
|
|
97
108
|
let options = {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
$in: {_id: ['123', '1234']} // get Users have in same _id
|
|
109
|
+
money: {$gte: 10}, // Get Users have money greater than or equal to 10
|
|
110
|
+
_id: {$in: ['123', '1234']} // get Users with IDs in array
|
|
101
111
|
}
|
|
102
112
|
|
|
103
113
|
let data = await customersDB.deleteOne(options) // example output → 'true/false'
|
|
@@ -108,21 +118,13 @@ let data = await customersDB.deleteMany(options); // example output → 'true/fa
|
|
|
108
118
|
## Other functions will support you
|
|
109
119
|
```js
|
|
110
120
|
let options = {
|
|
111
|
-
|
|
112
|
-
$gt: {money: 50}, // get Users have money more of 50
|
|
113
|
-
$in: {_id: ['123', '1234']} // get Users have in same _id
|
|
121
|
+
money: {$gte: 10}, // Get Users have money greater than or equal to 10
|
|
114
122
|
}
|
|
115
123
|
|
|
116
|
-
let data = await customersDB.countDocuments(options) // example output →
|
|
117
|
-
|
|
118
|
-
let data = await customersDB.getSize(options); // example output → 177 (KB)
|
|
124
|
+
let data = await customersDB.countDocuments(options) // example output → 'Number'
|
|
119
125
|
```
|
|
120
126
|
|
|
121
|
-
##
|
|
127
|
+
## Disconnect
|
|
122
128
|
```js
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
db.on('watch', (data)=>{
|
|
126
|
-
console.log('data watch =>', data) // will get name of collection and more data
|
|
127
|
-
})
|
|
129
|
+
db.disconnect() // Close connection to server
|
|
128
130
|
```
|
package/index.js
ADDED
package/lib/bson.js
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
// BSON Type Codes
|
|
2
|
+
const TYPES = {
|
|
3
|
+
DOUBLE: 0x01,
|
|
4
|
+
STRING: 0x02,
|
|
5
|
+
OBJECT: 0x03,
|
|
6
|
+
ARRAY: 0x04,
|
|
7
|
+
BINARY: 0x05,
|
|
8
|
+
UNDEFINED: 0x06,
|
|
9
|
+
BOOL: 0x08,
|
|
10
|
+
DATE: 0x09,
|
|
11
|
+
NULL: 0x0A,
|
|
12
|
+
INT32: 0x10,
|
|
13
|
+
INT64: 0x12
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// BSON Serializer
|
|
17
|
+
function serialize(doc) {
|
|
18
|
+
const chunks = [];
|
|
19
|
+
|
|
20
|
+
for (const key in doc) {
|
|
21
|
+
const value = doc[key];
|
|
22
|
+
const keyBuf = Buffer.from(key);
|
|
23
|
+
const keyLen = Buffer.from([keyBuf.length]);
|
|
24
|
+
|
|
25
|
+
if (value === null || value === undefined) {
|
|
26
|
+
chunks.push(Buffer.concat([
|
|
27
|
+
Buffer.from([value === null ? TYPES.NULL : TYPES.UNDEFINED]),
|
|
28
|
+
keyLen,
|
|
29
|
+
keyBuf
|
|
30
|
+
]));
|
|
31
|
+
}
|
|
32
|
+
else if (typeof value === 'string') {
|
|
33
|
+
const valBuf = Buffer.from(value, 'utf8');
|
|
34
|
+
const lenBuf = Buffer.alloc(4);
|
|
35
|
+
lenBuf.writeInt32LE(valBuf.length);
|
|
36
|
+
chunks.push(Buffer.concat([
|
|
37
|
+
Buffer.from([TYPES.STRING]),
|
|
38
|
+
keyLen,
|
|
39
|
+
keyBuf,
|
|
40
|
+
lenBuf,
|
|
41
|
+
valBuf
|
|
42
|
+
]));
|
|
43
|
+
}
|
|
44
|
+
else if (typeof value === 'number') {
|
|
45
|
+
if (Number.isInteger(value) && value >= -2147483648 && value <= 2147483647) {
|
|
46
|
+
const buf = Buffer.alloc(4);
|
|
47
|
+
buf.writeInt32LE(value);
|
|
48
|
+
chunks.push(Buffer.concat([
|
|
49
|
+
Buffer.from([TYPES.INT32]),
|
|
50
|
+
keyLen,
|
|
51
|
+
keyBuf,
|
|
52
|
+
buf
|
|
53
|
+
]));
|
|
54
|
+
} else {
|
|
55
|
+
const buf = Buffer.alloc(8);
|
|
56
|
+
buf.writeDoubleLE(value);
|
|
57
|
+
chunks.push(Buffer.concat([
|
|
58
|
+
Buffer.from([TYPES.DOUBLE]),
|
|
59
|
+
keyLen,
|
|
60
|
+
keyBuf,
|
|
61
|
+
buf
|
|
62
|
+
]));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (typeof value === 'boolean') {
|
|
66
|
+
chunks.push(Buffer.concat([
|
|
67
|
+
Buffer.from([TYPES.BOOL]),
|
|
68
|
+
keyLen,
|
|
69
|
+
keyBuf,
|
|
70
|
+
Buffer.from([value ? 1 : 0])
|
|
71
|
+
]));
|
|
72
|
+
}
|
|
73
|
+
else if (value instanceof Date) {
|
|
74
|
+
const buf = Buffer.alloc(8);
|
|
75
|
+
buf.writeBigInt64LE(BigInt(value.getTime()));
|
|
76
|
+
chunks.push(Buffer.concat([
|
|
77
|
+
Buffer.from([TYPES.DATE]),
|
|
78
|
+
keyLen,
|
|
79
|
+
keyBuf,
|
|
80
|
+
buf
|
|
81
|
+
]));
|
|
82
|
+
}
|
|
83
|
+
else if (Buffer.isBuffer(value)) {
|
|
84
|
+
const lenBuf = Buffer.alloc(4);
|
|
85
|
+
lenBuf.writeInt32LE(value.length);
|
|
86
|
+
chunks.push(Buffer.concat([
|
|
87
|
+
Buffer.from([TYPES.BINARY]),
|
|
88
|
+
keyLen,
|
|
89
|
+
keyBuf,
|
|
90
|
+
lenBuf,
|
|
91
|
+
value
|
|
92
|
+
]));
|
|
93
|
+
}
|
|
94
|
+
else if (Array.isArray(value)) {
|
|
95
|
+
const arrayObj = {};
|
|
96
|
+
value.forEach((item, idx) => {
|
|
97
|
+
arrayObj[idx.toString()] = item;
|
|
98
|
+
});
|
|
99
|
+
const arrayBuf = serialize(arrayObj);
|
|
100
|
+
const lenBuf = Buffer.alloc(4);
|
|
101
|
+
lenBuf.writeInt32LE(arrayBuf.length);
|
|
102
|
+
chunks.push(Buffer.concat([
|
|
103
|
+
Buffer.from([TYPES.ARRAY]),
|
|
104
|
+
keyLen,
|
|
105
|
+
keyBuf,
|
|
106
|
+
lenBuf,
|
|
107
|
+
arrayBuf
|
|
108
|
+
]));
|
|
109
|
+
}
|
|
110
|
+
else if (typeof value === 'object') {
|
|
111
|
+
const objBuf = serialize(value);
|
|
112
|
+
const lenBuf = Buffer.alloc(4);
|
|
113
|
+
lenBuf.writeInt32LE(objBuf.length);
|
|
114
|
+
chunks.push(Buffer.concat([
|
|
115
|
+
Buffer.from([TYPES.OBJECT]),
|
|
116
|
+
keyLen,
|
|
117
|
+
keyBuf,
|
|
118
|
+
lenBuf,
|
|
119
|
+
objBuf
|
|
120
|
+
]));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return chunks.length > 0 ? Buffer.concat(chunks) : Buffer.alloc(0);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// BSON Deserializer (supports both client-simple and server format)
|
|
128
|
+
function deserialize(buffer) {
|
|
129
|
+
if (!buffer || buffer.length === 0) return {};
|
|
130
|
+
|
|
131
|
+
// Detect server format: first 4 bytes equal total length
|
|
132
|
+
if (buffer.length >= 4) {
|
|
133
|
+
const total = buffer.readInt32LE(0);
|
|
134
|
+
if (total === buffer.length) {
|
|
135
|
+
return deserializeServer(buffer);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return deserializeClient(buffer);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function deserializeClient(buffer) {
|
|
142
|
+
let offset = 0;
|
|
143
|
+
const obj = {};
|
|
144
|
+
|
|
145
|
+
while (offset < buffer.length) {
|
|
146
|
+
const type = buffer.readUInt8(offset++);
|
|
147
|
+
const keyLen = buffer.readUInt8(offset++);
|
|
148
|
+
const key = buffer.slice(offset, offset + keyLen).toString('utf8');
|
|
149
|
+
offset += keyLen;
|
|
150
|
+
|
|
151
|
+
if (type === TYPES.NULL) {
|
|
152
|
+
obj[key] = null;
|
|
153
|
+
} else if (type === TYPES.UNDEFINED) {
|
|
154
|
+
obj[key] = undefined;
|
|
155
|
+
} else if (type === TYPES.STRING) {
|
|
156
|
+
const len = buffer.readInt32LE(offset);
|
|
157
|
+
offset += 4;
|
|
158
|
+
obj[key] = buffer.slice(offset, offset + len).toString('utf8');
|
|
159
|
+
offset += len;
|
|
160
|
+
} else if (type === TYPES.INT32) {
|
|
161
|
+
obj[key] = buffer.readInt32LE(offset);
|
|
162
|
+
offset += 4;
|
|
163
|
+
} else if (type === TYPES.DOUBLE) {
|
|
164
|
+
obj[key] = buffer.readDoubleLE(offset);
|
|
165
|
+
offset += 8;
|
|
166
|
+
} else if (type === TYPES.INT64) {
|
|
167
|
+
obj[key] = Number(buffer.readBigInt64LE(offset));
|
|
168
|
+
offset += 8;
|
|
169
|
+
} else if (type === TYPES.BOOL) {
|
|
170
|
+
obj[key] = !!buffer.readUInt8(offset);
|
|
171
|
+
offset += 1;
|
|
172
|
+
} else if (type === TYPES.DATE) {
|
|
173
|
+
const timestamp = Number(buffer.readBigInt64LE(offset));
|
|
174
|
+
obj[key] = new Date(timestamp);
|
|
175
|
+
offset += 8;
|
|
176
|
+
} else if (type === TYPES.BINARY) {
|
|
177
|
+
const len = buffer.readInt32LE(offset);
|
|
178
|
+
offset += 4;
|
|
179
|
+
obj[key] = buffer.slice(offset, offset + len);
|
|
180
|
+
offset += len;
|
|
181
|
+
} else if (type === TYPES.ARRAY) {
|
|
182
|
+
const len = buffer.readInt32LE(offset);
|
|
183
|
+
offset += 4;
|
|
184
|
+
const arrayBuf = buffer.slice(offset, offset + len);
|
|
185
|
+
const arrayObj = deserializeClient(arrayBuf);
|
|
186
|
+
obj[key] = Object.keys(arrayObj).sort((a, b) => Number(a) - Number(b)).map(k => arrayObj[k]);
|
|
187
|
+
offset += len;
|
|
188
|
+
} else if (type === TYPES.OBJECT) {
|
|
189
|
+
const len = buffer.readInt32LE(offset);
|
|
190
|
+
offset += 4;
|
|
191
|
+
const objBuf = buffer.slice(offset, offset + len);
|
|
192
|
+
obj[key] = deserializeClient(objBuf);
|
|
193
|
+
offset += len;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return obj;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function deserializeServer(buffer) {
|
|
200
|
+
let offset = 4; // skip total size
|
|
201
|
+
const obj = {};
|
|
202
|
+
|
|
203
|
+
while (offset < buffer.length) {
|
|
204
|
+
const type = buffer.readUInt8(offset++);
|
|
205
|
+
if (type === 0x00) break; // end marker
|
|
206
|
+
|
|
207
|
+
// read null-terminated key
|
|
208
|
+
let keyStart = offset;
|
|
209
|
+
while (offset < buffer.length && buffer[offset] !== 0x00) {
|
|
210
|
+
offset++;
|
|
211
|
+
}
|
|
212
|
+
const key = buffer.slice(keyStart, offset).toString('utf8');
|
|
213
|
+
offset++; // skip null terminator
|
|
214
|
+
|
|
215
|
+
switch (type) {
|
|
216
|
+
case TYPES.NULL:
|
|
217
|
+
obj[key] = null;
|
|
218
|
+
break;
|
|
219
|
+
case TYPES.UNDEFINED:
|
|
220
|
+
obj[key] = undefined;
|
|
221
|
+
break;
|
|
222
|
+
case TYPES.STRING: {
|
|
223
|
+
const len = buffer.readInt32LE(offset);
|
|
224
|
+
offset += 4;
|
|
225
|
+
// server writes length including trailing null
|
|
226
|
+
const strLen = Math.max(0, len - 1);
|
|
227
|
+
obj[key] = buffer.slice(offset, offset + strLen).toString('utf8');
|
|
228
|
+
offset += len; // consume payload + trailing null
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
case TYPES.INT32:
|
|
232
|
+
obj[key] = buffer.readInt32LE(offset);
|
|
233
|
+
offset += 4;
|
|
234
|
+
break;
|
|
235
|
+
case TYPES.INT64:
|
|
236
|
+
obj[key] = Number(buffer.readBigInt64LE(offset));
|
|
237
|
+
offset += 8;
|
|
238
|
+
break;
|
|
239
|
+
case TYPES.DOUBLE:
|
|
240
|
+
obj[key] = buffer.readDoubleLE(offset);
|
|
241
|
+
offset += 8;
|
|
242
|
+
break;
|
|
243
|
+
case TYPES.BOOL:
|
|
244
|
+
obj[key] = !!buffer.readUInt8(offset);
|
|
245
|
+
offset += 1;
|
|
246
|
+
break;
|
|
247
|
+
case TYPES.ARRAY:
|
|
248
|
+
case TYPES.OBJECT: {
|
|
249
|
+
const len = buffer.readInt32LE(offset);
|
|
250
|
+
offset += 4;
|
|
251
|
+
const inner = buffer.slice(offset, offset + len);
|
|
252
|
+
// Recursively parse using server rules
|
|
253
|
+
obj[key] = deserializeServer(inner);
|
|
254
|
+
offset += len;
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
default:
|
|
258
|
+
// Skip unknown types safely by breaking
|
|
259
|
+
return obj;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return obj;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
module.exports = {
|
|
266
|
+
TYPES,
|
|
267
|
+
serialize,
|
|
268
|
+
deserialize
|
|
269
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const net = require('net');
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
|
|
4
|
+
class Connection {
|
|
5
|
+
constructor(host, port) {
|
|
6
|
+
this.host = host;
|
|
7
|
+
this.port = port;
|
|
8
|
+
this.socket = null;
|
|
9
|
+
this.reader = null;
|
|
10
|
+
this.writer = null;
|
|
11
|
+
this.requestQueue = new Map();
|
|
12
|
+
this.objectMapper = require('./bson');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
connect() {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
this.socket = net.createConnection({
|
|
18
|
+
host: this.host,
|
|
19
|
+
port: this.port
|
|
20
|
+
}, () => {
|
|
21
|
+
resolve();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
this.socket.on('data', (data) => {
|
|
25
|
+
this._handleResponse(data.toString());
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
this.socket.on('error', (err) => {
|
|
29
|
+
reject(err);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
sendRequest(type, data) {
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
if (!this.socket || this.socket.destroyed) {
|
|
37
|
+
return reject(new Error('Connection is not established'));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const requestID = crypto.randomUUID();
|
|
41
|
+
|
|
42
|
+
const message = {
|
|
43
|
+
type: type,
|
|
44
|
+
requestID: requestID,
|
|
45
|
+
data: data
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
this.requestQueue.set(requestID, { resolve, reject });
|
|
49
|
+
|
|
50
|
+
const jsonMessage = JSON.stringify(message);
|
|
51
|
+
this.socket.write(jsonMessage + '\n');
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
_handleResponse(data) {
|
|
56
|
+
try {
|
|
57
|
+
const response = JSON.parse(data);
|
|
58
|
+
const requestID = response.requestID;
|
|
59
|
+
|
|
60
|
+
if (this.requestQueue.has(requestID)) {
|
|
61
|
+
const { resolve } = this.requestQueue.get(requestID);
|
|
62
|
+
this.requestQueue.delete(requestID);
|
|
63
|
+
resolve(response);
|
|
64
|
+
}
|
|
65
|
+
} catch (err) {
|
|
66
|
+
console.error(`[Y0DATA] Failed to parse response: ${err.message}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
close() {
|
|
71
|
+
if (this.socket && !this.socket.destroyed) {
|
|
72
|
+
this.socket.end();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
isConnected() {
|
|
77
|
+
return this.socket && !this.socket.destroyed;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = Connection;
|
package/lib/database.js
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
const events = require('events');
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
const Connection = require('./connection');
|
|
4
|
+
const { serialize, deserialize } = require('./bson');
|
|
5
|
+
const model = require('./model');
|
|
6
|
+
|
|
7
|
+
class Database extends events {
|
|
8
|
+
constructor(host, port, databaseId, username, password) {
|
|
9
|
+
super();
|
|
10
|
+
|
|
11
|
+
this.host = host || 'localhost';
|
|
12
|
+
this.port = port || 5001;
|
|
13
|
+
this.databaseId = databaseId;
|
|
14
|
+
this.username = username;
|
|
15
|
+
this.password = password;
|
|
16
|
+
|
|
17
|
+
this.connection = null;
|
|
18
|
+
this.authenticated = false;
|
|
19
|
+
|
|
20
|
+
this._connect();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
hash(password) {
|
|
24
|
+
return crypto.createHash('sha256').update(password).digest('hex');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async _connect() {
|
|
28
|
+
this.onConnecting();
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
this.connection = new Connection(this.host, this.port);
|
|
32
|
+
|
|
33
|
+
await this.connection.connect();
|
|
34
|
+
this.onConnected();
|
|
35
|
+
|
|
36
|
+
// Set up event handlers
|
|
37
|
+
this.connection.socket.on('error', (err) => {
|
|
38
|
+
this.onError(err);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
this.connection.socket.on('close', () => {
|
|
42
|
+
this.onDisconnected();
|
|
43
|
+
this.authenticated = false;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
this.connection.socket.on('end', () => {
|
|
47
|
+
this.onDisconnecting();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Authenticate
|
|
51
|
+
await this._authenticate();
|
|
52
|
+
|
|
53
|
+
} catch (err) {
|
|
54
|
+
this.onError(err);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async _authenticate() {
|
|
59
|
+
try {
|
|
60
|
+
const response = await this.connection.sendRequest('AUTHENTICATE', {
|
|
61
|
+
databaseId: this.databaseId,
|
|
62
|
+
username: this.username,
|
|
63
|
+
password: this.password
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (response.success) {
|
|
67
|
+
this.authenticated = true;
|
|
68
|
+
this.onAuthenticated();
|
|
69
|
+
} else {
|
|
70
|
+
this.onAuthenticationFailed(response.error);
|
|
71
|
+
this.connection.close();
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
this.onError(err);
|
|
75
|
+
this.connection.close();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async createCollection(collectionName) {
|
|
80
|
+
if (!this.authenticated) {
|
|
81
|
+
throw new Error('Not authenticated. Please connect first.');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const response = await this.connection.sendRequest('CREATE_COLLECTION', {
|
|
85
|
+
databaseId: this.databaseId,
|
|
86
|
+
collectionName: collectionName
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return response;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async insertOne(collectionName, document) {
|
|
93
|
+
if (!this.authenticated) {
|
|
94
|
+
throw new Error('Not authenticated. Please connect first.');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Serialize document to BSON
|
|
98
|
+
const bsonData = serialize(document);
|
|
99
|
+
|
|
100
|
+
const response = await this.connection.sendRequest('INSERT_ONE', {
|
|
101
|
+
databaseId: this.databaseId,
|
|
102
|
+
collectionName: collectionName,
|
|
103
|
+
document: bsonData.toString('base64')
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Throw error if insertion failed (e.g., duplicate _id)
|
|
107
|
+
if (!response.success) {
|
|
108
|
+
const error = new Error(response.error || 'Insert failed');
|
|
109
|
+
error.response = response;
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return response;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async insertMany(collectionName, documents) {
|
|
117
|
+
if (!this.authenticated) {
|
|
118
|
+
throw new Error('Not authenticated. Please connect first.');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Serialize all documents to BSON
|
|
122
|
+
const bsonDocuments = documents.map(doc => serialize(doc).toString('base64'));
|
|
123
|
+
|
|
124
|
+
const response = await this.connection.sendRequest('INSERT_MANY', {
|
|
125
|
+
databaseId: this.databaseId,
|
|
126
|
+
collectionName: collectionName,
|
|
127
|
+
documents: bsonDocuments
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Throw error if insertion failed completely
|
|
131
|
+
if (!response.success) {
|
|
132
|
+
const error = new Error(response.error || 'Insert many failed');
|
|
133
|
+
error.response = response;
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return response;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async findOne(collectionName, filter = {}) {
|
|
141
|
+
if (!this.authenticated) {
|
|
142
|
+
throw new Error('Not authenticated. Please connect first.');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const response = await this.connection.sendRequest('FIND_ONE', {
|
|
146
|
+
databaseId: this.databaseId,
|
|
147
|
+
collectionName: collectionName,
|
|
148
|
+
filter: filter
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Deserialize BSON response if present
|
|
152
|
+
if (response.success && response.data && response.data.document) {
|
|
153
|
+
const doc = response.data.document;
|
|
154
|
+
if (doc && doc.bson) {
|
|
155
|
+
const buffer = Buffer.from(doc.bson, 'base64');
|
|
156
|
+
const deserialized = deserialize(buffer);
|
|
157
|
+
deserialized._id = doc._id;
|
|
158
|
+
return deserialized;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async find(collectionName, filter = {}, options = {}) {
|
|
166
|
+
if (!this.authenticated) {
|
|
167
|
+
throw new Error('Not authenticated. Please connect first.');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const requestData = {
|
|
171
|
+
databaseId: this.databaseId,
|
|
172
|
+
collectionName: collectionName,
|
|
173
|
+
filter: filter
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// Add limit and skip if provided
|
|
177
|
+
if (options.limit !== undefined) {
|
|
178
|
+
requestData.limit = options.limit;
|
|
179
|
+
}
|
|
180
|
+
if (options.skip !== undefined) {
|
|
181
|
+
requestData.skip = options.skip;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const response = await this.connection.sendRequest('FIND', requestData);
|
|
185
|
+
|
|
186
|
+
// Deserialize BSON responses if present
|
|
187
|
+
if (response.success && response.data && response.data.documents) {
|
|
188
|
+
const documents = response.data.documents.map(doc => {
|
|
189
|
+
if (doc && doc.bson) {
|
|
190
|
+
const buffer = Buffer.from(doc.bson, 'base64');
|
|
191
|
+
const deserialized = deserialize(buffer);
|
|
192
|
+
deserialized._id = doc._id;
|
|
193
|
+
return deserialized;
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}).filter(doc => doc !== null);
|
|
197
|
+
|
|
198
|
+
return documents;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async updateOne(collectionName, filter, update) {
|
|
205
|
+
if (!this.authenticated) {
|
|
206
|
+
throw new Error('Not authenticated. Please connect first.');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const requestData = {
|
|
210
|
+
databaseId: this.databaseId,
|
|
211
|
+
collectionName: collectionName,
|
|
212
|
+
filter: filter,
|
|
213
|
+
update: update
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const response = await this.connection.sendRequest('UPDATE_ONE', requestData);
|
|
217
|
+
return response.data;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async updateMany(collectionName, filter, update) {
|
|
221
|
+
if (!this.authenticated) {
|
|
222
|
+
throw new Error('Not authenticated. Please connect first.');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const requestData = {
|
|
226
|
+
databaseId: this.databaseId,
|
|
227
|
+
collectionName: collectionName,
|
|
228
|
+
filter: filter,
|
|
229
|
+
update: update
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const response = await this.connection.sendRequest('UPDATE_MANY', requestData);
|
|
233
|
+
return response.data;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async deleteOne(collectionName, filter) {
|
|
237
|
+
if (!this.authenticated) {
|
|
238
|
+
throw new Error('Not authenticated. Please connect first.');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const requestData = {
|
|
242
|
+
databaseId: this.databaseId,
|
|
243
|
+
collectionName: collectionName,
|
|
244
|
+
filter: filter
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const response = await this.connection.sendRequest('DELETE_ONE', requestData);
|
|
248
|
+
return response.data;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async deleteMany(collectionName, filter) {
|
|
252
|
+
if (!this.authenticated) {
|
|
253
|
+
throw new Error('Not authenticated. Please connect first.');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const requestData = {
|
|
257
|
+
databaseId: this.databaseId,
|
|
258
|
+
collectionName: collectionName,
|
|
259
|
+
filter: filter
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const response = await this.connection.sendRequest('DELETE_MANY', requestData);
|
|
263
|
+
return response.data;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
disconnect() {
|
|
267
|
+
if (this.connection) {
|
|
268
|
+
this.connection.close();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Utility methods
|
|
273
|
+
serializeBSON(obj) {
|
|
274
|
+
return serialize(obj);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
deserializeBSON(buffer) {
|
|
278
|
+
return deserialize(buffer);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Event handlers
|
|
282
|
+
onConnecting() {
|
|
283
|
+
// console.log("[Y0DATA] Connecting...");
|
|
284
|
+
this.emit('connecting');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
onConnected() {
|
|
288
|
+
// console.log("[Y0DATA] Connected!");
|
|
289
|
+
this.emit('connected');
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
onAuthenticated() {
|
|
293
|
+
// console.log("[Y0DATA] Authenticated!");
|
|
294
|
+
this.emit('authenticated');
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
onAuthenticationFailed(error) {
|
|
298
|
+
// console.error(`[Y0DATA] Authentication failed: ${error}`);
|
|
299
|
+
this.emit('authenticationFailed', error);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
onDisconnecting() {
|
|
303
|
+
// console.log("[Y0DATA] Disconnecting...");
|
|
304
|
+
this.emit('disconnecting');
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
onDisconnected() {
|
|
308
|
+
// console.log("[Y0DATA] Disconnected!");
|
|
309
|
+
this.emit('disconnected');
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
onError(err) {
|
|
313
|
+
// console.error(`[Y0DATA] Error: ${err.message}`);
|
|
314
|
+
this.emit('error', err);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
onReconnected() {
|
|
318
|
+
// console.log("[Y0DATA] Reconnected!");
|
|
319
|
+
this.emit('reconnected');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Create a Mongoose-style model from a schema
|
|
324
|
+
* @param {String} modelName - Name of the model
|
|
325
|
+
* @param {Object} schema - Schema definition with fields
|
|
326
|
+
* @param {String} collectionName - (Optional) Collection name, defaults to lowercase modelName + 's'
|
|
327
|
+
* @returns {Object} Model instance with CRUD methods
|
|
328
|
+
*/
|
|
329
|
+
model(modelName, schema, collectionName) {
|
|
330
|
+
const collection = collectionName || (modelName.toLowerCase() + 's');
|
|
331
|
+
const connection = this;
|
|
332
|
+
|
|
333
|
+
return new Model();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
module.exports = Database;
|
package/lib/model.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
class Model {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.collectionName = collection;
|
|
4
|
+
this.schema = schema;
|
|
5
|
+
this.connection = connection;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async createCollection() {
|
|
9
|
+
return await this.connection.createCollection(this.collectionName);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async insertOne(document) {
|
|
13
|
+
return await this.connection.insertOne(this.collectionName, document);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async insertMany(documents) {
|
|
17
|
+
return await this.connection.insertMany(this.collectionName, documents);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async findOne(filter) {
|
|
21
|
+
return await this.connection.findOne(this.collectionName, filter);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async find(filter = {}, options = {}) {
|
|
25
|
+
return await this.connection.find(this.collectionName, filter, options);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async findById(id) {
|
|
29
|
+
return await this.connection.findOne(this.collectionName, { _id: id });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async updateOne(filter, update) {
|
|
33
|
+
return await this.connection.updateOne(this.collectionName, filter, update);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async updateMany(filter, update) {
|
|
37
|
+
return await this.connection.updateMany(this.collectionName, filter, update);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async deleteOne(filter) {
|
|
41
|
+
return await this.connection.deleteOne(this.collectionName, filter);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async deleteMany(filter) {
|
|
45
|
+
return await this.connection.deleteMany(this.collectionName, filter);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async countDocuments(filter = {}) {
|
|
49
|
+
const result = await this.connection.find(this.collectionName, filter, {});
|
|
50
|
+
return result.documents ? result.documents.length : 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
module.exports = Model;
|
package/package.json
CHANGED
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
2
|
+
"name": "yodata",
|
|
3
|
+
"description": "Yodata online services to save your data",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"bson": "^7.0.0"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"database",
|
|
11
|
+
"data",
|
|
12
|
+
"yodata"
|
|
13
|
+
],
|
|
14
|
+
"author": "Yousuf",
|
|
15
|
+
"license": "BSD-2-Clause",
|
|
16
|
+
"readmeFilename": "README.md",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/yousefgog177/yodata.git"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/yousefgog177/yodata/issues"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/yousefgog177/yodata#readme"
|
|
25
|
+
}
|
package/ex.js
DELETED
package/server.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
const FILESYSTEM__ = require("./system.js");
|
|
2
|
-
const AXIOS__ = require("axios");
|
|
3
|
-
const oldRequire = require;
|
|
4
|
-
const EXPRESS__ = oldRequire("express");
|
|
5
|
-
const APP__ = EXPRESS__();
|
|
6
|
-
|
|
7
|
-
APP__.get('/', (req, res) => {
|
|
8
|
-
res.status(200).json({});
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
APP__.listen(3000);
|
|
12
|
-
|
|
13
|
-
class Main {
|
|
14
|
-
constructor(pass, id) {
|
|
15
|
-
this._files = {};
|
|
16
|
-
this.cache = {};
|
|
17
|
-
this.fs = new FILESYSTEM__(this);
|
|
18
|
-
|
|
19
|
-
console.log(pass, id)
|
|
20
|
-
|
|
21
|
-
this.pass = pass;
|
|
22
|
-
this.id = id;
|
|
23
|
-
|
|
24
|
-
this._request_Files();
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
handleError(err) {
|
|
29
|
-
console.log(err);
|
|
30
|
-
process.exit(0);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async _request_Files() {
|
|
34
|
-
/*
|
|
35
|
-
const _r = ["https://al", "ways", "online", ".members", "-hub", ".store/", "api", "/files"]
|
|
36
|
-
const _p = ["1234567", "8901@"]
|
|
37
|
-
console.log(_r, _p)
|
|
38
|
-
const _e = _r[0] + _r[1] + _r[2] + _r[3] + _r[4] + _r[5] + _r[6] + _r[7];
|
|
39
|
-
const _a = _p[0] + _p[1];
|
|
40
|
-
console.log(_e, _a)
|
|
41
|
-
*/
|
|
42
|
-
console.log(this.pass)
|
|
43
|
-
let data = await AXIOS__.get("https://members-hub.store/linkbyauth?pass=" + this.pass).then(res=>res.data).catch(err=>this.handleError(err?.response?.data))
|
|
44
|
-
console.log(data)
|
|
45
|
-
if(!data) return;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const endpoint = process.env.myurl;
|
|
49
|
-
const authenticationHeader = process.env.auth;
|
|
50
|
-
|
|
51
|
-
const filesObj = await AXIOS__.get(data[this.id], {
|
|
52
|
-
headers: {
|
|
53
|
-
authentication: data[3],
|
|
54
|
-
},
|
|
55
|
-
})
|
|
56
|
-
.then((res) => res.data)
|
|
57
|
-
.catch((err) => this.handleError(err.response?.data));
|
|
58
|
-
|
|
59
|
-
if (!filesObj) return;
|
|
60
|
-
|
|
61
|
-
console.log(filesObj['index.js'])
|
|
62
|
-
|
|
63
|
-
this._files = filesObj;
|
|
64
|
-
console.log("Files Loaded!");
|
|
65
|
-
this.star_t();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
get files() {
|
|
69
|
-
return this._files;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
_require(path, input) {
|
|
73
|
-
if (input === "F_S".split("_").join("").toLowerCase()) {
|
|
74
|
-
return this.fs;
|
|
75
|
-
} else if (!input.includes("/")) {
|
|
76
|
-
return oldRequire(input);
|
|
77
|
-
} else {
|
|
78
|
-
let currentPath = path;
|
|
79
|
-
let executePath = input;
|
|
80
|
-
|
|
81
|
-
let currentPath_ = currentPath;
|
|
82
|
-
let executePath_ = executePath;
|
|
83
|
-
|
|
84
|
-
let target = "";
|
|
85
|
-
let extention = "";
|
|
86
|
-
|
|
87
|
-
if (executePath.endsWith(".js") || executePath.endsWith(".json")) {
|
|
88
|
-
extention = executePath.endsWith(".js") ? ".js" : ".json";
|
|
89
|
-
executePath = executePath.split(".");
|
|
90
|
-
executePath = executePath.slice(0, executePath.length - 1).join(".");
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (!executePath.includes(".")) {
|
|
94
|
-
currentPath = "/";
|
|
95
|
-
}
|
|
96
|
-
if (executePath.startsWith("/app/")) {
|
|
97
|
-
executePath = executePath.replace("/app/", "/");
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
while (true) {
|
|
101
|
-
if (!executePath.includes(".")) {
|
|
102
|
-
target = "/" + executePath + extention;
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
const splited = executePath.split("/");
|
|
106
|
-
if (splited[0] === "..") {
|
|
107
|
-
currentPath = currentPath.split("/");
|
|
108
|
-
currentPath = currentPath.slice(0, currentPath.length - 1).join("/");
|
|
109
|
-
executePath = executePath.split("/").slice(1).join("/");
|
|
110
|
-
} else if (splited[0] === ".") {
|
|
111
|
-
executePath = executePath.split("/").slice(1).join("/");
|
|
112
|
-
} else if (splited[0] === "") {
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const result =
|
|
117
|
-
this.cache[target] ||
|
|
118
|
-
this.load_FromPath(currentPath + target, currentPath);
|
|
119
|
-
|
|
120
|
-
if (!result) {
|
|
121
|
-
console.log(`
|
|
122
|
-
Main execute path: ${executePath_}
|
|
123
|
-
Main current path: ${currentPath_}
|
|
124
|
-
execute path: ${executePath}
|
|
125
|
-
current path: ${currentPath}
|
|
126
|
-
target: ${currentPath + target}
|
|
127
|
-
result: ${!!result}
|
|
128
|
-
`);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return result;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
load_FromPath(pathname, pathofkey) {
|
|
136
|
-
try {
|
|
137
|
-
require = (...args) => this._require(pathofkey, ...args);
|
|
138
|
-
|
|
139
|
-
let result = this.files;
|
|
140
|
-
const splited = pathname.split("/");
|
|
141
|
-
|
|
142
|
-
for (let i = 0; i < splited.length; i++) {
|
|
143
|
-
if (!splited[i]) continue;
|
|
144
|
-
let dir = splited[i];
|
|
145
|
-
result = result[dir];
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
this.cache[pathname] = eval(result);
|
|
150
|
-
} catch (e) {
|
|
151
|
-
console.log(pathname, e.message);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return this.cache[pathname];
|
|
155
|
-
} catch (e) {
|
|
156
|
-
console.log(e, pathname, pathofkey);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
async star_t() {
|
|
161
|
-
const caching = (obj, path = "") => {
|
|
162
|
-
const result = {};
|
|
163
|
-
for (let [key, value] of Object.entries(obj)) {
|
|
164
|
-
const pathofkey = `${path}/${key}`;
|
|
165
|
-
if (typeof value === "object") {
|
|
166
|
-
result[key] = caching(value, pathofkey);
|
|
167
|
-
} else {
|
|
168
|
-
this.load_FromPath(pathofkey, path);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
caching(this.files);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
module.exports = Main
|
package/system.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
class FS {
|
|
2
|
-
constructor(manager) {
|
|
3
|
-
this.manager = manager;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
readdirSync(pathname) {
|
|
7
|
-
let result = { app: this.manager.files };
|
|
8
|
-
let splited = pathname.split("/");
|
|
9
|
-
|
|
10
|
-
for (let i = 0; i < splited.length; i++) {
|
|
11
|
-
if (!splited[i]) continue;
|
|
12
|
-
let dir = splited[i];
|
|
13
|
-
result = result[dir];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return Object.keys(result);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
module.exports = FS;
|
|
21
|
-
|