inibase 1.1.21 → 1.1.23

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.js CHANGED
@@ -10,13 +10,12 @@ import * as Utils from "./utils.js";
10
10
  import * as UtilsServer from "./utils.server.js";
11
11
  // hide ExperimentalWarning glob()
12
12
  process.removeAllListeners("warning");
13
+ export const globalConfig = {};
13
14
  export default class Inibase {
14
15
  pageInfo;
15
16
  language;
16
- salt;
17
- databasePath;
18
17
  fileExtension = ".txt";
19
- tablesMap;
18
+ databasePath;
20
19
  uniqueMap;
21
20
  totalItems;
22
21
  constructor(database, mainFolder = ".", language = "en") {
@@ -27,11 +26,11 @@ export default class Inibase {
27
26
  if (existsSync(".env") &&
28
27
  readFileSync(".env").includes("INIBASE_SECRET="))
29
28
  throw this.createError("NO_ENV");
30
- this.salt = scryptSync(randomBytes(16), randomBytes(16), 32);
31
- appendFileSync(".env", `\nINIBASE_SECRET=${this.salt.toString("hex")}\n`);
29
+ globalConfig.salt = scryptSync(randomBytes(16), randomBytes(16), 32);
30
+ appendFileSync(".env", `\nINIBASE_SECRET=${globalConfig.salt.toString("hex")}\n`);
32
31
  }
33
32
  else
34
- this.salt = Buffer.from(process.env.INIBASE_SECRET, "hex");
33
+ globalConfig.salt = Buffer.from(process.env.INIBASE_SECRET, "hex");
35
34
  }
36
35
  static errorMessages = {
37
36
  en: {
@@ -112,7 +111,7 @@ export default class Inibase {
112
111
  return error;
113
112
  }
114
113
  clear() {
115
- this.tablesMap = new Map();
114
+ globalConfig[this.databasePath] = { tables: new Map() };
116
115
  this.totalItems = new Map();
117
116
  this.pageInfo = {};
118
117
  this.uniqueMap = new Map();
@@ -120,9 +119,9 @@ export default class Inibase {
120
119
  getFileExtension(tableName) {
121
120
  let mainExtension = this.fileExtension;
122
121
  // TODO: ADD ENCRYPTION
123
- // if(this.tablesMap.get(tableName).config.encryption)
122
+ // if(globalConfig[this.databasePath].tables.get(tableName).config.encryption)
124
123
  // mainExtension += ".enc"
125
- if (this.tablesMap.get(tableName).config.compression)
124
+ if (globalConfig[this.databasePath].tables.get(tableName).config.compression)
126
125
  mainExtension += ".gz";
127
126
  return mainExtension;
128
127
  }
@@ -134,9 +133,7 @@ export default class Inibase {
134
133
  Utils.isArrayOfObjects(field.children))
135
134
  Utils.deepMerge(RETURN, this._schemaToIdsPath(tableName, field.children, `${(prefix ?? "") + field.key}.`));
136
135
  else if (field.id)
137
- RETURN[Utils.isValidID(field.id)
138
- ? UtilsServer.decodeID(field.id, this.salt)
139
- : field.id] = `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`;
136
+ RETURN[Utils.isValidID(field.id) ? UtilsServer.decodeID(field.id) : field.id] = `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`;
140
137
  return RETURN;
141
138
  }
142
139
  /**
@@ -170,7 +167,7 @@ export default class Inibase {
170
167
  }
171
168
  if (schema) {
172
169
  const lastSchemaID = { value: 0 };
173
- await writeFile(join(tablePath, "schema.json"), JSON.stringify(UtilsServer.addIdToSchema(schema, lastSchemaID, this.salt), null, 2));
170
+ await writeFile(join(tablePath, "schema.json"), JSON.stringify(UtilsServer.addIdToSchema(schema, lastSchemaID), null, 2));
174
171
  await writeFile(join(tablePath, `${lastSchemaID.value}.schema`), "");
175
172
  }
176
173
  else
@@ -206,7 +203,7 @@ export default class Inibase {
206
203
  };
207
204
  if (await File.isExists(join(tablePath, "schema.json"))) {
208
205
  // update columns files names based on field id
209
- schema = UtilsServer.addIdToSchema(schema, lastSchemaID, this.salt);
206
+ schema = UtilsServer.addIdToSchema(schema, lastSchemaID);
210
207
  if (table.schema?.length) {
211
208
  const replaceOldPathes = Utils.findChangedProperties(this._schemaToIdsPath(tableName, table.schema), this._schemaToIdsPath(tableName, schema));
212
209
  if (replaceOldPathes)
@@ -217,7 +214,7 @@ export default class Inibase {
217
214
  }
218
215
  }
219
216
  else
220
- schema = UtilsServer.addIdToSchema(schema, lastSchemaID, this.salt);
217
+ schema = UtilsServer.addIdToSchema(schema, lastSchemaID);
221
218
  await writeFile(join(tablePath, "schema.json"), JSON.stringify(schema, null, 2));
222
219
  if (schemaIdFilePath)
223
220
  await rename(schemaIdFilePath, join(tablePath, `${lastSchemaID.value}.schema`));
@@ -291,7 +288,7 @@ export default class Inibase {
291
288
  await this.replaceStringInFile(schemaPath, `"table": "${tableName}"`, `"table": "${config.name}"`);
292
289
  }
293
290
  }
294
- this.tablesMap.delete(tableName);
291
+ globalConfig[this.databasePath].tables.delete(tableName);
295
292
  }
296
293
  /**
297
294
  * Get table schema and config
@@ -303,8 +300,8 @@ export default class Inibase {
303
300
  const tablePath = join(this.databasePath, tableName);
304
301
  if (!(await File.isExists(tablePath)))
305
302
  throw this.createError("TABLE_NOT_EXISTS", tableName);
306
- if (!this.tablesMap.has(tableName))
307
- this.tablesMap.set(tableName, {
303
+ if (!globalConfig[this.databasePath].tables.has(tableName))
304
+ globalConfig[this.databasePath].tables.set(tableName, {
308
305
  schema: await this.getTableSchema(tableName, encodeIDs),
309
306
  config: {
310
307
  compression: await File.isExists(join(tablePath, ".compression.config")),
@@ -313,7 +310,7 @@ export default class Inibase {
313
310
  decodeID: await File.isExists(join(tablePath, ".decodeID.config")),
314
311
  },
315
312
  });
316
- return this.tablesMap.get(tableName);
313
+ return globalConfig[this.databasePath].tables.get(tableName);
317
314
  }
318
315
  async getTableSchema(tableName, encodeIDs = true) {
319
316
  const tablePath = join(this.databasePath, tableName);
@@ -345,7 +342,7 @@ export default class Inibase {
345
342
  ];
346
343
  if (!encodeIDs)
347
344
  return schema;
348
- return UtilsServer.encodeSchemaID(schema, this.salt);
345
+ return UtilsServer.encodeSchemaID(schema);
349
346
  }
350
347
  async throwErrorIfTableEmpty(tableName) {
351
348
  const table = await this.getTable(tableName, false);
@@ -370,11 +367,7 @@ export default class Inibase {
370
367
  throw this.createError("FIELD_REQUIRED", field.key);
371
368
  continue;
372
369
  }
373
- if (!Utils.validateFieldType(data[field.key], field.type, (field.type === "array" || field.type === "object") &&
374
- field.children &&
375
- !Utils.isArrayOfObjects(field.children)
376
- ? field.children
377
- : undefined))
370
+ if (!Utils.validateFieldType(data[field.key], field))
378
371
  throw this.createError("INVALID_TYPE", [
379
372
  field.key,
380
373
  (Array.isArray(field.type) ? field.type.join(", ") : field.type) +
@@ -432,7 +425,7 @@ export default class Inibase {
432
425
  async validateData(tableName, data, skipRequiredField = false) {
433
426
  const clonedData = structuredClone(data);
434
427
  // Skip ID and (created|updated)At
435
- this._validateData(clonedData, this.tablesMap.get(tableName).schema.slice(1, -2), skipRequiredField);
428
+ this._validateData(clonedData, globalConfig[this.databasePath].tables.get(tableName).schema.slice(1, -2), skipRequiredField);
436
429
  await this.checkUnique(tableName);
437
430
  }
438
431
  cleanObject(obj) {
@@ -443,28 +436,30 @@ export default class Inibase {
443
436
  }, {});
444
437
  return Object.keys(cleanedObject).length > 0 ? cleanedObject : null;
445
438
  }
446
- formatField(value, fieldType, fieldChildrenType, _formatOnlyAvailiableKeys) {
439
+ formatField(value, field, _formatOnlyAvailiableKeys) {
447
440
  if (value === null || value === undefined)
448
441
  return value;
449
- if (Array.isArray(fieldType))
450
- fieldType = Utils.detectFieldType(value, fieldType) ?? fieldType[0];
451
- if (Array.isArray(value) && !["array", "json"].includes(fieldType))
442
+ if (Array.isArray(field.type))
443
+ field.type = Utils.detectFieldType(value, field.type) ?? field.type[0];
444
+ if (Array.isArray(value) && !["array", "json"].includes(field.type))
452
445
  value = value[0];
453
- switch (fieldType) {
446
+ switch (field.type) {
454
447
  case "array":
455
- if (!fieldChildrenType)
448
+ if (!field.children)
456
449
  return null;
457
450
  if (!Array.isArray(value))
458
451
  value = [value];
459
- if (Utils.isArrayOfObjects(fieldChildrenType)) {
460
- return this.formatData(value, fieldChildrenType, _formatOnlyAvailiableKeys);
461
- }
452
+ if (Utils.isArrayOfObjects(field.children))
453
+ return this.formatData(value, field.children, _formatOnlyAvailiableKeys);
462
454
  if (!value.length)
463
455
  return null;
464
- return value.map((_value) => this.formatField(_value, fieldChildrenType));
456
+ return value.map((_value) => this.formatField(_value, {
457
+ ...field,
458
+ type: field.children,
459
+ }));
465
460
  case "object":
466
- if (Utils.isArrayOfObjects(fieldChildrenType))
467
- return this.formatData(value, fieldChildrenType, _formatOnlyAvailiableKeys);
461
+ if (Utils.isArrayOfObjects(field.children))
462
+ return this.formatData(value, field.children, _formatOnlyAvailiableKeys);
468
463
  break;
469
464
  case "table":
470
465
  if (Utils.isObject(value)) {
@@ -473,12 +468,12 @@ export default class Inibase {
473
468
  Utils.isNumber(value.id)))
474
469
  return Utils.isNumber(value.id)
475
470
  ? Number(value.id)
476
- : UtilsServer.decodeID(value.id, this.salt);
471
+ : UtilsServer.decodeID(value.id);
477
472
  }
478
473
  else if (Utils.isValidID(value) || Utils.isNumber(value))
479
474
  return Utils.isNumber(value)
480
475
  ? Number(value)
481
- : UtilsServer.decodeID(value, this.salt);
476
+ : UtilsServer.decodeID(value);
482
477
  break;
483
478
  case "password":
484
479
  return Utils.isPassword(value)
@@ -493,7 +488,7 @@ export default class Inibase {
493
488
  case "id":
494
489
  return Utils.isNumber(value)
495
490
  ? value
496
- : UtilsServer.decodeID(value, this.salt);
491
+ : UtilsServer.decodeID(value);
497
492
  case "json": {
498
493
  if (typeof value === "string" && Utils.isStringified(value))
499
494
  return value;
@@ -513,7 +508,7 @@ export default class Inibase {
513
508
  }
514
509
  async checkUnique(tableName) {
515
510
  const tablePath = join(this.databasePath, tableName);
516
- const flattenSchema = Utils.flattenSchema(this.tablesMap.get(tableName).schema);
511
+ const flattenSchema = Utils.flattenSchema(globalConfig[this.databasePath].tables.get(tableName).schema);
517
512
  function hasDuplicates(setA, setB) {
518
513
  for (const value of setA)
519
514
  if (setB.has(value))
@@ -529,7 +524,7 @@ export default class Inibase {
529
524
  index++;
530
525
  const field = flattenSchema.find(({ id }) => id === columnID);
531
526
  fieldsKeys.push(field.key);
532
- const [_, totalLines, lineNumbers] = await File.search(join(tablePath, `${field.key}${this.getFileExtension(tableName)}`), "[]", Array.from(values), undefined, valueObject.exclude, field.type, field.children, 1, undefined, false, this.salt);
527
+ const [_, totalLines, lineNumbers] = await File.search(join(tablePath, `${field.key}${this.getFileExtension(tableName)}`), "[]", Array.from(values), undefined, valueObject.exclude, { ...field, databasePath: this.databasePath }, 1, undefined, false);
533
528
  if (totalLines > 0) {
534
529
  if (valueObject.columnsValues.size === 1 ||
535
530
  (valueObject.columnsValues.size === index &&
@@ -576,7 +571,7 @@ export default class Inibase {
576
571
  RETURN[field.key] = this.getDefaultValue(field);
577
572
  continue;
578
573
  }
579
- RETURN[field.key] = this.formatField(clonedData[field.key], field.type, field.children, formatOnlyAvailiableKeys);
574
+ RETURN[field.key] = this.formatField(clonedData[field.key], field, formatOnlyAvailiableKeys);
580
575
  }
581
576
  return RETURN;
582
577
  }
@@ -727,9 +722,14 @@ export default class Inibase {
727
722
  async processSimpleField(tableName, field, linesNumber, RETURN, _options, prefix) {
728
723
  const fieldPath = join(this.databasePath, tableName, `${prefix ?? ""}${field.key}${this.getFileExtension(tableName)}`);
729
724
  if (await File.isExists(fieldPath)) {
730
- const items = await File.get(fieldPath, linesNumber, field.key === "id" && this.tablesMap.get(tableName).config.decodeID
731
- ? "number"
732
- : field.type, field.children, this.salt);
725
+ const items = await File.get(fieldPath, linesNumber, {
726
+ ...field,
727
+ type: field.key === "id" &&
728
+ globalConfig[this.databasePath].tables.get(tableName).config.decodeID
729
+ ? "number"
730
+ : field.type,
731
+ databasePath: this.databasePath,
732
+ });
733
733
  if (items) {
734
734
  for (const [index, item] of Object.entries(items)) {
735
735
  if (typeof item === "undefined")
@@ -875,7 +875,10 @@ export default class Inibase {
875
875
  (await File.isExists(join(this.databasePath, field.table)))) {
876
876
  const fieldPath = join(this.databasePath, tableName, `${prefix ?? ""}${field.key}${this.getFileExtension(tableName)}`);
877
877
  if (await File.isExists(fieldPath)) {
878
- const itemsIDs = await File.get(fieldPath, linesNumber, field.type, field.children, this.salt);
878
+ const itemsIDs = (await File.get(fieldPath, linesNumber, {
879
+ ...field,
880
+ databasePath: this.databasePath,
881
+ }));
879
882
  const isArrayField = this.isArrayField(field.type);
880
883
  if (itemsIDs) {
881
884
  const searchableIDs = new Map();
@@ -888,26 +891,29 @@ export default class Inibase {
888
891
  searchableIDs.set(lineNumber, lineContent);
889
892
  }
890
893
  if (searchableIDs.size) {
891
- const items = await this.get(field.table, isArrayField
892
- ? Array.from(new Set(Array.from(searchableIDs.values()).flat())).flat()
893
- : Array.from(new Set(searchableIDs.values())), {
894
+ const items = await this.get(field.table, Array.from(new Set(isArrayField
895
+ ? Array.from(searchableIDs.values()).flat()
896
+ : searchableIDs.values())).flat(), {
894
897
  ...options,
895
898
  perPage: Number.POSITIVE_INFINITY,
896
899
  columns: options.columns
897
900
  ?.filter((column) => column.includes(`${field.key}.`))
898
901
  .map((column) => column.replace(`${field.key}.`, "")),
899
902
  });
900
- if (items) {
901
- for (const [lineNumber, lineContent] of searchableIDs.entries()) {
902
- const foundedItem = isArrayField
903
- ? Utils.isArrayOfArrays(lineContent)
904
- ? lineContent.map((item) => items.filter(({ id }) => item.includes(id)))
905
- : lineContent.flatMap((item) => items.find(({ id }) => item === id))
906
- : items.find(({ id }) => id === lineContent);
907
- if (foundedItem)
908
- RETURN[lineNumber][field.key] = foundedItem;
909
- }
910
- }
903
+ for (const [lineNumber, lineContent] of searchableIDs.entries())
904
+ RETURN[lineNumber][field.key] = isArrayField
905
+ ? Utils.isArrayOfArrays(lineContent)
906
+ ? lineContent.map((item) => items
907
+ ? items.filter(({ id }) => item.includes(id))
908
+ : {
909
+ id: item,
910
+ })
911
+ : lineContent.flatMap((item) => items
912
+ ? items.find(({ id }) => item === id)
913
+ : { id: item })
914
+ : (items?.find(({ id }) => id === lineContent) ?? {
915
+ id: lineContent,
916
+ });
911
917
  }
912
918
  }
913
919
  }
@@ -950,7 +956,7 @@ export default class Inibase {
950
956
  criteria = Utils.toDotNotation(criteria, ["or", "and"]);
951
957
  let index = -1;
952
958
  for await (const [key, value] of Object.entries(criteria)) {
953
- const field = Utils.getField(key, this.tablesMap.get(tableName).schema);
959
+ const field = Utils.getField(key, globalConfig[this.databasePath].tables.get(tableName).schema);
954
960
  index++;
955
961
  let searchOperator = undefined;
956
962
  let searchComparedAtValue = undefined;
@@ -1008,9 +1014,7 @@ export default class Inibase {
1008
1014
  searchOperator = "=";
1009
1015
  searchComparedAtValue = value;
1010
1016
  }
1011
- const [searchResult, totalLines, linesNumbers] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), searchOperator ?? "=", searchComparedAtValue ?? null, searchLogicalOperator, allTrue ? searchIn : undefined, field?.type, field?.children, options.perPage, (options.page - 1) * options.perPage + 1, true, field.key === "id" && this.tablesMap.get(tableName).config.decodeID
1012
- ? undefined
1013
- : this.salt);
1017
+ const [searchResult, totalLines, linesNumbers] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), searchOperator ?? "=", searchComparedAtValue ?? null, searchLogicalOperator, allTrue ? searchIn : undefined, { ...field, databasePath: this.databasePath }, options.perPage, (options.page - 1) * options.perPage + 1, true);
1014
1018
  if (searchResult) {
1015
1019
  const formatedSearchResult = Object.fromEntries(Object.entries(searchResult).map(([id, value]) => {
1016
1020
  const nestedObj = {};
@@ -1128,13 +1132,13 @@ export default class Inibase {
1128
1132
  .map((column) => [column, true]);
1129
1133
  let cacheKey = "";
1130
1134
  // Criteria
1131
- if (this.tablesMap.get(tableName).config.cache)
1135
+ if (globalConfig[this.databasePath].tables.get(tableName).config.cache)
1132
1136
  cacheKey = UtilsServer.hashString(inspect(sortArray, { sorted: true }));
1133
1137
  if (where) {
1134
1138
  const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
1135
1139
  if (!lineNumbers?.length)
1136
1140
  return null;
1137
- const itemsIDs = Object.values((await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), lineNumbers, "number", undefined, this.salt)) ?? {}).map(Number);
1141
+ const itemsIDs = Object.values((await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), lineNumbers, { key: "BLABLA", type: "number" })) ?? {}).map(Number);
1138
1142
  awkCommand = `awk '${itemsIDs.map((id) => `$1 == ${id}`).join(" || ")}'`;
1139
1143
  }
1140
1144
  else
@@ -1157,9 +1161,7 @@ export default class Inibase {
1157
1161
  .map(([key, ascending], i) => {
1158
1162
  const field = Utils.getField(key, schema);
1159
1163
  if (field)
1160
- return `-k${i + index},${i + index}${Utils.isFieldType(["id", "number", "date"], field.type, field.children)
1161
- ? "n"
1162
- : ""}${!ascending ? "r" : ""}`;
1164
+ return `-k${i + index},${i + index}${Utils.isFieldType(field, ["id", "number", "date"]) ? "n" : ""}${!ascending ? "r" : ""}`;
1163
1165
  return "";
1164
1166
  })
1165
1167
  .join(" ");
@@ -1168,7 +1170,7 @@ export default class Inibase {
1168
1170
  if (cacheKey)
1169
1171
  await File.lock(join(tablePath, ".tmp"), cacheKey);
1170
1172
  // Combine && Execute the commands synchronously
1171
- let lines = (await UtilsServer.exec(this.tablesMap.get(tableName).config.cache
1173
+ let lines = (await UtilsServer.exec(globalConfig[this.databasePath].tables.get(tableName).config.cache
1172
1174
  ? (await File.isExists(join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)))
1173
1175
  ? `${awkCommand} '${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}'`
1174
1176
  : `${pasteCommand} | ${sortCommand} -o '${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}' && ${awkCommand} '${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}'`
@@ -1192,10 +1194,11 @@ export default class Inibase {
1192
1194
  const field = Utils.getField(parse(fileName).name, schema);
1193
1195
  if (field) {
1194
1196
  if (field.key === "id" &&
1195
- this.tablesMap.get(tableName).config.decodeID)
1197
+ globalConfig[this.databasePath].tables.get(tableName).config
1198
+ .decodeID)
1196
1199
  outputObject[field.key] = splitedFileColumns[index];
1197
1200
  else
1198
- outputObject[field.key] = File.decode(splitedFileColumns[index], field?.type, field?.children, this.salt);
1201
+ outputObject[field.key] = File.decode(splitedFileColumns[index], { ...field, databasePath: this.databasePath });
1199
1202
  }
1200
1203
  });
1201
1204
  return outputObject;
@@ -1223,7 +1226,8 @@ export default class Inibase {
1223
1226
  }
1224
1227
  else if (((Array.isArray(where) && where.every(Utils.isNumber)) ||
1225
1228
  Utils.isNumber(where)) &&
1226
- (_whereIsLinesNumbers || !this.tablesMap.get(tableName).config.decodeID)) {
1229
+ (_whereIsLinesNumbers ||
1230
+ !globalConfig[this.databasePath].tables.get(tableName).config.decodeID)) {
1227
1231
  // "where" in this case, is the line(s) number(s) and not id(s)
1228
1232
  let lineNumbers = where;
1229
1233
  if (!Array.isArray(lineNumbers))
@@ -1238,7 +1242,7 @@ export default class Inibase {
1238
1242
  RETURN = RETURN[0];
1239
1243
  }
1240
1244
  else if ((!_whereIsLinesNumbers &&
1241
- this.tablesMap.get(tableName).config.decodeID &&
1245
+ globalConfig[this.databasePath].tables.get(tableName).config.decodeID &&
1242
1246
  ((Array.isArray(where) && where.every(Utils.isNumber)) ||
1243
1247
  Utils.isNumber(where))) ||
1244
1248
  (Array.isArray(where) && where.every(Utils.isValidID)) ||
@@ -1246,7 +1250,7 @@ export default class Inibase {
1246
1250
  let Ids = where;
1247
1251
  if (!Array.isArray(Ids))
1248
1252
  Ids = [Ids];
1249
- 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, undefined, "number", undefined, Ids.length, 0, !this.totalItems.has(`${tableName}-*`), this.salt);
1253
+ const [lineNumbers, countItems] = await File.search(join(tablePath, `id${this.getFileExtension(tableName)}`), "[]", Ids.map((id) => Utils.isNumber(id) ? Number(id) : UtilsServer.decodeID(id)), undefined, undefined, { key: "BLABLA", type: "number" }, Ids.length, 0, !this.totalItems.has(`${tableName}-*`));
1250
1254
  if (!lineNumbers)
1251
1255
  return null;
1252
1256
  if (!this.totalItems.has(`${tableName}-*`))
@@ -1267,7 +1271,7 @@ export default class Inibase {
1267
1271
  else if (Utils.isObject(where)) {
1268
1272
  let cachedFilePath = "";
1269
1273
  // Criteria
1270
- if (this.tablesMap.get(tableName).config.cache) {
1274
+ if (globalConfig[this.databasePath].tables.get(tableName).config.cache) {
1271
1275
  cachedFilePath = join(tablePath, ".cache", `${UtilsServer.hashString(inspect(where, { sorted: true }))}${this.fileExtension}`);
1272
1276
  if (await File.isExists(cachedFilePath)) {
1273
1277
  const cachedItems = (await readFile(cachedFilePath, "utf8")).split(",");
@@ -1292,9 +1296,9 @@ export default class Inibase {
1292
1296
  const alreadyExistsColumnsIDs = Utils.flattenSchema(schema)
1293
1297
  .filter(({ key }) => alreadyExistsColumns.includes(key))
1294
1298
  .map(({ id }) => id);
1295
- RETURN = Object.values(Utils.deepMerge(LineNumberDataMap, await this.processSchemaData(tableName, Utils.filterSchema(schema, ({ id, type, children }) => !alreadyExistsColumnsIDs.includes(id) ||
1296
- Utils.isFieldType("table", type, children)), Object.keys(LineNumberDataMap).map(Number), options)));
1297
- if (this.tablesMap.get(tableName).config.cache)
1299
+ RETURN = Object.values(Utils.deepMerge(LineNumberDataMap, await this.processSchemaData(tableName, Utils.filterSchema(schema, (field) => !alreadyExistsColumnsIDs.includes(field.id) ||
1300
+ Utils.isFieldType(field, "table")), Object.keys(LineNumberDataMap).map(Number), options)));
1301
+ if (globalConfig[this.databasePath].tables.get(tableName).config.cache)
1298
1302
  await writeFile(cachedFilePath, Array.from(linesNumbers).join(","));
1299
1303
  }
1300
1304
  }
@@ -1323,7 +1327,7 @@ export default class Inibase {
1323
1327
  };
1324
1328
  const tablePath = join(this.databasePath, tableName);
1325
1329
  await this.getTable(tableName);
1326
- if (!this.tablesMap.get(tableName).schema)
1330
+ if (!globalConfig[this.databasePath].tables.get(tableName).schema)
1327
1331
  throw this.createError("NO_SCHEMA", tableName);
1328
1332
  if (!returnPostedData)
1329
1333
  returnPostedData = false;
@@ -1352,25 +1356,25 @@ export default class Inibase {
1352
1356
  clonedData.createdAt = Date.now();
1353
1357
  clonedData.updatedAt = undefined;
1354
1358
  }
1355
- clonedData = this.formatData(clonedData, this.tablesMap.get(tableName).schema, false);
1356
- const pathesContents = this.joinPathesContents(tableName, this.tablesMap.get(tableName).config.prepend
1359
+ clonedData = this.formatData(clonedData, globalConfig[this.databasePath].tables.get(tableName).schema, false);
1360
+ const pathesContents = this.joinPathesContents(tableName, globalConfig[this.databasePath].tables.get(tableName).config.prepend
1357
1361
  ? Array.isArray(clonedData)
1358
1362
  ? clonedData.toReversed()
1359
1363
  : clonedData
1360
1364
  : clonedData);
1361
- await Promise.allSettled(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(this.tablesMap.get(tableName).config.prepend
1365
+ await Promise.allSettled(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(globalConfig[this.databasePath].tables.get(tableName).config.prepend
1362
1366
  ? await File.prepend(path, content)
1363
1367
  : await File.append(path, content))));
1364
1368
  await Promise.allSettled(renameList
1365
1369
  .filter(([_, filePath]) => filePath)
1366
1370
  .map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
1367
- if (this.tablesMap.get(tableName).config.cache)
1371
+ if (globalConfig[this.databasePath].tables.get(tableName).config.cache)
1368
1372
  await this.clearCache(tableName);
1369
1373
  const currentValue = this.totalItems.get(`${tableName}-*`) || 0;
1370
1374
  this.totalItems.set(`${tableName}-*`, currentValue + (Array.isArray(data) ? data.length : 1));
1371
1375
  await rename(paginationFilePath, join(tablePath, `${lastId}-${this.totalItems.get(`${tableName}-*`)}.pagination`));
1372
1376
  if (returnPostedData)
1373
- return this.get(tableName, this.tablesMap.get(tableName).config.prepend
1377
+ return this.get(tableName, globalConfig[this.databasePath].tables.get(tableName).config.prepend
1374
1378
  ? Array.isArray(clonedData)
1375
1379
  ? clonedData.map((_, index) => index + 1).toReversed()
1376
1380
  : 1
@@ -1381,10 +1385,10 @@ export default class Inibase {
1381
1385
  : this.totalItems.get(`${tableName}-*`), options, !Utils.isArrayOfObjects(clonedData), // return only one item if data is not array of objects
1382
1386
  undefined, true);
1383
1387
  return Array.isArray(clonedData)
1384
- ? (this.tablesMap.get(tableName).config.prepend
1388
+ ? (globalConfig[this.databasePath].tables.get(tableName).config.prepend
1385
1389
  ? clonedData.toReversed()
1386
- : clonedData).map(({ id }) => UtilsServer.encodeID(id, this.salt))
1387
- : UtilsServer.encodeID(clonedData.id, this.salt);
1390
+ : clonedData).map(({ id }) => UtilsServer.encodeID(id))
1391
+ : UtilsServer.encodeID(clonedData.id);
1388
1392
  }
1389
1393
  finally {
1390
1394
  if (renameList.length)
@@ -1412,7 +1416,7 @@ export default class Inibase {
1412
1416
  return this.put(tableName, clonedData, clonedData.id, options, returnUpdatedData);
1413
1417
  }
1414
1418
  await this.validateData(tableName, clonedData, true);
1415
- clonedData = this.formatData(clonedData, this.tablesMap.get(tableName).schema, true);
1419
+ clonedData = this.formatData(clonedData, globalConfig[this.databasePath].tables.get(tableName).schema, true);
1416
1420
  const pathesContents = this.joinPathesContents(tableName, {
1417
1421
  ...(({ id, ...restOfData }) => restOfData)(clonedData),
1418
1422
  updatedAt: Date.now(),
@@ -1427,7 +1431,7 @@ export default class Inibase {
1427
1431
  await Promise.allSettled(renameList
1428
1432
  .filter(([_, filePath]) => filePath)
1429
1433
  .map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
1430
- if (this.tablesMap.get(tableName).config.cache)
1434
+ if (globalConfig[this.databasePath].tables.get(tableName).config.cache)
1431
1435
  await this.clearCache(join(tablePath, ".cache"));
1432
1436
  if (returnUpdatedData)
1433
1437
  return await this.get(tableName, undefined, options);
@@ -1440,10 +1444,11 @@ export default class Inibase {
1440
1444
  }
1441
1445
  else if (((Array.isArray(where) && where.every(Utils.isNumber)) ||
1442
1446
  Utils.isNumber(where)) &&
1443
- (_whereIsLinesNumbers || !this.tablesMap.get(tableName).config.decodeID)) {
1447
+ (_whereIsLinesNumbers ||
1448
+ !globalConfig[this.databasePath].tables.get(tableName).config.decodeID)) {
1444
1449
  // "where" in this case, is the line(s) number(s) and not id(s)
1445
1450
  await this.validateData(tableName, clonedData, true);
1446
- clonedData = this.formatData(clonedData, this.tablesMap.get(tableName).schema, true);
1451
+ clonedData = this.formatData(clonedData, globalConfig[this.databasePath].tables.get(tableName).schema, true);
1447
1452
  const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(tableName, Array.isArray(clonedData)
1448
1453
  ? clonedData.map((item) => ({
1449
1454
  ...item,
@@ -1465,7 +1470,7 @@ export default class Inibase {
1465
1470
  await Promise.allSettled(renameList
1466
1471
  .filter(([_, filePath]) => filePath)
1467
1472
  .map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
1468
- if (this.tablesMap.get(tableName).config.cache)
1473
+ if (globalConfig[this.databasePath].tables.get(tableName).config.cache)
1469
1474
  await this.clearCache(tableName);
1470
1475
  if (returnUpdatedData)
1471
1476
  return this.get(tableName, where, options, !Array.isArray(where), undefined, true);
@@ -1477,7 +1482,7 @@ export default class Inibase {
1477
1482
  }
1478
1483
  }
1479
1484
  else if ((!_whereIsLinesNumbers &&
1480
- this.tablesMap.get(tableName).config.decodeID &&
1485
+ globalConfig[this.databasePath].tables.get(tableName).config.decodeID &&
1481
1486
  ((Array.isArray(where) && where.every(Utils.isNumber)) ||
1482
1487
  Utils.isNumber(where))) ||
1483
1488
  (Array.isArray(where) && where.every(Utils.isValidID)) ||
@@ -1520,7 +1525,7 @@ export default class Inibase {
1520
1525
  await Promise.all((await readdir(tablePath))
1521
1526
  ?.filter((fileName) => fileName.endsWith(this.getFileExtension(tableName)))
1522
1527
  .map(async (file) => unlink(join(tablePath, file))));
1523
- if (this.tablesMap.get(tableName).config.cache)
1528
+ if (globalConfig[this.databasePath].tables.get(tableName).config.cache)
1524
1529
  await this.clearCache(tableName);
1525
1530
  await rename(paginationFilePath, join(tablePath, `${pagination[0]}-0.pagination`));
1526
1531
  return true;
@@ -1531,7 +1536,8 @@ export default class Inibase {
1531
1536
  }
1532
1537
  if (((Array.isArray(where) && where.every(Utils.isNumber)) ||
1533
1538
  Utils.isNumber(where)) &&
1534
- (_whereIsLinesNumbers || !this.tablesMap.get(tableName).config.decodeID)) {
1539
+ (_whereIsLinesNumbers ||
1540
+ !globalConfig[this.databasePath].tables.get(tableName).config.decodeID)) {
1535
1541
  // "where" in this case, is the line(s) number(s) and not id(s)
1536
1542
  const files = (await readdir(tablePath))?.filter((fileName) => fileName.endsWith(this.getFileExtension(tableName)));
1537
1543
  if (files.length) {
@@ -1559,7 +1565,7 @@ export default class Inibase {
1559
1565
  await Promise.all((await readdir(tablePath))
1560
1566
  ?.filter((fileName) => fileName.endsWith(this.getFileExtension(tableName)))
1561
1567
  .map(async (file) => unlink(join(tablePath, file))));
1562
- if (this.tablesMap.get(tableName).config.cache)
1568
+ if (globalConfig[this.databasePath].tables.get(tableName).config.cache)
1563
1569
  await this.clearCache(tableName);
1564
1570
  await rename(paginationFilePath, join(tablePath, `${pagination[0]}-${pagination[1] - (Array.isArray(where) ? where.length : 1)}.pagination`));
1565
1571
  return true;
@@ -1572,7 +1578,7 @@ export default class Inibase {
1572
1578
  }
1573
1579
  }
1574
1580
  if ((!_whereIsLinesNumbers &&
1575
- this.tablesMap.get(tableName).config.decodeID &&
1581
+ globalConfig[this.databasePath].tables.get(tableName).config.decodeID &&
1576
1582
  ((Array.isArray(where) && where.every(Utils.isNumber)) ||
1577
1583
  Utils.isNumber(where))) ||
1578
1584
  (Array.isArray(where) && where.every(Utils.isValidID)) ||
package/dist/utils.d.ts CHANGED
@@ -156,18 +156,17 @@ export declare const findChangedProperties: (obj1: Record<string, string>, obj2:
156
156
  * @returns The detected field type as a string, or undefined if no matching type is found.
157
157
  */
158
158
  export declare const detectFieldType: (input: any, availableTypes: FieldType[]) => FieldType | undefined;
159
- export declare const isFieldType: (compareAtType: string | string[], fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[] | Schema) => boolean;
159
+ export declare const isFieldType: (field: Field, compareAtType: string | string[]) => boolean;
160
160
  export declare const flattenSchema: (schema: Schema, keepParents?: boolean) => Schema;
161
161
  export declare const filterSchema: (schema: Schema, callback: (arg0: Field) => boolean) => Field[];
162
162
  /**
163
163
  * Validates if the given value matches the specified field type(s).
164
164
  *
165
165
  * @param value - The value to be validated.
166
- * @param fieldType - The expected field type or an array of possible field types.
167
- * @param fieldChildrenType - Optional; the expected type(s) of children elements, used if the field type is an array.
166
+ * @param field - Field object config.
168
167
  * @returns A boolean indicating whether the value matches the specified field type(s).
169
168
  */
170
- export declare const validateFieldType: (value: any, fieldType: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[]) => boolean;
169
+ export declare const validateFieldType: (value: any, field: Field) => boolean;
171
170
  export declare const FormatObjectCriteriaValue: (value: string) => [ComparisonOperator, string | number | boolean | null | (string | number | null)[]];
172
171
  /**
173
172
  * Get field from schema