inibase 1.0.0-rc.95 → 1.0.0-rc.97

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 CHANGED
@@ -60,7 +60,7 @@ export default class Inibase {
60
60
  private checkIFunique;
61
61
  private totalItems;
62
62
  constructor(database: string, mainFolder?: string);
63
- private throwError;
63
+ private Error;
64
64
  private getFileExtension;
65
65
  private _schemaToIdsPath;
66
66
  /**
package/dist/index.js CHANGED
@@ -25,14 +25,14 @@ export default class Inibase {
25
25
  if (!process.env.INIBASE_SECRET) {
26
26
  if (existsSync(".env") &&
27
27
  readFileSync(".env").includes("INIBASE_SECRET="))
28
- throw this.throwError("NO_ENV");
28
+ throw this.Error("NO_ENV");
29
29
  this.salt = scryptSync(randomBytes(16), randomBytes(16), 32);
30
30
  appendFileSync(".env", `\nINIBASE_SECRET=${this.salt.toString("hex")}\n`);
31
31
  }
32
32
  else
33
33
  this.salt = Buffer.from(process.env.INIBASE_SECRET, "hex");
34
34
  }
35
- throwError(code, variable, language = "en") {
35
+ Error(code, variable, language = "en") {
36
36
  const errorMessages = {
37
37
  en: {
38
38
  FIELD_UNIQUE: "Field {variable} should be unique, got {variable} instead",
@@ -90,7 +90,7 @@ export default class Inibase {
90
90
  async createTable(tableName, schema, config) {
91
91
  const tablePath = join(this.databasePath, tableName);
92
92
  if (await File.isExists(tablePath))
93
- throw this.throwError("TABLE_EXISTS", tableName);
93
+ throw this.Error("TABLE_EXISTS", tableName);
94
94
  await mkdir(join(tablePath, ".tmp"), { recursive: true });
95
95
  await mkdir(join(tablePath, ".cache"));
96
96
  // if config not set => load default global env config
@@ -228,7 +228,7 @@ export default class Inibase {
228
228
  async getTable(tableName) {
229
229
  const tablePath = join(this.databasePath, tableName);
230
230
  if (!(await File.isExists(tablePath)))
231
- throw this.throwError("TABLE_NOT_EXISTS", tableName);
231
+ throw this.Error("TABLE_NOT_EXISTS", tableName);
232
232
  if (!this.tables[tableName])
233
233
  this.tables[tableName] = {
234
234
  schema: await this.getTableSchema(tableName),
@@ -277,9 +277,9 @@ export default class Inibase {
277
277
  async throwErrorIfTableEmpty(tableName) {
278
278
  const table = await this.getTable(tableName);
279
279
  if (!table.schema)
280
- throw this.throwError("NO_SCHEMA", tableName);
280
+ throw this.Error("NO_SCHEMA", tableName);
281
281
  if (!(await File.isExists(join(this.databasePath, tableName, `id${this.getFileExtension(tableName)}`))))
282
- throw this.throwError("NO_ITEMS", tableName);
282
+ throw this.Error("NO_ITEMS", tableName);
283
283
  return table;
284
284
  }
285
285
  validateData(data, schema, skipRequiredField = false) {
@@ -290,18 +290,18 @@ export default class Inibase {
290
290
  for (const field of schema) {
291
291
  if (!Object.hasOwn(data, field.key) ||
292
292
  data[field.key] === null ||
293
- data[field.key] === undefined) {
293
+ data[field.key] === undefined ||
294
+ data[field.key] === "") {
294
295
  if (field.required && !skipRequiredField)
295
- throw this.throwError("FIELD_REQUIRED", field.key);
296
+ throw this.Error("FIELD_REQUIRED", field.key);
296
297
  return;
297
298
  }
298
- if (Object.hasOwn(data, field.key) &&
299
- !Utils.validateFieldType(data[field.key], field.type, (field.type === "array" || field.type === "object") &&
300
- field.children &&
301
- !Utils.isArrayOfObjects(field.children)
302
- ? field.children
303
- : undefined))
304
- throw this.throwError("INVALID_TYPE", [
299
+ if (!Utils.validateFieldType(data[field.key], field.type, (field.type === "array" || field.type === "object") &&
300
+ field.children &&
301
+ !Utils.isArrayOfObjects(field.children)
302
+ ? field.children
303
+ : undefined))
304
+ throw this.Error("INVALID_TYPE", [
305
305
  field.key,
306
306
  Array.isArray(field.type) ? field.type.join(", ") : field.type,
307
307
  data[field.key],
@@ -328,11 +328,10 @@ export default class Inibase {
328
328
  }
329
329
  formatField(value, fieldType, fieldChildrenType, _formatOnlyAvailiableKeys) {
330
330
  if (Array.isArray(fieldType))
331
- fieldType = (Utils.detectFieldType(value, fieldType) ??
332
- fieldType[0]);
331
+ fieldType = Utils.detectFieldType(value, fieldType) ?? fieldType[0];
333
332
  if (!value)
334
333
  return null;
335
- if (fieldType !== "array" && fieldType !== "json" && Array.isArray(value))
334
+ if (Array.isArray(value) && !["array", "json"].includes(fieldType))
336
335
  value = value[0];
337
336
  switch (fieldType) {
338
337
  case "array":
@@ -369,12 +368,6 @@ export default class Inibase {
369
368
  : UtilsServer.hashPassword(String(value));
370
369
  case "number":
371
370
  return Utils.isNumber(value) ? Number(value) : null;
372
- case "date": {
373
- if (Utils.isNumber(value))
374
- return value;
375
- const dateToTimestamp = Date.parse(value);
376
- return Number.isNaN(dateToTimestamp) ? null : dateToTimestamp;
377
- }
378
371
  case "id":
379
372
  return Utils.isNumber(value)
380
373
  ? value
@@ -404,7 +397,7 @@ export default class Inibase {
404
397
  continue;
405
398
  const [searchResult, totalLines] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), Array.isArray(values) ? "=" : "[]", values, undefined, field.type, field.children, 1, undefined, false, this.salt);
406
399
  if (searchResult && totalLines > 0)
407
- throw this.throwError("FIELD_UNIQUE", [
400
+ throw this.Error("FIELD_UNIQUE", [
408
401
  field.key,
409
402
  Array.isArray(values) ? values.join(", ") : values,
410
403
  ]);
@@ -702,13 +695,6 @@ export default class Inibase {
702
695
  if (item !== null && item !== undefined)
703
696
  RETURN[index][field.key] = item;
704
697
  }
705
- // else
706
- // RETURN = Object.fromEntries(
707
- // Object.entries(RETURN).map(([index, data]) => [
708
- // index,
709
- // { ...data, [field.key]: this.getDefaultValue(field) },
710
- // ]),
711
- // );
712
698
  }
713
699
  }
714
700
  return RETURN;
@@ -871,7 +857,7 @@ export default class Inibase {
871
857
  let RETURN;
872
858
  let schema = (await this.getTable(tableName)).schema;
873
859
  if (!schema)
874
- throw this.throwError("NO_SCHEMA", tableName);
860
+ throw this.Error("NO_SCHEMA", tableName);
875
861
  if (!(await File.isExists(join(tablePath, `id${this.getFileExtension(tableName)}`))))
876
862
  return null;
877
863
  if (options.columns?.length)
@@ -1085,11 +1071,12 @@ export default class Inibase {
1085
1071
  };
1086
1072
  const tablePath = join(this.databasePath, tableName), schema = (await this.getTable(tableName)).schema;
1087
1073
  if (!schema)
1088
- throw this.throwError("NO_SCHEMA", tableName);
1074
+ throw this.Error("NO_SCHEMA", tableName);
1089
1075
  if (!returnPostedData)
1090
1076
  returnPostedData = false;
1091
- let RETURN;
1092
1077
  const keys = UtilsServer.hashString(Object.keys(Array.isArray(data) ? data[0] : data).join("."));
1078
+ // Skip Id and (created|updated)At
1079
+ this.validateData(data, schema.slice(1, -2));
1093
1080
  let lastId = 0, renameList = [];
1094
1081
  try {
1095
1082
  await File.lock(join(tablePath, ".tmp"), keys);
@@ -1107,25 +1094,24 @@ export default class Inibase {
1107
1094
  else
1108
1095
  this.totalItems[`${tableName}-*`] = 0;
1109
1096
  if (Utils.isArrayOfObjects(data))
1110
- RETURN = data.map(({ id, updatedAt, createdAt, ...rest }) => ({
1111
- id: ++lastId,
1112
- ...rest,
1113
- createdAt: Date.now(),
1114
- }));
1115
- else
1116
- RETURN = (({ id, updatedAt, createdAt, ...rest }) => ({
1117
- id: ++lastId,
1118
- ...rest,
1119
- createdAt: Date.now(),
1120
- }))(data);
1121
- this.validateData(RETURN, schema);
1097
+ for (let index = 0; index < data.length; index++) {
1098
+ const element = data[index];
1099
+ element.id = ++lastId;
1100
+ element.createdAt = Date.now();
1101
+ element.updatedAt = undefined;
1102
+ }
1103
+ else {
1104
+ data.id = ++lastId;
1105
+ data.createdAt = Date.now();
1106
+ data.updatedAt = undefined;
1107
+ }
1122
1108
  await this.checkUnique(tableName, schema);
1123
- RETURN = this.formatData(RETURN, schema);
1109
+ data = this.formatData(data, schema);
1124
1110
  const pathesContents = this.joinPathesContents(tableName, this.tables[tableName].config.prepend
1125
- ? Array.isArray(RETURN)
1126
- ? RETURN.toReversed()
1127
- : RETURN
1128
- : RETURN);
1111
+ ? Array.isArray(data)
1112
+ ? data.toReversed()
1113
+ : data
1114
+ : data);
1129
1115
  await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(this.tables[tableName].config.prepend
1130
1116
  ? await File.prepend(path, content)
1131
1117
  : await File.append(path, content))));
@@ -1133,17 +1119,19 @@ export default class Inibase {
1133
1119
  renameList = [];
1134
1120
  if (this.tables[tableName].config.cache)
1135
1121
  await this.clearCache(tableName);
1136
- this.totalItems[`${tableName}-*`] += Array.isArray(RETURN)
1137
- ? RETURN.length
1122
+ this.totalItems[`${tableName}-*`] += Array.isArray(data)
1123
+ ? data.length
1138
1124
  : 1;
1139
1125
  await writeFile(join(tablePath, ".cache", ".pagination"), `${lastId},${this.totalItems[`${tableName}-*`]}`);
1140
1126
  if (returnPostedData)
1141
1127
  return this.get(tableName, this.tables[tableName].config.prepend
1142
- ? Array.isArray(RETURN)
1143
- ? RETURN.map((_, index) => index + 1).toReversed()
1128
+ ? Array.isArray(data)
1129
+ ? data.map((_, index) => index + 1).toReversed()
1144
1130
  : 1
1145
- : Array.isArray(RETURN)
1146
- ? RETURN.map((_, index) => this.totalItems[`${tableName}-*`] - index).toReversed()
1131
+ : Array.isArray(data)
1132
+ ? data
1133
+ .map((_, index) => this.totalItems[`${tableName}-*`] - index)
1134
+ .toReversed()
1147
1135
  : this.totalItems[`${tableName}-*`], options, !Utils.isArrayOfObjects(data));
1148
1136
  }
1149
1137
  finally {
@@ -1163,12 +1151,12 @@ export default class Inibase {
1163
1151
  if (!where) {
1164
1152
  if (Utils.isArrayOfObjects(data)) {
1165
1153
  if (!data.every((item) => Object.hasOwn(item, "id") && Utils.isValidID(item.id)))
1166
- throw this.throwError("INVALID_ID");
1154
+ throw this.Error("INVALID_ID");
1167
1155
  return this.put(tableName, data, data.map(({ id }) => id), options, returnUpdatedData || undefined);
1168
1156
  }
1169
1157
  if (Object.hasOwn(data, "id")) {
1170
1158
  if (!Utils.isValidID(data.id))
1171
- throw this.throwError("INVALID_ID", data.id);
1159
+ throw this.Error("INVALID_ID", data.id);
1172
1160
  return this.put(tableName, data, data.id, options, returnUpdatedData || undefined);
1173
1161
  }
1174
1162
  let totalItems;
@@ -1251,7 +1239,7 @@ export default class Inibase {
1251
1239
  return this.put(tableName, data, lineNumbers, options, returnUpdatedData || undefined);
1252
1240
  }
1253
1241
  else
1254
- throw this.throwError("INVALID_PARAMETERS");
1242
+ throw this.Error("INVALID_PARAMETERS");
1255
1243
  }
1256
1244
  /**
1257
1245
  * Delete item(s) in a table
@@ -1314,7 +1302,7 @@ export default class Inibase {
1314
1302
  return this.delete(tableName, lineNumbers);
1315
1303
  }
1316
1304
  else
1317
- throw this.throwError("INVALID_PARAMETERS");
1305
+ throw this.Error("INVALID_PARAMETERS");
1318
1306
  return false;
1319
1307
  }
1320
1308
  async sum(tableName, columns, where) {
package/dist/utils.d.ts CHANGED
@@ -125,7 +125,7 @@ export declare const isPassword: (input: any) => input is string;
125
125
  * @param input - The input to be checked, can be of any type.
126
126
  * @returns A boolean indicating whether the input is a valid date.
127
127
  */
128
- export declare const isDate: (input: any) => boolean;
128
+ export declare function isDate(input?: any): boolean;
129
129
  /**
130
130
  * Checks if the input is a valid ID.
131
131
  *
package/dist/utils.js CHANGED
@@ -34,8 +34,8 @@ export const isArrayOfNulls = (input) => input.every((_input) => Array.isArray(_
34
34
  * Note: Checks if the input is non-null and either has 'Object' as its constructor name or is of type 'object' without being an array.
35
35
  */
36
36
  export const isObject = (obj) => obj != null &&
37
- (obj.constructor.name === "Object" ||
38
- (typeof obj === "object" && !Array.isArray(obj)));
37
+ ((typeof obj === "object" && !Array.isArray(obj)) ||
38
+ obj.constructor?.name === "Object");
39
39
  /**
40
40
  * Recursively merges properties from a source object into a target object. If a property exists in both, the source's value overwrites the target's.
41
41
  *
@@ -152,9 +152,20 @@ export const isPassword = (input) => typeof input === "string" && input.length =
152
152
  * @param input - The input to be checked, can be of any type.
153
153
  * @returns A boolean indicating whether the input is a valid date.
154
154
  */
155
- export const isDate = (input) => !Number.isNaN(new Date(input).getTime()) ||
156
- !Number.isNaN(Date.parse(input)) ||
157
- !!input.match(/\b\d{2}[/.-]\d{2}[/.-]\d{4}\b/);
155
+ export function isDate(input) {
156
+ // Check if the input is null, undefined, or an empty string
157
+ if (input == null || input === "")
158
+ return false;
159
+ // Convert to number and check if it's a valid number
160
+ const numTimestamp = Number(input);
161
+ // Check if the converted number is NaN or not finite
162
+ if (Number.isNaN(numTimestamp) || !Number.isFinite(numTimestamp))
163
+ return false;
164
+ // Create a Date object from the timestamp
165
+ const date = new Date(numTimestamp);
166
+ // Check if the date is valid
167
+ return date.getTime() === numTimestamp;
168
+ }
158
169
  /**
159
170
  * Checks if the input is a valid ID.
160
171
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inibase",
3
- "version": "1.0.0-rc.95",
3
+ "version": "1.0.0-rc.97",
4
4
  "type": "module",
5
5
  "author": {
6
6
  "name": "Karim Amahtil",