inibase 1.0.0-rc.96 → 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 +1 -1
- package/dist/index.js +48 -59
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +16 -5
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
280
|
+
throw this.Error("NO_SCHEMA", tableName);
|
|
281
281
|
if (!(await File.isExists(join(this.databasePath, tableName, `id${this.getFileExtension(tableName)}`))))
|
|
282
|
-
throw this.
|
|
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.
|
|
296
|
+
throw this.Error("FIELD_REQUIRED", field.key);
|
|
296
297
|
return;
|
|
297
298
|
}
|
|
298
|
-
if (
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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],
|
|
@@ -368,12 +368,6 @@ export default class Inibase {
|
|
|
368
368
|
: UtilsServer.hashPassword(String(value));
|
|
369
369
|
case "number":
|
|
370
370
|
return Utils.isNumber(value) ? Number(value) : null;
|
|
371
|
-
case "date": {
|
|
372
|
-
if (Utils.isNumber(value))
|
|
373
|
-
return value;
|
|
374
|
-
const dateToTimestamp = Date.parse(value);
|
|
375
|
-
return Number.isNaN(dateToTimestamp) ? null : dateToTimestamp;
|
|
376
|
-
}
|
|
377
371
|
case "id":
|
|
378
372
|
return Utils.isNumber(value)
|
|
379
373
|
? value
|
|
@@ -403,7 +397,7 @@ export default class Inibase {
|
|
|
403
397
|
continue;
|
|
404
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);
|
|
405
399
|
if (searchResult && totalLines > 0)
|
|
406
|
-
throw this.
|
|
400
|
+
throw this.Error("FIELD_UNIQUE", [
|
|
407
401
|
field.key,
|
|
408
402
|
Array.isArray(values) ? values.join(", ") : values,
|
|
409
403
|
]);
|
|
@@ -701,13 +695,6 @@ export default class Inibase {
|
|
|
701
695
|
if (item !== null && item !== undefined)
|
|
702
696
|
RETURN[index][field.key] = item;
|
|
703
697
|
}
|
|
704
|
-
// else
|
|
705
|
-
// RETURN = Object.fromEntries(
|
|
706
|
-
// Object.entries(RETURN).map(([index, data]) => [
|
|
707
|
-
// index,
|
|
708
|
-
// { ...data, [field.key]: this.getDefaultValue(field) },
|
|
709
|
-
// ]),
|
|
710
|
-
// );
|
|
711
698
|
}
|
|
712
699
|
}
|
|
713
700
|
return RETURN;
|
|
@@ -870,7 +857,7 @@ export default class Inibase {
|
|
|
870
857
|
let RETURN;
|
|
871
858
|
let schema = (await this.getTable(tableName)).schema;
|
|
872
859
|
if (!schema)
|
|
873
|
-
throw this.
|
|
860
|
+
throw this.Error("NO_SCHEMA", tableName);
|
|
874
861
|
if (!(await File.isExists(join(tablePath, `id${this.getFileExtension(tableName)}`))))
|
|
875
862
|
return null;
|
|
876
863
|
if (options.columns?.length)
|
|
@@ -1084,11 +1071,12 @@ export default class Inibase {
|
|
|
1084
1071
|
};
|
|
1085
1072
|
const tablePath = join(this.databasePath, tableName), schema = (await this.getTable(tableName)).schema;
|
|
1086
1073
|
if (!schema)
|
|
1087
|
-
throw this.
|
|
1074
|
+
throw this.Error("NO_SCHEMA", tableName);
|
|
1088
1075
|
if (!returnPostedData)
|
|
1089
1076
|
returnPostedData = false;
|
|
1090
|
-
let RETURN;
|
|
1091
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));
|
|
1092
1080
|
let lastId = 0, renameList = [];
|
|
1093
1081
|
try {
|
|
1094
1082
|
await File.lock(join(tablePath, ".tmp"), keys);
|
|
@@ -1106,25 +1094,24 @@ export default class Inibase {
|
|
|
1106
1094
|
else
|
|
1107
1095
|
this.totalItems[`${tableName}-*`] = 0;
|
|
1108
1096
|
if (Utils.isArrayOfObjects(data))
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
createdAt
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
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
|
+
}
|
|
1121
1108
|
await this.checkUnique(tableName, schema);
|
|
1122
|
-
|
|
1109
|
+
data = this.formatData(data, schema);
|
|
1123
1110
|
const pathesContents = this.joinPathesContents(tableName, this.tables[tableName].config.prepend
|
|
1124
|
-
? Array.isArray(
|
|
1125
|
-
?
|
|
1126
|
-
:
|
|
1127
|
-
:
|
|
1111
|
+
? Array.isArray(data)
|
|
1112
|
+
? data.toReversed()
|
|
1113
|
+
: data
|
|
1114
|
+
: data);
|
|
1128
1115
|
await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(this.tables[tableName].config.prepend
|
|
1129
1116
|
? await File.prepend(path, content)
|
|
1130
1117
|
: await File.append(path, content))));
|
|
@@ -1132,17 +1119,19 @@ export default class Inibase {
|
|
|
1132
1119
|
renameList = [];
|
|
1133
1120
|
if (this.tables[tableName].config.cache)
|
|
1134
1121
|
await this.clearCache(tableName);
|
|
1135
|
-
this.totalItems[`${tableName}-*`] += Array.isArray(
|
|
1136
|
-
?
|
|
1122
|
+
this.totalItems[`${tableName}-*`] += Array.isArray(data)
|
|
1123
|
+
? data.length
|
|
1137
1124
|
: 1;
|
|
1138
1125
|
await writeFile(join(tablePath, ".cache", ".pagination"), `${lastId},${this.totalItems[`${tableName}-*`]}`);
|
|
1139
1126
|
if (returnPostedData)
|
|
1140
1127
|
return this.get(tableName, this.tables[tableName].config.prepend
|
|
1141
|
-
? Array.isArray(
|
|
1142
|
-
?
|
|
1128
|
+
? Array.isArray(data)
|
|
1129
|
+
? data.map((_, index) => index + 1).toReversed()
|
|
1143
1130
|
: 1
|
|
1144
|
-
: Array.isArray(
|
|
1145
|
-
?
|
|
1131
|
+
: Array.isArray(data)
|
|
1132
|
+
? data
|
|
1133
|
+
.map((_, index) => this.totalItems[`${tableName}-*`] - index)
|
|
1134
|
+
.toReversed()
|
|
1146
1135
|
: this.totalItems[`${tableName}-*`], options, !Utils.isArrayOfObjects(data));
|
|
1147
1136
|
}
|
|
1148
1137
|
finally {
|
|
@@ -1162,12 +1151,12 @@ export default class Inibase {
|
|
|
1162
1151
|
if (!where) {
|
|
1163
1152
|
if (Utils.isArrayOfObjects(data)) {
|
|
1164
1153
|
if (!data.every((item) => Object.hasOwn(item, "id") && Utils.isValidID(item.id)))
|
|
1165
|
-
throw this.
|
|
1154
|
+
throw this.Error("INVALID_ID");
|
|
1166
1155
|
return this.put(tableName, data, data.map(({ id }) => id), options, returnUpdatedData || undefined);
|
|
1167
1156
|
}
|
|
1168
1157
|
if (Object.hasOwn(data, "id")) {
|
|
1169
1158
|
if (!Utils.isValidID(data.id))
|
|
1170
|
-
throw this.
|
|
1159
|
+
throw this.Error("INVALID_ID", data.id);
|
|
1171
1160
|
return this.put(tableName, data, data.id, options, returnUpdatedData || undefined);
|
|
1172
1161
|
}
|
|
1173
1162
|
let totalItems;
|
|
@@ -1250,7 +1239,7 @@ export default class Inibase {
|
|
|
1250
1239
|
return this.put(tableName, data, lineNumbers, options, returnUpdatedData || undefined);
|
|
1251
1240
|
}
|
|
1252
1241
|
else
|
|
1253
|
-
throw this.
|
|
1242
|
+
throw this.Error("INVALID_PARAMETERS");
|
|
1254
1243
|
}
|
|
1255
1244
|
/**
|
|
1256
1245
|
* Delete item(s) in a table
|
|
@@ -1313,7 +1302,7 @@ export default class Inibase {
|
|
|
1313
1302
|
return this.delete(tableName, lineNumbers);
|
|
1314
1303
|
}
|
|
1315
1304
|
else
|
|
1316
|
-
throw this.
|
|
1305
|
+
throw this.Error("INVALID_PARAMETERS");
|
|
1317
1306
|
return false;
|
|
1318
1307
|
}
|
|
1319
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
|
|
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
|
|
38
|
-
|
|
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
|
|
156
|
-
|
|
157
|
-
|
|
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
|
*
|