twin-db 1.2.0 → 1.3.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 +5 -3
- package/dist/index.cjs +168 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{structures/database.d.ts → index.d.cts} +3 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +141 -2
- package/dist/index.js.map +1 -0
- package/package.json +16 -3
- package/dist/structures/database.js +0 -133
package/README.md
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
### Before All
|
|
2
|
-
Make sure you're using `"type": "module"` in package.json.<br>
|
|
3
2
|
Make sure to pass just values that JSON accepts, if not, the values will be changed to `null`.
|
|
4
3
|
# How to Use?
|
|
5
4
|
To create a new database make the following step:
|
|
6
5
|
```js
|
|
7
|
-
import TwinDB from 'twin-db';
|
|
6
|
+
import { TwinDB } from 'twin-db';
|
|
8
7
|
const database = new TwinDB('db');
|
|
9
8
|
```
|
|
10
9
|
And your database is done.
|
|
11
10
|
### You can make various databases too:
|
|
12
11
|
```js
|
|
13
|
-
import TwinDB from 'twin-db';
|
|
12
|
+
import { TwinDB } from 'twin-db';
|
|
14
13
|
const database = new TwinDB('db');
|
|
15
14
|
const coolDatabase = new TwinDB('cool');
|
|
16
15
|
```
|
|
@@ -93,3 +92,6 @@ database.pull('hobbies', 'cs', 'sleep') // now the hobbies is ["pizza", "valoran
|
|
|
93
92
|
|
|
94
93
|
05/03/2026 - 1.2.*
|
|
95
94
|
- Now package doesn't uses eval anymore, providing better security.
|
|
95
|
+
|
|
96
|
+
06/29/2026 - 1.3.*
|
|
97
|
+
- Added support to require in commonjs.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
TwinDB: () => TwinDB
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
|
|
27
|
+
// src/structures/database.ts
|
|
28
|
+
var import_fs = require("fs");
|
|
29
|
+
var pathErrorMessage = "The path must be a string or you dont provide a path";
|
|
30
|
+
var TwinDB = class {
|
|
31
|
+
constructor(name = "db") {
|
|
32
|
+
this.path = "database/" + name + ".json";
|
|
33
|
+
this.name = name;
|
|
34
|
+
this.data = {};
|
|
35
|
+
if (!(0, import_fs.existsSync)("database")) (0, import_fs.mkdirSync)("database");
|
|
36
|
+
this.load();
|
|
37
|
+
}
|
|
38
|
+
load() {
|
|
39
|
+
let data;
|
|
40
|
+
try {
|
|
41
|
+
data = (0, import_fs.readFileSync)(this.path, "utf8");
|
|
42
|
+
} catch (e) {
|
|
43
|
+
data = "";
|
|
44
|
+
}
|
|
45
|
+
this.data = data ? JSON.parse(data) : {};
|
|
46
|
+
if (!data)
|
|
47
|
+
(0, import_fs.writeFileSync)(
|
|
48
|
+
this.path,
|
|
49
|
+
JSON.stringify(this.data, null, 2),
|
|
50
|
+
"utf8"
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
update(path, value) {
|
|
54
|
+
const keys = path.split(".");
|
|
55
|
+
let current = this.data;
|
|
56
|
+
for (let i = 0; i < keys.length; i++) {
|
|
57
|
+
let key = keys[i];
|
|
58
|
+
if (i === keys.length - 1) {
|
|
59
|
+
current[key] = value;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
if (typeof current[key] !== "object" || Array.isArray(current[key]) || !current[key]) {
|
|
63
|
+
current[key] = {};
|
|
64
|
+
}
|
|
65
|
+
current = current[key];
|
|
66
|
+
}
|
|
67
|
+
(0, import_fs.writeFileSync)(this.path, JSON.stringify(this.data, null, 2), "utf8");
|
|
68
|
+
return this.data;
|
|
69
|
+
}
|
|
70
|
+
set(path, value) {
|
|
71
|
+
if (!path || typeof path !== "string")
|
|
72
|
+
throw new Error(pathErrorMessage);
|
|
73
|
+
if (value === void 0)
|
|
74
|
+
throw new Error("You must provide a value to update");
|
|
75
|
+
return this.update(path, value);
|
|
76
|
+
}
|
|
77
|
+
get(path) {
|
|
78
|
+
if (!path || typeof path !== "string")
|
|
79
|
+
throw new Error(pathErrorMessage);
|
|
80
|
+
const keys = path.split(".");
|
|
81
|
+
let current = this.data;
|
|
82
|
+
let i = 0;
|
|
83
|
+
for (const key of keys) {
|
|
84
|
+
i++;
|
|
85
|
+
if (i === keys.length) return current[key] ?? null;
|
|
86
|
+
if (typeof current[key] !== "object") return null;
|
|
87
|
+
current = current[key];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
delete(path) {
|
|
91
|
+
if (!path || typeof path !== "string")
|
|
92
|
+
throw new Error(pathErrorMessage);
|
|
93
|
+
const keys = path.split(".");
|
|
94
|
+
const pathExists = this.get(path);
|
|
95
|
+
if (pathExists === null)
|
|
96
|
+
throw new Error("The path does not exists or its value is null");
|
|
97
|
+
this.update(path, null);
|
|
98
|
+
(0, import_fs.writeFileSync)(this.path, JSON.stringify(this.data, null, 2), "utf8");
|
|
99
|
+
return this.data;
|
|
100
|
+
}
|
|
101
|
+
sumOrSub(path, value, type) {
|
|
102
|
+
if (!path || typeof path !== "string")
|
|
103
|
+
throw new Error(pathErrorMessage);
|
|
104
|
+
if (!type || !["sum", "sub"].includes(type))
|
|
105
|
+
throw new Error('The type must be "sum" or "sub"');
|
|
106
|
+
const isSum = type === "sum";
|
|
107
|
+
if (!value || typeof value !== "number")
|
|
108
|
+
throw new Error(
|
|
109
|
+
`The value to ${isSum ? "sum" : "sub"} must be a number`
|
|
110
|
+
);
|
|
111
|
+
let currentValue = this.get(path) || 0;
|
|
112
|
+
if (typeof currentValue !== "number") currentValue = 0;
|
|
113
|
+
return this.update(
|
|
114
|
+
path,
|
|
115
|
+
isSum ? currentValue + value : currentValue - value
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
sum(path, value) {
|
|
119
|
+
return this.sumOrSub(path, value, "sum");
|
|
120
|
+
}
|
|
121
|
+
sub(path, value) {
|
|
122
|
+
return this.sumOrSub(path, value, "sub");
|
|
123
|
+
}
|
|
124
|
+
concat(path, value) {
|
|
125
|
+
if (!path || typeof path !== "string")
|
|
126
|
+
throw new Error(pathErrorMessage);
|
|
127
|
+
if (!value || typeof value !== "string")
|
|
128
|
+
throw new Error("You must provide a string value to update");
|
|
129
|
+
const currentValue = this.get(path);
|
|
130
|
+
if (typeof currentValue !== "string")
|
|
131
|
+
throw new Error(
|
|
132
|
+
"The value to concat is not a string or the path does not exists"
|
|
133
|
+
);
|
|
134
|
+
return this.update(path, currentValue + value);
|
|
135
|
+
}
|
|
136
|
+
push(path, ...values) {
|
|
137
|
+
if (!path || typeof path !== "string")
|
|
138
|
+
throw new Error(pathErrorMessage);
|
|
139
|
+
if (!values || values.length === 0)
|
|
140
|
+
throw new Error("You must provide a value to update");
|
|
141
|
+
let currentValue = this.get(path) || [];
|
|
142
|
+
if (!Array.isArray(currentValue)) currentValue = [];
|
|
143
|
+
currentValue.push(...values);
|
|
144
|
+
return this.update(path, currentValue);
|
|
145
|
+
}
|
|
146
|
+
pull(path, ...values) {
|
|
147
|
+
if (!path || typeof path !== "string")
|
|
148
|
+
throw new Error(pathErrorMessage);
|
|
149
|
+
if (!values || values.length === 0)
|
|
150
|
+
throw new Error("You must provide a value to update");
|
|
151
|
+
const currentValue = this.get(path);
|
|
152
|
+
if (!Array.isArray(currentValue))
|
|
153
|
+
throw new Error(
|
|
154
|
+
"The current value of this path is not an array or the path does not exists"
|
|
155
|
+
);
|
|
156
|
+
for (const value of values) {
|
|
157
|
+
const index = currentValue.indexOf(value);
|
|
158
|
+
if (index < 0) continue;
|
|
159
|
+
currentValue.splice(index, 1);
|
|
160
|
+
}
|
|
161
|
+
return this.update(path, currentValue);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
165
|
+
0 && (module.exports = {
|
|
166
|
+
TwinDB
|
|
167
|
+
});
|
|
168
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/structures/database.ts"],"sourcesContent":["import { TwinDB } from './structures/database';\n\nexport { TwinDB };","import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\n\nconst pathErrorMessage = 'The path must be a string or you dont provide a path';\n\nexport class TwinDB {\n public data: Record<string, unknown>;\n public path: string;\n public name: string;\n\n public constructor(name: string = 'db') {\n this.path = 'database/' + name + '.json';\n this.name = name;\n this.data = {};\n\n if (!existsSync('database')) mkdirSync('database');\n this.load();\n }\n\n private load() {\n let data: string;\n try {\n data = readFileSync(this.path, 'utf8');\n } catch (e) {\n data = '';\n }\n this.data = data ? JSON.parse(data) : {};\n\n if (!data)\n writeFileSync(\n this.path,\n JSON.stringify(this.data, null, 2),\n 'utf8',\n );\n }\n\n private update(path: string /*user.info.name*/, value: unknown) {\n const keys = path.split('.');\n\n let current = this.data;\n for (let i = 0; i < keys.length; i++) {\n let key = keys[i];\n\n if (i === keys.length - 1) {\n current[key] = value;\n break;\n } \n \n if (typeof current[key] !== 'object' || Array.isArray(current[key]) || !current[key]) {\n current[key] = {};\n }\n\n current = current[key] as Record<string, unknown>;\n }\n\n writeFileSync(this.path, JSON.stringify(this.data, null, 2), 'utf8');\n\n return this.data;\n }\n\n public set(path: string, value: unknown) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n if (value === undefined)\n throw new Error('You must provide a value to update');\n\n return this.update(path, value);\n }\n\n public get(path: string): unknown | null {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n const keys = path.split('.');\n let current = this.data;\n let i = 0;\n\n for (const key of keys) {\n i++;\n\n if (i === keys.length) return current[key] ?? null;\n\n if (typeof current[key] !== 'object') return null;\n\n current = current[key] as Record<string, unknown>;\n }\n }\n\n public delete(path: string) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n const keys = path.split('.');\n const pathExists = this.get(path);\n if (pathExists === null)\n throw new Error('The path does not exists or its value is null');\n\n this.update(path, null);\n\n writeFileSync(this.path, JSON.stringify(this.data, null, 2), 'utf8');\n\n return this.data;\n }\n\n private sumOrSub(path: string, value: number, type: SumOrSub) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n if (!type || !['sum', 'sub'].includes(type))\n throw new Error('The type must be \"sum\" or \"sub\"');\n const isSum = type === 'sum';\n if (!value || typeof value !== 'number')\n throw new Error(\n `The value to ${isSum ? 'sum' : 'sub'} must be a number`,\n );\n\n let currentValue = (this.get(path) || 0) as unknown as number;\n if (typeof currentValue !== 'number') currentValue = 0;\n\n return this.update(\n path,\n isSum ? currentValue + value : currentValue - value,\n );\n }\n\n public sum(path: string, value: number) {\n return this.sumOrSub(path, value, 'sum');\n }\n\n public sub(path: string, value: number) {\n return this.sumOrSub(path, value, 'sub');\n }\n\n public concat(path: string, value: string) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n if (!value || typeof value !== 'string')\n throw new Error('You must provide a string value to update');\n\n const currentValue = this.get(path);\n if (typeof currentValue !== 'string')\n throw new Error(\n 'The value to concat is not a string or the path does not exists',\n );\n\n return this.update(path, currentValue + value);\n }\n\n public push(path: string, ...values: unknown[]) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n if (!values || values.length === 0)\n throw new Error('You must provide a value to update');\n\n let currentValue = (this.get(path) || []) as unknown as unknown[];\n if (!Array.isArray(currentValue)) currentValue = [];\n\n currentValue.push(...values);\n return this.update(path, currentValue);\n }\n\n public pull(path: string, ...values: unknown[]) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n if (!values || values.length === 0)\n throw new Error('You must provide a value to update');\n\n const currentValue = this.get(path);\n if (!Array.isArray(currentValue))\n throw new Error(\n 'The current value of this path is not an array or the path does not exists',\n );\n\n for (const value of values) {\n const index = currentValue.indexOf(value);\n if (index < 0) continue;\n\n currentValue.splice(index, 1);\n }\n\n return this.update(path, currentValue);\n }\n}\n\nexport type SumOrSub = 'sum' | 'sub';\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
declare class TwinDB {
|
|
2
2
|
data: Record<string, unknown>;
|
|
3
3
|
path: string;
|
|
4
4
|
name: string;
|
|
@@ -15,4 +15,5 @@ export declare class TwinDB {
|
|
|
15
15
|
push(path: string, ...values: unknown[]): Record<string, unknown>;
|
|
16
16
|
pull(path: string, ...values: unknown[]): Record<string, unknown>;
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
export { TwinDB };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
declare class TwinDB {
|
|
2
|
+
data: Record<string, unknown>;
|
|
3
|
+
path: string;
|
|
4
|
+
name: string;
|
|
5
|
+
constructor(name?: string);
|
|
6
|
+
private load;
|
|
7
|
+
private update;
|
|
8
|
+
set(path: string, value: unknown): Record<string, unknown>;
|
|
9
|
+
get(path: string): unknown | null;
|
|
10
|
+
delete(path: string): Record<string, unknown>;
|
|
11
|
+
private sumOrSub;
|
|
12
|
+
sum(path: string, value: number): Record<string, unknown>;
|
|
13
|
+
sub(path: string, value: number): Record<string, unknown>;
|
|
14
|
+
concat(path: string, value: string): Record<string, unknown>;
|
|
15
|
+
push(path: string, ...values: unknown[]): Record<string, unknown>;
|
|
16
|
+
pull(path: string, ...values: unknown[]): Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { TwinDB };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,141 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// src/structures/database.ts
|
|
2
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
3
|
+
var pathErrorMessage = "The path must be a string or you dont provide a path";
|
|
4
|
+
var TwinDB = class {
|
|
5
|
+
constructor(name = "db") {
|
|
6
|
+
this.path = "database/" + name + ".json";
|
|
7
|
+
this.name = name;
|
|
8
|
+
this.data = {};
|
|
9
|
+
if (!existsSync("database")) mkdirSync("database");
|
|
10
|
+
this.load();
|
|
11
|
+
}
|
|
12
|
+
load() {
|
|
13
|
+
let data;
|
|
14
|
+
try {
|
|
15
|
+
data = readFileSync(this.path, "utf8");
|
|
16
|
+
} catch (e) {
|
|
17
|
+
data = "";
|
|
18
|
+
}
|
|
19
|
+
this.data = data ? JSON.parse(data) : {};
|
|
20
|
+
if (!data)
|
|
21
|
+
writeFileSync(
|
|
22
|
+
this.path,
|
|
23
|
+
JSON.stringify(this.data, null, 2),
|
|
24
|
+
"utf8"
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
update(path, value) {
|
|
28
|
+
const keys = path.split(".");
|
|
29
|
+
let current = this.data;
|
|
30
|
+
for (let i = 0; i < keys.length; i++) {
|
|
31
|
+
let key = keys[i];
|
|
32
|
+
if (i === keys.length - 1) {
|
|
33
|
+
current[key] = value;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
if (typeof current[key] !== "object" || Array.isArray(current[key]) || !current[key]) {
|
|
37
|
+
current[key] = {};
|
|
38
|
+
}
|
|
39
|
+
current = current[key];
|
|
40
|
+
}
|
|
41
|
+
writeFileSync(this.path, JSON.stringify(this.data, null, 2), "utf8");
|
|
42
|
+
return this.data;
|
|
43
|
+
}
|
|
44
|
+
set(path, value) {
|
|
45
|
+
if (!path || typeof path !== "string")
|
|
46
|
+
throw new Error(pathErrorMessage);
|
|
47
|
+
if (value === void 0)
|
|
48
|
+
throw new Error("You must provide a value to update");
|
|
49
|
+
return this.update(path, value);
|
|
50
|
+
}
|
|
51
|
+
get(path) {
|
|
52
|
+
if (!path || typeof path !== "string")
|
|
53
|
+
throw new Error(pathErrorMessage);
|
|
54
|
+
const keys = path.split(".");
|
|
55
|
+
let current = this.data;
|
|
56
|
+
let i = 0;
|
|
57
|
+
for (const key of keys) {
|
|
58
|
+
i++;
|
|
59
|
+
if (i === keys.length) return current[key] ?? null;
|
|
60
|
+
if (typeof current[key] !== "object") return null;
|
|
61
|
+
current = current[key];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
delete(path) {
|
|
65
|
+
if (!path || typeof path !== "string")
|
|
66
|
+
throw new Error(pathErrorMessage);
|
|
67
|
+
const keys = path.split(".");
|
|
68
|
+
const pathExists = this.get(path);
|
|
69
|
+
if (pathExists === null)
|
|
70
|
+
throw new Error("The path does not exists or its value is null");
|
|
71
|
+
this.update(path, null);
|
|
72
|
+
writeFileSync(this.path, JSON.stringify(this.data, null, 2), "utf8");
|
|
73
|
+
return this.data;
|
|
74
|
+
}
|
|
75
|
+
sumOrSub(path, value, type) {
|
|
76
|
+
if (!path || typeof path !== "string")
|
|
77
|
+
throw new Error(pathErrorMessage);
|
|
78
|
+
if (!type || !["sum", "sub"].includes(type))
|
|
79
|
+
throw new Error('The type must be "sum" or "sub"');
|
|
80
|
+
const isSum = type === "sum";
|
|
81
|
+
if (!value || typeof value !== "number")
|
|
82
|
+
throw new Error(
|
|
83
|
+
`The value to ${isSum ? "sum" : "sub"} must be a number`
|
|
84
|
+
);
|
|
85
|
+
let currentValue = this.get(path) || 0;
|
|
86
|
+
if (typeof currentValue !== "number") currentValue = 0;
|
|
87
|
+
return this.update(
|
|
88
|
+
path,
|
|
89
|
+
isSum ? currentValue + value : currentValue - value
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
sum(path, value) {
|
|
93
|
+
return this.sumOrSub(path, value, "sum");
|
|
94
|
+
}
|
|
95
|
+
sub(path, value) {
|
|
96
|
+
return this.sumOrSub(path, value, "sub");
|
|
97
|
+
}
|
|
98
|
+
concat(path, value) {
|
|
99
|
+
if (!path || typeof path !== "string")
|
|
100
|
+
throw new Error(pathErrorMessage);
|
|
101
|
+
if (!value || typeof value !== "string")
|
|
102
|
+
throw new Error("You must provide a string value to update");
|
|
103
|
+
const currentValue = this.get(path);
|
|
104
|
+
if (typeof currentValue !== "string")
|
|
105
|
+
throw new Error(
|
|
106
|
+
"The value to concat is not a string or the path does not exists"
|
|
107
|
+
);
|
|
108
|
+
return this.update(path, currentValue + value);
|
|
109
|
+
}
|
|
110
|
+
push(path, ...values) {
|
|
111
|
+
if (!path || typeof path !== "string")
|
|
112
|
+
throw new Error(pathErrorMessage);
|
|
113
|
+
if (!values || values.length === 0)
|
|
114
|
+
throw new Error("You must provide a value to update");
|
|
115
|
+
let currentValue = this.get(path) || [];
|
|
116
|
+
if (!Array.isArray(currentValue)) currentValue = [];
|
|
117
|
+
currentValue.push(...values);
|
|
118
|
+
return this.update(path, currentValue);
|
|
119
|
+
}
|
|
120
|
+
pull(path, ...values) {
|
|
121
|
+
if (!path || typeof path !== "string")
|
|
122
|
+
throw new Error(pathErrorMessage);
|
|
123
|
+
if (!values || values.length === 0)
|
|
124
|
+
throw new Error("You must provide a value to update");
|
|
125
|
+
const currentValue = this.get(path);
|
|
126
|
+
if (!Array.isArray(currentValue))
|
|
127
|
+
throw new Error(
|
|
128
|
+
"The current value of this path is not an array or the path does not exists"
|
|
129
|
+
);
|
|
130
|
+
for (const value of values) {
|
|
131
|
+
const index = currentValue.indexOf(value);
|
|
132
|
+
if (index < 0) continue;
|
|
133
|
+
currentValue.splice(index, 1);
|
|
134
|
+
}
|
|
135
|
+
return this.update(path, currentValue);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
export {
|
|
139
|
+
TwinDB
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/structures/database.ts"],"sourcesContent":["import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\n\nconst pathErrorMessage = 'The path must be a string or you dont provide a path';\n\nexport class TwinDB {\n public data: Record<string, unknown>;\n public path: string;\n public name: string;\n\n public constructor(name: string = 'db') {\n this.path = 'database/' + name + '.json';\n this.name = name;\n this.data = {};\n\n if (!existsSync('database')) mkdirSync('database');\n this.load();\n }\n\n private load() {\n let data: string;\n try {\n data = readFileSync(this.path, 'utf8');\n } catch (e) {\n data = '';\n }\n this.data = data ? JSON.parse(data) : {};\n\n if (!data)\n writeFileSync(\n this.path,\n JSON.stringify(this.data, null, 2),\n 'utf8',\n );\n }\n\n private update(path: string /*user.info.name*/, value: unknown) {\n const keys = path.split('.');\n\n let current = this.data;\n for (let i = 0; i < keys.length; i++) {\n let key = keys[i];\n\n if (i === keys.length - 1) {\n current[key] = value;\n break;\n } \n \n if (typeof current[key] !== 'object' || Array.isArray(current[key]) || !current[key]) {\n current[key] = {};\n }\n\n current = current[key] as Record<string, unknown>;\n }\n\n writeFileSync(this.path, JSON.stringify(this.data, null, 2), 'utf8');\n\n return this.data;\n }\n\n public set(path: string, value: unknown) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n if (value === undefined)\n throw new Error('You must provide a value to update');\n\n return this.update(path, value);\n }\n\n public get(path: string): unknown | null {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n const keys = path.split('.');\n let current = this.data;\n let i = 0;\n\n for (const key of keys) {\n i++;\n\n if (i === keys.length) return current[key] ?? null;\n\n if (typeof current[key] !== 'object') return null;\n\n current = current[key] as Record<string, unknown>;\n }\n }\n\n public delete(path: string) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n const keys = path.split('.');\n const pathExists = this.get(path);\n if (pathExists === null)\n throw new Error('The path does not exists or its value is null');\n\n this.update(path, null);\n\n writeFileSync(this.path, JSON.stringify(this.data, null, 2), 'utf8');\n\n return this.data;\n }\n\n private sumOrSub(path: string, value: number, type: SumOrSub) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n if (!type || !['sum', 'sub'].includes(type))\n throw new Error('The type must be \"sum\" or \"sub\"');\n const isSum = type === 'sum';\n if (!value || typeof value !== 'number')\n throw new Error(\n `The value to ${isSum ? 'sum' : 'sub'} must be a number`,\n );\n\n let currentValue = (this.get(path) || 0) as unknown as number;\n if (typeof currentValue !== 'number') currentValue = 0;\n\n return this.update(\n path,\n isSum ? currentValue + value : currentValue - value,\n );\n }\n\n public sum(path: string, value: number) {\n return this.sumOrSub(path, value, 'sum');\n }\n\n public sub(path: string, value: number) {\n return this.sumOrSub(path, value, 'sub');\n }\n\n public concat(path: string, value: string) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n if (!value || typeof value !== 'string')\n throw new Error('You must provide a string value to update');\n\n const currentValue = this.get(path);\n if (typeof currentValue !== 'string')\n throw new Error(\n 'The value to concat is not a string or the path does not exists',\n );\n\n return this.update(path, currentValue + value);\n }\n\n public push(path: string, ...values: unknown[]) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n if (!values || values.length === 0)\n throw new Error('You must provide a value to update');\n\n let currentValue = (this.get(path) || []) as unknown as unknown[];\n if (!Array.isArray(currentValue)) currentValue = [];\n\n currentValue.push(...values);\n return this.update(path, currentValue);\n }\n\n public pull(path: string, ...values: unknown[]) {\n if (!path || typeof path !== 'string')\n throw new Error(pathErrorMessage);\n if (!values || values.length === 0)\n throw new Error('You must provide a value to update');\n\n const currentValue = this.get(path);\n if (!Array.isArray(currentValue))\n throw new Error(\n 'The current value of this path is not an array or the path does not exists',\n );\n\n for (const value of values) {\n const index = currentValue.indexOf(value);\n if (index < 0) continue;\n\n currentValue.splice(index, 1);\n }\n\n return this.update(path, currentValue);\n }\n}\n\nexport type SumOrSub = 'sum' | 'sub';\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "twin-db",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "A usefully local database.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist"
|
|
11
11
|
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": {
|
|
15
|
+
"types": "./dist/index.d.mts",
|
|
16
|
+
"default": "./dist/index.mjs"
|
|
17
|
+
},
|
|
18
|
+
"require": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
12
24
|
"scripts": {
|
|
13
25
|
"test": "tsx src/index.ts",
|
|
14
26
|
"prettier": "npx prettier --write \"**/*.{js,ts}\"",
|
|
15
|
-
"build": "npx
|
|
27
|
+
"build": "npx tsup"
|
|
16
28
|
},
|
|
17
29
|
"author": {
|
|
18
30
|
"name": "Jaelson Kaciel",
|
|
@@ -31,6 +43,7 @@
|
|
|
31
43
|
"devDependencies": {
|
|
32
44
|
"@types/node": "^25.6.0",
|
|
33
45
|
"prettier": "^3.8.1",
|
|
46
|
+
"tsup": "^8.5.1",
|
|
34
47
|
"tsx": "^4.21.0",
|
|
35
48
|
"typescript": "^6.0.2"
|
|
36
49
|
},
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
2
|
-
const pathErrorMessage = 'The path must be a string or you dont provide a path';
|
|
3
|
-
export class TwinDB {
|
|
4
|
-
data;
|
|
5
|
-
path;
|
|
6
|
-
name;
|
|
7
|
-
constructor(name = 'db') {
|
|
8
|
-
this.path = 'database/' + name + '.json';
|
|
9
|
-
this.name = name;
|
|
10
|
-
this.data = {};
|
|
11
|
-
if (!existsSync('database'))
|
|
12
|
-
mkdirSync('database');
|
|
13
|
-
this.load();
|
|
14
|
-
}
|
|
15
|
-
load() {
|
|
16
|
-
let data;
|
|
17
|
-
try {
|
|
18
|
-
data = readFileSync(this.path, 'utf8');
|
|
19
|
-
}
|
|
20
|
-
catch (e) {
|
|
21
|
-
data = '';
|
|
22
|
-
}
|
|
23
|
-
this.data = data ? JSON.parse(data) : {};
|
|
24
|
-
if (!data)
|
|
25
|
-
writeFileSync(this.path, JSON.stringify(this.data, null, 2), 'utf8');
|
|
26
|
-
}
|
|
27
|
-
update(path /*user.info.name*/, value) {
|
|
28
|
-
const keys = path.split('.');
|
|
29
|
-
let current = this.data;
|
|
30
|
-
for (let i = 0; i < keys.length; i++) {
|
|
31
|
-
let key = keys[i];
|
|
32
|
-
if (i === keys.length - 1) {
|
|
33
|
-
current[key] = value;
|
|
34
|
-
break;
|
|
35
|
-
}
|
|
36
|
-
if (typeof current[key] !== 'object' || Array.isArray(current[key]) || !current[key]) {
|
|
37
|
-
current[key] = {};
|
|
38
|
-
}
|
|
39
|
-
current = current[key];
|
|
40
|
-
}
|
|
41
|
-
writeFileSync(this.path, JSON.stringify(this.data, null, 2), 'utf8');
|
|
42
|
-
return this.data;
|
|
43
|
-
}
|
|
44
|
-
set(path, value) {
|
|
45
|
-
if (!path || typeof path !== 'string')
|
|
46
|
-
throw new Error(pathErrorMessage);
|
|
47
|
-
if (value === undefined)
|
|
48
|
-
throw new Error('You must provide a value to update');
|
|
49
|
-
return this.update(path, value);
|
|
50
|
-
}
|
|
51
|
-
get(path) {
|
|
52
|
-
if (!path || typeof path !== 'string')
|
|
53
|
-
throw new Error(pathErrorMessage);
|
|
54
|
-
const keys = path.split('.');
|
|
55
|
-
let current = this.data;
|
|
56
|
-
let i = 0;
|
|
57
|
-
for (const key of keys) {
|
|
58
|
-
i++;
|
|
59
|
-
if (i === keys.length)
|
|
60
|
-
return current[key] ?? null;
|
|
61
|
-
if (typeof current[key] !== 'object')
|
|
62
|
-
return null;
|
|
63
|
-
current = current[key];
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
delete(path) {
|
|
67
|
-
if (!path || typeof path !== 'string')
|
|
68
|
-
throw new Error(pathErrorMessage);
|
|
69
|
-
const keys = path.split('.');
|
|
70
|
-
const pathExists = this.get(path);
|
|
71
|
-
if (pathExists === null)
|
|
72
|
-
throw new Error('The path does not exists or its value is null');
|
|
73
|
-
this.update(path, null);
|
|
74
|
-
writeFileSync(this.path, JSON.stringify(this.data, null, 2), 'utf8');
|
|
75
|
-
return this.data;
|
|
76
|
-
}
|
|
77
|
-
sumOrSub(path, value, type) {
|
|
78
|
-
if (!path || typeof path !== 'string')
|
|
79
|
-
throw new Error(pathErrorMessage);
|
|
80
|
-
if (!type || !['sum', 'sub'].includes(type))
|
|
81
|
-
throw new Error('The type must be "sum" or "sub"');
|
|
82
|
-
const isSum = type === 'sum';
|
|
83
|
-
if (!value || typeof value !== 'number')
|
|
84
|
-
throw new Error(`The value to ${isSum ? 'sum' : 'sub'} must be a number`);
|
|
85
|
-
let currentValue = (this.get(path) || 0);
|
|
86
|
-
if (typeof currentValue !== 'number')
|
|
87
|
-
currentValue = 0;
|
|
88
|
-
return this.update(path, isSum ? currentValue + value : currentValue - value);
|
|
89
|
-
}
|
|
90
|
-
sum(path, value) {
|
|
91
|
-
return this.sumOrSub(path, value, 'sum');
|
|
92
|
-
}
|
|
93
|
-
sub(path, value) {
|
|
94
|
-
return this.sumOrSub(path, value, 'sub');
|
|
95
|
-
}
|
|
96
|
-
concat(path, value) {
|
|
97
|
-
if (!path || typeof path !== 'string')
|
|
98
|
-
throw new Error(pathErrorMessage);
|
|
99
|
-
if (!value || typeof value !== 'string')
|
|
100
|
-
throw new Error('You must provide a string value to update');
|
|
101
|
-
const currentValue = this.get(path);
|
|
102
|
-
if (typeof currentValue !== 'string')
|
|
103
|
-
throw new Error('The value to concat is not a string or the path does not exists');
|
|
104
|
-
return this.update(path, currentValue + value);
|
|
105
|
-
}
|
|
106
|
-
push(path, ...values) {
|
|
107
|
-
if (!path || typeof path !== 'string')
|
|
108
|
-
throw new Error(pathErrorMessage);
|
|
109
|
-
if (!values || values.length === 0)
|
|
110
|
-
throw new Error('You must provide a value to update');
|
|
111
|
-
let currentValue = (this.get(path) || []);
|
|
112
|
-
if (!Array.isArray(currentValue))
|
|
113
|
-
currentValue = [];
|
|
114
|
-
currentValue.push(...values);
|
|
115
|
-
return this.update(path, currentValue);
|
|
116
|
-
}
|
|
117
|
-
pull(path, ...values) {
|
|
118
|
-
if (!path || typeof path !== 'string')
|
|
119
|
-
throw new Error(pathErrorMessage);
|
|
120
|
-
if (!values || values.length === 0)
|
|
121
|
-
throw new Error('You must provide a value to update');
|
|
122
|
-
const currentValue = this.get(path);
|
|
123
|
-
if (!Array.isArray(currentValue))
|
|
124
|
-
throw new Error('The current value of this path is not an array or the path does not exists');
|
|
125
|
-
for (const value of values) {
|
|
126
|
-
const index = currentValue.indexOf(value);
|
|
127
|
-
if (index < 0)
|
|
128
|
-
continue;
|
|
129
|
-
currentValue.splice(index, 1);
|
|
130
|
-
}
|
|
131
|
-
return this.update(path, currentValue);
|
|
132
|
-
}
|
|
133
|
-
}
|