inibase 1.2.9 → 1.2.11
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/index.d.ts +1 -0
- package/dist/index.js +75 -62
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -696,19 +696,19 @@ export default class Inibase {
|
|
|
696
696
|
for (const field of schema) {
|
|
697
697
|
// If the field is of simple type (non-recursive), process it directly
|
|
698
698
|
if (this.isSimpleField(field.type)) {
|
|
699
|
-
await this.processSimpleField(tableName, field,
|
|
699
|
+
await this.processSimpleField(tableName, field, RETURN, linesNumber, prefix);
|
|
700
700
|
}
|
|
701
701
|
else if (this.isArrayField(field.type)) {
|
|
702
702
|
// Process array fields (recursive if needed)
|
|
703
|
-
await this.processArrayField(tableName, field,
|
|
703
|
+
await this.processArrayField(tableName, field, RETURN, linesNumber, options, prefix);
|
|
704
704
|
}
|
|
705
705
|
else if (this.isObjectField(field.type)) {
|
|
706
706
|
// Process object fields (recursive if needed)
|
|
707
|
-
await this.processObjectField(tableName, field,
|
|
707
|
+
await this.processObjectField(tableName, field, RETURN, linesNumber, options, prefix);
|
|
708
708
|
}
|
|
709
709
|
else if (this.isTableField(field.type)) {
|
|
710
710
|
// Process table reference fields
|
|
711
|
-
await this.processTableField(tableName, field,
|
|
711
|
+
await this.processTableField(tableName, field, RETURN, linesNumber, options, prefix);
|
|
712
712
|
}
|
|
713
713
|
}
|
|
714
714
|
return RETURN;
|
|
@@ -721,7 +721,7 @@ export default class Inibase {
|
|
|
721
721
|
return !complexTypes.includes(fieldType);
|
|
722
722
|
}
|
|
723
723
|
// Process a simple field (non-recursive)
|
|
724
|
-
async processSimpleField(tableName, field,
|
|
724
|
+
async processSimpleField(tableName, field, RETURN, linesNumber, prefix) {
|
|
725
725
|
const fieldPath = join(this.databasePath, tableName, `${prefix ?? ""}${field.key}${this.getFileExtension(tableName)}`);
|
|
726
726
|
if (await File.isExists(fieldPath)) {
|
|
727
727
|
const items = await File.get(fieldPath, linesNumber, {
|
|
@@ -751,13 +751,13 @@ export default class Inibase {
|
|
|
751
751
|
fieldType === "array");
|
|
752
752
|
}
|
|
753
753
|
// Process array fields (recursive if needed)
|
|
754
|
-
async processArrayField(tableName, field,
|
|
754
|
+
async processArrayField(tableName, field, RETURN, linesNumber, options, prefix) {
|
|
755
755
|
if (Array.isArray(field.children)) {
|
|
756
756
|
if (this.isSimpleField(field.children)) {
|
|
757
|
-
await this.processSimpleField(tableName, field,
|
|
757
|
+
await this.processSimpleField(tableName, field, RETURN, linesNumber, prefix);
|
|
758
758
|
}
|
|
759
759
|
else if (this.isTableField(field.children)) {
|
|
760
|
-
await this.processTableField(tableName, field,
|
|
760
|
+
await this.processTableField(tableName, field, RETURN, linesNumber, options, prefix);
|
|
761
761
|
}
|
|
762
762
|
else {
|
|
763
763
|
let _fieldChildren = field.children;
|
|
@@ -835,10 +835,10 @@ export default class Inibase {
|
|
|
835
835
|
}
|
|
836
836
|
else if (this.isSimpleField(field.children)) {
|
|
837
837
|
// If `children` is FieldType, handle it as an array of simple types (no recursion needed here)
|
|
838
|
-
await this.processSimpleField(tableName, field,
|
|
838
|
+
await this.processSimpleField(tableName, field, RETURN, linesNumber, prefix);
|
|
839
839
|
}
|
|
840
840
|
else if (this.isTableField(field.children)) {
|
|
841
|
-
await this.processTableField(tableName, field,
|
|
841
|
+
await this.processTableField(tableName, field, RETURN, linesNumber, options, prefix);
|
|
842
842
|
}
|
|
843
843
|
}
|
|
844
844
|
// Helper function to check if the field type is object
|
|
@@ -849,7 +849,7 @@ export default class Inibase {
|
|
|
849
849
|
fieldType.includes("object")));
|
|
850
850
|
}
|
|
851
851
|
// Process object fields (recursive if needed)
|
|
852
|
-
async processObjectField(tableName, field,
|
|
852
|
+
async processObjectField(tableName, field, RETURN, linesNumber, options, prefix) {
|
|
853
853
|
if (Array.isArray(field.children)) {
|
|
854
854
|
// If `children` is a Schema (array of Field objects), recurse
|
|
855
855
|
const items = await this.processSchemaData(tableName, field.children, linesNumber, options, `${prefix ?? ""}${field.key}.`);
|
|
@@ -873,7 +873,7 @@ export default class Inibase {
|
|
|
873
873
|
fieldType.includes("table")));
|
|
874
874
|
}
|
|
875
875
|
// Process table reference fields
|
|
876
|
-
async processTableField(tableName, field,
|
|
876
|
+
async processTableField(tableName, field, RETURN, linesNumber, options, prefix) {
|
|
877
877
|
if (field.table &&
|
|
878
878
|
(await File.isExists(join(this.databasePath, field.table)))) {
|
|
879
879
|
const fieldPath = join(this.databasePath, tableName, `${prefix ?? ""}${field.key}${this.getFileExtension(tableName)}`);
|
|
@@ -899,7 +899,7 @@ export default class Inibase {
|
|
|
899
899
|
.flat()
|
|
900
900
|
.filter((item) => item), {
|
|
901
901
|
...options,
|
|
902
|
-
perPage:
|
|
902
|
+
perPage: -1,
|
|
903
903
|
columns: options.columns
|
|
904
904
|
?.filter((column) => column.includes(`${field.key}.`))
|
|
905
905
|
.map((column) => column.replace(`${field.key}.`, "")),
|
|
@@ -927,47 +927,49 @@ export default class Inibase {
|
|
|
927
927
|
}
|
|
928
928
|
}
|
|
929
929
|
}
|
|
930
|
+
_setNestedKey(obj, path, value) {
|
|
931
|
+
const keys = path.split(".");
|
|
932
|
+
const lastKey = keys.pop();
|
|
933
|
+
const target = keys.reduce((acc, key) => {
|
|
934
|
+
if (typeof acc[key] !== "object" || acc[key] === null) {
|
|
935
|
+
acc[key] = {};
|
|
936
|
+
}
|
|
937
|
+
return acc[key];
|
|
938
|
+
}, obj);
|
|
939
|
+
target[lastKey] = value;
|
|
940
|
+
}
|
|
930
941
|
async applyCriteria(tableName, options, criteria, allTrue, searchIn) {
|
|
931
942
|
const tablePath = join(this.databasePath, tableName);
|
|
932
|
-
|
|
933
|
-
const RETURN = {};
|
|
934
|
-
/* ---------- fast exit ---------- */
|
|
943
|
+
let RETURN = {};
|
|
935
944
|
if (!criteria || Object.keys(criteria).length === 0)
|
|
936
945
|
return null;
|
|
937
|
-
/* ---------- split top-level logical groups ---------- */
|
|
938
946
|
const criteriaAND = criteria.and;
|
|
939
|
-
const criteriaOR = criteria.or;
|
|
940
947
|
if (criteriaAND)
|
|
941
948
|
delete criteria.and;
|
|
949
|
+
const criteriaOR = criteria.or;
|
|
942
950
|
if (criteriaOR)
|
|
943
951
|
delete criteria.or;
|
|
944
|
-
/** cache table schema once – Utils.getField() is cheap but we call it a lot */
|
|
945
952
|
const schema = globalConfig[this.databasePath].tables.get(tableName).schema;
|
|
946
|
-
/* ---------- MAIN LOOP (top-level criteria only) ---------- */
|
|
947
953
|
if (Object.keys(criteria).length) {
|
|
948
954
|
if (allTrue === undefined)
|
|
949
955
|
allTrue = true;
|
|
950
|
-
for (
|
|
951
|
-
/* bail early if no candidates left for an “AND” chain */
|
|
952
|
-
if (allTrue && searchIn && searchIn.size === 0)
|
|
953
|
-
return null;
|
|
956
|
+
for await (let [key, value] of Object.entries(criteria)) {
|
|
954
957
|
const field = Utils.getField(key, schema);
|
|
955
958
|
if (!field)
|
|
956
959
|
continue;
|
|
957
|
-
let value = rawValue;
|
|
958
|
-
/* ----- resolve relational sub-queries ----- */
|
|
959
960
|
if (field.table && Utils.isObject(value)) {
|
|
960
|
-
const
|
|
961
|
+
const items = await this.get(field.table, value, {
|
|
961
962
|
columns: "id",
|
|
963
|
+
perPage: -1,
|
|
962
964
|
});
|
|
963
|
-
|
|
964
|
-
|
|
965
|
+
if (items?.length)
|
|
966
|
+
value = `[]${items.map(({ id }) => id)}`;
|
|
967
|
+
else if (allTrue)
|
|
965
968
|
return null;
|
|
966
969
|
}
|
|
967
|
-
|
|
968
|
-
let
|
|
969
|
-
let
|
|
970
|
-
let searchLogicalOperator;
|
|
970
|
+
let searchOperator = undefined;
|
|
971
|
+
let searchComparedAtValue = undefined;
|
|
972
|
+
let searchLogicalOperator = undefined;
|
|
971
973
|
if (Utils.isObject(value)) {
|
|
972
974
|
/* nested object with .and / .or inside */
|
|
973
975
|
const nestedAnd = value.and;
|
|
@@ -985,6 +987,7 @@ export default class Inibase {
|
|
|
985
987
|
searchComparedAtValue = crit.map((c) => c[1]);
|
|
986
988
|
searchLogicalOperator = logic;
|
|
987
989
|
}
|
|
990
|
+
delete value[logic];
|
|
988
991
|
}
|
|
989
992
|
}
|
|
990
993
|
else if (Array.isArray(value)) {
|
|
@@ -1006,45 +1009,53 @@ export default class Inibase {
|
|
|
1006
1009
|
searchOperator = "=";
|
|
1007
1010
|
searchComparedAtValue = value;
|
|
1008
1011
|
}
|
|
1009
|
-
|
|
1010
|
-
const [hitRows, totalLines, lineSet] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), searchOperator ?? "=", searchComparedAtValue ?? null, searchLogicalOperator, searchIn, {
|
|
1012
|
+
const [searchResult, totalLines, linesNumbers] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), searchOperator ?? "=", searchComparedAtValue, searchLogicalOperator, searchIn, {
|
|
1011
1013
|
...field,
|
|
1012
1014
|
databasePath: this.databasePath,
|
|
1013
1015
|
table: field.table ?? tableName,
|
|
1014
|
-
}, options.perPage
|
|
1015
|
-
|
|
1016
|
-
|
|
1016
|
+
}, options.perPage < 0 ? undefined : options.perPage, options.perPage < 0
|
|
1017
|
+
? undefined
|
|
1018
|
+
: (options.page - 1) * options.perPage +
|
|
1019
|
+
(options.page > 1 ? 1 : 0), true);
|
|
1020
|
+
if (!searchResult) {
|
|
1017
1021
|
if (allTrue)
|
|
1018
|
-
return null;
|
|
1019
|
-
continue;
|
|
1020
|
-
}
|
|
1021
|
-
/* ---------- map rows into RETURN without deep-merge ---------- */
|
|
1022
|
-
for (const [lnStr, val] of Object.entries(hitRows)) {
|
|
1023
|
-
const ln = +lnStr;
|
|
1024
|
-
const row = (RETURN[ln] ??= {});
|
|
1025
|
-
row[key] = val;
|
|
1022
|
+
return null;
|
|
1023
|
+
continue;
|
|
1026
1024
|
}
|
|
1025
|
+
const formatedSearchResult = Object.fromEntries(Object.entries(searchResult).map(([id, value]) => {
|
|
1026
|
+
const nestedObj = {};
|
|
1027
|
+
this._setNestedKey(nestedObj, key, value);
|
|
1028
|
+
return [id, nestedObj];
|
|
1029
|
+
}));
|
|
1030
|
+
RETURN = allTrue
|
|
1031
|
+
? formatedSearchResult
|
|
1032
|
+
: Utils.deepMerge(RETURN, formatedSearchResult);
|
|
1027
1033
|
this.totalItems.set(`${tableName}-${key}`, totalLines);
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
searchIn = lineSet;
|
|
1034
|
+
if (linesNumbers?.size && allTrue)
|
|
1035
|
+
searchIn = linesNumbers;
|
|
1031
1036
|
}
|
|
1032
1037
|
}
|
|
1033
|
-
/* ---------- process nested .and / .or recursively (unchanged) ---------- */
|
|
1034
1038
|
if (criteriaAND && Utils.isObject(criteriaAND)) {
|
|
1035
|
-
const
|
|
1036
|
-
if (
|
|
1039
|
+
const searchResult = await this.applyCriteria(tableName, options, criteriaAND, true, searchIn);
|
|
1040
|
+
if (searchResult)
|
|
1041
|
+
RETURN = Utils.deepMerge(RETURN, Object.fromEntries(Object.entries(searchResult).filter(([_k, v], _i) => Object.keys(v).filter((key) => Object.keys(criteriaAND).includes(key)).length)));
|
|
1042
|
+
else
|
|
1037
1043
|
return null;
|
|
1038
|
-
for (const [lnStr, data] of Object.entries(res))
|
|
1039
|
-
(RETURN[+lnStr] ??= {}), Object.assign(RETURN[+lnStr], data);
|
|
1040
1044
|
}
|
|
1041
1045
|
if (criteriaOR && Utils.isObject(criteriaOR)) {
|
|
1042
|
-
const
|
|
1043
|
-
if (
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
+
const searchResult = await this.applyCriteria(tableName, options, criteriaOR, false, searchIn);
|
|
1047
|
+
if (searchResult) {
|
|
1048
|
+
RETURN = Utils.deepMerge(RETURN, searchResult);
|
|
1049
|
+
if (!Object.keys(RETURN).length)
|
|
1050
|
+
RETURN = {};
|
|
1051
|
+
RETURN = Object.fromEntries(Object.entries(RETURN).filter(([_index, item]) => Object.keys(item).filter((key) => Object.keys(criteriaOR).includes(key) ||
|
|
1052
|
+
Object.keys(criteriaOR).some((criteriaKey) => criteriaKey.startsWith(`${key}.`))).length));
|
|
1053
|
+
if (!Object.keys(RETURN).length)
|
|
1054
|
+
RETURN = {};
|
|
1055
|
+
}
|
|
1056
|
+
else
|
|
1057
|
+
RETURN = {};
|
|
1046
1058
|
}
|
|
1047
|
-
/* ---------- final answer ---------- */
|
|
1048
1059
|
return Object.keys(RETURN).length ? RETURN : null;
|
|
1049
1060
|
}
|
|
1050
1061
|
_filterSchemaByColumns(schema, columns) {
|
|
@@ -1214,9 +1225,11 @@ export default class Inibase {
|
|
|
1214
1225
|
}
|
|
1215
1226
|
if (!where) {
|
|
1216
1227
|
// Display all data
|
|
1217
|
-
RETURN = Object.values(await this.processSchemaData(tableName, schema,
|
|
1218
|
-
|
|
1219
|
-
1)
|
|
1228
|
+
RETURN = Object.values(await this.processSchemaData(tableName, schema, options.perPage < 0
|
|
1229
|
+
? undefined
|
|
1230
|
+
: Array.from({ length: options.perPage }, (_, index) => (options.page - 1) * options.perPage +
|
|
1231
|
+
index +
|
|
1232
|
+
1), options));
|
|
1220
1233
|
if (!this.totalItems.has(`${tableName}-*`))
|
|
1221
1234
|
this.totalItems.set(`${tableName}-*`, pagination[1]);
|
|
1222
1235
|
}
|