remult 0.26.19 → 0.26.21

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.
@@ -307,6 +307,23 @@ class FilterConsumerBridgeToKnexRequest {
307
307
  }
308
308
  })());
309
309
  }
310
+ not(element) {
311
+ this.promises.push((async () => {
312
+ let f = new FilterConsumerBridgeToKnexRequest(this.innerNameProvider, this.rawSqlWrapIdentifier);
313
+ f._addWhere = false;
314
+ element.__applyToConsumer(f);
315
+ let where = await f.resolveWhere();
316
+ if (where.length > 0) {
317
+ this.result.push((b) => {
318
+ b.whereNot((b) => {
319
+ where.forEach((x) => x(b));
320
+ });
321
+ });
322
+ }
323
+ else
324
+ return; //empty or means all rows
325
+ })());
326
+ }
310
327
  isNull(col) {
311
328
  this.result.push((b) => b.whereNull(this.innerNameProvider.$dbNameOf(col)));
312
329
  }
@@ -350,6 +367,22 @@ class FilterConsumerBridgeToKnexRequest {
350
367
  "%')"));
351
368
  this.promises.push((async () => { })());
352
369
  }
370
+ startsWithCaseInsensitive(col, val) {
371
+ this.result.push((b) => b.whereRaw('lower (' +
372
+ b.client.ref(this.innerNameProvider.$dbNameOf(col)) +
373
+ ") like lower ('" +
374
+ val.replace(/'/g, "''") +
375
+ "%')"));
376
+ this.promises.push((async () => { })());
377
+ }
378
+ endsWithCaseInsensitive(col, val) {
379
+ this.result.push((b) => b.whereRaw('lower (' +
380
+ b.client.ref(this.innerNameProvider.$dbNameOf(col)) +
381
+ ") like lower ('%" +
382
+ val.replace(/'/g, "''") +
383
+ "')"));
384
+ this.promises.push((async () => { })());
385
+ }
353
386
  add(col, val, operator) {
354
387
  this.result.push((b) => b.where(this.innerNameProvider.$dbNameOf(col), operator, translateValueAndHandleArrayAndHandleArray(col, val)));
355
388
  }
@@ -203,6 +203,19 @@ class FilterConsumerBridgeToMongo {
203
203
  }));
204
204
  })());
205
205
  }
206
+ not(element) {
207
+ this.promises.push((async () => {
208
+ let f = new FilterConsumerBridgeToMongo(this.nameProvider);
209
+ f._addWhere = false;
210
+ element.__applyToConsumer(f);
211
+ let where = await f.resolveWhere();
212
+ if (where) {
213
+ this.result.push(() => ({
214
+ $nor: [where],
215
+ }));
216
+ }
217
+ })());
218
+ }
206
219
  isNull(col) {
207
220
  this.add(col, NULL, '$eq');
208
221
  }
@@ -247,6 +260,12 @@ class FilterConsumerBridgeToMongo {
247
260
  },
248
261
  }));
249
262
  }
263
+ startsWithCaseInsensitive(col, val) {
264
+ this.add(col, `^${val}`, '$regex', { $options: 'i' });
265
+ }
266
+ endsWithCaseInsensitive(col, val) {
267
+ this.add(col, `${val}$`, '$regex', { $options: 'i' });
268
+ }
250
269
  add(col, val, operator, moreOptions) {
251
270
  this.result.push(() => ({
252
271
  [this.nameProvider.$dbNameOf(col)]: {
@@ -123,6 +123,8 @@ export class DataApi {
123
123
  w.__applyToConsumer({
124
124
  containsCaseInsensitive: () => { },
125
125
  notContainsCaseInsensitive: () => { },
126
+ startsWithCaseInsensitive: () => { },
127
+ endsWithCaseInsensitive: () => { },
126
128
  isDifferentFrom: () => { },
127
129
  isEqualTo: (col, val) => {
128
130
  if (this.repository.metadata.idMetadata.isIdField(col))
@@ -140,6 +142,7 @@ export class DataApi {
140
142
  isLessThan: () => { },
141
143
  isNotNull: () => { },
142
144
  isNull: () => { },
145
+ not: () => { },
143
146
  or: () => { },
144
147
  });
145
148
  }
@@ -215,6 +215,12 @@ class FilterConsumerBridgeToObject {
215
215
  }
216
216
  this.ok = false;
217
217
  }
218
+ not(element) {
219
+ let filter = new FilterConsumerBridgeToObject(this.row, this.dbNames);
220
+ element.__applyToConsumer(filter);
221
+ if (filter.ok)
222
+ this.ok = false;
223
+ }
218
224
  isNull(col) {
219
225
  if (this.row[this.dbNames.$dbNameOf(col)] != null)
220
226
  this.ok = false;
@@ -283,4 +289,32 @@ class FilterConsumerBridgeToObject {
283
289
  if (s.toLowerCase().indexOf(val) >= 0)
284
290
  this.ok = false;
285
291
  }
292
+ startsWithCaseInsensitive(col, val) {
293
+ let v = this.row[this.dbNames.$dbNameOf(col)];
294
+ if (!v) {
295
+ this.ok = false;
296
+ return;
297
+ }
298
+ let s = '' + v;
299
+ if (val)
300
+ val = col.valueConverter.toJson(val);
301
+ if (val)
302
+ val = val.toString().toLowerCase();
303
+ if (!s.toLowerCase().startsWith(val))
304
+ this.ok = false;
305
+ }
306
+ endsWithCaseInsensitive(col, val) {
307
+ let v = this.row[this.dbNames.$dbNameOf(col)];
308
+ if (!v) {
309
+ this.ok = false;
310
+ return;
311
+ }
312
+ let s = '' + v;
313
+ if (val)
314
+ val = col.valueConverter.toJson(val);
315
+ if (val)
316
+ val = val.toString().toLowerCase();
317
+ if (!s.toLowerCase().endsWith(val))
318
+ this.ok = false;
319
+ }
286
320
  }
@@ -316,6 +316,8 @@ export function addFilterToUrlAndReturnTrueIfSuccessful(filter, url) {
316
316
  if (element.length > 10)
317
317
  return false;
318
318
  }
319
+ if (key === 'NOT')
320
+ return false;
319
321
  }
320
322
  }
321
323
  for (const key in filter) {
@@ -49,6 +49,17 @@ export class FilterConsumerBridgeToSqlRequest {
49
49
  this.addToWhere('(' + statement + ')');
50
50
  })());
51
51
  }
52
+ not(element) {
53
+ this.promises.push((async () => {
54
+ let f = new FilterConsumerBridgeToSqlRequest(this.r, this.nameProvider);
55
+ f._addWhere = false;
56
+ element.__applyToConsumer(f);
57
+ let where = await f.resolveWhere();
58
+ if (!where)
59
+ return; //since if any member of or is empty, then the entire or is irrelevant
60
+ this.addToWhere('not (' + where + ')');
61
+ })());
62
+ }
52
63
  isNull(col) {
53
64
  this.promises.push((async () => this.addToWhere(this.nameProvider.$dbNameOf(col) + ' is null'))());
54
65
  }
@@ -104,6 +115,24 @@ export class FilterConsumerBridgeToSqlRequest {
104
115
  "%')");
105
116
  })());
106
117
  }
118
+ startsWithCaseInsensitive(col, val) {
119
+ this.promises.push((async () => {
120
+ this.addToWhere('lower (' +
121
+ this.nameProvider.$dbNameOf(col) +
122
+ ") like lower ('" +
123
+ val.replace(/'/g, "''") +
124
+ "%')");
125
+ })());
126
+ }
127
+ endsWithCaseInsensitive(col, val) {
128
+ this.promises.push((async () => {
129
+ this.addToWhere('lower (' +
130
+ this.nameProvider.$dbNameOf(col) +
131
+ ") like lower ('%" +
132
+ val.replace(/'/g, "''") +
133
+ "')");
134
+ })());
135
+ }
107
136
  add(col, val, operator) {
108
137
  this.promises.push((async () => {
109
138
  let x = this.nameProvider.$dbNameOf(col) +
@@ -159,6 +159,9 @@ export class Filter {
159
159
  if (key == '$or') {
160
160
  result.push(new OrFilter(...fieldToFilter.map((x) => Filter.fromEntityFilter(entity, x))));
161
161
  }
162
+ else if (key == '$not') {
163
+ result.push(new NotFilter(Filter.fromEntityFilter(entity, fieldToFilter)));
164
+ }
162
165
  else if (key == '$and') {
163
166
  result.push(new AndFilter(...fieldToFilter.map((x) => Filter.fromEntityFilter(entity, x))));
164
167
  }
@@ -225,6 +228,14 @@ export class Filter {
225
228
  found = true;
226
229
  result.push(fh.contains(element));
227
230
  break;
231
+ case '$startsWith':
232
+ found = true;
233
+ result.push(fh.startsWith(element));
234
+ break;
235
+ case '$endsWith':
236
+ found = true;
237
+ result.push(fh.endsWith(element));
238
+ break;
228
239
  case '$notContains':
229
240
  found = true;
230
241
  result.push(fh.notContains(element));
@@ -327,6 +338,12 @@ class filterHelper {
327
338
  notContains(val) {
328
339
  return new Filter((add) => add.notContainsCaseInsensitive(this.metadata, val));
329
340
  }
341
+ startsWith(val) {
342
+ return new Filter((add) => add.startsWithCaseInsensitive(this.metadata, val));
343
+ }
344
+ endsWith(val) {
345
+ return new Filter((add) => add.endsWithCaseInsensitive(this.metadata, val));
346
+ }
330
347
  isLessThan(val) {
331
348
  val = this.processVal(val);
332
349
  return new Filter((add) => add.isLessThan(this.metadata, val));
@@ -396,6 +413,12 @@ class manyToOneFilterHelper {
396
413
  notContains(val) {
397
414
  throw new Error('Invalid for Many To One Relation Field');
398
415
  }
416
+ endsWith(val) {
417
+ throw new Error('Invalid for Many To One Relation Field');
418
+ }
419
+ startsWith(val) {
420
+ throw new Error('Invalid for Many To One Relation Field');
421
+ }
399
422
  isLessThan(val) {
400
423
  throw new Error('Invalid for Many To One Relation Field');
401
424
  }
@@ -474,6 +497,15 @@ export class OrFilter extends Filter {
474
497
  this.filters = filters;
475
498
  }
476
499
  }
500
+ export class NotFilter extends Filter {
501
+ filter;
502
+ constructor(filter) {
503
+ super((add) => {
504
+ add.not(filter);
505
+ });
506
+ this.filter = filter;
507
+ }
508
+ }
477
509
  export const customUrlToken = '$custom$';
478
510
  export const customDatabaseFilterToken = '$db$';
479
511
  const customArrayToken = '$an array';
@@ -512,6 +544,11 @@ export class FilterSerializer {
512
544
  return f.result;
513
545
  }));
514
546
  }
547
+ not(filter) {
548
+ let f = new FilterSerializer();
549
+ filter.__applyToConsumer(f);
550
+ this.add('NOT', f.result);
551
+ }
515
552
  isNull(col) {
516
553
  this.add(col.key + '.null', true);
517
554
  }
@@ -545,6 +582,12 @@ export class FilterSerializer {
545
582
  notContainsCaseInsensitive(col, val) {
546
583
  this.add(col.key + '.notContains', val);
547
584
  }
585
+ startsWithCaseInsensitive(col, val) {
586
+ this.add(col.key + '.startsWith', val);
587
+ }
588
+ endsWithCaseInsensitive(col, val) {
589
+ this.add(col.key + '.endsWith', val);
590
+ }
548
591
  }
549
592
  export function entityFilterToJson(entityDefs, where) {
550
593
  if (!where)
@@ -629,6 +672,8 @@ export function buildFilterFromRequestParameters(entity, filterInfo) {
629
672
  }
630
673
  addFilter('.contains', (val) => ({ $contains: val }), false, true);
631
674
  addFilter('.notContains', (val) => ({ $notContains: val }), false, true);
675
+ addFilter('.startsWith', (val) => ({ $startsWith: val }), false, true);
676
+ addFilter('.endsWith', (val) => ({ $endsWith: val }), false, true);
632
677
  });
633
678
  let val = filterInfo.get('OR');
634
679
  if (val) {
@@ -652,6 +697,37 @@ export function buildFilterFromRequestParameters(entity, filterInfo) {
652
697
  });
653
698
  }
654
699
  }
700
+ val = filterInfo.get('NOT');
701
+ if (val) {
702
+ let array = separateArrayFromInnerArray(val);
703
+ const not = [];
704
+ for (const e1 of array) {
705
+ let z = e1;
706
+ if (Array.isArray(e1)) {
707
+ for (const e2 of e1) {
708
+ not.push({
709
+ $not: buildFilterFromRequestParameters(entity, {
710
+ get: (key) => e2[key],
711
+ }),
712
+ });
713
+ }
714
+ }
715
+ else
716
+ not.push({
717
+ $not: buildFilterFromRequestParameters(entity, {
718
+ get: (key) => e1[key],
719
+ }),
720
+ });
721
+ }
722
+ if (not.length == 1 && !where.$not) {
723
+ where = not[0];
724
+ }
725
+ else {
726
+ addAnd({
727
+ $and: not,
728
+ });
729
+ }
730
+ }
655
731
  for (const key in entity.entityType) {
656
732
  const element = entity.entityType[key];
657
733
  if (element &&
@@ -710,6 +786,16 @@ class customTranslator {
710
786
  }));
711
787
  this.commands.push((x) => x.or(newOrElements));
712
788
  }
789
+ not(filter) {
790
+ let newNotElement;
791
+ this.promises.push((async () => {
792
+ let c = new customTranslator(this.translateCustom);
793
+ filter.__applyToConsumer(c);
794
+ await c.resolve();
795
+ newNotElement = new Filter((x) => c.applyTo(x));
796
+ })());
797
+ this.commands.push((x) => x.not(newNotElement));
798
+ }
713
799
  isEqualTo(col, val) {
714
800
  this.commands.push((x) => x.isEqualTo(col, val));
715
801
  }
@@ -740,6 +826,12 @@ class customTranslator {
740
826
  notContainsCaseInsensitive(col, val) {
741
827
  this.commands.push((x) => x.notContainsCaseInsensitive(col, val));
742
828
  }
829
+ startsWithCaseInsensitive(col, val) {
830
+ this.commands.push((x) => x.startsWithCaseInsensitive(col, val));
831
+ }
832
+ endsWithCaseInsensitive(col, val) {
833
+ this.commands.push((x) => x.endsWithCaseInsensitive(col, val));
834
+ }
743
835
  isIn(col, val) {
744
836
  this.commands.push((x) => x.isIn(col, val));
745
837
  }
@@ -773,6 +865,8 @@ export function __updateEntityBasedOnWhere(entityDefs, where, r) {
773
865
  databaseCustom: emptyFunction,
774
866
  containsCaseInsensitive: emptyFunction,
775
867
  notContainsCaseInsensitive: emptyFunction,
868
+ startsWithCaseInsensitive: emptyFunction,
869
+ endsWithCaseInsensitive: emptyFunction,
776
870
  isDifferentFrom: emptyFunction,
777
871
  isEqualTo: (col, val) => {
778
872
  r[col.key] = val;
@@ -784,6 +878,7 @@ export function __updateEntityBasedOnWhere(entityDefs, where, r) {
784
878
  isLessThan: emptyFunction,
785
879
  isNotNull: emptyFunction,
786
880
  isNull: emptyFunction,
881
+ not: emptyFunction,
787
882
  or: emptyFunction,
788
883
  });
789
884
  }
@@ -839,6 +934,7 @@ class preciseValuesCollector {
839
934
  x.bad = true;
840
935
  }
841
936
  }
937
+ not(filter) { }
842
938
  or(orElements) {
843
939
  const result = orElements.map((or) => {
844
940
  let x = new preciseValuesCollector();
@@ -899,6 +995,12 @@ class preciseValuesCollector {
899
995
  notContainsCaseInsensitive(col, val) {
900
996
  this.notOk(col);
901
997
  }
998
+ startsWithCaseInsensitive(col, val) {
999
+ this.notOk(col);
1000
+ }
1001
+ endsWithCaseInsensitive(col, val) {
1002
+ this.notOk(col);
1003
+ }
902
1004
  isIn(col, val) {
903
1005
  this.ok(col, ...val);
904
1006
  }
@@ -8,6 +8,8 @@ export function __updateEntityBasedOnWhere(entityDefs, where, r) {
8
8
  databaseCustom: emptyFunction,
9
9
  containsCaseInsensitive: emptyFunction,
10
10
  notContainsCaseInsensitive: emptyFunction,
11
+ startsWithCaseInsensitive: emptyFunction,
12
+ endsWithCaseInsensitive: emptyFunction,
11
13
  isDifferentFrom: emptyFunction,
12
14
  isEqualTo: (col, val) => {
13
15
  r[col.key] = val;
@@ -19,6 +21,7 @@ export function __updateEntityBasedOnWhere(entityDefs, where, r) {
19
21
  isLessThan: emptyFunction,
20
22
  isNotNull: emptyFunction,
21
23
  isNull: emptyFunction,
24
+ not: emptyFunction,
22
25
  or: emptyFunction,
23
26
  });
24
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.26.19",
3
+ "version": "0.26.21",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -606,6 +606,33 @@ var FilterConsumerBridgeToKnexRequest = /** @class */ (function () {
606
606
  });
607
607
  }); })());
608
608
  };
609
+ FilterConsumerBridgeToKnexRequest.prototype.not = function (element) {
610
+ var _this = this;
611
+ this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
612
+ var f, where;
613
+ return tslib_1.__generator(this, function (_a) {
614
+ switch (_a.label) {
615
+ case 0:
616
+ f = new FilterConsumerBridgeToKnexRequest(this.innerNameProvider, this.rawSqlWrapIdentifier);
617
+ f._addWhere = false;
618
+ element.__applyToConsumer(f);
619
+ return [4 /*yield*/, f.resolveWhere()];
620
+ case 1:
621
+ where = _a.sent();
622
+ if (where.length > 0) {
623
+ this.result.push(function (b) {
624
+ b.whereNot(function (b) {
625
+ where.forEach(function (x) { return x(b); });
626
+ });
627
+ });
628
+ }
629
+ else
630
+ return [2 /*return*/]; //empty or means all rows
631
+ return [2 /*return*/];
632
+ }
633
+ });
634
+ }); })());
635
+ };
609
636
  FilterConsumerBridgeToKnexRequest.prototype.isNull = function (col) {
610
637
  var _this = this;
611
638
  this.result.push(function (b) { return b.whereNull(_this.innerNameProvider.$dbNameOf(col)); });
@@ -666,6 +693,32 @@ var FilterConsumerBridgeToKnexRequest = /** @class */ (function () {
666
693
  return [2 /*return*/];
667
694
  }); }); })());
668
695
  };
696
+ FilterConsumerBridgeToKnexRequest.prototype.startsWithCaseInsensitive = function (col, val) {
697
+ var _this = this;
698
+ this.result.push(function (b) {
699
+ return b.whereRaw('lower (' +
700
+ b.client.ref(_this.innerNameProvider.$dbNameOf(col)) +
701
+ ") like lower ('" +
702
+ val.replace(/'/g, "''") +
703
+ "%')");
704
+ });
705
+ this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
706
+ return [2 /*return*/];
707
+ }); }); })());
708
+ };
709
+ FilterConsumerBridgeToKnexRequest.prototype.endsWithCaseInsensitive = function (col, val) {
710
+ var _this = this;
711
+ this.result.push(function (b) {
712
+ return b.whereRaw('lower (' +
713
+ b.client.ref(_this.innerNameProvider.$dbNameOf(col)) +
714
+ ") like lower ('%" +
715
+ val.replace(/'/g, "''") +
716
+ "')");
717
+ });
718
+ this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
719
+ return [2 /*return*/];
720
+ }); }); })());
721
+ };
669
722
  FilterConsumerBridgeToKnexRequest.prototype.add = function (col, val, operator) {
670
723
  var _this = this;
671
724
  this.result.push(function (b) {
package/remult-mongo.js CHANGED
@@ -431,6 +431,29 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
431
431
  });
432
432
  }); })());
433
433
  };
434
+ FilterConsumerBridgeToMongo.prototype.not = function (element) {
435
+ var _this = this;
436
+ this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
437
+ var f, where;
438
+ return tslib_1.__generator(this, function (_a) {
439
+ switch (_a.label) {
440
+ case 0:
441
+ f = new FilterConsumerBridgeToMongo(this.nameProvider);
442
+ f._addWhere = false;
443
+ element.__applyToConsumer(f);
444
+ return [4 /*yield*/, f.resolveWhere()];
445
+ case 1:
446
+ where = _a.sent();
447
+ if (where) {
448
+ this.result.push(function () { return ({
449
+ $nor: [where],
450
+ }); });
451
+ }
452
+ return [2 /*return*/];
453
+ }
454
+ });
455
+ }); })());
456
+ };
434
457
  FilterConsumerBridgeToMongo.prototype.isNull = function (col) {
435
458
  this.add(col, NULL, '$eq');
436
459
  };
@@ -483,6 +506,12 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
483
506
  _a);
484
507
  });
485
508
  };
509
+ FilterConsumerBridgeToMongo.prototype.startsWithCaseInsensitive = function (col, val) {
510
+ this.add(col, "^".concat(val), '$regex', { $options: 'i' });
511
+ };
512
+ FilterConsumerBridgeToMongo.prototype.endsWithCaseInsensitive = function (col, val) {
513
+ this.add(col, "".concat(val, "$"), '$regex', { $options: 'i' });
514
+ };
486
515
  FilterConsumerBridgeToMongo.prototype.add = function (col, val, operator, moreOptions) {
487
516
  var _this = this;
488
517
  this.result.push(function () {
package/src/data-api.js CHANGED
@@ -233,6 +233,8 @@ var DataApi = /** @class */ (function () {
233
233
  w.__applyToConsumer({
234
234
  containsCaseInsensitive: function () { },
235
235
  notContainsCaseInsensitive: function () { },
236
+ startsWithCaseInsensitive: function () { },
237
+ endsWithCaseInsensitive: function () { },
236
238
  isDifferentFrom: function () { },
237
239
  isEqualTo: function (col, val) {
238
240
  if (_this.repository.metadata.idMetadata.isIdField(col))
@@ -250,6 +252,7 @@ var DataApi = /** @class */ (function () {
250
252
  isLessThan: function () { },
251
253
  isNotNull: function () { },
252
254
  isNull: function () { },
255
+ not: function () { },
253
256
  or: function () { },
254
257
  });
255
258
  }
@@ -353,6 +353,12 @@ var FilterConsumerBridgeToObject = /** @class */ (function () {
353
353
  }
354
354
  this.ok = false;
355
355
  };
356
+ FilterConsumerBridgeToObject.prototype.not = function (element) {
357
+ var filter = new FilterConsumerBridgeToObject(this.row, this.dbNames);
358
+ element.__applyToConsumer(filter);
359
+ if (filter.ok)
360
+ this.ok = false;
361
+ };
356
362
  FilterConsumerBridgeToObject.prototype.isNull = function (col) {
357
363
  if (this.row[this.dbNames.$dbNameOf(col)] != null)
358
364
  this.ok = false;
@@ -432,5 +438,33 @@ var FilterConsumerBridgeToObject = /** @class */ (function () {
432
438
  if (s.toLowerCase().indexOf(val) >= 0)
433
439
  this.ok = false;
434
440
  };
441
+ FilterConsumerBridgeToObject.prototype.startsWithCaseInsensitive = function (col, val) {
442
+ var v = this.row[this.dbNames.$dbNameOf(col)];
443
+ if (!v) {
444
+ this.ok = false;
445
+ return;
446
+ }
447
+ var s = '' + v;
448
+ if (val)
449
+ val = col.valueConverter.toJson(val);
450
+ if (val)
451
+ val = val.toString().toLowerCase();
452
+ if (!s.toLowerCase().startsWith(val))
453
+ this.ok = false;
454
+ };
455
+ FilterConsumerBridgeToObject.prototype.endsWithCaseInsensitive = function (col, val) {
456
+ var v = this.row[this.dbNames.$dbNameOf(col)];
457
+ if (!v) {
458
+ this.ok = false;
459
+ return;
460
+ }
461
+ var s = '' + v;
462
+ if (val)
463
+ val = col.valueConverter.toJson(val);
464
+ if (val)
465
+ val = val.toString().toLowerCase();
466
+ if (!s.toLowerCase().endsWith(val))
467
+ this.ok = false;
468
+ };
435
469
  return FilterConsumerBridgeToObject;
436
470
  }());
@@ -446,6 +446,8 @@ function addFilterToUrlAndReturnTrueIfSuccessful(filter, url) {
446
446
  if (element.length > 10)
447
447
  return false;
448
448
  }
449
+ if (key === 'NOT')
450
+ return false;
449
451
  }
450
452
  }
451
453
  var _loop_1 = function (key) {
@@ -13,6 +13,7 @@ export declare class FilterConsumerBridgeToSqlRequest implements FilterConsumer
13
13
  constructor(r: SqlCommandWithParameters, nameProvider: EntityDbNamesBase);
14
14
  custom(key: string, customItem: any): void;
15
15
  or(orElements: Filter[]): void;
16
+ not(element: Filter): void;
16
17
  isNull(col: FieldMetadata): void;
17
18
  isNotNull(col: FieldMetadata): void;
18
19
  isIn(col: FieldMetadata, val: any[]): void;
@@ -24,6 +25,8 @@ export declare class FilterConsumerBridgeToSqlRequest implements FilterConsumer
24
25
  isLessThan(col: FieldMetadata, val: any): void;
25
26
  containsCaseInsensitive(col: FieldMetadata, val: any): void;
26
27
  notContainsCaseInsensitive(col: FieldMetadata, val: any): void;
28
+ startsWithCaseInsensitive(col: FieldMetadata, val: any): void;
29
+ endsWithCaseInsensitive(col: FieldMetadata, val: any): void;
27
30
  private add;
28
31
  private addToWhere;
29
32
  databaseCustom(databaseCustom: CustomSqlFilterObject): void;
@@ -114,6 +114,27 @@ var FilterConsumerBridgeToSqlRequest = /** @class */ (function () {
114
114
  });
115
115
  }); })());
116
116
  };
117
+ FilterConsumerBridgeToSqlRequest.prototype.not = function (element) {
118
+ var _this = this;
119
+ this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
120
+ var f, where;
121
+ return tslib_1.__generator(this, function (_a) {
122
+ switch (_a.label) {
123
+ case 0:
124
+ f = new FilterConsumerBridgeToSqlRequest(this.r, this.nameProvider);
125
+ f._addWhere = false;
126
+ element.__applyToConsumer(f);
127
+ return [4 /*yield*/, f.resolveWhere()];
128
+ case 1:
129
+ where = _a.sent();
130
+ if (!where)
131
+ return [2 /*return*/]; //since if any member of or is empty, then the entire or is irrelevant
132
+ this.addToWhere('not (' + where + ')');
133
+ return [2 /*return*/];
134
+ }
135
+ });
136
+ }); })());
137
+ };
117
138
  FilterConsumerBridgeToSqlRequest.prototype.isNull = function (col) {
118
139
  var _this = this;
119
140
  this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
@@ -188,6 +209,32 @@ var FilterConsumerBridgeToSqlRequest = /** @class */ (function () {
188
209
  });
189
210
  }); })());
190
211
  };
212
+ FilterConsumerBridgeToSqlRequest.prototype.startsWithCaseInsensitive = function (col, val) {
213
+ var _this = this;
214
+ this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
215
+ return tslib_1.__generator(this, function (_a) {
216
+ this.addToWhere('lower (' +
217
+ this.nameProvider.$dbNameOf(col) +
218
+ ") like lower ('" +
219
+ val.replace(/'/g, "''") +
220
+ "%')");
221
+ return [2 /*return*/];
222
+ });
223
+ }); })());
224
+ };
225
+ FilterConsumerBridgeToSqlRequest.prototype.endsWithCaseInsensitive = function (col, val) {
226
+ var _this = this;
227
+ this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
228
+ return tslib_1.__generator(this, function (_a) {
229
+ this.addToWhere('lower (' +
230
+ this.nameProvider.$dbNameOf(col) +
231
+ ") like lower ('%" +
232
+ val.replace(/'/g, "''") +
233
+ "')");
234
+ return [2 /*return*/];
235
+ });
236
+ }); })());
237
+ };
191
238
  FilterConsumerBridgeToSqlRequest.prototype.add = function (col, val, operator) {
192
239
  var _this = this;
193
240
  this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
@@ -184,7 +184,8 @@ export declare class Filter {
184
184
  toJson(): any;
185
185
  }
186
186
  export interface FilterConsumer {
187
- or(orElements: Filter[]): any;
187
+ or(orElements: Filter[]): void;
188
+ not(filter: Filter): void;
188
189
  isEqualTo(col: FieldMetadata, val: any): void;
189
190
  isDifferentFrom(col: FieldMetadata, val: any): void;
190
191
  isNull(col: FieldMetadata): void;
@@ -195,6 +196,8 @@ export interface FilterConsumer {
195
196
  isLessThan(col: FieldMetadata, val: any): void;
196
197
  containsCaseInsensitive(col: FieldMetadata, val: any): void;
197
198
  notContainsCaseInsensitive(col: FieldMetadata, val: any): void;
199
+ startsWithCaseInsensitive(col: FieldMetadata, val: any): void;
200
+ endsWithCaseInsensitive(col: FieldMetadata, val: any): void;
198
201
  isIn(col: FieldMetadata, val: any[]): void;
199
202
  custom(key: string, customItem: any): void;
200
203
  databaseCustom(databaseCustom: any): void;
@@ -208,6 +211,10 @@ export declare class OrFilter extends Filter {
208
211
  readonly filters: Filter[];
209
212
  constructor(...filters: Filter[]);
210
213
  }
214
+ export declare class NotFilter extends Filter {
215
+ readonly filter: Filter;
216
+ constructor(filter: Filter);
217
+ }
211
218
  export declare const customUrlToken = "$custom$";
212
219
  export declare const customDatabaseFilterToken = "$db$";
213
220
  export declare class FilterSerializer implements FilterConsumer {
@@ -218,6 +225,7 @@ export declare class FilterSerializer implements FilterConsumer {
218
225
  hasUndefined: boolean;
219
226
  add(key: string, val: any): void;
220
227
  or(orElements: Filter[]): void;
228
+ not(filter: Filter): void;
221
229
  isNull(col: FieldMetadata): void;
222
230
  isNotNull(col: FieldMetadata): void;
223
231
  isIn(col: FieldMetadata, val: any[]): void;
@@ -229,6 +237,8 @@ export declare class FilterSerializer implements FilterConsumer {
229
237
  isLessThan(col: FieldMetadata, val: any): void;
230
238
  containsCaseInsensitive(col: FieldMetadata, val: any): void;
231
239
  notContainsCaseInsensitive(col: FieldMetadata, val: any): void;
240
+ startsWithCaseInsensitive(col: FieldMetadata, val: any): void;
241
+ endsWithCaseInsensitive(col: FieldMetadata, val: any): void;
232
242
  }
233
243
  export declare function entityFilterToJson<T>(entityDefs: EntityMetadata<T>, where: EntityFilter<T>): any;
234
244
  export declare function buildFilterFromRequestParameters(entity: EntityMetadata, filterInfo: {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.__updateEntityBasedOnWhere = exports.buildFilterFromRequestParameters = exports.entityFilterToJson = exports.FilterSerializer = exports.customDatabaseFilterToken = exports.customUrlToken = exports.OrFilter = exports.AndFilter = exports.Filter = void 0;
3
+ exports.__updateEntityBasedOnWhere = exports.buildFilterFromRequestParameters = exports.entityFilterToJson = exports.FilterSerializer = exports.customDatabaseFilterToken = exports.customUrlToken = exports.NotFilter = exports.OrFilter = exports.AndFilter = exports.Filter = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var getEntityRef_js_1 = require("../remult3/getEntityRef.js");
6
6
  var relationInfoMember_js_1 = require("../remult3/relationInfoMember.js");
@@ -208,6 +208,9 @@ var Filter = /** @class */ (function () {
208
208
  if (key == '$or') {
209
209
  result.push(new (OrFilter.bind.apply(OrFilter, tslib_1.__spreadArray([void 0], tslib_1.__read(fieldToFilter_1.map(function (x) { return Filter.fromEntityFilter(entity, x); })), false)))());
210
210
  }
211
+ else if (key == '$not') {
212
+ result.push(new NotFilter(Filter.fromEntityFilter(entity, fieldToFilter_1)));
213
+ }
211
214
  else if (key == '$and') {
212
215
  result.push(new (AndFilter.bind.apply(AndFilter, tslib_1.__spreadArray([void 0], tslib_1.__read(fieldToFilter_1.map(function (x) { return Filter.fromEntityFilter(entity, x); })), false)))());
213
216
  }
@@ -274,6 +277,14 @@ var Filter = /** @class */ (function () {
274
277
  found = true;
275
278
  result.push(fh.contains(element));
276
279
  break;
280
+ case '$startsWith':
281
+ found = true;
282
+ result.push(fh.startsWith(element));
283
+ break;
284
+ case '$endsWith':
285
+ found = true;
286
+ result.push(fh.endsWith(element));
287
+ break;
277
288
  case '$notContains':
278
289
  found = true;
279
290
  result.push(fh.notContains(element));
@@ -423,6 +434,16 @@ var filterHelper = /** @class */ (function () {
423
434
  return add.notContainsCaseInsensitive(_this.metadata, val);
424
435
  });
425
436
  };
437
+ filterHelper.prototype.startsWith = function (val) {
438
+ var _this = this;
439
+ return new Filter(function (add) {
440
+ return add.startsWithCaseInsensitive(_this.metadata, val);
441
+ });
442
+ };
443
+ filterHelper.prototype.endsWith = function (val) {
444
+ var _this = this;
445
+ return new Filter(function (add) { return add.endsWithCaseInsensitive(_this.metadata, val); });
446
+ };
426
447
  filterHelper.prototype.isLessThan = function (val) {
427
448
  var _this = this;
428
449
  val = this.processVal(val);
@@ -514,6 +535,12 @@ var manyToOneFilterHelper = /** @class */ (function () {
514
535
  manyToOneFilterHelper.prototype.notContains = function (val) {
515
536
  throw new Error('Invalid for Many To One Relation Field');
516
537
  };
538
+ manyToOneFilterHelper.prototype.endsWith = function (val) {
539
+ throw new Error('Invalid for Many To One Relation Field');
540
+ };
541
+ manyToOneFilterHelper.prototype.startsWith = function (val) {
542
+ throw new Error('Invalid for Many To One Relation Field');
543
+ };
517
544
  manyToOneFilterHelper.prototype.isLessThan = function (val) {
518
545
  throw new Error('Invalid for Many To One Relation Field');
519
546
  };
@@ -627,6 +654,18 @@ var OrFilter = /** @class */ (function (_super) {
627
654
  return OrFilter;
628
655
  }(Filter));
629
656
  exports.OrFilter = OrFilter;
657
+ var NotFilter = /** @class */ (function (_super) {
658
+ tslib_1.__extends(NotFilter, _super);
659
+ function NotFilter(filter) {
660
+ var _this = _super.call(this, function (add) {
661
+ add.not(filter);
662
+ }) || this;
663
+ _this.filter = filter;
664
+ return _this;
665
+ }
666
+ return NotFilter;
667
+ }(Filter));
668
+ exports.NotFilter = NotFilter;
630
669
  exports.customUrlToken = '$custom$';
631
670
  exports.customDatabaseFilterToken = '$db$';
632
671
  var customArrayToken = '$an array';
@@ -667,6 +706,11 @@ var FilterSerializer = /** @class */ (function () {
667
706
  return f.result;
668
707
  }));
669
708
  };
709
+ FilterSerializer.prototype.not = function (filter) {
710
+ var f = new FilterSerializer();
711
+ filter.__applyToConsumer(f);
712
+ this.add('NOT', f.result);
713
+ };
670
714
  FilterSerializer.prototype.isNull = function (col) {
671
715
  this.add(col.key + '.null', true);
672
716
  };
@@ -700,6 +744,12 @@ var FilterSerializer = /** @class */ (function () {
700
744
  FilterSerializer.prototype.notContainsCaseInsensitive = function (col, val) {
701
745
  this.add(col.key + '.notContains', val);
702
746
  };
747
+ FilterSerializer.prototype.startsWithCaseInsensitive = function (col, val) {
748
+ this.add(col.key + '.startsWith', val);
749
+ };
750
+ FilterSerializer.prototype.endsWithCaseInsensitive = function (col, val) {
751
+ this.add(col.key + '.endsWith', val);
752
+ };
703
753
  return FilterSerializer;
704
754
  }());
705
755
  exports.FilterSerializer = FilterSerializer;
@@ -710,6 +760,7 @@ function entityFilterToJson(entityDefs, where) {
710
760
  }
711
761
  exports.entityFilterToJson = entityFilterToJson;
712
762
  function buildFilterFromRequestParameters(entity, filterInfo) {
763
+ var e_5, _a;
713
764
  var where = {};
714
765
  function addAnd(what) {
715
766
  if (!where.$and) {
@@ -728,7 +779,7 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
728
779
  ;
729
780
  tslib_1.__spreadArray([], tslib_1.__read(entity.fields), false).forEach(function (col) {
730
781
  function addFilter(operation, theFilter, jsonArray, asString) {
731
- var e_5, _a;
782
+ var e_6, _a;
732
783
  if (jsonArray === void 0) { jsonArray = false; }
733
784
  if (asString === void 0) { asString = false; }
734
785
  var val = filterInfo.get(col.key + operation);
@@ -765,17 +816,17 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
765
816
  }
766
817
  var array = separateArrayFromInnerArray(val);
767
818
  try {
768
- for (var array_1 = tslib_1.__values(array), array_1_1 = array_1.next(); !array_1_1.done; array_1_1 = array_1.next()) {
769
- var x = array_1_1.value;
819
+ for (var array_2 = tslib_1.__values(array), array_2_1 = array_2.next(); !array_2_1.done; array_2_1 = array_2.next()) {
820
+ var x = array_2_1.value;
770
821
  addFilter_1(x);
771
822
  }
772
823
  }
773
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
824
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
774
825
  finally {
775
826
  try {
776
- if (array_1_1 && !array_1_1.done && (_a = array_1.return)) _a.call(array_1);
827
+ if (array_2_1 && !array_2_1.done && (_a = array_2.return)) _a.call(array_2);
777
828
  }
778
- finally { if (e_5) throw e_5.error; }
829
+ finally { if (e_6) throw e_6.error; }
779
830
  }
780
831
  }
781
832
  }
@@ -803,6 +854,8 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
803
854
  }
804
855
  addFilter('.contains', function (val) { return ({ $contains: val }); }, false, true);
805
856
  addFilter('.notContains', function (val) { return ({ $notContains: val }); }, false, true);
857
+ addFilter('.startsWith', function (val) { return ({ $startsWith: val }); }, false, true);
858
+ addFilter('.endsWith', function (val) { return ({ $endsWith: val }); }, false, true);
806
859
  });
807
860
  var val = filterInfo.get('OR');
808
861
  if (val) {
@@ -828,7 +881,65 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
828
881
  });
829
882
  }
830
883
  }
831
- var _loop_3 = function (key) {
884
+ val = filterInfo.get('NOT');
885
+ if (val) {
886
+ var array = separateArrayFromInnerArray(val);
887
+ var not = [];
888
+ var _loop_3 = function (e1) {
889
+ var e_7, _b;
890
+ var z = e1;
891
+ if (Array.isArray(e1)) {
892
+ var _loop_5 = function (e2) {
893
+ not.push({
894
+ $not: buildFilterFromRequestParameters(entity, {
895
+ get: function (key) { return e2[key]; },
896
+ }),
897
+ });
898
+ };
899
+ try {
900
+ for (var e1_1 = (e_7 = void 0, tslib_1.__values(e1)), e1_1_1 = e1_1.next(); !e1_1_1.done; e1_1_1 = e1_1.next()) {
901
+ var e2 = e1_1_1.value;
902
+ _loop_5(e2);
903
+ }
904
+ }
905
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
906
+ finally {
907
+ try {
908
+ if (e1_1_1 && !e1_1_1.done && (_b = e1_1.return)) _b.call(e1_1);
909
+ }
910
+ finally { if (e_7) throw e_7.error; }
911
+ }
912
+ }
913
+ else
914
+ not.push({
915
+ $not: buildFilterFromRequestParameters(entity, {
916
+ get: function (key) { return e1[key]; },
917
+ }),
918
+ });
919
+ };
920
+ try {
921
+ for (var array_1 = tslib_1.__values(array), array_1_1 = array_1.next(); !array_1_1.done; array_1_1 = array_1.next()) {
922
+ var e1 = array_1_1.value;
923
+ _loop_3(e1);
924
+ }
925
+ }
926
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
927
+ finally {
928
+ try {
929
+ if (array_1_1 && !array_1_1.done && (_a = array_1.return)) _a.call(array_1);
930
+ }
931
+ finally { if (e_5) throw e_5.error; }
932
+ }
933
+ if (not.length == 1 && !where.$not) {
934
+ where = not[0];
935
+ }
936
+ else {
937
+ addAnd({
938
+ $and: not,
939
+ });
940
+ }
941
+ }
942
+ var _loop_4 = function (key) {
832
943
  var element = entity.entityType[key];
833
944
  if (element &&
834
945
  element.rawFilterInfo &&
@@ -849,11 +960,11 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
849
960
  }
850
961
  };
851
962
  for (var key in entity.entityType) {
852
- _loop_3(key);
963
+ _loop_4(key);
853
964
  }
854
965
  return where;
855
966
  function separateArrayFromInnerArray(val) {
856
- var e_6, _a;
967
+ var e_8, _a;
857
968
  if (!Array.isArray(val))
858
969
  return [val];
859
970
  var nonArray = [], array = [];
@@ -867,12 +978,12 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
867
978
  nonArray.push(v);
868
979
  }
869
980
  }
870
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
981
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
871
982
  finally {
872
983
  try {
873
984
  if (val_1_1 && !val_1_1.done && (_a = val_1.return)) _a.call(val_1);
874
985
  }
875
- finally { if (e_6) throw e_6.error; }
986
+ finally { if (e_8) throw e_8.error; }
876
987
  }
877
988
  array.push(nonArray);
878
989
  return array;
@@ -909,6 +1020,26 @@ var customTranslator = /** @class */ (function () {
909
1020
  }));
910
1021
  this.commands.push(function (x) { return x.or(newOrElements); });
911
1022
  };
1023
+ customTranslator.prototype.not = function (filter) {
1024
+ var _this = this;
1025
+ var newNotElement;
1026
+ this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1027
+ var c;
1028
+ return tslib_1.__generator(this, function (_a) {
1029
+ switch (_a.label) {
1030
+ case 0:
1031
+ c = new customTranslator(this.translateCustom);
1032
+ filter.__applyToConsumer(c);
1033
+ return [4 /*yield*/, c.resolve()];
1034
+ case 1:
1035
+ _a.sent();
1036
+ newNotElement = new Filter(function (x) { return c.applyTo(x); });
1037
+ return [2 /*return*/];
1038
+ }
1039
+ });
1040
+ }); })());
1041
+ this.commands.push(function (x) { return x.not(newNotElement); });
1042
+ };
912
1043
  customTranslator.prototype.isEqualTo = function (col, val) {
913
1044
  this.commands.push(function (x) { return x.isEqualTo(col, val); });
914
1045
  };
@@ -939,6 +1070,12 @@ var customTranslator = /** @class */ (function () {
939
1070
  customTranslator.prototype.notContainsCaseInsensitive = function (col, val) {
940
1071
  this.commands.push(function (x) { return x.notContainsCaseInsensitive(col, val); });
941
1072
  };
1073
+ customTranslator.prototype.startsWithCaseInsensitive = function (col, val) {
1074
+ this.commands.push(function (x) { return x.startsWithCaseInsensitive(col, val); });
1075
+ };
1076
+ customTranslator.prototype.endsWithCaseInsensitive = function (col, val) {
1077
+ this.commands.push(function (x) { return x.endsWithCaseInsensitive(col, val); });
1078
+ };
942
1079
  customTranslator.prototype.isIn = function (col, val) {
943
1080
  this.commands.push(function (x) { return x.isIn(col, val); });
944
1081
  };
@@ -994,6 +1131,8 @@ function __updateEntityBasedOnWhere(entityDefs, where, r) {
994
1131
  databaseCustom: emptyFunction,
995
1132
  containsCaseInsensitive: emptyFunction,
996
1133
  notContainsCaseInsensitive: emptyFunction,
1134
+ startsWithCaseInsensitive: emptyFunction,
1135
+ endsWithCaseInsensitive: emptyFunction,
997
1136
  isDifferentFrom: emptyFunction,
998
1137
  isEqualTo: function (col, val) {
999
1138
  r[col.key] = val;
@@ -1005,6 +1144,7 @@ function __updateEntityBasedOnWhere(entityDefs, where, r) {
1005
1144
  isLessThan: emptyFunction,
1006
1145
  isNotNull: emptyFunction,
1007
1146
  isNull: emptyFunction,
1147
+ not: emptyFunction,
1008
1148
  or: emptyFunction,
1009
1149
  });
1010
1150
  }
@@ -1068,8 +1208,9 @@ var preciseValuesCollector = /** @class */ (function () {
1068
1208
  x.bad = true;
1069
1209
  }
1070
1210
  };
1211
+ preciseValuesCollector.prototype.not = function (filter) { };
1071
1212
  preciseValuesCollector.prototype.or = function (orElements) {
1072
- var e_7, _a, e_8, _b;
1213
+ var e_9, _a, e_10, _b;
1073
1214
  var result = orElements.map(function (or) {
1074
1215
  var x = new preciseValuesCollector();
1075
1216
  or.__applyToConsumer(x);
@@ -1092,29 +1233,29 @@ var preciseValuesCollector = /** @class */ (function () {
1092
1233
  }
1093
1234
  }
1094
1235
  }
1095
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
1236
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
1096
1237
  finally {
1097
1238
  try {
1098
1239
  if (result_1_1 && !result_1_1.done && (_a = result_1.return)) _a.call(result_1);
1099
1240
  }
1100
- finally { if (e_7) throw e_7.error; }
1241
+ finally { if (e_9) throw e_9.error; }
1101
1242
  }
1102
1243
  for (var key in this.rawValues) {
1103
1244
  if (Object.prototype.hasOwnProperty.call(this.rawValues, key)) {
1104
1245
  try {
1105
- for (var result_2 = (e_8 = void 0, tslib_1.__values(result)), result_2_1 = result_2.next(); !result_2_1.done; result_2_1 = result_2.next()) {
1246
+ for (var result_2 = (e_10 = void 0, tslib_1.__values(result)), result_2_1 = result_2.next(); !result_2_1.done; result_2_1 = result_2.next()) {
1106
1247
  var r = result_2_1.value;
1107
1248
  var element = r.rawValues[key];
1108
1249
  if (!element)
1109
1250
  this.notOk(this.rawValues[key].field);
1110
1251
  }
1111
1252
  }
1112
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
1253
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
1113
1254
  finally {
1114
1255
  try {
1115
1256
  if (result_2_1 && !result_2_1.done && (_b = result_2.return)) _b.call(result_2);
1116
1257
  }
1117
- finally { if (e_8) throw e_8.error; }
1258
+ finally { if (e_10) throw e_10.error; }
1118
1259
  }
1119
1260
  }
1120
1261
  }
@@ -1149,6 +1290,12 @@ var preciseValuesCollector = /** @class */ (function () {
1149
1290
  preciseValuesCollector.prototype.notContainsCaseInsensitive = function (col, val) {
1150
1291
  this.notOk(col);
1151
1292
  };
1293
+ preciseValuesCollector.prototype.startsWithCaseInsensitive = function (col, val) {
1294
+ this.notOk(col);
1295
+ };
1296
+ preciseValuesCollector.prototype.endsWithCaseInsensitive = function (col, val) {
1297
+ this.notOk(col);
1298
+ };
1152
1299
  preciseValuesCollector.prototype.isIn = function (col, val) {
1153
1300
  this.ok.apply(this, tslib_1.__spreadArray([col], tslib_1.__read(val), false));
1154
1301
  };
@@ -11,6 +11,8 @@ function __updateEntityBasedOnWhere(entityDefs, where, r) {
11
11
  databaseCustom: emptyFunction,
12
12
  containsCaseInsensitive: emptyFunction,
13
13
  notContainsCaseInsensitive: emptyFunction,
14
+ startsWithCaseInsensitive: emptyFunction,
15
+ endsWithCaseInsensitive: emptyFunction,
14
16
  isDifferentFrom: emptyFunction,
15
17
  isEqualTo: function (col, val) {
16
18
  r[col.key] = val;
@@ -22,6 +24,7 @@ function __updateEntityBasedOnWhere(entityDefs, where, r) {
22
24
  isLessThan: emptyFunction,
23
25
  isNotNull: emptyFunction,
24
26
  isNull: emptyFunction,
27
+ not: emptyFunction,
25
28
  or: emptyFunction,
26
29
  });
27
30
  }
@@ -485,28 +485,220 @@ export declare type EntityFilter<entityType> = {
485
485
  id?: string | number;
486
486
  } | undefined ? IdFilter<Partial<entityType>[Properties]> : ValueFilter<Partial<entityType>[Properties]>) | ContainsStringValueFilter;
487
487
  } & {
488
+ /**
489
+ * Represents an 'OR' filter condition where any of the specified filters can be true.
490
+ *
491
+ * @example
492
+ * // Matches entities where the status is 1 or the archive is false
493
+ * const filter = {
494
+ * $or: [
495
+ * { status: 1 },
496
+ * { archive: false }
497
+ * ]
498
+ * };
499
+ */
488
500
  $or?: EntityFilter<entityType>[];
501
+ /**
502
+ * Represents an 'AND' filter condition where all of the specified filters must be true.
503
+ *
504
+ * @example
505
+ * // Matches entities where the status is 1 and the archive is false
506
+ * const filter = {
507
+ * $and: [
508
+ * { status: 1 },
509
+ * { archive: false }
510
+ * ]
511
+ * };
512
+ */
489
513
  $and?: EntityFilter<entityType>[];
514
+ /**
515
+ * Represents a 'NOT' filter condition where the specified filter must be false.
516
+ *
517
+ * @example
518
+ * // Matches entities where the status is not 1
519
+ * const filter = {
520
+ * $not: { status: 1 }
521
+ * };
522
+ */
523
+ $not?: EntityFilter<entityType>;
490
524
  };
491
525
  export type ValueFilter<valueType> = valueType | valueType[] | {
526
+ /**
527
+ * Represents a 'NOT EQUAL' filter condition where the value must not match the specified value or values.
528
+ *
529
+ * @example
530
+ * // Matches entities where the status is not 1
531
+ * const filter = {
532
+ * status: { $ne: 1 }
533
+ * };
534
+ *
535
+ * @example
536
+ * // Matches entities where the status is not 1, 2, or 3
537
+ * const filter = {
538
+ * status: { $ne: [1, 2, 3] }
539
+ * };
540
+ */
492
541
  $ne?: valueType | valueType[];
542
+ /**
543
+ * Represents a 'NOT EQUAL' filter condition using the '!=' operator where the value must not match the specified value or values.
544
+ *
545
+ * @example
546
+ * // Matches entities where the status is not 1
547
+ * const filter = {
548
+ * status: { '!=': 1 }
549
+ * };
550
+ *
551
+ * @example
552
+ * // Matches entities where the status is not 1, 2, or 3
553
+ * const filter = {
554
+ * status: { '!=': [1, 2, 3] }
555
+ * };
556
+ */
493
557
  '!='?: valueType | valueType[];
558
+ /**
559
+ * Represents an 'IN' filter condition where the value must match one of the specified values.
560
+ *
561
+ * @example
562
+ * // Matches entities where the status is 1, 3, or 5
563
+ * const filter = {
564
+ * status: { $in: [1, 3, 5] }
565
+ * };
566
+ */
494
567
  $in?: valueType[];
568
+ /**
569
+ * Represents a 'NOT IN' filter condition where the value must not match any of the specified values.
570
+ *
571
+ * @example
572
+ * // Matches entities where the status is not 1, 2, or 3
573
+ * const filter = {
574
+ * status: { $nin: [1, 2, 3] }
575
+ * };
576
+ */
495
577
  $nin?: valueType[];
496
578
  };
497
579
  export type ComparisonValueFilter<valueType> = ValueFilter<valueType> & {
580
+ /**
581
+ * Represents a 'GREATER THAN' filter condition where the value must be greater than the specified value.
582
+ *
583
+ * @example
584
+ * // Matches entities where the status is greater than 1
585
+ * const filter = {
586
+ * status: { $gt: 1 }
587
+ * };
588
+ */
498
589
  $gt?: valueType;
590
+ /**
591
+ * Represents a 'GREATER THAN' filter condition using the '>' operator where the value must be greater than the specified value.
592
+ *
593
+ * @example
594
+ * // Matches entities where the status is greater than 1
595
+ * const filter = {
596
+ * status: { '>': 1 }
597
+ * };
598
+ */
499
599
  '>'?: valueType;
600
+ /**
601
+ * Represents a 'GREATER THAN OR EQUAL TO' filter condition where the value must be greater than or equal to the specified value.
602
+ *
603
+ * @example
604
+ * // Matches entities where the status is greater than or equal to 1
605
+ * const filter = {
606
+ * status: { $gte: 1 }
607
+ * };
608
+ */
500
609
  $gte?: valueType;
610
+ /**
611
+ * Represents a 'GREATER THAN OR EQUAL TO' filter condition using the '>=' operator where the value must be greater than or equal to the specified value.
612
+ *
613
+ * @example
614
+ * // Matches entities where the status is greater than or equal to 1
615
+ * const filter = {
616
+ * status: { '>=': 1 }
617
+ * };
618
+ */
501
619
  '>='?: valueType;
620
+ /**
621
+ * Represents a 'LESS THAN' filter condition where the value must be less than the specified value.
622
+ *
623
+ * @example
624
+ * // Matches entities where the status is less than 1
625
+ * const filter = {
626
+ * status: { $lt: 1 }
627
+ * };
628
+ */
502
629
  $lt?: valueType;
630
+ /**
631
+ * Represents a 'LESS THAN' filter condition using the '<' operator where the value must be less than the specified value.
632
+ *
633
+ * @example
634
+ * // Matches entities where the status is less than 1
635
+ * const filter = {
636
+ * status: { '<': 1 }
637
+ * };
638
+ */
503
639
  '<'?: valueType;
640
+ /**
641
+ * Represents a 'LESS THAN OR EQUAL TO' filter condition where the value must be less than or equal to the specified value.
642
+ *
643
+ * @example
644
+ * // Matches entities where the status is less than or equal to 1
645
+ * const filter = {
646
+ * status: { $lte: 1 }
647
+ * };
648
+ */
504
649
  $lte?: valueType;
650
+ /**
651
+ * Represents a 'LESS THAN OR EQUAL TO' filter condition using the '<=' operator where the value must be less than or equal to the specified value.
652
+ *
653
+ * @example
654
+ * // Matches entities where the status is less than or equal to 1
655
+ * const filter = {
656
+ * status: { '<=': 1 }
657
+ * };
658
+ */
505
659
  '<='?: valueType;
506
660
  };
507
661
  export interface ContainsStringValueFilter {
662
+ /**
663
+ * Represents a 'CONTAINS' filter condition where the value must contain the specified substring.
664
+ *
665
+ * @example
666
+ * // Matches entities where the name contains 'joe'
667
+ * const filter = {
668
+ * name: { $contains: 'joe' }
669
+ * };
670
+ */
508
671
  $contains?: string;
672
+ /**
673
+ * Represents a 'NOT CONTAINS' filter condition where the value must not contain the specified substring.
674
+ *
675
+ * @example
676
+ * // Matches entities where the name does not contain 'joe'
677
+ * const filter = {
678
+ * name: { $notContains: 'joe' }
679
+ * };
680
+ */
509
681
  $notContains?: string;
682
+ /**
683
+ * Represents a 'STARTS WITH' filter condition where the value must start with the specified substring.
684
+ *
685
+ * @example
686
+ * // Matches entities where the name starts with 'joe'
687
+ * const filter = {
688
+ * name: { $startsWith: 'joe' }
689
+ * };
690
+ */
691
+ $startsWith?: string;
692
+ /**
693
+ * Represents an 'ENDS WITH' filter condition where the value must end with the specified substring.
694
+ *
695
+ * @example
696
+ * // Matches entities where the name ends with 'joe'
697
+ * const filter = {
698
+ * name: { $endsWith: 'joe' }
699
+ * };
700
+ */
701
+ $endsWith?: string;
510
702
  }
511
703
  export type IdFilter<valueType> = ValueFilter<valueType> | {
512
704
  $id: ValueFilter<valueType extends {