inibase 1.0.0-rc.18 → 1.0.0-rc.20
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/file.js +6 -6
- package/dist/index.d.ts +3 -0
- package/dist/index.js +305 -306
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +10 -4
- package/package.json +2 -2
package/dist/file.js
CHANGED
|
@@ -51,7 +51,7 @@ export const encode = (input, secretKey) => {
|
|
|
51
51
|
? joinMultidimensionalArray(secureArray(input))
|
|
52
52
|
: secureString(input);
|
|
53
53
|
};
|
|
54
|
-
const unSecureString = (input) =>
|
|
54
|
+
const unSecureString = (input) => input
|
|
55
55
|
.replaceAll("<", "<")
|
|
56
56
|
.replaceAll(">", ">")
|
|
57
57
|
.replaceAll("%2C", ",")
|
|
@@ -93,11 +93,11 @@ const decodeHelper = (value, fieldType, fieldChildrenType, secretKey) => {
|
|
|
93
93
|
if (!Array.isArray(value))
|
|
94
94
|
return [value];
|
|
95
95
|
if (fieldChildrenType)
|
|
96
|
-
return
|
|
97
|
-
?
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
return fieldChildrenType
|
|
97
|
+
? value.map((v) => decode(v, Array.isArray(fieldChildrenType)
|
|
98
|
+
? detectFieldType(v, fieldChildrenType)
|
|
99
|
+
: fieldChildrenType, undefined, secretKey))
|
|
100
|
+
: value;
|
|
101
101
|
case "id":
|
|
102
102
|
return isNumber(value) ? encodeID(value, secretKey) : value;
|
|
103
103
|
default:
|
package/dist/index.d.ts
CHANGED
|
@@ -73,6 +73,9 @@ export default class Inibase {
|
|
|
73
73
|
formatData<dataType extends Data | Data[]>(data: dataType, schema: Schema, formatOnlyAvailiableKeys?: boolean): dataType extends Data ? Data : Data[];
|
|
74
74
|
private getDefaultValue;
|
|
75
75
|
private joinPathesContents;
|
|
76
|
+
private getItemsFromSchema;
|
|
77
|
+
private FormatObjectCriteriaValue;
|
|
78
|
+
private applyCriteria;
|
|
76
79
|
get(tableName: string, where?: string | number | (string | number)[] | Criteria | undefined, options?: Options | undefined, onlyOne?: true, onlyLinesNumbers?: undefined): Promise<Data | null>;
|
|
77
80
|
get(tableName: string, where?: string | number | (string | number)[] | Criteria | undefined, options?: Options | undefined, onlyOne?: boolean | undefined, onlyLinesNumbers?: true): Promise<number[] | null>;
|
|
78
81
|
post(tableName: string, data: Data | Data[], options: Options | undefined, returnPostedData?: false): Promise<void | null>;
|
package/dist/index.js
CHANGED
|
@@ -291,6 +291,304 @@ export default class Inibase {
|
|
|
291
291
|
File.encode(value, this.salt),
|
|
292
292
|
]));
|
|
293
293
|
}
|
|
294
|
+
async getItemsFromSchema(tableName, schema, linesNumber, options, prefix) {
|
|
295
|
+
const path = join(this.folder, this.database, tableName);
|
|
296
|
+
let RETURN = {};
|
|
297
|
+
for (const field of schema) {
|
|
298
|
+
if ((field.type === "array" ||
|
|
299
|
+
(Array.isArray(field.type) &&
|
|
300
|
+
field.type.includes("array"))) &&
|
|
301
|
+
field.children) {
|
|
302
|
+
if (Utils.isArrayOfObjects(field.children)) {
|
|
303
|
+
if (field.children.filter((children) => children.type === "array" &&
|
|
304
|
+
Utils.isArrayOfObjects(children.children)).length) {
|
|
305
|
+
// one of children has array field type and has children array of object = Schema
|
|
306
|
+
Object.entries((await this.getItemsFromSchema(tableName, field.children.filter((children) => children.type === "array" &&
|
|
307
|
+
Utils.isArrayOfObjects(children.children)), linesNumber, options, (prefix ?? "") + field.key + ".")) ?? {}).forEach(([index, item]) => {
|
|
308
|
+
if (Utils.isObject(item)) {
|
|
309
|
+
if (!RETURN[index])
|
|
310
|
+
RETURN[index] = {};
|
|
311
|
+
if (!RETURN[index][field.key])
|
|
312
|
+
RETURN[index][field.key] = [];
|
|
313
|
+
for (const child_field of field.children.filter((children) => children.type === "array" &&
|
|
314
|
+
Utils.isArrayOfObjects(children.children))) {
|
|
315
|
+
if (Utils.isObject(item[child_field.key])) {
|
|
316
|
+
Object.entries(item[child_field.key]).forEach(([key, value]) => {
|
|
317
|
+
if (!Utils.isArrayOfArrays(value))
|
|
318
|
+
value = value.map((_value) => child_field.type === "array" ? [[_value]] : [_value]);
|
|
319
|
+
for (let _i = 0; _i < value.length; _i++) {
|
|
320
|
+
if (Utils.isArrayOfNulls(value[_i]))
|
|
321
|
+
continue;
|
|
322
|
+
if (!RETURN[index][field.key][_i])
|
|
323
|
+
RETURN[index][field.key][_i] = {};
|
|
324
|
+
if (!RETURN[index][field.key][_i][child_field.key])
|
|
325
|
+
RETURN[index][field.key][_i][child_field.key] = [];
|
|
326
|
+
value[_i].forEach((_element, _index) => {
|
|
327
|
+
if (!RETURN[index][field.key][_i][child_field.key][_index])
|
|
328
|
+
RETURN[index][field.key][_i][child_field.key][_index] = {};
|
|
329
|
+
RETURN[index][field.key][_i][child_field.key][_index][key] = _element;
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
field.children = field.children.filter((children) => children.type !== "array" ||
|
|
338
|
+
!Utils.isArrayOfObjects(children.children));
|
|
339
|
+
}
|
|
340
|
+
Object.entries((await this.getItemsFromSchema(tableName, field.children, linesNumber, options, (prefix ?? "") + field.key + ".")) ?? {}).forEach(([index, item]) => {
|
|
341
|
+
if (!RETURN[index])
|
|
342
|
+
RETURN[index] = {};
|
|
343
|
+
if (Utils.isObject(item)) {
|
|
344
|
+
if (!Object.values(item).every((i) => i === null)) {
|
|
345
|
+
if (RETURN[index][field.key]) {
|
|
346
|
+
Object.entries(item).forEach(([key, value], _index) => {
|
|
347
|
+
RETURN[index][field.key] = RETURN[index][field.key].map((_obj, _i) => ({
|
|
348
|
+
..._obj,
|
|
349
|
+
[key]: value[_i],
|
|
350
|
+
}));
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
else if (Object.values(item).every((_i) => Utils.isArrayOfArrays(_i) || Array.isArray(_i)))
|
|
354
|
+
RETURN[index][field.key] = item;
|
|
355
|
+
else {
|
|
356
|
+
RETURN[index][field.key] = [];
|
|
357
|
+
Object.entries(item).forEach(([key, value]) => {
|
|
358
|
+
for (let _i = 0; _i < value.length; _i++) {
|
|
359
|
+
if (value[_i] === null ||
|
|
360
|
+
(Array.isArray(value[_i]) &&
|
|
361
|
+
value[_i].every((_item) => _item === null)))
|
|
362
|
+
continue;
|
|
363
|
+
if (!RETURN[index][field.key][_i])
|
|
364
|
+
RETURN[index][field.key][_i] = {};
|
|
365
|
+
RETURN[index][field.key][_i][key] = value[_i];
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
else
|
|
371
|
+
RETURN[index][field.key] = null;
|
|
372
|
+
}
|
|
373
|
+
else
|
|
374
|
+
RETURN[index][field.key] = item;
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
else if (field.children === "table" ||
|
|
378
|
+
(Array.isArray(field.children) && field.children.includes("table"))) {
|
|
379
|
+
if (options.columns)
|
|
380
|
+
options.columns = options.columns
|
|
381
|
+
.filter((column) => column.includes(`${field.key}.`))
|
|
382
|
+
.map((column) => column.replace(`${field.key}.`, ""));
|
|
383
|
+
const [items, total_lines] = await File.get(join(path, (prefix ?? "") + field.key + ".inib"), linesNumber, field.type, field.children, this.salt);
|
|
384
|
+
this.totalItems[tableName + "-" + field.key] = total_lines;
|
|
385
|
+
for (const [index, item] of Object.entries(items)) {
|
|
386
|
+
if (!RETURN[index])
|
|
387
|
+
RETURN[index] = {};
|
|
388
|
+
RETURN[index][field.key] = item
|
|
389
|
+
? await this.get(field.key, item, options)
|
|
390
|
+
: this.getDefaultValue(field);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else if (await File.isExists(join(path, (prefix ?? "") + field.key + ".inib"))) {
|
|
394
|
+
const [items, total_lines] = await File.get(join(path, (prefix ?? "") + field.key + ".inib"), linesNumber, field.type, field?.children, this.salt);
|
|
395
|
+
this.totalItems[tableName + "-" + field.key] = total_lines;
|
|
396
|
+
for (const [index, item] of Object.entries(items)) {
|
|
397
|
+
if (!RETURN[index])
|
|
398
|
+
RETURN[index] = {};
|
|
399
|
+
RETURN[index][field.key] = item ?? this.getDefaultValue(field);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
else if (field.type === "object") {
|
|
404
|
+
for (const [index, item] of Object.entries((await this.getItemsFromSchema(tableName, field.children, linesNumber, options, (prefix ?? "") + field.key + ".")) ?? {})) {
|
|
405
|
+
if (!RETURN[index])
|
|
406
|
+
RETURN[index] = {};
|
|
407
|
+
if (Utils.isObject(item)) {
|
|
408
|
+
if (!Object.values(item).every((i) => i === null))
|
|
409
|
+
RETURN[index][field.key] = item;
|
|
410
|
+
else
|
|
411
|
+
RETURN[index][field.key] = null;
|
|
412
|
+
}
|
|
413
|
+
else
|
|
414
|
+
RETURN[index][field.key] = null;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
else if (field.type === "table") {
|
|
418
|
+
if ((await File.isExists(join(this.folder, this.database, field.key))) &&
|
|
419
|
+
(await File.isExists(join(path, (prefix ?? "") + field.key + ".inib")))) {
|
|
420
|
+
if (options.columns)
|
|
421
|
+
options.columns = options.columns
|
|
422
|
+
.filter((column) => column.includes(`${field.key}.`) &&
|
|
423
|
+
!column.includes(`${field.key}.`))
|
|
424
|
+
.map((column) => column.replace(`${field.key}.`, ""));
|
|
425
|
+
const [items, total_lines] = await File.get(join(path, (prefix ?? "") + field.key + ".inib"), linesNumber, "number", undefined, this.salt);
|
|
426
|
+
this.totalItems[tableName + "-" + field.key] = total_lines;
|
|
427
|
+
for (const [index, item] of Object.entries(items)) {
|
|
428
|
+
if (!RETURN[index])
|
|
429
|
+
RETURN[index] = {};
|
|
430
|
+
RETURN[index][field.key] = item
|
|
431
|
+
? await this.get(field.key, item, options)
|
|
432
|
+
: this.getDefaultValue(field);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
else if (await File.isExists(join(path, (prefix ?? "") + field.key + ".inib"))) {
|
|
437
|
+
const [items, total_lines] = await File.get(join(path, (prefix ?? "") + field.key + ".inib"), linesNumber, field.type, field?.children, this.salt);
|
|
438
|
+
this.totalItems[tableName + "-" + field.key] = total_lines;
|
|
439
|
+
for (const [index, item] of Object.entries(items)) {
|
|
440
|
+
if (!RETURN[index])
|
|
441
|
+
RETURN[index] = {};
|
|
442
|
+
RETURN[index][field.key] = item ?? this.getDefaultValue(field);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return RETURN;
|
|
447
|
+
}
|
|
448
|
+
FormatObjectCriteriaValue(value, isParentArray = false) {
|
|
449
|
+
switch (value[0]) {
|
|
450
|
+
case ">":
|
|
451
|
+
case "<":
|
|
452
|
+
case "[":
|
|
453
|
+
return ["=", "]", "*"].includes(value[1])
|
|
454
|
+
? [
|
|
455
|
+
value.slice(0, 2),
|
|
456
|
+
value.slice(2),
|
|
457
|
+
]
|
|
458
|
+
: [
|
|
459
|
+
value.slice(0, 1),
|
|
460
|
+
value.slice(1),
|
|
461
|
+
];
|
|
462
|
+
case "!":
|
|
463
|
+
return ["=", "*"].includes(value[1])
|
|
464
|
+
? [
|
|
465
|
+
value.slice(0, 2),
|
|
466
|
+
value.slice(2),
|
|
467
|
+
]
|
|
468
|
+
: value[1] === "["
|
|
469
|
+
? [
|
|
470
|
+
value.slice(0, 3),
|
|
471
|
+
value.slice(3),
|
|
472
|
+
]
|
|
473
|
+
: [
|
|
474
|
+
(value.slice(0, 1) + "="),
|
|
475
|
+
value.slice(1),
|
|
476
|
+
];
|
|
477
|
+
case "=":
|
|
478
|
+
return isParentArray
|
|
479
|
+
? [
|
|
480
|
+
value.slice(0, 1),
|
|
481
|
+
value.slice(1),
|
|
482
|
+
]
|
|
483
|
+
: [
|
|
484
|
+
value.slice(0, 1),
|
|
485
|
+
(value.slice(1) + ","),
|
|
486
|
+
];
|
|
487
|
+
case "*":
|
|
488
|
+
return [
|
|
489
|
+
value.slice(0, 1),
|
|
490
|
+
value.slice(1),
|
|
491
|
+
];
|
|
492
|
+
default:
|
|
493
|
+
return ["=", value];
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
async applyCriteria(tableName, schema, options, criteria, allTrue) {
|
|
497
|
+
let RETURN = {};
|
|
498
|
+
if (!criteria)
|
|
499
|
+
return null;
|
|
500
|
+
if (criteria.and && Utils.isObject(criteria.and)) {
|
|
501
|
+
const searchResult = await this.applyCriteria(tableName, schema, options, criteria.and, true);
|
|
502
|
+
if (searchResult) {
|
|
503
|
+
RETURN = Utils.deepMerge(RETURN, Object.fromEntries(Object.entries(searchResult).filter(([_k, v], _i) => Object.keys(v).length === Object.keys(criteria.and ?? {}).length)));
|
|
504
|
+
delete criteria.and;
|
|
505
|
+
}
|
|
506
|
+
else
|
|
507
|
+
return null;
|
|
508
|
+
}
|
|
509
|
+
if (criteria.or && Utils.isObject(criteria.or)) {
|
|
510
|
+
const searchResult = await this.applyCriteria(tableName, schema, options, criteria.or, false);
|
|
511
|
+
delete criteria.or;
|
|
512
|
+
if (searchResult)
|
|
513
|
+
RETURN = Utils.deepMerge(RETURN, searchResult);
|
|
514
|
+
}
|
|
515
|
+
if (Object.keys(criteria).length > 0) {
|
|
516
|
+
if (allTrue === undefined)
|
|
517
|
+
allTrue = true;
|
|
518
|
+
let index = -1;
|
|
519
|
+
for (const [key, value] of Object.entries(criteria)) {
|
|
520
|
+
const field = this.getField(key, schema);
|
|
521
|
+
index++;
|
|
522
|
+
let searchOperator = undefined, searchComparedAtValue = undefined, searchLogicalOperator = undefined;
|
|
523
|
+
if (Utils.isObject(value)) {
|
|
524
|
+
if (value?.or &&
|
|
525
|
+
Array.isArray(value.or)) {
|
|
526
|
+
const searchCriteria = value.or
|
|
527
|
+
.map((single_or) => typeof single_or === "string"
|
|
528
|
+
? this.FormatObjectCriteriaValue(single_or)
|
|
529
|
+
: ["=", single_or])
|
|
530
|
+
.filter((a) => a);
|
|
531
|
+
if (searchCriteria.length > 0) {
|
|
532
|
+
searchOperator = searchCriteria.map((single_or) => single_or[0]);
|
|
533
|
+
searchComparedAtValue = searchCriteria.map((single_or) => single_or[1]);
|
|
534
|
+
searchLogicalOperator = "or";
|
|
535
|
+
}
|
|
536
|
+
delete value.or;
|
|
537
|
+
}
|
|
538
|
+
if (value?.and &&
|
|
539
|
+
Array.isArray(value.and)) {
|
|
540
|
+
const searchCriteria = value.and
|
|
541
|
+
.map((single_and) => typeof single_and === "string"
|
|
542
|
+
? this.FormatObjectCriteriaValue(single_and)
|
|
543
|
+
: ["=", single_and])
|
|
544
|
+
.filter((a) => a);
|
|
545
|
+
if (searchCriteria.length > 0) {
|
|
546
|
+
searchOperator = searchCriteria.map((single_and) => single_and[0]);
|
|
547
|
+
searchComparedAtValue = searchCriteria.map((single_and) => single_and[1]);
|
|
548
|
+
searchLogicalOperator = "and";
|
|
549
|
+
}
|
|
550
|
+
delete value.and;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
else if (Array.isArray(value)) {
|
|
554
|
+
const searchCriteria = value
|
|
555
|
+
.map((single) => typeof single === "string"
|
|
556
|
+
? this.FormatObjectCriteriaValue(single)
|
|
557
|
+
: ["=", single])
|
|
558
|
+
.filter((a) => a);
|
|
559
|
+
if (searchCriteria.length > 0) {
|
|
560
|
+
searchOperator = searchCriteria.map((single) => single[0]);
|
|
561
|
+
searchComparedAtValue = searchCriteria.map((single) => single[1]);
|
|
562
|
+
searchLogicalOperator = "and";
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
else if (typeof value === "string") {
|
|
566
|
+
const ComparisonOperatorValue = this.FormatObjectCriteriaValue(value);
|
|
567
|
+
if (ComparisonOperatorValue) {
|
|
568
|
+
searchOperator = ComparisonOperatorValue[0];
|
|
569
|
+
searchComparedAtValue = ComparisonOperatorValue[1];
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
searchOperator = "=";
|
|
574
|
+
searchComparedAtValue = value;
|
|
575
|
+
}
|
|
576
|
+
const [searchResult, total_lines] = await File.search(join(this.folder, this.database, tableName, key + ".inib"), searchOperator, searchComparedAtValue, searchLogicalOperator, field?.type, field?.children, options.per_page, options.page - 1 * options.per_page + 1, true, this.salt);
|
|
577
|
+
if (searchResult) {
|
|
578
|
+
RETURN = Utils.deepMerge(RETURN, searchResult);
|
|
579
|
+
this.totalItems[tableName + "-" + key] = total_lines;
|
|
580
|
+
}
|
|
581
|
+
if (allTrue && index > 0) {
|
|
582
|
+
if (!Object.keys(RETURN).length)
|
|
583
|
+
RETURN = {};
|
|
584
|
+
RETURN = Object.fromEntries(Object.entries(RETURN).filter(([_index, item]) => Object.keys(item).length > index));
|
|
585
|
+
if (!Object.keys(RETURN).length)
|
|
586
|
+
RETURN = {};
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return Object.keys(RETURN).length ? RETURN : null;
|
|
591
|
+
}
|
|
294
592
|
async get(tableName, where, options = {
|
|
295
593
|
page: 1,
|
|
296
594
|
per_page: 15,
|
|
@@ -333,166 +631,11 @@ export default class Inibase {
|
|
|
333
631
|
.filter((i) => i);
|
|
334
632
|
if (options.columns.length)
|
|
335
633
|
schema = filterSchemaByColumns(schema, options.columns);
|
|
336
|
-
const getItemsFromSchema = async (path, schema, linesNumber, prefix) => {
|
|
337
|
-
let RETURN = {};
|
|
338
|
-
for (const field of schema) {
|
|
339
|
-
if ((field.type === "array" ||
|
|
340
|
-
(Array.isArray(field.type) &&
|
|
341
|
-
field.type.includes("array"))) &&
|
|
342
|
-
field
|
|
343
|
-
.children) {
|
|
344
|
-
if (Utils.isArrayOfObjects(field
|
|
345
|
-
.children)) {
|
|
346
|
-
if (field
|
|
347
|
-
.children.filter((children) => children.type === "array" &&
|
|
348
|
-
Utils.isArrayOfObjects(children.children)).length) {
|
|
349
|
-
// one of children has array field type and has children array of object = Schema
|
|
350
|
-
Object.entries((await getItemsFromSchema(path, field.children.filter((children) => children.type === "array" &&
|
|
351
|
-
Utils.isArrayOfObjects(children.children)), linesNumber, (prefix ?? "") + field.key + ".")) ?? {}).forEach(([index, item]) => {
|
|
352
|
-
if (Utils.isObject(item)) {
|
|
353
|
-
if (!RETURN[index])
|
|
354
|
-
RETURN[index] = {};
|
|
355
|
-
if (!RETURN[index][field.key])
|
|
356
|
-
RETURN[index][field.key] = [];
|
|
357
|
-
for (const child_field of field.children.filter((children) => children.type === "array" &&
|
|
358
|
-
Utils.isArrayOfObjects(children.children))) {
|
|
359
|
-
if (Utils.isObject(item[child_field.key])) {
|
|
360
|
-
Object.entries(item[child_field.key]).forEach(([key, value]) => {
|
|
361
|
-
for (let _i = 0; _i < value.length; _i++) {
|
|
362
|
-
if (!RETURN[index][field.key][_i])
|
|
363
|
-
RETURN[index][field.key][_i] = {};
|
|
364
|
-
if (!RETURN[index][field.key][_i][child_field.key])
|
|
365
|
-
RETURN[index][field.key][_i][child_field.key] =
|
|
366
|
-
[];
|
|
367
|
-
value[_i].forEach((_element, _index) => {
|
|
368
|
-
if (!RETURN[index][field.key][_i][child_field.key][_index])
|
|
369
|
-
RETURN[index][field.key][_i][child_field.key][_index] = {};
|
|
370
|
-
RETURN[index][field.key][_i][child_field.key][_index][key] = _element;
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
field.children = field
|
|
379
|
-
.children.filter((children) => children.type !== "array" ||
|
|
380
|
-
!Utils.isArrayOfObjects(children.children));
|
|
381
|
-
}
|
|
382
|
-
Object.entries((await getItemsFromSchema(path, field
|
|
383
|
-
.children, linesNumber, (prefix ?? "") + field.key + ".")) ?? {}).forEach(([index, item]) => {
|
|
384
|
-
if (!RETURN[index])
|
|
385
|
-
RETURN[index] = {};
|
|
386
|
-
if (Utils.isObject(item)) {
|
|
387
|
-
if (!Object.values(item).every((i) => i === null)) {
|
|
388
|
-
if (RETURN[index][field.key])
|
|
389
|
-
Object.entries(item).forEach(([key, value], _index) => {
|
|
390
|
-
RETURN[index][field.key] = RETURN[index][field.key].map((_obj, _i) => ({
|
|
391
|
-
..._obj,
|
|
392
|
-
[key]: value[_i],
|
|
393
|
-
}));
|
|
394
|
-
});
|
|
395
|
-
else if (Object.values(item).every(Utils.isArrayOfArrays))
|
|
396
|
-
RETURN[index][field.key] = item;
|
|
397
|
-
else {
|
|
398
|
-
RETURN[index][field.key] = [];
|
|
399
|
-
Object.entries(item).forEach(([key, value]) => {
|
|
400
|
-
for (let _i = 0; _i < value.length; _i++) {
|
|
401
|
-
if (!RETURN[index][field.key][_i])
|
|
402
|
-
RETURN[index][field.key][_i] = {};
|
|
403
|
-
RETURN[index][field.key][_i][key] = value[_i];
|
|
404
|
-
}
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
else
|
|
409
|
-
RETURN[index][field.key] = null;
|
|
410
|
-
}
|
|
411
|
-
else
|
|
412
|
-
RETURN[index][field.key] = item;
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
else if (field
|
|
416
|
-
.children === "table" ||
|
|
417
|
-
(Array.isArray(field
|
|
418
|
-
.children) &&
|
|
419
|
-
field
|
|
420
|
-
.children.includes("table"))) {
|
|
421
|
-
if (options.columns)
|
|
422
|
-
options.columns = options.columns
|
|
423
|
-
.filter((column) => column.includes(`${field.key}.`))
|
|
424
|
-
.map((column) => column.replace(`${field.key}.`, ""));
|
|
425
|
-
const [items, total_lines] = await File.get(join(path, (prefix ?? "") + field.key + ".inib"), linesNumber, field.type, field
|
|
426
|
-
.children, this.salt);
|
|
427
|
-
this.totalItems[tableName + "-" + field.key] = total_lines;
|
|
428
|
-
for (const [index, item] of Object.entries(items)) {
|
|
429
|
-
if (!RETURN[index])
|
|
430
|
-
RETURN[index] = {};
|
|
431
|
-
RETURN[index][field.key] = item
|
|
432
|
-
? await this.get(field.key, item, options)
|
|
433
|
-
: this.getDefaultValue(field);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
else if (await File.isExists(join(path, (prefix ?? "") + field.key + ".inib"))) {
|
|
437
|
-
const [items, total_lines] = await File.get(join(path, (prefix ?? "") + field.key + ".inib"), linesNumber, field.type, field?.children, this.salt);
|
|
438
|
-
this.totalItems[tableName + "-" + field.key] = total_lines;
|
|
439
|
-
for (const [index, item] of Object.entries(items)) {
|
|
440
|
-
if (!RETURN[index])
|
|
441
|
-
RETURN[index] = {};
|
|
442
|
-
RETURN[index][field.key] = item ?? this.getDefaultValue(field);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
else if (field.type === "object") {
|
|
447
|
-
for (const [index, item] of Object.entries((await getItemsFromSchema(path, field.children, linesNumber, (prefix ?? "") + field.key + ".")) ?? {})) {
|
|
448
|
-
if (!RETURN[index])
|
|
449
|
-
RETURN[index] = {};
|
|
450
|
-
if (Utils.isObject(item)) {
|
|
451
|
-
if (!Object.values(item).every((i) => i === null))
|
|
452
|
-
RETURN[index][field.key] = item;
|
|
453
|
-
else
|
|
454
|
-
RETURN[index][field.key] = null;
|
|
455
|
-
}
|
|
456
|
-
else
|
|
457
|
-
RETURN[index][field.key] = null;
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
else if (field.type === "table") {
|
|
461
|
-
if ((await File.isExists(join(this.folder, this.database, field.key))) &&
|
|
462
|
-
(await File.isExists(join(path, (prefix ?? "") + field.key + ".inib")))) {
|
|
463
|
-
if (options.columns)
|
|
464
|
-
options.columns = options.columns
|
|
465
|
-
.filter((column) => column.includes(`${field.key}.`) &&
|
|
466
|
-
!column.includes(`${field.key}.`))
|
|
467
|
-
.map((column) => column.replace(`${field.key}.`, ""));
|
|
468
|
-
const [items, total_lines] = await File.get(join(path, (prefix ?? "") + field.key + ".inib"), linesNumber, "number", undefined, this.salt);
|
|
469
|
-
this.totalItems[tableName + "-" + field.key] = total_lines;
|
|
470
|
-
for (const [index, item] of Object.entries(items)) {
|
|
471
|
-
if (!RETURN[index])
|
|
472
|
-
RETURN[index] = {};
|
|
473
|
-
RETURN[index][field.key] = item
|
|
474
|
-
? await this.get(field.key, item, options)
|
|
475
|
-
: this.getDefaultValue(field);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
else if (await File.isExists(join(path, (prefix ?? "") + field.key + ".inib"))) {
|
|
480
|
-
const [items, total_lines] = await File.get(join(path, (prefix ?? "") + field.key + ".inib"), linesNumber, field.type, field?.children, this.salt);
|
|
481
|
-
this.totalItems[tableName + "-" + field.key] = total_lines;
|
|
482
|
-
for (const [index, item] of Object.entries(items)) {
|
|
483
|
-
if (!RETURN[index])
|
|
484
|
-
RETURN[index] = {};
|
|
485
|
-
RETURN[index][field.key] = item ?? this.getDefaultValue(field);
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
return RETURN;
|
|
490
|
-
};
|
|
491
634
|
if (!where) {
|
|
492
635
|
// Display all data
|
|
493
|
-
RETURN = Object.values(await getItemsFromSchema(
|
|
636
|
+
RETURN = Object.values(await this.getItemsFromSchema(tableName, schema, Array.from({ length: options.per_page }, (_, index) => (options.page - 1) * options.per_page +
|
|
494
637
|
index +
|
|
495
|
-
1)));
|
|
638
|
+
1), options));
|
|
496
639
|
}
|
|
497
640
|
else if ((Array.isArray(where) &&
|
|
498
641
|
(where.every(Utils.isValidID) || where.every(Utils.isNumber))) ||
|
|
@@ -508,163 +651,18 @@ export default class Inibase {
|
|
|
508
651
|
return Object.keys(lineNumbers).length
|
|
509
652
|
? Object.keys(lineNumbers).map(Number)
|
|
510
653
|
: null;
|
|
511
|
-
RETURN = Object.values((await getItemsFromSchema(
|
|
654
|
+
RETURN = Object.values((await this.getItemsFromSchema(tableName, schema, Object.keys(lineNumbers).map(Number), options)) ?? {});
|
|
512
655
|
if (RETURN.length && !Array.isArray(where))
|
|
513
656
|
RETURN = RETURN[0];
|
|
514
657
|
}
|
|
515
658
|
else if (Utils.isObject(where)) {
|
|
516
659
|
// Criteria
|
|
517
|
-
|
|
518
|
-
switch (value[0]) {
|
|
519
|
-
case ">":
|
|
520
|
-
case "<":
|
|
521
|
-
case "[":
|
|
522
|
-
return ["=", "]", "*"].includes(value[1])
|
|
523
|
-
? [
|
|
524
|
-
value.slice(0, 2),
|
|
525
|
-
value.slice(2),
|
|
526
|
-
]
|
|
527
|
-
: [
|
|
528
|
-
value.slice(0, 1),
|
|
529
|
-
value.slice(1),
|
|
530
|
-
];
|
|
531
|
-
case "!":
|
|
532
|
-
return ["=", "*"].includes(value[1])
|
|
533
|
-
? [
|
|
534
|
-
value.slice(0, 2),
|
|
535
|
-
value.slice(2),
|
|
536
|
-
]
|
|
537
|
-
: value[1] === "["
|
|
538
|
-
? [
|
|
539
|
-
value.slice(0, 3),
|
|
540
|
-
value.slice(3),
|
|
541
|
-
]
|
|
542
|
-
: [
|
|
543
|
-
(value.slice(0, 1) + "="),
|
|
544
|
-
value.slice(1),
|
|
545
|
-
];
|
|
546
|
-
case "=":
|
|
547
|
-
return isParentArray
|
|
548
|
-
? [
|
|
549
|
-
value.slice(0, 1),
|
|
550
|
-
value.slice(1),
|
|
551
|
-
]
|
|
552
|
-
: [
|
|
553
|
-
value.slice(0, 1),
|
|
554
|
-
(value.slice(1) + ","),
|
|
555
|
-
];
|
|
556
|
-
case "*":
|
|
557
|
-
return [
|
|
558
|
-
value.slice(0, 1),
|
|
559
|
-
value.slice(1),
|
|
560
|
-
];
|
|
561
|
-
default:
|
|
562
|
-
return ["=", value];
|
|
563
|
-
}
|
|
564
|
-
};
|
|
565
|
-
const applyCriteria = async (criteria, allTrue) => {
|
|
566
|
-
let RETURN = {};
|
|
567
|
-
if (!criteria)
|
|
568
|
-
return null;
|
|
569
|
-
if (criteria.and && Utils.isObject(criteria.and)) {
|
|
570
|
-
const searchResult = await applyCriteria(criteria.and, true);
|
|
571
|
-
if (searchResult) {
|
|
572
|
-
RETURN = Utils.deepMerge(RETURN, Object.fromEntries(Object.entries(searchResult).filter(([_k, v], _i) => Object.keys(v).length ===
|
|
573
|
-
Object.keys(criteria.and ?? {}).length)));
|
|
574
|
-
delete criteria.and;
|
|
575
|
-
}
|
|
576
|
-
else
|
|
577
|
-
return null;
|
|
578
|
-
}
|
|
579
|
-
if (criteria.or && Utils.isObject(criteria.or)) {
|
|
580
|
-
const searchResult = await applyCriteria(criteria.or, false);
|
|
581
|
-
delete criteria.or;
|
|
582
|
-
if (searchResult)
|
|
583
|
-
RETURN = Utils.deepMerge(RETURN, searchResult);
|
|
584
|
-
}
|
|
585
|
-
if (Object.keys(criteria).length > 0) {
|
|
586
|
-
if (allTrue === undefined)
|
|
587
|
-
allTrue = true;
|
|
588
|
-
let index = -1;
|
|
589
|
-
for (const [key, value] of Object.entries(criteria)) {
|
|
590
|
-
const field = this.getField(key, schema);
|
|
591
|
-
index++;
|
|
592
|
-
let searchOperator = undefined, searchComparedAtValue = undefined, searchLogicalOperator = undefined;
|
|
593
|
-
if (Utils.isObject(value)) {
|
|
594
|
-
if (value?.or &&
|
|
595
|
-
Array.isArray(value.or)) {
|
|
596
|
-
const searchCriteria = value.or
|
|
597
|
-
.map((single_or) => typeof single_or === "string"
|
|
598
|
-
? FormatObjectCriteriaValue(single_or)
|
|
599
|
-
: ["=", single_or])
|
|
600
|
-
.filter((a) => a);
|
|
601
|
-
if (searchCriteria.length > 0) {
|
|
602
|
-
searchOperator = searchCriteria.map((single_or) => single_or[0]);
|
|
603
|
-
searchComparedAtValue = searchCriteria.map((single_or) => single_or[1]);
|
|
604
|
-
searchLogicalOperator = "or";
|
|
605
|
-
}
|
|
606
|
-
delete value.or;
|
|
607
|
-
}
|
|
608
|
-
if (value?.and &&
|
|
609
|
-
Array.isArray(value.and)) {
|
|
610
|
-
const searchCriteria = value.and
|
|
611
|
-
.map((single_and) => typeof single_and === "string"
|
|
612
|
-
? FormatObjectCriteriaValue(single_and)
|
|
613
|
-
: ["=", single_and])
|
|
614
|
-
.filter((a) => a);
|
|
615
|
-
if (searchCriteria.length > 0) {
|
|
616
|
-
searchOperator = searchCriteria.map((single_and) => single_and[0]);
|
|
617
|
-
searchComparedAtValue = searchCriteria.map((single_and) => single_and[1]);
|
|
618
|
-
searchLogicalOperator = "and";
|
|
619
|
-
}
|
|
620
|
-
delete value.and;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
else if (Array.isArray(value)) {
|
|
624
|
-
const searchCriteria = value
|
|
625
|
-
.map((single) => typeof single === "string"
|
|
626
|
-
? FormatObjectCriteriaValue(single)
|
|
627
|
-
: ["=", single])
|
|
628
|
-
.filter((a) => a);
|
|
629
|
-
if (searchCriteria.length > 0) {
|
|
630
|
-
searchOperator = searchCriteria.map((single) => single[0]);
|
|
631
|
-
searchComparedAtValue = searchCriteria.map((single) => single[1]);
|
|
632
|
-
searchLogicalOperator = "and";
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
else if (typeof value === "string") {
|
|
636
|
-
const ComparisonOperatorValue = FormatObjectCriteriaValue(value);
|
|
637
|
-
if (ComparisonOperatorValue) {
|
|
638
|
-
searchOperator = ComparisonOperatorValue[0];
|
|
639
|
-
searchComparedAtValue = ComparisonOperatorValue[1];
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
else {
|
|
643
|
-
searchOperator = "=";
|
|
644
|
-
searchComparedAtValue = value;
|
|
645
|
-
}
|
|
646
|
-
const [searchResult, total_lines] = await File.search(join(this.folder, this.database, tableName, key + ".inib"), searchOperator, searchComparedAtValue, searchLogicalOperator, field?.type, field?.children, options.per_page, options.page - 1 * options.per_page + 1, true, this.salt);
|
|
647
|
-
if (searchResult) {
|
|
648
|
-
RETURN = Utils.deepMerge(RETURN, searchResult);
|
|
649
|
-
this.totalItems[tableName + "-" + key] = total_lines;
|
|
650
|
-
}
|
|
651
|
-
if (allTrue && index > 0) {
|
|
652
|
-
if (!Object.keys(RETURN).length)
|
|
653
|
-
RETURN = {};
|
|
654
|
-
RETURN = Object.fromEntries(Object.entries(RETURN).filter(([_index, item]) => Object.keys(item).length > index));
|
|
655
|
-
if (!Object.keys(RETURN).length)
|
|
656
|
-
RETURN = {};
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
return Object.keys(RETURN).length ? RETURN : null;
|
|
661
|
-
};
|
|
662
|
-
RETURN = await applyCriteria(where);
|
|
660
|
+
RETURN = await this.applyCriteria(tableName, schema, options, where);
|
|
663
661
|
if (RETURN) {
|
|
664
662
|
if (onlyLinesNumbers)
|
|
665
663
|
return Object.keys(RETURN).map(Number);
|
|
666
664
|
const alreadyExistsColumns = Object.keys(Object.values(RETURN)[0]).map((key) => parse(key).name);
|
|
667
|
-
RETURN = Object.values(Utils.deepMerge(RETURN, await getItemsFromSchema(
|
|
665
|
+
RETURN = Object.values(Utils.deepMerge(RETURN, await this.getItemsFromSchema(tableName, schema.filter((field) => !alreadyExistsColumns.includes(field.key)), Object.keys(RETURN).map(Number), options)));
|
|
668
666
|
}
|
|
669
667
|
}
|
|
670
668
|
if (!RETURN ||
|
|
@@ -691,7 +689,8 @@ export default class Inibase {
|
|
|
691
689
|
throw this.throwError("NO_SCHEMA", tableName);
|
|
692
690
|
const idFilePath = join(this.folder, this.database, tableName, "id.inib");
|
|
693
691
|
let [last_line_number, last_id] = (await File.isExists(idFilePath))
|
|
694
|
-
? Object.entries((await File.get(idFilePath, -1, "number", undefined, this.salt))[0]
|
|
692
|
+
? Object.entries((await File.get(idFilePath, -1, "number", undefined, this.salt))[0] ??
|
|
693
|
+
{})[0]?.map(Number) ?? [0, 0]
|
|
695
694
|
: [0, 0];
|
|
696
695
|
if (Utils.isArrayOfObjects(data))
|
|
697
696
|
RETURN = data.map(({ id, updatedAt, createdAt, ...rest }) => ({
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type FieldType } from "./index.js";
|
|
2
2
|
export declare const isArrayOfObjects: (input: any) => input is Record<any, any>[];
|
|
3
3
|
export declare const isArrayOfArrays: (input: any) => input is any[][];
|
|
4
|
+
export declare const isArrayOfNulls: (input: any) => input is null[] | null[][];
|
|
4
5
|
export declare const isObject: (obj: any) => boolean;
|
|
5
6
|
export declare const deepMerge: (target: any, source: any) => any;
|
|
6
7
|
export declare const combineObjects: (arr: Record<string, any>[]) => Record<string, any>;
|
|
@@ -38,4 +39,5 @@ export default class Utils {
|
|
|
38
39
|
static isIP: (input: any) => boolean;
|
|
39
40
|
static validateFieldType: (value: any, fieldType: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[]) => boolean;
|
|
40
41
|
static objectToDotNotation: (input: Record<string, any>) => Record<string, string | number | (string | number)[]>;
|
|
42
|
+
static isArrayOfNulls: (input: any) => input is null[] | null[][];
|
|
41
43
|
}
|
package/dist/utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const isArrayOfObjects = (input) => Array.isArray(input) && (input.length === 0 || input.every(isObject));
|
|
2
2
|
export const isArrayOfArrays = (input) => Array.isArray(input) && (input.length === 0 || input.every(Array.isArray));
|
|
3
|
+
export const isArrayOfNulls = (input) => input.every((_input) => Array.isArray(_input) ? isArrayOfNulls(_input) : _input === null);
|
|
3
4
|
export const isObject = (obj) => obj != null &&
|
|
4
5
|
(obj.constructor.name === "Object" ||
|
|
5
6
|
(typeof obj === "object" && !Array.isArray(obj)));
|
|
@@ -21,8 +22,8 @@ export const combineObjects = (arr) => {
|
|
|
21
22
|
if (obj.hasOwnProperty(key)) {
|
|
22
23
|
const existingValue = result[key];
|
|
23
24
|
const newValue = obj[key];
|
|
24
|
-
if (
|
|
25
|
-
|
|
25
|
+
if (isObject(existingValue) &&
|
|
26
|
+
isObject(newValue) &&
|
|
26
27
|
existingValue !== null &&
|
|
27
28
|
existingValue !== undefined &&
|
|
28
29
|
newValue !== null &&
|
|
@@ -35,8 +36,12 @@ export const combineObjects = (arr) => {
|
|
|
35
36
|
result[key] =
|
|
36
37
|
existingValue !== null && existingValue !== undefined
|
|
37
38
|
? Array.isArray(existingValue)
|
|
38
|
-
?
|
|
39
|
-
|
|
39
|
+
? Array.isArray(newValue)
|
|
40
|
+
? [...existingValue, ...newValue]
|
|
41
|
+
: [...existingValue, newValue]
|
|
42
|
+
: Array.isArray(newValue)
|
|
43
|
+
? [existingValue, ...newValue]
|
|
44
|
+
: [existingValue, newValue]
|
|
40
45
|
: newValue;
|
|
41
46
|
}
|
|
42
47
|
}
|
|
@@ -232,4 +237,5 @@ export default class Utils {
|
|
|
232
237
|
static isIP = isIP;
|
|
233
238
|
static validateFieldType = validateFieldType;
|
|
234
239
|
static objectToDotNotation = objectToDotNotation;
|
|
240
|
+
static isArrayOfNulls = isArrayOfNulls;
|
|
235
241
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inibase",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.20",
|
|
4
4
|
"description": "File-based Relational Database for large data",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
65
|
"build": "npx tsc",
|
|
66
|
-
"test": "npx tsx watch ./index
|
|
66
|
+
"test": "npx tsx watch ./text/index",
|
|
67
67
|
"benchmark": "npx tsx watch ./benchmark.ts"
|
|
68
68
|
}
|
|
69
69
|
}
|