inibase 1.0.0-rc.53 → 1.0.0-rc.55

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
@@ -109,7 +109,7 @@ Ps: Testing by default with `user` table, with username, email, password fields
109
109
  - [ ] TO-DO:
110
110
  - [x] Improve caching
111
111
  - [ ] Commenting the code
112
- - [ ] Add property "unique" for schema fields
112
+ - [x] Add property "unique" for schema fields
113
113
  - [ ] Add Backup feature (generate a tar.gz)
114
114
  - [ ] Add Custom field validation property to schema (using RegEx?)
115
115
  - [ ] Features:
package/dist/index.d.ts CHANGED
@@ -40,7 +40,7 @@ declare global {
40
40
  entries<T extends object>(o: T): Entries<T>;
41
41
  }
42
42
  }
43
- export type ErrorCodes = "FIELD_UNIQUE" | "FIELD_REQUIRED" | "NO_SCHEMA" | "NO_ITEMS" | "NO_RESULTS" | "INVALID_ID" | "INVALID_TYPE" | "INVALID_PARAMETERS";
43
+ export type ErrorCodes = "FIELD_UNIQUE" | "FIELD_REQUIRED" | "NO_SCHEMA" | "NO_ITEMS" | "NO_RESULTS" | "INVALID_ID" | "INVALID_TYPE" | "INVALID_PARAMETERS" | "NO_ENV";
44
44
  export type ErrorLang = "en";
45
45
  export default class Inibase {
46
46
  folder: string;
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import { unlink, rename, mkdir, readdir } from "node:fs/promises";
2
- import { existsSync, appendFileSync } from "node:fs";
2
+ import { existsSync, appendFileSync, readFileSync } from "node:fs";
3
3
  import { join, parse } from "node:path";
4
4
  import { scryptSync, randomBytes } from "node:crypto";
5
5
  import { Worker } from "node:worker_threads";
6
+ import { inspect } from "node:util";
7
+ import Inison from "inison";
6
8
  import * as File from "./file.js";
7
9
  import * as Utils from "./utils.js";
8
10
  import * as UtilsServer from "./utils.server.js";
9
11
  import * as Config from "./config.js";
10
- import { inspect } from "node:util";
11
- import Inison from "inison";
12
12
  export default class Inibase {
13
13
  folder;
14
14
  database;
@@ -26,7 +26,10 @@ export default class Inibase {
26
26
  this.pageInfo = _pageInfo;
27
27
  this.isThreadEnabled = _isThreadEnabled;
28
28
  this.checkIFunique = {};
29
- if (!existsSync(".env") || !process.env.INIBASE_SECRET) {
29
+ if (!process.env.INIBASE_SECRET) {
30
+ if (existsSync(".env") &&
31
+ readFileSync(".env").includes("INIBASE_SECRET="))
32
+ this.throwError("NO_ENV");
30
33
  this.salt = scryptSync(randomBytes(16), randomBytes(16), 32);
31
34
  appendFileSync(".env", `\nINIBASE_SECRET=${this.salt.toString("hex")}\n`);
32
35
  }
@@ -44,6 +47,9 @@ export default class Inibase {
44
47
  INVALID_ID: "The given ID(s) is/are not valid(s)",
45
48
  INVALID_TYPE: "Expect {variable} to be {variable}, got {variable} instead",
46
49
  INVALID_PARAMETERS: "The given parameters are not valid",
50
+ NO_ENV: Number(process.versions.node.split(".").reduce((a, b) => a + b)) >= 26
51
+ ? "please run with '--env-file=.env'"
52
+ : "please use dotenv",
47
53
  },
48
54
  // Add more languages and error messages as needed
49
55
  };
@@ -329,12 +335,14 @@ export default class Inibase {
329
335
  }),
330
336
  ]
331
337
  : null;
332
- case "object":
338
+ case "object": {
333
339
  if (!field.children || !Utils.isArrayOfObjects(field.children))
334
340
  return null;
335
- return Utils.combineObjects(field.children.map((f) => ({
336
- [f.key]: this.getDefaultValue(f),
337
- })));
341
+ const RETURN = {};
342
+ for (const f of field.children)
343
+ RETURN[f.key] = this.getDefaultValue(f);
344
+ return RETURN;
345
+ }
338
346
  case "boolean":
339
347
  return false;
340
348
  default:
@@ -923,16 +931,14 @@ export default class Inibase {
923
931
  });
924
932
  try {
925
933
  await File.lock(join(tablePath, ".tmp"));
926
- await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(this.isThreadEnabled
927
- ? await File.createWorker("replace", [
928
- path,
929
- Utils.combineObjects([...Array(totalItems)].map((_, i) => ({
930
- [`${i + 1}`]: content,
931
- }))),
932
- ])
933
- : await File.replace(path, Utils.combineObjects([...Array(totalItems)].map((_, i) => ({
934
- [`${i + 1}`]: content,
935
- })))))));
934
+ await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => {
935
+ const replacementObject = {};
936
+ for (const index of [...Array(totalItems)].keys())
937
+ replacementObject[`${index + 1}`] = content;
938
+ renameList.push(this.isThreadEnabled
939
+ ? await File.createWorker("replace", [path, replacementObject])
940
+ : await File.replace(path, replacementObject));
941
+ }));
936
942
  await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
937
943
  if (Config.isCacheEnabled)
938
944
  await this.clearCache(join(tablePath, ".cache"));
@@ -1022,7 +1028,7 @@ export default class Inibase {
1022
1028
  const files = (await readdir(tablePath))?.filter((fileName) => fileName.endsWith(".inib"));
1023
1029
  if (files.length) {
1024
1030
  if (!_id)
1025
- _id = Object.entries((await File.get(join(tablePath, "id.inib"), where, "number", undefined, this.salt)) ?? {}).map(([_key, id]) => UtilsServer.encodeID(Number(id), this.salt));
1031
+ _id = Object.entries((await File.get(join(tablePath, "id.inib"), where, "number", undefined, this.salt)) ?? {}).map(([_, id]) => UtilsServer.encodeID(id, this.salt));
1026
1032
  if (!_id.length)
1027
1033
  throw this.throwError("NO_RESULTS", tableName);
1028
1034
  try {
package/dist/utils.d.ts CHANGED
@@ -45,15 +45,6 @@ export declare const isObject: (obj: any) => obj is Record<any, any>;
45
45
  * Note: Performs a deep merge for nested objects. Non-object properties are directly overwritten.
46
46
  */
47
47
  export declare const deepMerge: (target: any, source: any) => any;
48
- /**
49
- * Combines an array of objects into a single object. If the same key exists in multiple objects, the values are merged.
50
- *
51
- * @param arr - Array of objects to be combined.
52
- * @returns Record<string, any> - A single object with combined keys and values.
53
- *
54
- * Note: Handles nested objects by recursively combining them. Non-object values with the same key are merged into arrays.
55
- */
56
- export declare const combineObjects: (arr: Record<string, any>[]) => Record<string, any>;
57
48
  /**
58
49
  * Type guard function to check if the input is a number.
59
50
  *
package/dist/utils.js CHANGED
@@ -56,48 +56,6 @@ export const deepMerge = (target, source) => {
56
56
  }
57
57
  return target;
58
58
  };
59
- /**
60
- * Combines an array of objects into a single object. If the same key exists in multiple objects, the values are merged.
61
- *
62
- * @param arr - Array of objects to be combined.
63
- * @returns Record<string, any> - A single object with combined keys and values.
64
- *
65
- * Note: Handles nested objects by recursively combining them. Non-object values with the same key are merged into arrays.
66
- */
67
- export const combineObjects = (arr) => {
68
- const result = {};
69
- for (const obj of arr) {
70
- for (const key in obj) {
71
- if (Object.hasOwn(obj, key)) {
72
- const existingValue = result[key];
73
- const newValue = obj[key];
74
- if (isObject(existingValue) &&
75
- isObject(newValue) &&
76
- existingValue !== null &&
77
- existingValue !== undefined &&
78
- newValue !== null &&
79
- newValue !== undefined) {
80
- // If both values are objects, recursively combine them
81
- result[key] = combineObjects([existingValue, newValue]);
82
- }
83
- else {
84
- // If one or both values are not objects, overwrite the existing value
85
- result[key] =
86
- existingValue !== null && existingValue !== undefined
87
- ? Array.isArray(existingValue)
88
- ? Array.isArray(newValue)
89
- ? [...existingValue, ...newValue]
90
- : [...existingValue, newValue]
91
- : Array.isArray(newValue)
92
- ? [existingValue, ...newValue]
93
- : [existingValue, newValue]
94
- : newValue;
95
- }
96
- }
97
- }
98
- }
99
- return result;
100
- };
101
59
  /**
102
60
  * Type guard function to check if the input is a number.
103
61
  *
@@ -178,11 +136,7 @@ export const isIP = (input) => /^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$
178
136
  *
179
137
  * Note: Recognizes both boolean literals (true, false) and their string representations ("true", "false").
180
138
  */
181
- export const isBoolean = (input) => typeof input === "boolean" ||
182
- input === "true" ||
183
- input === "false" ||
184
- input === true ||
185
- input === false;
139
+ export const isBoolean = (input) => typeof input === "boolean" || input === "true" || input === "false";
186
140
  /**
187
141
  * Type guard function to check if the input is a password based on a specific length criterion.
188
142
  *
@@ -217,7 +217,7 @@ export const isEqual = (originalValue, comparedAtValue, fieldType) => {
217
217
  return Number(originalValue) === Number(comparedAtValue);
218
218
  // Default comparison.
219
219
  default:
220
- return originalValue === comparedAtValue;
220
+ return originalValue == comparedAtValue;
221
221
  }
222
222
  };
223
223
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inibase",
3
- "version": "1.0.0-rc.53",
3
+ "version": "1.0.0-rc.55",
4
4
  "author": {
5
5
  "name": "Karim Amahtil",
6
6
  "email": "karim.amahtil@gmail.com"
@@ -87,7 +87,7 @@
87
87
  "scripts": {
88
88
  "build": "npx tsc",
89
89
  "test": "npx tsx watch --expose-gc --env-file=.env ./index.test",
90
- "benchmark": "npx tsx watch --env-file=.env ./benchmark/index",
90
+ "benchmark": "npx tsx --env-file=.env ./benchmark/index",
91
91
  "benchmark:single": "npx tsx --expose-gc --env-file=.env ./benchmark/single",
92
92
  "benchmark:bulk": "npx tsx --expose-gc --env-file=.env ./benchmark/bulk"
93
93
  }