@e22m4u/js-repository 0.6.1 → 0.6.3

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.
@@ -218,64 +218,6 @@ var init_is_pure_object = __esm({
218
218
  }
219
219
  });
220
220
 
221
- // src/utils/string-to-regexp.js
222
- function stringToRegexp(pattern, flags = void 0) {
223
- if (pattern instanceof RegExp) {
224
- return new RegExp(pattern, flags);
225
- }
226
- let regex = "";
227
- for (let i = 0, n = pattern.length; i < n; i++) {
228
- const char = pattern.charAt(i);
229
- if (char === "%") {
230
- regex += ".*";
231
- } else {
232
- regex += char;
233
- }
234
- }
235
- return new RegExp(regex, flags);
236
- }
237
- var init_string_to_regexp = __esm({
238
- "src/utils/string-to-regexp.js"() {
239
- "use strict";
240
- __name(stringToRegexp, "stringToRegexp");
241
- }
242
- });
243
-
244
- // src/utils/get-value-by-path.js
245
- function getValueByPath(obj, path, orElse = void 0) {
246
- if (!obj || typeof obj !== "object") return orElse;
247
- if (!path || typeof path !== "string") return orElse;
248
- const keys = path.split(".");
249
- let value = obj;
250
- for (const key of keys) {
251
- if (typeof value === "object" && value !== null && key in value) {
252
- value = value[key];
253
- } else {
254
- value = orElse;
255
- break;
256
- }
257
- }
258
- return value;
259
- }
260
- var init_get_value_by_path = __esm({
261
- "src/utils/get-value-by-path.js"() {
262
- "use strict";
263
- __name(getValueByPath, "getValueByPath");
264
- }
265
- });
266
-
267
- // src/utils/transform-promise.js
268
- function transformPromise(valueOrPromise, transformer) {
269
- return isPromise(valueOrPromise) ? valueOrPromise.then(transformer) : transformer(valueOrPromise);
270
- }
271
- var init_transform_promise = __esm({
272
- "src/utils/transform-promise.js"() {
273
- "use strict";
274
- init_is_promise();
275
- __name(transformPromise, "transformPromise");
276
- }
277
- });
278
-
279
221
  // src/errors/not-implemented-error.js
280
222
  var import_js_format, _NotImplementedError, NotImplementedError;
281
223
  var init_not_implemented_error = __esm({
@@ -342,6 +284,96 @@ var init_errors = __esm({
342
284
  }
343
285
  });
344
286
 
287
+ // src/utils/like-to-regexp.js
288
+ function likeToRegexp(pattern, isCaseInsensitive = false) {
289
+ if (typeof pattern !== "string") {
290
+ throw new InvalidArgumentError(
291
+ "The first argument of `likeToRegexp` should be a String, but %v was given.",
292
+ pattern
293
+ );
294
+ }
295
+ const regexSpecials = "-[]{}()*+?.\\^$|";
296
+ let regexString = "";
297
+ let isEscaping = false;
298
+ for (const char of pattern) {
299
+ if (isEscaping) {
300
+ regexString += regexSpecials.includes(char) ? `\\${char}` : char;
301
+ isEscaping = false;
302
+ } else if (char === "\\") {
303
+ isEscaping = true;
304
+ } else if (char === "%") {
305
+ regexString += ".*";
306
+ } else if (char === "_") {
307
+ regexString += ".";
308
+ } else if (regexSpecials.includes(char)) {
309
+ regexString += `\\${char}`;
310
+ } else {
311
+ regexString += char;
312
+ }
313
+ }
314
+ if (isEscaping) {
315
+ regexString += "\\\\";
316
+ }
317
+ const flags = isCaseInsensitive ? "i" : "";
318
+ return new RegExp(`^${regexString}$`, flags);
319
+ }
320
+ var init_like_to_regexp = __esm({
321
+ "src/utils/like-to-regexp.js"() {
322
+ "use strict";
323
+ init_errors();
324
+ __name(likeToRegexp, "likeToRegexp");
325
+ }
326
+ });
327
+
328
+ // src/utils/string-to-regexp.js
329
+ function stringToRegexp(pattern, flags = void 0) {
330
+ if (pattern instanceof RegExp) {
331
+ return new RegExp(pattern, flags);
332
+ }
333
+ return new RegExp(pattern, flags);
334
+ }
335
+ var init_string_to_regexp = __esm({
336
+ "src/utils/string-to-regexp.js"() {
337
+ "use strict";
338
+ __name(stringToRegexp, "stringToRegexp");
339
+ }
340
+ });
341
+
342
+ // src/utils/get-value-by-path.js
343
+ function getValueByPath(obj, path, orElse = void 0) {
344
+ if (!obj || typeof obj !== "object") return orElse;
345
+ if (!path || typeof path !== "string") return orElse;
346
+ const keys = path.split(".");
347
+ let value = obj;
348
+ for (const key of keys) {
349
+ if (typeof value === "object" && value !== null && key in value) {
350
+ value = value[key];
351
+ } else {
352
+ value = orElse;
353
+ break;
354
+ }
355
+ }
356
+ return value;
357
+ }
358
+ var init_get_value_by_path = __esm({
359
+ "src/utils/get-value-by-path.js"() {
360
+ "use strict";
361
+ __name(getValueByPath, "getValueByPath");
362
+ }
363
+ });
364
+
365
+ // src/utils/transform-promise.js
366
+ function transformPromise(valueOrPromise, transformer) {
367
+ return isPromise(valueOrPromise) ? valueOrPromise.then(transformer) : transformer(valueOrPromise);
368
+ }
369
+ var init_transform_promise = __esm({
370
+ "src/utils/transform-promise.js"() {
371
+ "use strict";
372
+ init_is_promise();
373
+ __name(transformPromise, "transformPromise");
374
+ }
375
+ });
376
+
345
377
  // src/utils/select-object-keys.js
346
378
  function selectObjectKeys(obj, keys) {
347
379
  if (!obj || typeof obj !== "object" || Array.isArray(obj))
@@ -466,6 +498,7 @@ var init_utils = __esm({
466
498
  init_is_deep_equal();
467
499
  init_get_ctor_name();
468
500
  init_is_pure_object();
501
+ init_like_to_regexp();
469
502
  init_string_to_regexp();
470
503
  init_get_value_by_path();
471
504
  init_transform_promise();
@@ -646,41 +679,43 @@ var init_operator_clause_tool = __esm({
646
679
  import_js_service3 = require("@e22m4u/js-service");
647
680
  init_utils();
648
681
  init_errors();
649
- init_errors();
650
682
  _OperatorClauseTool = class _OperatorClauseTool extends import_js_service3.Service {
651
683
  /**
652
684
  * Compare.
653
685
  *
654
686
  * @param {*} val1 The 1st value
655
687
  * @param {*} val2 The 2nd value
688
+ * @param {*} noTypeConversion
656
689
  * @returns {number} 0: =, positive: >, negative <
657
690
  */
658
- compare(val1, val2) {
691
+ compare(val1, val2, noTypeConversion = false) {
692
+ if (val1 === val2) {
693
+ return 0;
694
+ }
659
695
  if (val1 == null || val2 == null) {
660
696
  return val1 == val2 ? 0 : NaN;
661
697
  }
662
- if (typeof val1 === "number") {
663
- if (typeof val2 === "number" || typeof val2 === "string" || typeof val2 === "boolean") {
664
- if (val1 === val2) return 0;
665
- return val1 - Number(val2);
666
- }
667
- return NaN;
698
+ const type1 = typeof val1;
699
+ const type2 = typeof val2;
700
+ if (type1 === "object" || type2 === "object") {
701
+ return isDeepEqual(val1, val2) ? 0 : NaN;
668
702
  }
669
- if (typeof val1 === "string") {
670
- const isDigits = /^\d+$/.test(val1);
671
- if (isDigits) return this.compare(Number(val1), val2);
672
- try {
673
- if (val1 > val2) return 1;
674
- if (val1 < val2) return -1;
675
- if (val1 == val2) return 0;
676
- } catch (e) {
703
+ if ((type1 === "number" || type1 === "string" || type1 === "boolean") && (type2 === "number" || type2 === "string" || type2 === "boolean")) {
704
+ if (noTypeConversion && type1 !== type2) {
705
+ return NaN;
706
+ }
707
+ const num1 = Number(val1);
708
+ const num2 = Number(val2);
709
+ if (!isNaN(num1) && !isNaN(num2)) {
710
+ return num1 - num2;
677
711
  }
678
- return NaN;
679
712
  }
680
- if (typeof val1 === "boolean") {
681
- return Number(val1) - Number(val2);
713
+ if (type1 === "string" && type2 === "string") {
714
+ if (val1 > val2) return 1;
715
+ if (val1 < val2) return -1;
716
+ return 0;
682
717
  }
683
- return val1 === val2 ? 0 : NaN;
718
+ return NaN;
684
719
  }
685
720
  /**
686
721
  * Test all operators.
@@ -695,28 +730,37 @@ var init_operator_clause_tool = __esm({
695
730
  "The first argument of OperatorUtils.testAll should be an Object, but %v was given.",
696
731
  clause
697
732
  );
698
- const eqNeqTest = this.testEqNeq(clause, value);
699
- if (eqNeqTest !== void 0) return eqNeqTest;
700
- const gtLtTest = this.testGtLt(clause, value);
701
- if (gtLtTest !== void 0) return gtLtTest;
702
- const incTest = this.testInq(clause, value);
703
- if (incTest !== void 0) return incTest;
704
- const ninTest = this.testNin(clause, value);
705
- if (ninTest !== void 0) return ninTest;
706
- const betweenTest = this.testBetween(clause, value);
707
- if (betweenTest !== void 0) return betweenTest;
708
- const existsTest = this.testExists(clause, value);
709
- if (existsTest !== void 0) return existsTest;
710
- const likeTest = this.testLike(clause, value);
711
- if (likeTest !== void 0) return likeTest;
712
- const nlikeTest = this.testNlike(clause, value);
713
- if (nlikeTest !== void 0) return nlikeTest;
714
- const ilikeTest = this.testIlike(clause, value);
715
- if (ilikeTest !== void 0) return ilikeTest;
716
- const nilikeTest = this.testNilike(clause, value);
717
- if (nilikeTest !== void 0) return nilikeTest;
718
- const regExpTest = this.testRegexp(clause, value);
719
- if (regExpTest !== void 0) return regExpTest;
733
+ const operatorMap = {
734
+ eq: this.testEqNeq,
735
+ neq: this.testEqNeq,
736
+ gt: this.testGtLt,
737
+ gte: this.testGtLt,
738
+ lt: this.testGtLt,
739
+ lte: this.testGtLt,
740
+ inq: this.testInq,
741
+ nin: this.testNin,
742
+ between: this.testBetween,
743
+ exists: this.testExists,
744
+ like: this.testLike,
745
+ nlike: this.testNlike,
746
+ ilike: this.testIlike,
747
+ nilike: this.testNilike,
748
+ regexp: this.testRegexp
749
+ };
750
+ const clauseKeys = Object.keys(clause);
751
+ const knownOperators = clauseKeys.filter((key) => operatorMap[key]);
752
+ if (knownOperators.length === 0) {
753
+ return void 0;
754
+ }
755
+ return knownOperators.every((op) => {
756
+ const singleOpClause = { [op]: clause[op] };
757
+ if (op === "regexp" && "flags" in clause) {
758
+ singleOpClause.flags = clause.flags;
759
+ }
760
+ const testFn = operatorMap[op];
761
+ const result = testFn.call(this, singleOpClause, value);
762
+ return result;
763
+ });
720
764
  }
721
765
  /**
722
766
  * Test eq/neq operator.
@@ -745,8 +789,8 @@ var init_operator_clause_tool = __esm({
745
789
  "The first argument of OperatorUtils.testEqNeq should be an Object, but %v was given.",
746
790
  clause
747
791
  );
748
- if ("eq" in clause) return this.compare(clause.eq, value) === 0;
749
- if ("neq" in clause) return this.compare(clause.neq, value) !== 0;
792
+ if ("eq" in clause) return this.compare(clause.eq, value, true) === 0;
793
+ if ("neq" in clause) return this.compare(clause.neq, value, true) !== 0;
750
794
  }
751
795
  /**
752
796
  * Test lt/gt/lte/gte operator.
@@ -823,7 +867,9 @@ var init_operator_clause_tool = __esm({
823
867
  );
824
868
  }
825
869
  for (let i = 0; i < clause.inq.length; i++) {
826
- if (clause.inq[i] == value) return true;
870
+ if (this.compare(clause.inq[i], value, true) === 0) {
871
+ return true;
872
+ }
827
873
  }
828
874
  return false;
829
875
  }
@@ -856,10 +902,9 @@ var init_operator_clause_tool = __esm({
856
902
  clause.nin
857
903
  );
858
904
  }
859
- for (let i = 0; i < clause.nin.length; i++) {
860
- if (clause.nin[i] == value) return false;
861
- }
862
- return true;
905
+ return clause.nin.every((element) => {
906
+ return this.compare(element, value, true) !== 0;
907
+ });
863
908
  }
864
909
  }
865
910
  /**
@@ -939,15 +984,15 @@ var init_operator_clause_tool = __esm({
939
984
  * @returns {boolean|undefined}
940
985
  */
941
986
  testLike(clause, value) {
942
- if (!clause || typeof clause !== "object")
987
+ if (!clause || typeof clause !== "object" || Array.isArray(clause))
943
988
  throw new InvalidArgumentError(
944
989
  "The first argument of OperatorUtils.testLike should be an Object, but %v was given.",
945
990
  clause
946
991
  );
947
992
  if ("like" in clause && clause.like !== void 0) {
948
- if (typeof clause.like !== "string" && !(clause.like instanceof RegExp))
993
+ if (typeof clause.like !== "string")
949
994
  throw new InvalidOperatorValueError("like", "a String", clause.like);
950
- return stringToRegexp(clause.like).test(value);
995
+ return likeToRegexp(clause.like).test(value);
951
996
  }
952
997
  }
953
998
  /**
@@ -965,16 +1010,16 @@ var init_operator_clause_tool = __esm({
965
1010
  * @returns {boolean|undefined}
966
1011
  */
967
1012
  testNlike(clause, value) {
968
- if (!clause || typeof clause !== "object")
1013
+ if (!clause || typeof clause !== "object" || Array.isArray(clause))
969
1014
  throw new InvalidArgumentError(
970
1015
  "The first argument of OperatorUtils.testNlike should be an Object, but %v was given.",
971
1016
  clause
972
1017
  );
973
1018
  if ("nlike" in clause && clause.nlike !== void 0) {
974
- if (typeof clause.nlike !== "string" && !(clause.nlike instanceof RegExp)) {
1019
+ if (typeof clause.nlike !== "string") {
975
1020
  throw new InvalidOperatorValueError("nlike", "a String", clause.nlike);
976
1021
  }
977
- return !stringToRegexp(clause.nlike).test(value);
1022
+ return !likeToRegexp(clause.nlike).test(value);
978
1023
  }
979
1024
  }
980
1025
  /**
@@ -992,16 +1037,16 @@ var init_operator_clause_tool = __esm({
992
1037
  * @returns {boolean|undefined}
993
1038
  */
994
1039
  testIlike(clause, value) {
995
- if (!clause || typeof clause !== "object")
1040
+ if (!clause || typeof clause !== "object" || Array.isArray(clause))
996
1041
  throw new InvalidArgumentError(
997
1042
  "The first argument of OperatorUtils.testIlike should be an Object, but %v was given.",
998
1043
  clause
999
1044
  );
1000
1045
  if ("ilike" in clause && clause.ilike !== void 0) {
1001
- if (typeof clause.ilike !== "string" && !(clause.ilike instanceof RegExp)) {
1046
+ if (typeof clause.ilike !== "string") {
1002
1047
  throw new InvalidOperatorValueError("ilike", "a String", clause.ilike);
1003
1048
  }
1004
- return stringToRegexp(clause.ilike, "i").test(value);
1049
+ return likeToRegexp(clause.ilike, true).test(value);
1005
1050
  }
1006
1051
  }
1007
1052
  /**
@@ -1019,20 +1064,20 @@ var init_operator_clause_tool = __esm({
1019
1064
  * @returns {boolean|undefined}
1020
1065
  */
1021
1066
  testNilike(clause, value) {
1022
- if (!clause || typeof clause !== "object")
1067
+ if (!clause || typeof clause !== "object" || Array.isArray(clause))
1023
1068
  throw new InvalidArgumentError(
1024
1069
  "The first argument of OperatorUtils.testNilike should be an Object, but %v was given.",
1025
1070
  clause
1026
1071
  );
1027
1072
  if ("nilike" in clause && clause.nilike !== void 0) {
1028
- if (typeof clause.nilike !== "string" && !(clause.nilike instanceof RegExp)) {
1073
+ if (typeof clause.nilike !== "string") {
1029
1074
  throw new InvalidOperatorValueError(
1030
1075
  "nilike",
1031
1076
  "a String",
1032
1077
  clause.nilike
1033
1078
  );
1034
1079
  }
1035
- return !stringToRegexp(clause.nilike, "i").test(value);
1080
+ return !likeToRegexp(clause.nilike, true).test(value);
1036
1081
  }
1037
1082
  }
1038
1083
  /**
@@ -1094,9 +1139,9 @@ var init_where_clause_tool = __esm({
1094
1139
  "src/filter/where-clause-tool.js"() {
1095
1140
  "use strict";
1096
1141
  import_js_service4 = require("@e22m4u/js-service");
1097
- init_utils();
1098
1142
  init_errors();
1099
1143
  init_operator_clause_tool();
1144
+ init_utils();
1100
1145
  _WhereClauseTool = class _WhereClauseTool extends import_js_service4.Service {
1101
1146
  /**
1102
1147
  * Filter by where clause.
@@ -1167,21 +1212,6 @@ var init_where_clause_tool = __esm({
1167
1212
  }
1168
1213
  const value = getValueByPath(data, key);
1169
1214
  const matcher = whereClause[key];
1170
- if (Array.isArray(value)) {
1171
- if (typeof matcher === "object" && matcher !== null && "neq" in matcher && matcher.neq !== void 0) {
1172
- if (value.length === 0) return true;
1173
- return value.every((el, index) => {
1174
- const where = {};
1175
- where[index] = matcher;
1176
- return this._createFilter(where)({ ...value });
1177
- });
1178
- }
1179
- return value.some((el, index) => {
1180
- const where = {};
1181
- where[index] = matcher;
1182
- return this._createFilter(where)({ ...value });
1183
- });
1184
- }
1185
1215
  if (this._test(matcher, value)) return true;
1186
1216
  });
1187
1217
  };
@@ -1194,6 +1224,9 @@ var init_where_clause_tool = __esm({
1194
1224
  * @returns {boolean}
1195
1225
  */
1196
1226
  _test(example, value) {
1227
+ if (example === value) {
1228
+ return true;
1229
+ }
1197
1230
  if (example === null) {
1198
1231
  return value === null;
1199
1232
  }
@@ -1201,17 +1234,31 @@ var init_where_clause_tool = __esm({
1201
1234
  return value === void 0;
1202
1235
  }
1203
1236
  if (example instanceof RegExp) {
1204
- if (typeof value === "string") return !!value.match(example);
1237
+ if (typeof value === "string") {
1238
+ return example.test(value);
1239
+ }
1240
+ if (Array.isArray(value)) {
1241
+ return value.some((el) => typeof el === "string" && example.test(el));
1242
+ }
1205
1243
  return false;
1206
1244
  }
1207
- if (typeof example === "object") {
1245
+ if (isPureObject(example)) {
1208
1246
  const operatorsTest = this.getService(OperatorClauseTool).testAll(
1209
1247
  example,
1210
1248
  value
1211
1249
  );
1212
- if (operatorsTest !== void 0) return operatorsTest;
1250
+ if (operatorsTest !== void 0) {
1251
+ if ("neq" in example && Array.isArray(value)) {
1252
+ return !value.some((el) => isDeepEqual(el, example.neq));
1253
+ }
1254
+ return operatorsTest;
1255
+ }
1256
+ }
1257
+ if (Array.isArray(value)) {
1258
+ const isElementMatched = value.some((el) => isDeepEqual(el, example));
1259
+ if (isElementMatched) return true;
1213
1260
  }
1214
- return example == value;
1261
+ return isDeepEqual(example, value);
1215
1262
  }
1216
1263
  /**
1217
1264
  * Validate where clause.
@@ -6438,6 +6485,7 @@ __export(index_exports, {
6438
6485
  isDeepEqual: () => isDeepEqual,
6439
6486
  isPromise: () => isPromise,
6440
6487
  isPureObject: () => isPureObject,
6488
+ likeToRegexp: () => likeToRegexp,
6441
6489
  modelNameToModelKey: () => modelNameToModelKey,
6442
6490
  selectObjectKeys: () => selectObjectKeys,
6443
6491
  singularize: () => singularize,
@@ -6543,6 +6591,7 @@ init_repository2();
6543
6591
  isDeepEqual,
6544
6592
  isPromise,
6545
6593
  isPureObject,
6594
+ likeToRegexp,
6546
6595
  modelNameToModelKey,
6547
6596
  selectObjectKeys,
6548
6597
  singularize,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e22m4u/js-repository",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Реализация репозитория для работы с базами данных в Node.js",
5
5
  "author": "Mikhail Evstropov <e22m4u@yandex.ru>",
6
6
  "license": "MIT",
@@ -58,7 +58,7 @@
58
58
  "eslint": "~9.38.0",
59
59
  "eslint-config-prettier": "~10.1.8",
60
60
  "eslint-plugin-chai-expect": "~3.1.0",
61
- "eslint-plugin-jsdoc": "~61.1.5",
61
+ "eslint-plugin-jsdoc": "~61.1.7",
62
62
  "eslint-plugin-mocha": "~11.2.0",
63
63
  "husky": "~9.1.7",
64
64
  "mocha": "~11.7.4",
@@ -3409,7 +3409,7 @@ describe('MemoryAdapter', function () {
3409
3409
  await adapter.create('model', input2);
3410
3410
  await adapter.create('model', input3);
3411
3411
  const filter1 = {where: {foo: 10}};
3412
- const filter2 = {where: {foo: {gte: 15}, baz: {like: 'bc'}}};
3412
+ const filter2 = {where: {foo: {gte: 15}, baz: {like: '%bc'}}};
3413
3413
  const filter3 = {where: {bar: true}};
3414
3414
  const result1 = await adapter.find('model', filter1);
3415
3415
  const result2 = await adapter.find('model', filter2);
@@ -3466,7 +3466,7 @@ describe('MemoryAdapter', function () {
3466
3466
  baz: tableInput2.bazCol,
3467
3467
  };
3468
3468
  const filter1 = {where: {foo: 10}};
3469
- const filter2 = {where: {foo: {gte: 15}, baz: {like: 'bc'}}};
3469
+ const filter2 = {where: {foo: {gte: 15}, baz: {like: '%bc'}}};
3470
3470
  const filter3 = {where: {bar: true}};
3471
3471
  const result1 = await adapter.find('model', filter1);
3472
3472
  const result2 = await adapter.find('model', filter2);
@@ -113,10 +113,10 @@ export declare type OperatorClause = {
113
113
  nin?: PrimitiveValue[];
114
114
  between?: readonly [string | number, string | number];
115
115
  exists?: boolean;
116
- like?: string | RegExp;
117
- nlike?: string | RegExp;
118
- ilike?: string | RegExp;
119
- nilike?: string | RegExp;
116
+ like?: string;
117
+ nlike?: string;
118
+ ilike?: string;
119
+ nilike?: string;
120
120
  regexp?: string | RegExp;
121
121
  flags?: string;
122
122
  };
@@ -9,8 +9,9 @@ export declare class OperatorClauseTool extends Service {
9
9
  *
10
10
  * @param val1
11
11
  * @param val2
12
+ * @param noTypeConversion
12
13
  */
13
- compare(val1: unknown, val2: unknown): number;
14
+ compare(val1: unknown, val2: unknown, noTypeConversion?: boolean): number;
14
15
 
15
16
  /**
16
17
  * Test all operators.