inibase 1.1.3 → 1.1.5

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 CHANGED
@@ -26,6 +26,7 @@
26
26
 
27
27
  ```js
28
28
  import Inibase from "inibase";
29
+ // const db = new Inibase("databaseName", ".", "es");
29
30
  const db = new Inibase("databaseName");
30
31
 
31
32
  // Get all items from "user" table
package/dist/file.js CHANGED
@@ -108,6 +108,7 @@ const secureString = (input) => {
108
108
  export const encode = (input) => Array.isArray(input)
109
109
  ? input.every((_input) => _input === null ||
110
110
  _input === undefined ||
111
+ _input === "" ||
111
112
  (typeof _input === "string" && isStringified(_input)))
112
113
  ? `[${input.join(",")}]`
113
114
  : Inison.stringify(input)
package/dist/index.d.ts CHANGED
@@ -50,19 +50,20 @@ declare global {
50
50
  entries<T extends object>(o: T): Entries<T>;
51
51
  }
52
52
  }
53
- export type ErrorCodes = "FIELD_UNIQUE" | "FIELD_REQUIRED" | "NO_SCHEMA" | "TABLE_EMPTY" | "INVALID_ID" | "INVALID_TYPE" | "INVALID_PARAMETERS" | "NO_ENV" | "TABLE_EXISTS" | "TABLE_NOT_EXISTS" | "INVALID_REGEX_MATCH";
54
- export type ErrorLang = "en";
53
+ export type ErrorCodes = "GROUP_UNIQUE" | "FIELD_UNIQUE" | "FIELD_REQUIRED" | "NO_SCHEMA" | "TABLE_EMPTY" | "INVALID_ID" | "INVALID_TYPE" | "INVALID_PARAMETERS" | "NO_ENV" | "TABLE_EXISTS" | "TABLE_NOT_EXISTS" | "INVALID_REGEX_MATCH";
54
+ export type ErrorLang = "en" | "ar" | "fr" | "es";
55
55
  export default class Inibase {
56
56
  pageInfo: Record<string, pageInfo>;
57
+ language: ErrorLang;
57
58
  salt: Buffer;
58
59
  private databasePath;
59
60
  private fileExtension;
60
61
  private tablesMap;
61
62
  private uniqueMap;
62
63
  private totalItems;
63
- constructor(database: string, mainFolder?: string);
64
+ constructor(database: string, mainFolder?: string, language?: ErrorLang);
64
65
  private static errorMessages;
65
- createError(name: ErrorCodes, variable?: string | number | (string | number)[], language?: ErrorLang): Error;
66
+ createError(name: ErrorCodes, variable?: string | number | (string | number)[]): Error;
66
67
  clear(): void;
67
68
  private getFileExtension;
68
69
  private _schemaToIdsPath;
package/dist/index.js CHANGED
@@ -12,15 +12,17 @@ import * as UtilsServer from "./utils.server.js";
12
12
  process.removeAllListeners("warning");
13
13
  export default class Inibase {
14
14
  pageInfo;
15
+ language;
15
16
  salt;
16
17
  databasePath;
17
18
  fileExtension = ".txt";
18
19
  tablesMap;
19
20
  uniqueMap;
20
21
  totalItems;
21
- constructor(database, mainFolder = ".") {
22
+ constructor(database, mainFolder = ".", language = "en") {
22
23
  this.databasePath = join(mainFolder, database);
23
24
  this.clear();
25
+ this.language = language;
24
26
  if (!process.env.INIBASE_SECRET) {
25
27
  if (existsSync(".env") &&
26
28
  readFileSync(".env").includes("INIBASE_SECRET="))
@@ -37,6 +39,7 @@ export default class Inibase {
37
39
  TABLE_EXISTS: "Table {variable} already exists",
38
40
  TABLE_NOT_EXISTS: "Table {variable} doesn't exist",
39
41
  NO_SCHEMA: "Table {variable} does't have a schema",
42
+ GROUP_UNIQUE: "Group {variable} should be unique, got duplicated content in {variable}",
40
43
  FIELD_UNIQUE: "Field {variable} should be unique, got {variable} instead",
41
44
  FIELD_REQUIRED: "Field {variable} is required",
42
45
  INVALID_ID: "The given ID(s) is/are not valid(s)",
@@ -47,9 +50,57 @@ export default class Inibase {
47
50
  ? "please run with '--env-file=.env'"
48
51
  : "please use dotenv",
49
52
  },
53
+ ar: {
54
+ TABLE_EMPTY: "الجدول {variable} فارغ",
55
+ TABLE_EXISTS: "الجدول {variable} موجود بالفعل",
56
+ TABLE_NOT_EXISTS: "الجدول {variable} غير موجود",
57
+ NO_SCHEMA: "الجدول {variable} ليس لديه مخطط",
58
+ GROUP_UNIQUE: "المجموعة {variable} يجب أن تكون فريدة، تم العثور على محتوى مكرر في {variable}",
59
+ FIELD_UNIQUE: "الحقل {variable} يجب أن يكون فريدًا، تم العثور على {variable} بدلاً من ذلك",
60
+ FIELD_REQUIRED: "الحقل {variable} مطلوب",
61
+ INVALID_ID: "المعرف أو المعرفات المقدمة غير صالحة",
62
+ INVALID_TYPE: "من المتوقع أن يكون {variable} من النوع {variable}، لكن تم العثور على {variable} بدلاً من ذلك",
63
+ INVALID_PARAMETERS: "المعلمات المقدمة غير صالحة",
64
+ INVALID_REGEX_MATCH: "الحقل {variable} لا يتطابق مع النمط المتوقع",
65
+ NO_ENV: Number(process.versions.node.split(".").reduce((a, b) => a + b)) >= 26
66
+ ? "يرجى التشغيل باستخدام '--env-file=.env'"
67
+ : "يرجى استخدام dotenv",
68
+ },
69
+ fr: {
70
+ TABLE_EMPTY: "La table {variable} est vide",
71
+ TABLE_EXISTS: "La table {variable} existe déjà",
72
+ TABLE_NOT_EXISTS: "La table {variable} n'existe pas",
73
+ NO_SCHEMA: "La table {variable} n'a pas de schéma",
74
+ GROUP_UNIQUE: "Le groupe {variable} doit être unique, contenu dupliqué trouvé dans {variable}",
75
+ FIELD_UNIQUE: "Le champ {variable} doit être unique, trouvé {variable} à la place",
76
+ FIELD_REQUIRED: "Le champ {variable} est obligatoire",
77
+ INVALID_ID: "Le(s) ID donné(s) n'est/ne sont pas valide(s)",
78
+ INVALID_TYPE: "Attendu que {variable} soit de type {variable}, mais trouvé {variable} à la place",
79
+ INVALID_PARAMETERS: "Les paramètres donnés ne sont pas valides",
80
+ INVALID_REGEX_MATCH: "Le champ {variable} ne correspond pas au modèle attendu",
81
+ NO_ENV: Number(process.versions.node.split(".").reduce((a, b) => a + b)) >= 26
82
+ ? "veuillez exécuter avec '--env-file=.env'"
83
+ : "veuillez utiliser dotenv",
84
+ },
85
+ es: {
86
+ TABLE_EMPTY: "La tabla {variable} está vacía",
87
+ TABLE_EXISTS: "La tabla {variable} ya existe",
88
+ TABLE_NOT_EXISTS: "La tabla {variable} no existe",
89
+ NO_SCHEMA: "La tabla {variable} no tiene un esquema",
90
+ GROUP_UNIQUE: "El grupo {variable} debe ser único, se encontró contenido duplicado en {variable}",
91
+ FIELD_UNIQUE: "El campo {variable} debe ser único, se encontró {variable} en su lugar",
92
+ FIELD_REQUIRED: "El campo {variable} es obligatorio",
93
+ INVALID_ID: "El/los ID proporcionado(s) no es/son válido(s)",
94
+ INVALID_TYPE: "Se espera que {variable} sea {variable}, pero se encontró {variable} en su lugar",
95
+ INVALID_PARAMETERS: "Los parámetros proporcionados no son válidos",
96
+ INVALID_REGEX_MATCH: "El campo {variable} no coincide con el patrón esperado",
97
+ NO_ENV: Number(process.versions.node.split(".").reduce((a, b) => a + b)) >= 26
98
+ ? "por favor ejecute con '--env-file=.env'"
99
+ : "por favor use dotenv",
100
+ },
50
101
  };
51
- createError(name, variable, language = "en") {
52
- const errorMessage = Inibase.errorMessages[language]?.[name];
102
+ createError(name, variable) {
103
+ const errorMessage = Inibase.errorMessages[this.language]?.[name];
53
104
  if (!errorMessage)
54
105
  return new Error("ERR");
55
106
  const error = new Error(variable
@@ -332,6 +383,10 @@ export default class Inibase {
332
383
  Utils.isArrayOfObjects(field.children))
333
384
  this._validateData(data[field.key], field.children, skipRequiredField);
334
385
  else {
386
+ if (field.table &&
387
+ Utils.isObject(data[field.key]) &&
388
+ Object.hasOwn(data[field.key], "id"))
389
+ data[field.key] = data[field.key].id;
335
390
  if (field.regex) {
336
391
  const regex = UtilsServer.getCachedRegex(field.regex);
337
392
  if (!regex.test(data[field.key]))
@@ -366,8 +421,9 @@ export default class Inibase {
366
421
  }
367
422
  }
368
423
  async validateData(tableName, data, skipRequiredField = false) {
424
+ const clonedData = structuredClone(data);
369
425
  // Skip ID and (created|updated)At
370
- this._validateData(data, this.tablesMap.get(tableName).schema.slice(1, -2), skipRequiredField);
426
+ this._validateData(clonedData, this.tablesMap.get(tableName).schema.slice(1, -2), skipRequiredField);
371
427
  await this.checkUnique(tableName);
372
428
  }
373
429
  cleanObject(obj) {
@@ -455,16 +511,24 @@ export default class Inibase {
455
511
  let index = 0;
456
512
  let shouldContinueParent = false; // Flag to manage parent loop continuation
457
513
  const mergedLineNumbers = new Set();
514
+ const fieldsKeys = [];
458
515
  for await (const [columnID, values] of valueObject.columnsValues) {
459
516
  index++;
460
517
  const field = flattenSchema.find(({ id }) => id === columnID);
518
+ fieldsKeys.push(field.key);
461
519
  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);
462
520
  if (totalLines > 0) {
463
521
  if (valueObject.columnsValues.size === 1 ||
464
- hasDuplicates(lineNumbers, mergedLineNumbers)) {
522
+ (valueObject.columnsValues.size === index &&
523
+ hasDuplicates(lineNumbers, mergedLineNumbers))) {
465
524
  this.uniqueMap = new Map();
525
+ if (valueObject.columnsValues.size > 1)
526
+ throw this.createError("GROUP_UNIQUE", [
527
+ fieldsKeys.join(" & "),
528
+ field.key,
529
+ ]);
466
530
  throw this.createError("FIELD_UNIQUE", [
467
- field.key,
531
+ fieldsKeys.join(" & "),
468
532
  Array.from(values).join(", "),
469
533
  ]);
470
534
  }
@@ -489,8 +553,9 @@ export default class Inibase {
489
553
  for (const field of schema) {
490
554
  if (!Object.hasOwn(clonedData, field.key)) {
491
555
  if (formatOnlyAvailiableKeys)
492
- continue;
493
- RETURN[field.key] = this.getDefaultValue(field);
556
+ RETURN[field.key] = "undefined";
557
+ else
558
+ RETURN[field.key] = this.getDefaultValue(field);
494
559
  continue;
495
560
  }
496
561
  if (Array.isArray(clonedData[field.key]) &&
@@ -551,8 +616,12 @@ export default class Inibase {
551
616
  else if (Utils.isArrayOfArrays(value) &&
552
617
  value.every(Utils.isArrayOfObjects))
553
618
  Object.assign(RETURN, this._CombineData(this._combineObjectsToArray(value.map(this._combineObjectsToArray)), `${(prefix ?? "") + key}.`));
554
- else
555
- RETURN[(prefix ?? "") + key] = File.encode(value);
619
+ else if (value !== "undefined")
620
+ RETURN[(prefix ?? "") + key] = File.encode(Array.isArray(value)
621
+ ? value.map((_value) => typeof _value === "string" && _value === "undefined"
622
+ ? ""
623
+ : _value)
624
+ : value);
556
625
  }
557
626
  return RETURN;
558
627
  }
@@ -1331,16 +1400,17 @@ export default class Inibase {
1331
1400
  // "where" in this case, is the line(s) number(s) and not id(s)
1332
1401
  await this.validateData(tableName, clonedData, true);
1333
1402
  clonedData = this.formatData(clonedData, this.tablesMap.get(tableName).schema, true);
1334
- const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(tableName, Utils.isArrayOfObjects(clonedData)
1403
+ const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(tableName, Array.isArray(clonedData)
1335
1404
  ? clonedData.map((item) => ({
1336
1405
  ...item,
1337
1406
  updatedAt: Date.now(),
1338
1407
  }))
1339
1408
  : { ...clonedData, updatedAt: Date.now() })).map(([path, content]) => [
1340
1409
  path,
1341
- [...(Array.isArray(where) ? where : [where])].reduce((obj, lineNum, index) => Object.assign(obj, {
1342
- [lineNum]: Array.isArray(content) ? content[index] : content,
1343
- }), {}),
1410
+ (Array.isArray(where) ? where : [where]).reduce((obj, lineNum, index) => {
1411
+ obj[lineNum] = Array.isArray(content) ? content[index] : content;
1412
+ return obj;
1413
+ }, {}),
1344
1414
  ]));
1345
1415
  const keys = UtilsServer.hashString(Object.keys(pathesContents)
1346
1416
  .map((path) => path.replaceAll(this.getFileExtension(tableName), ""))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inibase",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "type": "module",
5
5
  "author": {
6
6
  "name": "Karim Amahtil",