@wxn0brp/db 0.0.2 → 0.0.4
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 +4 -2
- package/action.js +25 -17
- package/database.d.ts +44 -0
- package/database.js +4 -9
- package/docs/database.md +1 -1
- package/docs/graph.md +8 -0
- package/docs/relation.md +51 -0
- package/docs/search_opts.md +227 -0
- package/file/find.js +2 -1
- package/file/remove.js +6 -7
- package/file/update.js +6 -6
- package/gen.d.ts +1 -0
- package/graph.d.ts +27 -0
- package/graph.js +12 -2
- package/index.d.ts +7 -0
- package/index.js +10 -1
- package/package.json +6 -2
- package/relation.d.ts +23 -0
- package/relation.js +86 -0
- package/remote/client/database.d.ts +41 -0
- package/remote/client/database.js +2 -2
- package/remote/client/graph.d.ts +31 -0
- package/remote/client/graph.js +10 -0
- package/remote/server/db.js +2 -2
- package/remote/server/graph.js +15 -0
- package/test/hasFieldsAdvanced.test.js +70 -0
- package/utils/hasFields.js +19 -0
- package/utils/hasFieldsAdvanced.js +184 -0
- package/utils/updateFindObject.js +34 -0
- package/utils/updateObject.js +15 -0
- package/more.js +0 -103
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ npm install @wxn0brp/db
|
|
|
15
15
|
You can import the necessary classes from the package as follows:
|
|
16
16
|
|
|
17
17
|
```javascript
|
|
18
|
-
import { DataBase, Graph, DataBaseRemote, GraphRemote } from "@wxn0brp/db";
|
|
18
|
+
import { DataBase, Graph, DataBaseRemote, GraphRemote, Relation, genId } from "@wxn0brp/db";
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
## Documentation
|
|
@@ -25,4 +25,6 @@ For detailed information, refer to the following resources:
|
|
|
25
25
|
- [DataBase Documentation](./docs/database.md)
|
|
26
26
|
- [Graph Documentation](./docs/graph.md)
|
|
27
27
|
- [Remote Database and Graph Client Documentation](./docs/remote.md)
|
|
28
|
-
- [Remote Server Documentation](./docs/remote_server.md)
|
|
28
|
+
- [Remote Server Documentation](./docs/remote_server.md)
|
|
29
|
+
- [Search Options Documentation](./docs/search_opts.md)
|
|
30
|
+
- [Relation Documentation](./docs/relation.md)
|
package/action.js
CHANGED
|
@@ -3,8 +3,6 @@ import gen from "./gen.js";
|
|
|
3
3
|
import { stringify } from "./format.js";
|
|
4
4
|
import { find as _find, findOne as _findOne, update as _update, remove as _remove } from "./file/index.js";
|
|
5
5
|
|
|
6
|
-
const maxFileSize = 2 * 1024 * 1024; //2 MB
|
|
7
|
-
|
|
8
6
|
/**
|
|
9
7
|
* A class representing database actions on files.
|
|
10
8
|
* @class
|
|
@@ -18,11 +16,18 @@ class dbActionC{
|
|
|
18
16
|
*/
|
|
19
17
|
constructor(folder, options){
|
|
20
18
|
this.folder = folder;
|
|
21
|
-
|
|
19
|
+
this.options = {
|
|
20
|
+
maxFileSize: 2 * 1024 * 1024, //2 MB
|
|
21
|
+
...options,
|
|
22
|
+
};
|
|
22
23
|
|
|
23
24
|
if(!existsSync(folder)) mkdirSync(folder, { recursive: true });
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
_getCollectionPath(collection){
|
|
28
|
+
return this.folder + "/" + collection + "/";
|
|
29
|
+
}
|
|
30
|
+
|
|
26
31
|
/**
|
|
27
32
|
* Get a list of available databases in the specified folder.
|
|
28
33
|
* @returns {string[]} An array of database names.
|
|
@@ -44,8 +49,8 @@ class dbActionC{
|
|
|
44
49
|
* @param {string} collection - The collection to check.
|
|
45
50
|
*/
|
|
46
51
|
checkCollection(collection){
|
|
47
|
-
const
|
|
48
|
-
if(!existsSync(
|
|
52
|
+
const cpath = this._getCollectionPath(collection);
|
|
53
|
+
if(!existsSync(cpath)) mkdirSync(cpath, { recursive: true });
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
/**
|
|
@@ -69,7 +74,8 @@ class dbActionC{
|
|
|
69
74
|
*/
|
|
70
75
|
async add(collection, arg, id_gen=true){
|
|
71
76
|
await this.checkCollection(collection);
|
|
72
|
-
const
|
|
77
|
+
const cpath = this._getCollectionPath(collection);
|
|
78
|
+
const file = cpath + getLastFile(cpath, this.options.maxFileSize);
|
|
73
79
|
|
|
74
80
|
if(id_gen) arg._id = arg._id || gen();
|
|
75
81
|
const data = stringify(arg);
|
|
@@ -94,14 +100,15 @@ class dbActionC{
|
|
|
94
100
|
options.max = options.max || -1;
|
|
95
101
|
|
|
96
102
|
await this.checkCollection(collection);
|
|
97
|
-
const
|
|
103
|
+
const cpath = this._getCollectionPath(collection);
|
|
104
|
+
const files = getSortedFiles(cpath).map(f => f.f);
|
|
98
105
|
if(options.reverse) files.reverse();
|
|
99
106
|
let datas = [];
|
|
100
107
|
|
|
101
108
|
let totalEntries = 0;
|
|
102
109
|
|
|
103
110
|
for(let f of files){
|
|
104
|
-
let data = await _find(
|
|
111
|
+
let data = await _find(cpath + f, arg, context, findOpts);
|
|
105
112
|
if(options.reverse) data.reverse();
|
|
106
113
|
|
|
107
114
|
if(options.max !== -1){
|
|
@@ -132,11 +139,11 @@ class dbActionC{
|
|
|
132
139
|
*/
|
|
133
140
|
async findOne(collection, arg, context={}, findOpts={}){
|
|
134
141
|
await this.checkCollection(collection);
|
|
135
|
-
const
|
|
136
|
-
files.
|
|
142
|
+
const cpath = this._getCollectionPath(collection);
|
|
143
|
+
const files = getSortedFiles(cpath).map(f => f.f);
|
|
137
144
|
|
|
138
145
|
for(let f of files){
|
|
139
|
-
let data = await _findOne(
|
|
146
|
+
let data = await _findOne(cpath + f, arg, context, findOpts);
|
|
140
147
|
if(data){
|
|
141
148
|
return data;
|
|
142
149
|
}
|
|
@@ -155,7 +162,7 @@ class dbActionC{
|
|
|
155
162
|
*/
|
|
156
163
|
async update(collection, arg, obj, context={}){
|
|
157
164
|
await this.checkCollection(collection);
|
|
158
|
-
return await _update(this.
|
|
165
|
+
return await _update(this._getCollectionPath(collection), arg, obj, context);
|
|
159
166
|
}
|
|
160
167
|
|
|
161
168
|
/**
|
|
@@ -169,7 +176,7 @@ class dbActionC{
|
|
|
169
176
|
*/
|
|
170
177
|
async updateOne(collection, arg, obj, context={}){
|
|
171
178
|
await this.checkCollection(collection);
|
|
172
|
-
return await _update(this.
|
|
179
|
+
return await _update(this._getCollectionPath(collection), arg, obj, context, true);
|
|
173
180
|
}
|
|
174
181
|
|
|
175
182
|
/**
|
|
@@ -182,7 +189,7 @@ class dbActionC{
|
|
|
182
189
|
*/
|
|
183
190
|
async remove(collection, arg, context={}){
|
|
184
191
|
await this.checkCollection(collection);
|
|
185
|
-
return await _remove(this.
|
|
192
|
+
return await _remove(this._getCollectionPath(collection), arg, context);
|
|
186
193
|
}
|
|
187
194
|
|
|
188
195
|
/**
|
|
@@ -195,7 +202,7 @@ class dbActionC{
|
|
|
195
202
|
*/
|
|
196
203
|
async removeOne(collection, arg, context={}){
|
|
197
204
|
await this.checkCollection(collection);
|
|
198
|
-
return await _remove(this.
|
|
205
|
+
return await _remove(this._getCollectionPath(collection), arg, context, true);
|
|
199
206
|
}
|
|
200
207
|
|
|
201
208
|
/**
|
|
@@ -204,7 +211,7 @@ class dbActionC{
|
|
|
204
211
|
* @param {string} collection - The name of the collection to remove.
|
|
205
212
|
* @return {void}
|
|
206
213
|
*/
|
|
207
|
-
|
|
214
|
+
removeCollection(collection){
|
|
208
215
|
rmSync(this.folder + "/" + collection, { recursive: true, force: true });
|
|
209
216
|
}
|
|
210
217
|
}
|
|
@@ -212,9 +219,10 @@ class dbActionC{
|
|
|
212
219
|
/**
|
|
213
220
|
* Get the last file in the specified directory.
|
|
214
221
|
* @param {string} path - The directory path.
|
|
222
|
+
* @param {number} maxFileSize - The maximum file size in bytes. Default is 1 MB.
|
|
215
223
|
* @returns {string} The name of the last file in the directory.
|
|
216
224
|
*/
|
|
217
|
-
function getLastFile(path){
|
|
225
|
+
function getLastFile(path, maxFileSize=1024*1024){
|
|
218
226
|
if(!existsSync(path)) mkdirSync(path, { recursive: true });
|
|
219
227
|
const files = getSortedFiles(path);
|
|
220
228
|
|
package/database.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import dbActionC from "./action.js";
|
|
2
|
+
import executorC from "./executor.js";
|
|
3
|
+
import CollectionManager from "./CollectionManager.js";
|
|
4
|
+
|
|
5
|
+
declare class DataBase {
|
|
6
|
+
constructor(folder: string, options?: {
|
|
7
|
+
cacheThreshold?: number,
|
|
8
|
+
cacheTTL?: number
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
dbAction: dbActionC;
|
|
12
|
+
executor: executorC;
|
|
13
|
+
|
|
14
|
+
c(collection: string): CollectionManager;
|
|
15
|
+
|
|
16
|
+
getCollections(): Promise<string[]>;
|
|
17
|
+
|
|
18
|
+
checkCollection(collection: string): Promise<void>;
|
|
19
|
+
|
|
20
|
+
issetCollection(collection: string): Promise<boolean>;
|
|
21
|
+
|
|
22
|
+
add(collection: string, data: object, id_gen?: boolean): Promise<object>;
|
|
23
|
+
|
|
24
|
+
find(collection: string, search: object | Function, context?: object, options?: {
|
|
25
|
+
max?: number,
|
|
26
|
+
reverse?: boolean
|
|
27
|
+
}, findOpts?: object): Promise<object[]>;
|
|
28
|
+
|
|
29
|
+
findOne(collection: string, search: object | Function, context?: object, findOpts?: object): Promise<object | null>;
|
|
30
|
+
|
|
31
|
+
update(collection: string, search: object | Function, arg: object | Function, context?: object): Promise<boolean>;
|
|
32
|
+
|
|
33
|
+
updateOne(collection: string, search: object | Function, arg: object | Function, context?: object): Promise<boolean>;
|
|
34
|
+
|
|
35
|
+
remove(collection: string, search: object | Function, context?: object): Promise<boolean>;
|
|
36
|
+
|
|
37
|
+
removeOne(collection: string, search: object | Function, context?: object): Promise<boolean>;
|
|
38
|
+
|
|
39
|
+
updateOneOrAdd(collection: string, search: object | Function, arg: object | Function, add_arg?: object, context?: object, id_gen?: boolean): Promise<boolean>;
|
|
40
|
+
|
|
41
|
+
removeCollection(collection: string): void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default DataBase;
|
package/database.js
CHANGED
|
@@ -12,15 +12,10 @@ class DataBase{
|
|
|
12
12
|
* @constructor
|
|
13
13
|
* @param {string} folder - The folder path where the database files are stored.
|
|
14
14
|
* @param {object} [options] - The options object.
|
|
15
|
-
* @param {number} [options.
|
|
16
|
-
* @param {number}
|
|
15
|
+
* @param {number} [options.maxFileSize=2*1024*1024] - The maximum size of a file in bytes. Default is 2 MB.
|
|
16
|
+
* @param {number}
|
|
17
17
|
*/
|
|
18
18
|
constructor(folder, options={}){
|
|
19
|
-
options = {
|
|
20
|
-
cacheThreshold: 3,
|
|
21
|
-
cacheTTL: 300_000,
|
|
22
|
-
...options
|
|
23
|
-
}
|
|
24
19
|
this.dbAction = new dbActionC(folder, options);
|
|
25
20
|
this.executor = new executorC();
|
|
26
21
|
}
|
|
@@ -200,8 +195,8 @@ class DataBase{
|
|
|
200
195
|
* @param {string} collection - The name of the collection to remove.
|
|
201
196
|
* @return {void}
|
|
202
197
|
*/
|
|
203
|
-
|
|
204
|
-
this.dbAction.
|
|
198
|
+
removeCollection(collection){
|
|
199
|
+
this.dbAction.removeCollection(collection);
|
|
205
200
|
}
|
|
206
201
|
}
|
|
207
202
|
|
package/docs/database.md
CHANGED
|
@@ -131,7 +131,7 @@ Removes one entry from a collection.
|
|
|
131
131
|
- **Returns:**
|
|
132
132
|
- `Promise<boolean>`: A promise that resolves when the entry is removed.
|
|
133
133
|
|
|
134
|
-
### Method: `
|
|
134
|
+
### Method: `removeCollection(collection)`
|
|
135
135
|
Removes the specified collection from the database file system.
|
|
136
136
|
|
|
137
137
|
- **Parameters:**
|
package/docs/graph.md
CHANGED
|
@@ -76,3 +76,11 @@ Checks if the specified collection exists.
|
|
|
76
76
|
- `collection` (`string`): The name of the collection.
|
|
77
77
|
- **Returns:**
|
|
78
78
|
- `Promise<boolean>`: A promise that resolves to `true` if the collection exists, otherwise `false`.
|
|
79
|
+
|
|
80
|
+
### Method: `removeCollection(collection)`
|
|
81
|
+
Removes the specified collection from the database file system.
|
|
82
|
+
|
|
83
|
+
- **Parameters:**
|
|
84
|
+
- `collection` (`string`): The name of the collection to remove.
|
|
85
|
+
- **Returns:**
|
|
86
|
+
- `void`
|
package/docs/relation.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Relation Class Documentation
|
|
2
|
+
|
|
3
|
+
This documentation provides an overview of the `Relation` class, which is designed to manage and resolve relations between database collections.
|
|
4
|
+
|
|
5
|
+
## Class: `Relation`
|
|
6
|
+
|
|
7
|
+
### Constructor: `Relation(databases)`
|
|
8
|
+
Creates a new instance of the `Relation` class.
|
|
9
|
+
|
|
10
|
+
- **Parameters:**
|
|
11
|
+
- `databases` (`Record<string, Database>`): An object containing database instances, where keys are database names.
|
|
12
|
+
|
|
13
|
+
### Method: `async find(path: string, search: object | Function, relations?: Record<string, any>, options?: object)`
|
|
14
|
+
Finds items with relations based on the provided path and search criteria.
|
|
15
|
+
|
|
16
|
+
- **Parameters:**
|
|
17
|
+
- `path` (`string`): Path in format 'dbName.collectionName'.
|
|
18
|
+
- `search` (`object | Function`): The search query or function to execute.
|
|
19
|
+
- `relations` (`Record<string, any>`, optional): Relations configuration for resolving related data.
|
|
20
|
+
- `options` (`object`, optional): Additional search options.
|
|
21
|
+
- **Returns:**
|
|
22
|
+
- `Promise<Array<object>>`: A promise that resolves with an array of items, each containing resolved relations.
|
|
23
|
+
|
|
24
|
+
### Method: `async findOne(path: string, search: object | Function, relations?: Record<string, any>)`
|
|
25
|
+
Finds one item with relations based on the provided path and search criteria.
|
|
26
|
+
|
|
27
|
+
- **Parameters:**
|
|
28
|
+
- `path` (`string`): Path in format 'dbName.collectionName'.
|
|
29
|
+
- `search` (`object | Function`): The search query or function to execute.
|
|
30
|
+
- `relations` (`Record<string, any>`, optional): Relations configuration for resolving related data.
|
|
31
|
+
- **Returns:**
|
|
32
|
+
- `Promise<object | null>`: A promise that resolves with the found item containing resolved relations or `null` if no match is found.
|
|
33
|
+
|
|
34
|
+
### Method: `private _processItemRelations(item: object, relations: Record<string, any>)`
|
|
35
|
+
Processes relations for a single item.
|
|
36
|
+
|
|
37
|
+
- **Parameters:**
|
|
38
|
+
- `item` (`object`): The item to process relations for.
|
|
39
|
+
- `relations` (`Record<string, any>`): Relations configuration.
|
|
40
|
+
- **Returns:**
|
|
41
|
+
- `Promise<object>`: A promise that resolves with the processed item containing resolved relations.
|
|
42
|
+
|
|
43
|
+
### Private Method: `_resolvePath(path: string)`
|
|
44
|
+
Resolves the relation path in the format 'dbName.collectionName'.
|
|
45
|
+
|
|
46
|
+
- **Parameters:**
|
|
47
|
+
- `path` (`string`): The path to resolve, supporting escaped dots (`\.`).
|
|
48
|
+
- **Returns:**
|
|
49
|
+
- `{ db: Database; collection: string }`: An object containing the resolved database and collection names.
|
|
50
|
+
- **Throws:**
|
|
51
|
+
- `Error`: If the database does not exist or if the path format is invalid.
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# Predefined Search Options Quick Reference
|
|
2
|
+
|
|
3
|
+
## Operators
|
|
4
|
+
|
|
5
|
+
### Logical Operators
|
|
6
|
+
|
|
7
|
+
#### $and
|
|
8
|
+
Checks if all conditions in an array are true.
|
|
9
|
+
```javascript
|
|
10
|
+
{
|
|
11
|
+
$and: [
|
|
12
|
+
{ $gt: { age: 20 } },
|
|
13
|
+
{ $exists: { name: true } }
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
#### $or
|
|
19
|
+
Checks if at least one condition in an array is true.
|
|
20
|
+
```javascript
|
|
21
|
+
{
|
|
22
|
+
$or: [
|
|
23
|
+
{ $lt: { age: 20 } },
|
|
24
|
+
{ $gt: { age: 60 } }
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
#### $not
|
|
30
|
+
Negates a condition.
|
|
31
|
+
```javascript
|
|
32
|
+
{
|
|
33
|
+
$not: { $type: { age: "string" } }
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Comparison Operators
|
|
38
|
+
|
|
39
|
+
#### $gt
|
|
40
|
+
Greater than comparison.
|
|
41
|
+
```javascript
|
|
42
|
+
{ $gt: { age: 18 } }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
#### $lt
|
|
46
|
+
Less than comparison.
|
|
47
|
+
```javascript
|
|
48
|
+
{ $lt: { score: 100 } }
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### $gte
|
|
52
|
+
Greater than or equal comparison.
|
|
53
|
+
```javascript
|
|
54
|
+
{ $gte: { price: 9.99 } }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### $lte
|
|
58
|
+
Less than or equal comparison.
|
|
59
|
+
```javascript
|
|
60
|
+
{ $lte: { quantity: 50 } }
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### $in
|
|
64
|
+
Checks if value is in an array.
|
|
65
|
+
```javascript
|
|
66
|
+
{ $in: { status: ["active", "pending"] } }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### $nin
|
|
70
|
+
Checks if value is not in an array.
|
|
71
|
+
```javascript
|
|
72
|
+
{ $nin: { category: ["archived", "deleted"] } }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### $between
|
|
76
|
+
Checks if a number is between two values (inclusive).
|
|
77
|
+
```javascript
|
|
78
|
+
{ $between: { age: [18, 65] } }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Type and Existence Operators
|
|
82
|
+
|
|
83
|
+
#### $exists
|
|
84
|
+
Checks if a field exists (or doesn't exist).
|
|
85
|
+
```javascript
|
|
86
|
+
{ $exists: { email: true, deletedAt: false } }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### $type
|
|
90
|
+
Checks the type of a field.
|
|
91
|
+
```javascript
|
|
92
|
+
{ $type: { age: "number", name: "string" } }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Array Operators
|
|
96
|
+
|
|
97
|
+
#### $arrinc
|
|
98
|
+
Checks if an array includes at least one of the specified values.
|
|
99
|
+
```javascript
|
|
100
|
+
{ $arrinc: { tags: ["developer", "designer"] } }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### $arrincall
|
|
104
|
+
Checks if an array includes all of the specified values.
|
|
105
|
+
```javascript
|
|
106
|
+
{ $arrincall: { permissions: ["read", "write"] } }
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### $size
|
|
110
|
+
Checks the length of an array or string.
|
|
111
|
+
```javascript
|
|
112
|
+
{ $size: { tags: 3 } }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### String Operators
|
|
116
|
+
|
|
117
|
+
#### $regex
|
|
118
|
+
Tests a string against a regular expression.
|
|
119
|
+
```javascript
|
|
120
|
+
{ $regex: { email: /^[^@]+@[^@]+\.[^@]+$/ } }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### $startsWith
|
|
124
|
+
Checks if a string starts with a specified value.
|
|
125
|
+
```javascript
|
|
126
|
+
{ $startsWith: { name: "Dr." } }
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### $endsWith
|
|
130
|
+
Checks if a string ends with a specified value.
|
|
131
|
+
```javascript
|
|
132
|
+
{ $endsWith: { email: "@example.com" } }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Other Operators
|
|
136
|
+
|
|
137
|
+
#### $subset
|
|
138
|
+
Allows for skipping advanced validation for specific fields, applying only basic validation. This is useful when validation data may conflict with predefined functions (starting with $), while user data might also contain similar keys. Use this operator as a compromise.
|
|
139
|
+
```javascript
|
|
140
|
+
{ $subset: { $lt: "John Doe" } } // chcek if "$lt" is "John Doe"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Examples
|
|
144
|
+
|
|
145
|
+
### Complex Validation
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
const criteria = {
|
|
149
|
+
$and: [
|
|
150
|
+
{
|
|
151
|
+
$or: [
|
|
152
|
+
{ $gt: { age: 18 } },
|
|
153
|
+
{ $exists: { guardianConsent: true } }
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
$type: { email: "string" },
|
|
158
|
+
$regex: { email: /^[^@]+@[^@]+\.[^@]+$/ }
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
$arrincall: { roles: ["user"] },
|
|
162
|
+
$not: { $in: { status: ["banned", "suspended"] } }
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const user = {
|
|
168
|
+
age: 16,
|
|
169
|
+
guardianConsent: true,
|
|
170
|
+
email: "john@example.com",
|
|
171
|
+
roles: ["user", "premium"],
|
|
172
|
+
status: "active"
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const isValid = hasFieldsAdvanced(user, criteria); // true
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Nested Conditions
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
const criteria = {
|
|
182
|
+
$and: [
|
|
183
|
+
{
|
|
184
|
+
$exists: { address: true },
|
|
185
|
+
$type: { address: "object" }
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
$or: [
|
|
189
|
+
{ $exists: { "address.zipCode": true } },
|
|
190
|
+
{
|
|
191
|
+
$and: [
|
|
192
|
+
{ $exists: { "address.city": true } },
|
|
193
|
+
{ $exists: { "address.country": true } }
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const user = {
|
|
202
|
+
address: {
|
|
203
|
+
city: "New York",
|
|
204
|
+
country: "USA"
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const isValid = hasFieldsAdvanced(user, criteria); // true
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Error Handling
|
|
212
|
+
|
|
213
|
+
The function will throw an error if:
|
|
214
|
+
- The `fields` parameter is not an object
|
|
215
|
+
- The `fields` parameter is null
|
|
216
|
+
|
|
217
|
+
Always wrap the function call in a try-catch block when using with untrusted input:
|
|
218
|
+
|
|
219
|
+
```javascript
|
|
220
|
+
try {
|
|
221
|
+
const isValid = hasFieldsAdvanced(obj, criteria);
|
|
222
|
+
// Handle result
|
|
223
|
+
} catch (error) {
|
|
224
|
+
// Handle error
|
|
225
|
+
console.error('Validation error:', error.message);
|
|
226
|
+
}
|
|
227
|
+
```
|
package/file/find.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { existsSync, promises } from "fs";
|
|
2
2
|
import { pathRepair, createRL } from "./utils.js";
|
|
3
3
|
import { parse } from "../format.js";
|
|
4
|
-
import
|
|
4
|
+
import hasFieldsAdvanced from "../utils/hasFieldsAdvanced.js";
|
|
5
|
+
import updateFindObject from "../utils/updateFindObject.js";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Processes a line of text from a file and checks if it matches the search criteria.
|
package/file/remove.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { existsSync, promises, appendFileSync, readdirSync } from "fs";
|
|
1
|
+
import { existsSync, promises, appendFileSync, readdirSync, cp } from "fs";
|
|
2
2
|
import { pathRepair, createRL } from "./utils.js";
|
|
3
3
|
import { parse } from "../format.js";
|
|
4
|
-
import
|
|
4
|
+
import hasFieldsAdvanced from "../utils/hasFieldsAdvanced.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Removes entries from a file based on search criteria.
|
|
@@ -53,19 +53,18 @@ async function removeWorker(file, search, context={}, one=false){
|
|
|
53
53
|
/**
|
|
54
54
|
* Asynchronously removes entries from a file based on search criteria.
|
|
55
55
|
* @function
|
|
56
|
-
* @param {string}
|
|
57
|
-
* @param {string} name - The name of the file to remove entries from.
|
|
56
|
+
* @param {string} cpath - Path to the collection.
|
|
58
57
|
* @param {function|Object} arg - The search criteria. It can be a function or an object.
|
|
59
58
|
* @param {Object} context - The context object (for functions).
|
|
60
59
|
* @param {boolean} one - Indicates whether to remove only one matching entry (default: false).
|
|
61
60
|
* @returns {Promise<boolean>} A Promise that resolves to `true` if entries were removed, or `false` otherwise.
|
|
62
61
|
*/
|
|
63
|
-
async function remove(
|
|
64
|
-
let files = readdirSync(
|
|
62
|
+
async function remove(cpath, arg, context={}, one){
|
|
63
|
+
let files = readdirSync(cpath).filter(file => !/\.tmp$/.test(file));
|
|
65
64
|
files.reverse();
|
|
66
65
|
let remove = false;
|
|
67
66
|
for(const file of files){
|
|
68
|
-
const removed = await removeWorker(
|
|
67
|
+
const removed = await removeWorker(cpath + file, arg, context, one);
|
|
69
68
|
if(one && removed) break;
|
|
70
69
|
remove = remove || removed;
|
|
71
70
|
}
|
package/file/update.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { existsSync, promises, appendFileSync, readdirSync } from "fs";
|
|
2
2
|
import { pathRepair, createRL } from "./utils.js";
|
|
3
3
|
import { parse, stringify } from "../format.js";
|
|
4
|
-
import
|
|
4
|
+
import hasFieldsAdvanced from "../utils/hasFieldsAdvanced.js";
|
|
5
|
+
import updateObject from "../utils/updateObject.js";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Updates a file based on search criteria and an updater function or object.
|
|
@@ -60,20 +61,19 @@ async function updateWorker(file, search, updater, context={}, one=false){
|
|
|
60
61
|
/**
|
|
61
62
|
* Asynchronously updates entries in a file based on search criteria and an updater function or object.
|
|
62
63
|
* @function
|
|
63
|
-
* @param {string}
|
|
64
|
-
* @param {string} name - The name of the file to update.
|
|
64
|
+
* @param {string} cpath - Path to the collection.
|
|
65
65
|
* @param {function|Object} arg - The search criteria. It can be a function or an object.
|
|
66
66
|
* @param {function|Object} obj - The updater function or object.
|
|
67
67
|
* @param {Object} context - The context object (for functions).
|
|
68
68
|
* @param {boolean} one - Indicates whether to update only one matching entry (default: false).
|
|
69
69
|
* @returns {Promise<boolean>} A Promise that resolves to `true` if entries were updated, or `false` otherwise.
|
|
70
70
|
*/
|
|
71
|
-
async function update(
|
|
72
|
-
let files = readdirSync(
|
|
71
|
+
async function update(cpath, arg, obj, context={}, one){
|
|
72
|
+
let files = readdirSync(cpath).filter(file => !/\.tmp$/.test(file));
|
|
73
73
|
files.reverse();
|
|
74
74
|
let update = false;
|
|
75
75
|
for(const file of files){
|
|
76
|
-
const updated = await updateWorker(
|
|
76
|
+
const updated = await updateWorker(cpath + file, arg, obj, context, one);
|
|
77
77
|
if(one && updated) return true;
|
|
78
78
|
update = update || updated;
|
|
79
79
|
}
|
package/gen.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function genId(parts: number | number[], fill?: number): string;
|
package/graph.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import DataBase from "./database.js";
|
|
2
|
+
|
|
3
|
+
declare class Graph {
|
|
4
|
+
db: DataBase;
|
|
5
|
+
|
|
6
|
+
constructor(databaseFolder: string);
|
|
7
|
+
|
|
8
|
+
add(collection: string, nodeA: string, nodeB: string): Promise<object>;
|
|
9
|
+
|
|
10
|
+
remove(collection: string, nodeA: string, nodeB: string): Promise<boolean>;
|
|
11
|
+
|
|
12
|
+
find(collection: string, node: string): Promise<object[]>;
|
|
13
|
+
|
|
14
|
+
findOne(collection: string, nodeA: string, nodeB: string): Promise<object | null>;
|
|
15
|
+
|
|
16
|
+
getAll(collection: string): Promise<object[]>;
|
|
17
|
+
|
|
18
|
+
getCollections(): Promise<string[]>;
|
|
19
|
+
|
|
20
|
+
checkCollection(collection: string): Promise<void>;
|
|
21
|
+
|
|
22
|
+
issetCollection(collection: string): Promise<boolean>;
|
|
23
|
+
|
|
24
|
+
removeCollection(collection: string): void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default Graph;
|
package/graph.js
CHANGED
|
@@ -112,7 +112,7 @@ class Graph{
|
|
|
112
112
|
* @param {string} collection - The collection to check.
|
|
113
113
|
*/
|
|
114
114
|
async checkCollection(collection){
|
|
115
|
-
await this.
|
|
115
|
+
await this.db.checkCollection(collection);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
/**
|
|
@@ -123,7 +123,17 @@ class Graph{
|
|
|
123
123
|
* @returns {boolean} True if the collection exists, false otherwise.
|
|
124
124
|
*/
|
|
125
125
|
async issetCollection(collection){
|
|
126
|
-
return await this.
|
|
126
|
+
return await this.db.issetCollection(collection);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Removes a database collection from the file system.
|
|
131
|
+
*
|
|
132
|
+
* @param {string} collection - The name of the collection to remove.
|
|
133
|
+
* @return {void}
|
|
134
|
+
*/
|
|
135
|
+
removeCollection(collection){
|
|
136
|
+
this.db.removeCollection(collection);
|
|
127
137
|
}
|
|
128
138
|
}
|
|
129
139
|
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import DataBase from "./database.js";
|
|
2
|
+
import Graph from "./graph.js";
|
|
3
|
+
import DataBaseRemote from "./remote/client/database.js";
|
|
4
|
+
import GraphRemote from "./remote/client/graph.js";
|
|
5
|
+
import genId from "./gen.js";
|
|
6
|
+
|
|
7
|
+
export { DataBase, Graph, DataBaseRemote, GraphRemote, genId };
|