inibase 1.0.0-rc.18 → 1.0.0-rc.19

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 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) => decodeURIComponent(input)
54
+ const unSecureString = (input) => input
55
55
  .replaceAll("&lt;", "<")
56
56
  .replaceAll("&gt;", ">")
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 value.map((v) => decode(v, Array.isArray(fieldChildrenType)
97
- ? detectFieldType(v, fieldChildrenType)
98
- : fieldChildrenType, undefined, secretKey));
99
- else
100
- return value;
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(join(this.folder, this.database, tableName), schema, Array.from({ length: options.per_page }, (_, index) => (options.page - 1) * options.per_page +
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(join(this.folder, this.database, tableName), schema, Object.keys(lineNumbers).map(Number))) ?? {});
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
- const FormatObjectCriteriaValue = (value, isParentArray = false) => {
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(join(this.folder, this.database, tableName), schema.filter((field) => !alreadyExistsColumns.includes(field.key)), Object.keys(RETURN).map(Number))));
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 ||
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 (typeof existingValue === "object" &&
25
- typeof newValue === "object" &&
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
- ? [...existingValue, newValue]
39
- : [existingValue, newValue]
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.18",
3
+ "version": "1.0.0-rc.19",
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.test",
66
+ "test": "npx tsx watch ./text/index",
67
67
  "benchmark": "npx tsx watch ./benchmark.ts"
68
68
  }
69
69
  }