inibase 1.0.0-rc.65 → 1.0.0-rc.66
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 +1 -34
- package/dist/cli.js +235 -63
- package/dist/file.d.ts +11 -2
- package/dist/file.js +35 -4
- package/dist/index.d.ts +1 -2
- package/dist/index.js +53 -32
- package/dist/utils.server.d.ts +2 -1
- package/dist/utils.server.js +2 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -68,42 +68,9 @@ This structure ensures efficient storage, retrieval, and updates, making our sys
|
|
|
68
68
|
|
|
69
69
|
```shell
|
|
70
70
|
npx inibase -p <databaseFolderPath>
|
|
71
|
+
# by default it will diplay a list of available commands (or type 'help')
|
|
71
72
|
```
|
|
72
73
|
|
|
73
|
-
<blockquote>
|
|
74
|
-
<details>
|
|
75
|
-
<summary>GET</summary>
|
|
76
|
-
|
|
77
|
-
```shell
|
|
78
|
-
get <tableName> -w <ID|LineNumber|Criteria> -p <pageNumber> -l <perPage> -c <columnName1> -c <columnName2>
|
|
79
|
-
```
|
|
80
|
-
</details>
|
|
81
|
-
|
|
82
|
-
<details>
|
|
83
|
-
<summary>POST</summary>
|
|
84
|
-
|
|
85
|
-
```shell
|
|
86
|
-
post <tableName> -d <InisonStrigifedData>
|
|
87
|
-
```
|
|
88
|
-
</details>
|
|
89
|
-
|
|
90
|
-
<details>
|
|
91
|
-
<summary>PUT</summary>
|
|
92
|
-
|
|
93
|
-
```shell
|
|
94
|
-
put <tableName> -d <InisonStrigifedData> -w <ID|LineNumber|Criteria>
|
|
95
|
-
```
|
|
96
|
-
</details>
|
|
97
|
-
|
|
98
|
-
<details>
|
|
99
|
-
<summary>DELETE</summary>
|
|
100
|
-
|
|
101
|
-
```shell
|
|
102
|
-
delete <tableName> -w <ID|LineNumber|Criteria>
|
|
103
|
-
```
|
|
104
|
-
</details>
|
|
105
|
-
</blockquote>
|
|
106
|
-
|
|
107
74
|
## Examples
|
|
108
75
|
|
|
109
76
|
<details>
|
package/dist/cli.js
CHANGED
|
@@ -2,90 +2,262 @@
|
|
|
2
2
|
import "dotenv/config";
|
|
3
3
|
import { createInterface } from "node:readline/promises";
|
|
4
4
|
import { parseArgs } from "node:util";
|
|
5
|
-
import { basename } from "node:path";
|
|
5
|
+
import { basename, join } from "node:path";
|
|
6
|
+
import { readFileSync } from "node:fs";
|
|
6
7
|
import Inison from "inison";
|
|
7
8
|
import Inibase from "./index.js";
|
|
8
|
-
import { isJSON, isNumber } from "./utils.js";
|
|
9
|
-
|
|
9
|
+
import { isJSON, isNumber, setField, unsetField } from "./utils.js";
|
|
10
|
+
import { isExists } from "./file.js";
|
|
11
|
+
const textGreen = (input) => `\u001b[1;32m${input}\u001b[0m`;
|
|
12
|
+
const textRed = (input) => `\u001b[1;31m${input}\u001b[0m`;
|
|
13
|
+
const textBlue = (input) => `\u001b[1;34m${input}\u001b[0m`;
|
|
14
|
+
const textMagenta = (input) => `\u001b[1;35m${input}\u001b[0m`;
|
|
15
|
+
let { path, version } = parseArgs({
|
|
10
16
|
options: {
|
|
11
17
|
path: { type: "string", short: "p" },
|
|
18
|
+
version: { type: "boolean", short: "v" },
|
|
12
19
|
},
|
|
13
20
|
}).values;
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
if (version) {
|
|
22
|
+
console.log(JSON.parse(readFileSync("package.json", "utf8")).version);
|
|
23
|
+
process.exit();
|
|
24
|
+
}
|
|
17
25
|
const rl = createInterface({
|
|
18
26
|
input: process.stdin,
|
|
19
27
|
output: process.stdout,
|
|
20
|
-
prompt: "
|
|
28
|
+
prompt: textBlue("> "),
|
|
21
29
|
});
|
|
30
|
+
const setPath = async (firstTime) => {
|
|
31
|
+
if (!path)
|
|
32
|
+
path = await rl.question(firstTime ? "Database path: " : "Please type a valid database path: ");
|
|
33
|
+
if (!path || !(await isExists(basename(path))))
|
|
34
|
+
await setPath();
|
|
35
|
+
};
|
|
36
|
+
console.clear();
|
|
37
|
+
await setPath(true);
|
|
38
|
+
const db = new Inibase(basename(path));
|
|
39
|
+
process.stdout.write("\u001b[3J\u001b[2J\u001b[1J");
|
|
22
40
|
console.clear();
|
|
23
41
|
rl.prompt();
|
|
42
|
+
let table;
|
|
24
43
|
rl.on("line", async (input) => {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
const splitedInput = input
|
|
45
|
+
.trim()
|
|
46
|
+
.match(/[^\s"']+|"([^"]*)"|'([^']*)'/g);
|
|
47
|
+
switch (splitedInput[0].toLocaleLowerCase()) {
|
|
48
|
+
case "clear":
|
|
49
|
+
process.stdout.write("\u001b[3J\u001b[2J\u001b[1J");
|
|
50
|
+
console.clear();
|
|
51
|
+
rl.prompt();
|
|
52
|
+
break;
|
|
53
|
+
case "exit":
|
|
54
|
+
return process.exit();
|
|
55
|
+
// biome-ignore format:
|
|
56
|
+
case "help": {
|
|
57
|
+
if (!table)
|
|
58
|
+
console.log(` ${textBlue("table")} | ${textBlue("t")} ${textRed("<")}tableName${textRed(">*")}`);
|
|
59
|
+
console.log(` ${textGreen("config")} | ${textGreen("c")}
|
|
60
|
+
${textMagenta("get")} | ${textMagenta("g")} (compression|cache|prepend)?
|
|
61
|
+
${textMagenta("set")} | ${textMagenta("s")} (compression true|false)? (cache true|false)? (prepend true|false)?
|
|
62
|
+
${textGreen("schema")} | ${textGreen("s")}
|
|
63
|
+
${textMagenta("get")} | ${textMagenta("g")} ${textRed("<")}keyName${textRed(">*")}
|
|
64
|
+
${textMagenta("set")} | ${textMagenta("s")} ${textRed("<")}keyName${textRed(">*")} {{ Inison.stringify(Field) }}
|
|
65
|
+
${textGreen("get")} | ${textGreen("g")}
|
|
66
|
+
${textGreen("delete")} | ${textGreen("d")}
|
|
67
|
+
${textGreen("post")} | ${textGreen("p")}
|
|
68
|
+
${textGreen("put")} | ${textGreen("pu")}
|
|
69
|
+
${textMagenta("--where")} | ${textMagenta("-w")} (ID|Inison.stringify(Criteria)|LineNumber)?
|
|
70
|
+
${textMagenta("--page")} | ${textMagenta("-p")} number?
|
|
71
|
+
${textMagenta("--per-page")} | ${textMagenta("-l")} number?
|
|
72
|
+
${textMagenta("--columns")} | ${textMagenta("-c")} columnName[]?
|
|
73
|
+
${textMagenta("--data")} | ${textMagenta("-d")} Inison.stringify(Data) ${textRed("* POST & PUT")}`);
|
|
74
|
+
break;
|
|
54
75
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
76
|
+
case "c":
|
|
77
|
+
case "config": {
|
|
78
|
+
if (!table) {
|
|
79
|
+
console.log(`${textRed(" Err:")} Please specify table name`);
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
const config = (await db.getTable(table)).config;
|
|
83
|
+
if (!splitedInput[1]) {
|
|
84
|
+
console.log(JSON.stringify(config, undefined, 2));
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
switch (splitedInput[1].toLocaleLowerCase()) {
|
|
88
|
+
case "g":
|
|
89
|
+
case "get": {
|
|
90
|
+
if (!splitedInput[2])
|
|
91
|
+
console.log(JSON.stringify(config, undefined, 2));
|
|
92
|
+
else
|
|
93
|
+
console.log(JSON.stringify(config[splitedInput[2]], undefined, 2));
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
case "s":
|
|
97
|
+
case "set": {
|
|
98
|
+
const newConfigObject = {};
|
|
99
|
+
splitedInput.splice(0, 2);
|
|
100
|
+
for (let index = 0; index < splitedInput.length; index++) {
|
|
101
|
+
const configName = splitedInput[index].toLocaleLowerCase();
|
|
102
|
+
if (["true", "false"].includes(configName))
|
|
103
|
+
continue;
|
|
104
|
+
if (!["compression", "cache", "prepend"].includes(configName)) {
|
|
105
|
+
console.log(`${textRed(" Err:")} '${configName}' is not a valid config`);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
newConfigObject[configName] =
|
|
109
|
+
splitedInput[index + 1].trim() === "true";
|
|
110
|
+
}
|
|
111
|
+
await db.updateTable(table, undefined, newConfigObject);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
default:
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
60
118
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
perPage: Number(perPage) ?? 15,
|
|
66
|
-
columns,
|
|
67
|
-
}));
|
|
119
|
+
case "s":
|
|
120
|
+
case "schema": {
|
|
121
|
+
if (!table) {
|
|
122
|
+
console.log(`${textRed(" Err:")} Please specify table name`);
|
|
68
123
|
break;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
columns,
|
|
74
|
-
}, true));
|
|
124
|
+
}
|
|
125
|
+
const schema = (await db.getTable(table)).schema;
|
|
126
|
+
if (!splitedInput[1] || !splitedInput[2]) {
|
|
127
|
+
console.log(JSON.stringify(schema, undefined, 2));
|
|
75
128
|
break;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
columns,
|
|
81
|
-
}, true));
|
|
129
|
+
}
|
|
130
|
+
const key = splitedInput[2];
|
|
131
|
+
if (!key) {
|
|
132
|
+
console.log(`${textRed(" Err:")} Please specify key name`);
|
|
82
133
|
break;
|
|
83
|
-
|
|
84
|
-
|
|
134
|
+
}
|
|
135
|
+
const field = {};
|
|
136
|
+
field.key = key;
|
|
137
|
+
switch (splitedInput[1].toLocaleLowerCase()) {
|
|
138
|
+
case "p":
|
|
139
|
+
case "push":
|
|
140
|
+
await db.updateTable(table, [...(schema ?? []), field]);
|
|
141
|
+
break;
|
|
142
|
+
case "u":
|
|
143
|
+
case "unset":
|
|
144
|
+
case "s":
|
|
145
|
+
case "set": {
|
|
146
|
+
if (!schema) {
|
|
147
|
+
console.log(`${textRed(" Err:")} Schema is empty, please push first`);
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
if (["set", "s"].includes(splitedInput[1].toLocaleLowerCase())) {
|
|
151
|
+
if (!splitedInput[2]) {
|
|
152
|
+
console.log(`${textRed(" Err:")} Give the field a schema`);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
Object.assign(field, Inison.unstringify(splitedInput[2]));
|
|
157
|
+
setField(key, schema, field);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
console.log(`${textRed(" Err:")} Give the field a valid schema`);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else
|
|
165
|
+
unsetField(key, schema);
|
|
166
|
+
await db.updateTable(table, schema);
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
default:
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
case "t":
|
|
175
|
+
case "table":
|
|
176
|
+
if (!splitedInput[1]) {
|
|
177
|
+
console.log(`${textRed(" Err:")} Please specify table name`);
|
|
85
178
|
break;
|
|
86
|
-
|
|
179
|
+
}
|
|
180
|
+
if (!(await isExists(join(path, splitedInput[1]))))
|
|
181
|
+
console.log(`${textRed(" Err:")} Table doesn't exist`);
|
|
182
|
+
else {
|
|
183
|
+
table = splitedInput[1];
|
|
184
|
+
rl.setPrompt(textBlue(`${table} > `));
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
case "p":
|
|
188
|
+
case "post":
|
|
189
|
+
case "g":
|
|
190
|
+
case "get":
|
|
191
|
+
case "pu":
|
|
192
|
+
case "put":
|
|
193
|
+
case "d":
|
|
194
|
+
case "delete": {
|
|
195
|
+
if (!table) {
|
|
196
|
+
console.log(`${textRed(" Err:")} Please specify table name`);
|
|
87
197
|
break;
|
|
198
|
+
}
|
|
199
|
+
let where = undefined, page = undefined, perPage = undefined, columns = undefined, data = undefined;
|
|
200
|
+
if (splitedInput.toSpliced(0, 1).length) {
|
|
201
|
+
const parsedArgs = parseArgs({
|
|
202
|
+
args: splitedInput.toSpliced(0, table ? 1 : 2),
|
|
203
|
+
options: {
|
|
204
|
+
where: { type: "string", short: "w" },
|
|
205
|
+
page: { type: "string", short: "p" },
|
|
206
|
+
perPage: { type: "string", short: "l" },
|
|
207
|
+
columns: { type: "string", short: "c", multiple: true },
|
|
208
|
+
data: { type: "string", short: "d" },
|
|
209
|
+
},
|
|
210
|
+
}).values;
|
|
211
|
+
if (parsedArgs.where) {
|
|
212
|
+
if (parsedArgs.where === "'-1'" || parsedArgs.where === '"-1"')
|
|
213
|
+
where = -1;
|
|
214
|
+
else if (isNumber(parsedArgs.where))
|
|
215
|
+
where = Number(parsedArgs.where);
|
|
216
|
+
else if (isJSON(parsedArgs.where))
|
|
217
|
+
where = Inison.unstringify(parsedArgs.where);
|
|
218
|
+
}
|
|
219
|
+
page = Number(parsedArgs.page) ?? undefined;
|
|
220
|
+
perPage = Number(parsedArgs.perPage) ?? undefined;
|
|
221
|
+
columns = parsedArgs.columns;
|
|
222
|
+
if (parsedArgs.data && isJSON(parsedArgs.data))
|
|
223
|
+
data = Inison.unstringify(parsedArgs.data);
|
|
224
|
+
}
|
|
225
|
+
switch (splitedInput[0].toLocaleLowerCase()) {
|
|
226
|
+
case "g":
|
|
227
|
+
case "get":
|
|
228
|
+
console.log(await db.get(table, where, {
|
|
229
|
+
page: Number(page) ?? 1,
|
|
230
|
+
perPage: Number(perPage) ?? 15,
|
|
231
|
+
columns,
|
|
232
|
+
}));
|
|
233
|
+
break;
|
|
234
|
+
case "p":
|
|
235
|
+
case "post":
|
|
236
|
+
console.log(await db.post(table, data, {
|
|
237
|
+
page: Number(page) ?? 1,
|
|
238
|
+
perPage: Number(perPage) ?? 15,
|
|
239
|
+
columns,
|
|
240
|
+
}, true));
|
|
241
|
+
break;
|
|
242
|
+
case "pu":
|
|
243
|
+
case "put":
|
|
244
|
+
console.log(await db.put(table, data, where, {
|
|
245
|
+
page: Number(page) ?? 1,
|
|
246
|
+
perPage: Number(perPage) ?? 15,
|
|
247
|
+
columns,
|
|
248
|
+
}, true));
|
|
249
|
+
break;
|
|
250
|
+
case "d":
|
|
251
|
+
case "delete":
|
|
252
|
+
console.log(await db.delete(table, where));
|
|
253
|
+
break;
|
|
254
|
+
default:
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
break;
|
|
88
258
|
}
|
|
259
|
+
default:
|
|
260
|
+
break;
|
|
89
261
|
}
|
|
90
262
|
rl.prompt();
|
|
91
263
|
});
|
package/dist/file.d.ts
CHANGED
|
@@ -61,14 +61,23 @@ export declare function get(filePath: string, lineNumbers: undefined | number |
|
|
|
61
61
|
*/
|
|
62
62
|
export declare const replace: (filePath: string, replacements: string | number | boolean | null | (string | number | boolean | null)[] | Record<number, string | boolean | number | null | (string | boolean | number | null)[]>) => Promise<string[]>;
|
|
63
63
|
/**
|
|
64
|
-
* Asynchronously appends data to the
|
|
64
|
+
* Asynchronously appends data to the end of a file.
|
|
65
65
|
*
|
|
66
66
|
* @param filePath - Path of the file to append to.
|
|
67
67
|
* @param data - Data to append. Can be a string, number, or an array of strings/numbers.
|
|
68
68
|
* @returns Promise<string[]>. Modifies the file by appending data.
|
|
69
69
|
*
|
|
70
70
|
*/
|
|
71
|
-
export declare const append: (filePath: string, data: string | number | (string | number)[]
|
|
71
|
+
export declare const append: (filePath: string, data: string | number | (string | number)[]) => Promise<string[]>;
|
|
72
|
+
/**
|
|
73
|
+
* Asynchronously prepends data to the beginning of a file.
|
|
74
|
+
*
|
|
75
|
+
* @param filePath - Path of the file to append to.
|
|
76
|
+
* @param data - Data to append. Can be a string, number, or an array of strings/numbers.
|
|
77
|
+
* @returns Promise<string[]>. Modifies the file by appending data.
|
|
78
|
+
*
|
|
79
|
+
*/
|
|
80
|
+
export declare const prepend: (filePath: string, data: string | number | (string | number)[]) => Promise<string[]>;
|
|
72
81
|
/**
|
|
73
82
|
* Asynchronously removes specified lines from a file.
|
|
74
83
|
*
|
package/dist/file.js
CHANGED
|
@@ -281,21 +281,42 @@ export const replace = async (filePath, replacements) => {
|
|
|
281
281
|
return [];
|
|
282
282
|
};
|
|
283
283
|
/**
|
|
284
|
-
* Asynchronously appends data to the
|
|
284
|
+
* Asynchronously appends data to the end of a file.
|
|
285
285
|
*
|
|
286
286
|
* @param filePath - Path of the file to append to.
|
|
287
287
|
* @param data - Data to append. Can be a string, number, or an array of strings/numbers.
|
|
288
288
|
* @returns Promise<string[]>. Modifies the file by appending data.
|
|
289
289
|
*
|
|
290
290
|
*/
|
|
291
|
-
export const append = async (filePath, data
|
|
291
|
+
export const append = async (filePath, data) => {
|
|
292
292
|
const fileTempPath = filePath.replace(/([^/]+)\/?$/, ".tmp/$1");
|
|
293
293
|
if (await isExists(filePath)) {
|
|
294
|
-
|
|
295
|
-
|
|
294
|
+
await copyFile(filePath, fileTempPath);
|
|
295
|
+
if (!filePath.endsWith(".gz")) {
|
|
296
296
|
await appendFile(fileTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
|
|
297
297
|
}
|
|
298
298
|
else {
|
|
299
|
+
await exec(`echo $'${(Array.isArray(data) ? data.join("\n") : data)
|
|
300
|
+
.toString()
|
|
301
|
+
.replace(/'/g, "\\'")}' | gzip - >> ${fileTempPath}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
else
|
|
305
|
+
await write(fileTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
|
|
306
|
+
return [fileTempPath, filePath];
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* Asynchronously prepends data to the beginning of a file.
|
|
310
|
+
*
|
|
311
|
+
* @param filePath - Path of the file to append to.
|
|
312
|
+
* @param data - Data to append. Can be a string, number, or an array of strings/numbers.
|
|
313
|
+
* @returns Promise<string[]>. Modifies the file by appending data.
|
|
314
|
+
*
|
|
315
|
+
*/
|
|
316
|
+
export const prepend = async (filePath, data) => {
|
|
317
|
+
const fileTempPath = filePath.replace(/([^/]+)\/?$/, ".tmp/$1");
|
|
318
|
+
if (await isExists(filePath)) {
|
|
319
|
+
if (!filePath.endsWith(".gz")) {
|
|
299
320
|
let fileHandle = null;
|
|
300
321
|
let fileTempHandle = null;
|
|
301
322
|
try {
|
|
@@ -319,6 +340,16 @@ export const append = async (filePath, data, prepend) => {
|
|
|
319
340
|
await fileTempHandle?.close();
|
|
320
341
|
}
|
|
321
342
|
}
|
|
343
|
+
else {
|
|
344
|
+
const fileChildTempPath = filePath.replace(/([^/]+)\/?$/, ".tmp/tmp_$1");
|
|
345
|
+
try {
|
|
346
|
+
await write(fileChildTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
|
|
347
|
+
await exec(`cat ${fileChildTempPath} ${filePath} > ${fileTempPath}`);
|
|
348
|
+
}
|
|
349
|
+
finally {
|
|
350
|
+
await unlink(fileChildTempPath);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
322
353
|
}
|
|
323
354
|
else
|
|
324
355
|
await write(fileTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
|
package/dist/index.d.ts
CHANGED
|
@@ -149,8 +149,7 @@ export default class Inibase {
|
|
|
149
149
|
* Delete item(s) in a table
|
|
150
150
|
*
|
|
151
151
|
* @param {string} tableName
|
|
152
|
-
* @param {(number | string)} [where]
|
|
153
|
-
* @param {(string | string[])} [_id]
|
|
152
|
+
* @param {(number | string | (number | string)[] | Criteria)} [where]
|
|
154
153
|
* @return {*} {(Promise<string | number | (string | number)[] | null>)}
|
|
155
154
|
*/
|
|
156
155
|
delete(tableName: string, where?: number | string, _id?: string | string[]): Promise<string | null>;
|
package/dist/index.js
CHANGED
|
@@ -25,7 +25,7 @@ export default class Inibase {
|
|
|
25
25
|
if (!process.env.INIBASE_SECRET) {
|
|
26
26
|
if (existsSync(".env") &&
|
|
27
27
|
readFileSync(".env").includes("INIBASE_SECRET="))
|
|
28
|
-
this.throwError("NO_ENV");
|
|
28
|
+
throw this.throwError("NO_ENV");
|
|
29
29
|
this.salt = scryptSync(randomBytes(16), randomBytes(16), 32);
|
|
30
30
|
appendFileSync(".env", `\nINIBASE_SECRET=${this.salt.toString("hex")}\n`);
|
|
31
31
|
}
|
|
@@ -91,9 +91,16 @@ export default class Inibase {
|
|
|
91
91
|
async createTable(tableName, schema, config) {
|
|
92
92
|
const tablePath = join(this.databasePath, tableName);
|
|
93
93
|
if (await File.isExists(tablePath))
|
|
94
|
-
this.throwError("TABLE_EXISTS", tableName);
|
|
94
|
+
throw this.throwError("TABLE_EXISTS", tableName);
|
|
95
95
|
await mkdir(join(tablePath, ".tmp"), { recursive: true });
|
|
96
96
|
await mkdir(join(tablePath, ".cache"));
|
|
97
|
+
// if config not set => load default global env config
|
|
98
|
+
if (!config)
|
|
99
|
+
config = {
|
|
100
|
+
compression: process.env.INIBASE_COMPRESSION === "true",
|
|
101
|
+
cache: process.env.INIBASE_CACHE === "true",
|
|
102
|
+
prepend: process.env.INIBASE_PREPEND === "true",
|
|
103
|
+
};
|
|
97
104
|
if (config) {
|
|
98
105
|
if (config.compression)
|
|
99
106
|
await writeFile(join(tablePath, ".compression.config"), "");
|
|
@@ -115,40 +122,52 @@ export default class Inibase {
|
|
|
115
122
|
async updateTable(tableName, schema, config) {
|
|
116
123
|
const table = await this.getTable(tableName), tablePath = join(this.databasePath, tableName);
|
|
117
124
|
if (config) {
|
|
118
|
-
if (config.compression !== undefined
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
125
|
+
if (config.compression !== undefined &&
|
|
126
|
+
config.compression !== table.config.compression) {
|
|
127
|
+
await UtilsServer.execFile("find", [
|
|
128
|
+
tableName,
|
|
129
|
+
"-type",
|
|
130
|
+
"f",
|
|
131
|
+
"-name",
|
|
132
|
+
`*${this.fileExtension}${config.compression ? "" : ".gz"}`,
|
|
133
|
+
"-exec",
|
|
134
|
+
config.compression ? "gzip" : "gunzip",
|
|
135
|
+
"-f",
|
|
136
|
+
"{}",
|
|
137
|
+
"+",
|
|
138
|
+
], { cwd: this.databasePath });
|
|
139
|
+
if (config.compression)
|
|
131
140
|
await writeFile(join(tablePath, ".compression.config"), "");
|
|
132
|
-
|
|
141
|
+
else
|
|
142
|
+
await unlink(join(tablePath, ".compression.config"));
|
|
133
143
|
}
|
|
134
|
-
if (config.cache !== undefined) {
|
|
135
|
-
if (config.cache
|
|
144
|
+
if (config.cache !== undefined && config.cache !== table.config.cache) {
|
|
145
|
+
if (config.cache)
|
|
136
146
|
await writeFile(join(tablePath, ".cache.config"), "");
|
|
137
|
-
else
|
|
147
|
+
else
|
|
138
148
|
await unlink(join(tablePath, ".cache.config"));
|
|
139
149
|
}
|
|
140
|
-
if (config.prepend !== undefined
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
+
if (config.prepend !== undefined &&
|
|
151
|
+
config.prepend !== table.config.prepend) {
|
|
152
|
+
await UtilsServer.execFile("find", [
|
|
153
|
+
tableName,
|
|
154
|
+
"-type",
|
|
155
|
+
"f",
|
|
156
|
+
"-name",
|
|
157
|
+
`*${this.fileExtension}${config.compression ? ".gz" : ""}`,
|
|
158
|
+
"-exec",
|
|
159
|
+
"sh",
|
|
160
|
+
"-c",
|
|
161
|
+
`for file; do ${config.compression
|
|
162
|
+
? 'zcat "$file" | tac | gzip > "$file.reversed" && mv "$file.reversed" "$file"'
|
|
163
|
+
: 'tac "$file" > "$file.reversed" && mv "$file.reversed" "$file"'}; done`,
|
|
164
|
+
"_",
|
|
165
|
+
"{}",
|
|
166
|
+
"+",
|
|
167
|
+
], { cwd: this.databasePath });
|
|
168
|
+
if (config.prepend)
|
|
150
169
|
await writeFile(join(tablePath, ".prepend.config"), "");
|
|
151
|
-
else
|
|
170
|
+
else
|
|
152
171
|
await unlink(join(tablePath, ".prepend.config"));
|
|
153
172
|
}
|
|
154
173
|
}
|
|
@@ -184,7 +203,7 @@ export default class Inibase {
|
|
|
184
203
|
async getTable(tableName) {
|
|
185
204
|
const tablePath = join(this.databasePath, tableName);
|
|
186
205
|
if (!(await File.isExists(tablePath)))
|
|
187
|
-
this.throwError("TABLE_NOT_EXISTS", tableName);
|
|
206
|
+
throw this.throwError("TABLE_NOT_EXISTS", tableName);
|
|
188
207
|
if (!this.tables[tableName])
|
|
189
208
|
this.tables[tableName] = {
|
|
190
209
|
schema: await this.getTableSchema(tableName),
|
|
@@ -961,7 +980,9 @@ export default class Inibase {
|
|
|
961
980
|
? RETURN.toReversed()
|
|
962
981
|
: RETURN
|
|
963
982
|
: RETURN);
|
|
964
|
-
await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(
|
|
983
|
+
await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(this.tables[tableName].config.prepend
|
|
984
|
+
? await File.prepend(path, content)
|
|
985
|
+
: await File.append(path, content))));
|
|
965
986
|
await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
966
987
|
renameList = [];
|
|
967
988
|
totalItems += Array.isArray(RETURN) ? RETURN.length : 1;
|
package/dist/utils.server.d.ts
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
/// <reference types="node" resolution-mode="require"/>
|
|
3
3
|
/// <reference types="node" resolution-mode="require"/>
|
|
4
4
|
import type { ComparisonOperator, FieldType, Schema } from "./index.js";
|
|
5
|
-
import { exec as execAsync } from "node:child_process";
|
|
5
|
+
import { exec as execAsync, execFile as execFileAsync } from "node:child_process";
|
|
6
6
|
import { gunzip as gunzipAsync, gzip as gzipAsync } from "node:zlib";
|
|
7
7
|
export declare const exec: typeof execAsync.__promisify__;
|
|
8
|
+
export declare const execFile: typeof execFileAsync.__promisify__;
|
|
8
9
|
export declare const gzip: typeof gzipAsync.__promisify__;
|
|
9
10
|
export declare const gunzip: typeof gunzipAsync.__promisify__;
|
|
10
11
|
/**
|
package/dist/utils.server.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createCipheriv, createDecipheriv, randomBytes, scryptSync, createHash, } from "node:crypto";
|
|
2
2
|
import { detectFieldType, isArrayOfObjects, isNumber, isPassword, isValidID, } from "./utils.js";
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
|
-
import { exec as execAsync } from "node:child_process";
|
|
4
|
+
import { exec as execAsync, execFile as execFileAsync, } from "node:child_process";
|
|
5
5
|
import { gunzip as gunzipAsync, gzip as gzipAsync } from "node:zlib";
|
|
6
6
|
export const exec = promisify(execAsync);
|
|
7
|
+
export const execFile = promisify(execFileAsync);
|
|
7
8
|
export const gzip = promisify(gzipAsync);
|
|
8
9
|
export const gunzip = promisify(gunzipAsync);
|
|
9
10
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inibase",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.66",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"author": {
|
|
5
6
|
"name": "Karim Amahtil",
|
|
6
7
|
"email": "karim.amahtil@gmail.com"
|
|
@@ -49,7 +50,6 @@
|
|
|
49
50
|
"bin": {
|
|
50
51
|
"inibase": "./dist/cli.js"
|
|
51
52
|
},
|
|
52
|
-
"type": "module",
|
|
53
53
|
"types": "./dist",
|
|
54
54
|
"typesVersions": {
|
|
55
55
|
"*": {
|