inibase 1.0.0-rc.77 → 1.0.0-rc.78
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/dist/cli.js +6 -5
- package/dist/file.d.ts +1 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.js +33 -23
- package/dist/utils.server.d.ts +0 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "dotenv/config";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
|
-
import {
|
|
4
|
+
import { join } from "node:path";
|
|
5
5
|
import { createInterface } from "node:readline/promises";
|
|
6
6
|
import { parseArgs } from "node:util";
|
|
7
7
|
import Inison from "inison";
|
|
@@ -12,10 +12,11 @@ const textGreen = (input) => `\u001b[1;32m${input}\u001b[0m`;
|
|
|
12
12
|
const textRed = (input) => `\u001b[1;31m${input}\u001b[0m`;
|
|
13
13
|
const textBlue = (input) => `\u001b[1;34m${input}\u001b[0m`;
|
|
14
14
|
const textMagenta = (input) => `\u001b[1;35m${input}\u001b[0m`;
|
|
15
|
-
let { path, version } = parseArgs({
|
|
15
|
+
let { path, version, table } = parseArgs({
|
|
16
16
|
options: {
|
|
17
17
|
path: { type: "string", short: "p" },
|
|
18
18
|
version: { type: "boolean", short: "v" },
|
|
19
|
+
table: { type: "string", short: "t" },
|
|
19
20
|
},
|
|
20
21
|
}).values;
|
|
21
22
|
if (version) {
|
|
@@ -30,16 +31,15 @@ const rl = createInterface({
|
|
|
30
31
|
const setPath = async (firstTime) => {
|
|
31
32
|
if (!path)
|
|
32
33
|
path = await rl.question(firstTime ? "Database path: " : "Please type a valid database path: ");
|
|
33
|
-
if (!path || !(await isExists(
|
|
34
|
+
if (!path || !(await isExists(path)))
|
|
34
35
|
await setPath();
|
|
35
36
|
};
|
|
36
37
|
console.clear();
|
|
37
38
|
await setPath(true);
|
|
38
|
-
const db = new Inibase(
|
|
39
|
+
const db = new Inibase(path);
|
|
39
40
|
process.stdout.write("\u001b[3J\u001b[2J\u001b[1J");
|
|
40
41
|
console.clear();
|
|
41
42
|
rl.prompt();
|
|
42
|
-
let table;
|
|
43
43
|
rl.on("line", async (input) => {
|
|
44
44
|
const splitedInput = input
|
|
45
45
|
.trim()
|
|
@@ -70,6 +70,7 @@ rl.on("line", async (input) => {
|
|
|
70
70
|
${textMagenta("--page")} | ${textMagenta("-p")} number?
|
|
71
71
|
${textMagenta("--per-page")} | ${textMagenta("-l")} number?
|
|
72
72
|
${textMagenta("--columns")} | ${textMagenta("-c")} columnName[]?
|
|
73
|
+
${textMagenta("--sort")} | ${textMagenta("-s")} (string|string[]|Inison.stringify(sortObject))?
|
|
73
74
|
${textMagenta("--data")} | ${textMagenta("-d")} Inison.stringify(Data) ${textRed("* POST & PUT")}`);
|
|
74
75
|
break;
|
|
75
76
|
}
|
package/dist/file.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import type { ComparisonOperator, FieldType, Schema } from "./index.js";
|
|
3
2
|
export declare const lock: (folderPath: string, prefix?: string) => Promise<void>;
|
|
4
3
|
export declare const unlock: (folderPath: string, prefix?: string) => Promise<void>;
|
|
@@ -107,11 +106,7 @@ export declare const remove: (filePath: string, linesToDelete: number | number[]
|
|
|
107
106
|
*
|
|
108
107
|
* Note: Decodes each line for comparison and can handle complex queries with multiple conditions.
|
|
109
108
|
*/
|
|
110
|
-
export declare const search: (filePath: string, operator: ComparisonOperator | ComparisonOperator[], comparedAtValue: string | number | boolean | null | (string | number | boolean | null)[], logicalOperator?: "and" | "or", fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[] | Schema, limit?: number, offset?: number, readWholeFile?: boolean, secretKey?: string | Buffer) => Promise<[
|
|
111
|
-
Record<number, string | number | boolean | null | (string | number | boolean | null)[]> | null,
|
|
112
|
-
number,
|
|
113
|
-
Set<number> | null
|
|
114
|
-
]>;
|
|
109
|
+
export declare const search: (filePath: string, operator: ComparisonOperator | ComparisonOperator[], comparedAtValue: string | number | boolean | null | (string | number | boolean | null)[], logicalOperator?: "and" | "or", fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[] | Schema, limit?: number, offset?: number, readWholeFile?: boolean, secretKey?: string | Buffer) => Promise<[Record<number, string | number | boolean | null | (string | number | boolean | null)[]> | null, number, Set<number> | null]>;
|
|
115
110
|
/**
|
|
116
111
|
* Asynchronously counts the number of lines in a file.
|
|
117
112
|
*
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -822,7 +822,7 @@ export default class Inibase {
|
|
|
822
822
|
(Utils.isObject(where) && !Object.keys(where).length)))
|
|
823
823
|
where = undefined;
|
|
824
824
|
if (options.sort) {
|
|
825
|
-
let sortArray,
|
|
825
|
+
let sortArray, awkCommand = "";
|
|
826
826
|
if (Utils.isObject(options.sort) && !Array.isArray(options.sort)) {
|
|
827
827
|
// {name: "ASC", age: "DESC"}
|
|
828
828
|
sortArray = Object.entries(options.sort).map(([key, value]) => [
|
|
@@ -840,16 +840,17 @@ export default class Inibase {
|
|
|
840
840
|
cacheKey = UtilsServer.hashString(inspect(sortArray, { sorted: true }));
|
|
841
841
|
if (where) {
|
|
842
842
|
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
843
|
-
|
|
844
|
-
isLineNumbers = false;
|
|
845
|
-
if (!keepItems.length)
|
|
843
|
+
if (!lineNumbers.length)
|
|
846
844
|
throw this.throwError("NO_RESULTS", tableName);
|
|
847
|
-
|
|
845
|
+
const itemsIDs = Object.values((await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), lineNumbers, "number", undefined, this.salt)) ?? {}).map(Number);
|
|
846
|
+
awkCommand = `awk '${itemsIDs.map((id) => `$1 == ${id}`).join(" || ")}'`;
|
|
848
847
|
}
|
|
849
|
-
|
|
850
|
-
|
|
848
|
+
else
|
|
849
|
+
awkCommand = `awk '${Array.from({ length: options.perPage }, (_, index) => (options.page - 1) * options.perPage +
|
|
851
850
|
index +
|
|
852
|
-
1)
|
|
851
|
+
1)
|
|
852
|
+
.map((lineNumber) => `NR==${lineNumber}`)
|
|
853
|
+
.join(" || ")}'`;
|
|
853
854
|
const filesPathes = [["id", true], ...sortArray].map((column) => join(tablePath, `${column[0]}${this.getFileExtension(tableName)}`));
|
|
854
855
|
for await (const path of filesPathes.slice(1))
|
|
855
856
|
if (!(await File.isExists(path)))
|
|
@@ -869,15 +870,11 @@ export default class Inibase {
|
|
|
869
870
|
})
|
|
870
871
|
.join(" ");
|
|
871
872
|
const sortCommand = `sort ${sortColumns} -T=${join(tablePath, ".tmp")}`;
|
|
872
|
-
// Construct the awk command to keep only the specified lines after sorting
|
|
873
|
-
const awkCommand = isLineNumbers
|
|
874
|
-
? `awk '${keepItems.map((lineNumber) => `NR==${lineNumber}`).join(" || ")}'`
|
|
875
|
-
: `awk '${keepItems.map((id) => `$1 ~ /^${id} */`).join(" || ")}'`;
|
|
876
873
|
try {
|
|
877
874
|
if (cacheKey)
|
|
878
875
|
await File.lock(join(tablePath, ".tmp"), cacheKey);
|
|
879
876
|
// Combine && Execute the commands synchronously
|
|
880
|
-
|
|
877
|
+
let lines = (await UtilsServer.exec(this.tables[tableName].config.cache
|
|
881
878
|
? (await File.isExists(join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)))
|
|
882
879
|
? `${awkCommand} ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}`
|
|
883
880
|
: `${pasteCommand} | ${sortCommand} -o ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)} && ${awkCommand} ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}`
|
|
@@ -886,6 +883,12 @@ export default class Inibase {
|
|
|
886
883
|
})).stdout
|
|
887
884
|
.trim()
|
|
888
885
|
.split("\n");
|
|
886
|
+
if (where)
|
|
887
|
+
lines = lines.slice((options.page - 1) * options.perPage, options.page * options.perPage);
|
|
888
|
+
else if (!this.totalItems[`${tableName}-*`])
|
|
889
|
+
this.totalItems[`${tableName}-*`] = await File.count(join(tablePath, `id${this.getFileExtension(tableName)}`));
|
|
890
|
+
if (!lines.length)
|
|
891
|
+
return null;
|
|
889
892
|
// Parse the result and extract the specified lines
|
|
890
893
|
const outputArray = lines.map((line) => {
|
|
891
894
|
const splitedFileColumns = line.split("\t"); // Assuming tab-separated columns
|
|
@@ -916,11 +919,14 @@ export default class Inibase {
|
|
|
916
919
|
RETURN = Object.values(await this.getItemsFromSchema(tableName, schema, Array.from({ length: options.perPage }, (_, index) => (options.page - 1) * options.perPage +
|
|
917
920
|
index +
|
|
918
921
|
1), options));
|
|
919
|
-
if (await File.isExists(join(tablePath, ".cache", ".pagination")))
|
|
920
|
-
this.totalItems[`${tableName}-*`]
|
|
922
|
+
if (await File.isExists(join(tablePath, ".cache", ".pagination"))) {
|
|
923
|
+
if (!this.totalItems[`${tableName}-*`])
|
|
924
|
+
this.totalItems[`${tableName}-*`] = Number((await readFile(join(tablePath, ".cache", ".pagination"), "utf8")).split(",")[1]);
|
|
925
|
+
}
|
|
921
926
|
else {
|
|
922
927
|
const lastId = Number(Object.keys((await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), -1, "number", undefined, this.salt, true))?.[0] ?? 0));
|
|
923
|
-
this.totalItems[`${tableName}-*`]
|
|
928
|
+
if (!this.totalItems[`${tableName}-*`])
|
|
929
|
+
this.totalItems[`${tableName}-*`] = await File.count(join(tablePath, `id${this.getFileExtension(tableName)}`));
|
|
924
930
|
await writeFile(join(tablePath, ".cache", ".pagination"), `${lastId},${this.totalItems[`${tableName}-*`]}`);
|
|
925
931
|
}
|
|
926
932
|
}
|
|
@@ -930,12 +936,12 @@ export default class Inibase {
|
|
|
930
936
|
let lineNumbers = where;
|
|
931
937
|
if (!Array.isArray(lineNumbers))
|
|
932
938
|
lineNumbers = [lineNumbers];
|
|
939
|
+
if (!this.totalItems[`${tableName}-*`])
|
|
940
|
+
this.totalItems[`${tableName}-*`] = lineNumbers.length;
|
|
933
941
|
// useless
|
|
934
942
|
if (onlyLinesNumbers)
|
|
935
943
|
return lineNumbers;
|
|
936
944
|
RETURN = Object.values((await this.getItemsFromSchema(tableName, schema, lineNumbers, options)) ?? {});
|
|
937
|
-
if (!this.totalItems[`${tableName}-*`])
|
|
938
|
-
this.totalItems[`${tableName}-*`] = lineNumbers.length;
|
|
939
945
|
if (RETURN?.length && !Array.isArray(where))
|
|
940
946
|
RETURN = RETURN[0];
|
|
941
947
|
}
|
|
@@ -947,6 +953,8 @@ export default class Inibase {
|
|
|
947
953
|
const [lineNumbers, countItems] = await File.search(join(tablePath, `id${this.getFileExtension(tableName)}`), "[]", Ids.map((id) => Utils.isNumber(id) ? Number(id) : UtilsServer.decodeID(id, this.salt)), undefined, "number", undefined, Ids.length, 0, !this.totalItems[`${tableName}-*`], this.salt);
|
|
948
954
|
if (!lineNumbers)
|
|
949
955
|
throw this.throwError("NO_RESULTS", tableName);
|
|
956
|
+
if (!this.totalItems[`${tableName}-*`])
|
|
957
|
+
this.totalItems[`${tableName}-*`] = countItems;
|
|
950
958
|
if (onlyLinesNumbers)
|
|
951
959
|
return Object.keys(lineNumbers).length
|
|
952
960
|
? Object.keys(lineNumbers).map(Number)
|
|
@@ -957,8 +965,6 @@ export default class Inibase {
|
|
|
957
965
|
options.columns = undefined;
|
|
958
966
|
}
|
|
959
967
|
RETURN = Object.values((await this.getItemsFromSchema(tableName, schema, Object.keys(lineNumbers).map(Number), options)) ?? {});
|
|
960
|
-
if (!this.totalItems[`${tableName}-*`])
|
|
961
|
-
this.totalItems[`${tableName}-*`] = countItems;
|
|
962
968
|
if (RETURN?.length && !Array.isArray(where))
|
|
963
969
|
RETURN = RETURN[0];
|
|
964
970
|
}
|
|
@@ -970,7 +976,8 @@ export default class Inibase {
|
|
|
970
976
|
if (this.tables[tableName].config.cache &&
|
|
971
977
|
(await File.isExists(cachedFilePath))) {
|
|
972
978
|
const cachedItems = (await readFile(cachedFilePath, "utf8")).split(",");
|
|
973
|
-
this.totalItems[`${tableName}-*`]
|
|
979
|
+
if (!this.totalItems[`${tableName}-*`])
|
|
980
|
+
this.totalItems[`${tableName}-*`] = cachedItems.length;
|
|
974
981
|
if (onlyLinesNumbers)
|
|
975
982
|
return cachedItems.map(Number);
|
|
976
983
|
return this.get(tableName, cachedItems
|
|
@@ -980,8 +987,10 @@ export default class Inibase {
|
|
|
980
987
|
let linesNumbers = null;
|
|
981
988
|
[RETURN, linesNumbers] = await this.applyCriteria(tableName, schema, options, where);
|
|
982
989
|
if (RETURN && linesNumbers) {
|
|
990
|
+
if (!this.totalItems[`${tableName}-*`])
|
|
991
|
+
this.totalItems[`${tableName}-*`] = linesNumbers.size;
|
|
983
992
|
if (onlyLinesNumbers)
|
|
984
|
-
return
|
|
993
|
+
return Array.from(linesNumbers);
|
|
985
994
|
const alreadyExistsColumns = Object.keys(Object.values(RETURN)[0]), alreadyExistsColumnsIDs = Utils.flattenSchema(schema)
|
|
986
995
|
.filter(({ key }) => alreadyExistsColumns.includes(key))
|
|
987
996
|
.map(({ id }) => id);
|
|
@@ -1030,7 +1039,8 @@ export default class Inibase {
|
|
|
1030
1039
|
.map(Number);
|
|
1031
1040
|
else {
|
|
1032
1041
|
lastId = Number(Object.keys((await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), -1, "number", undefined, this.salt, true))?.[0] ?? 0));
|
|
1033
|
-
this.totalItems[`${tableName}-*`]
|
|
1042
|
+
if (!this.totalItems[`${tableName}-*`])
|
|
1043
|
+
this.totalItems[`${tableName}-*`] = await File.count(join(tablePath, `id${this.getFileExtension(tableName)}`));
|
|
1034
1044
|
}
|
|
1035
1045
|
}
|
|
1036
1046
|
else
|
package/dist/utils.server.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
3
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
4
1
|
import { exec as execAsync, execFile as execFileAsync } from "node:child_process";
|
|
5
2
|
import { gunzip as gunzipAsync, gzip as gzipAsync } from "node:zlib";
|
|
6
3
|
import type { ComparisonOperator, Field, FieldType, Schema } from "./index.js";
|