@flusys/nestjs-entity-builder 9.1.1 → 9.2.0

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.
Files changed (41) hide show
  1. package/README.md +24 -12
  2. package/config/message-keys.d.ts +29 -0
  3. package/controllers/entity-definition.controller.d.ts +1 -0
  4. package/controllers/field-definition.controller.d.ts +1 -0
  5. package/controllers/flow-definition.controller.d.ts +1 -0
  6. package/dtos/definition-bundle.dto.d.ts +1 -0
  7. package/dtos/entity-definition.dto.d.ts +1 -2
  8. package/fesm/21.js +31 -2
  9. package/fesm/458.js +8 -3
  10. package/fesm/677.js +890 -465
  11. package/fesm/{582.js → 857.js} +201 -265
  12. package/fesm/870.js +580 -247
  13. package/fesm/897.js +164 -22
  14. package/fesm/946.js +5 -1
  15. package/fesm/controllers/index.js +1 -1
  16. package/fesm/dtos/index.js +11 -0
  17. package/fesm/guards/index.js +2 -2
  18. package/fesm/index.js +39 -6
  19. package/fesm/interfaces/index.js +74 -3
  20. package/fesm/modules/index.js +1 -1
  21. package/fesm/rule-engine/index.js +2 -2
  22. package/fesm/services/index.js +13 -3
  23. package/flow-engine/flow-input.validator.d.ts +2 -1
  24. package/flow-engine/flow-run.types.d.ts +1 -0
  25. package/flow-engine/flow.types.d.ts +25 -4
  26. package/interfaces/definition-bundle.interface.d.ts +2 -1
  27. package/interfaces/generic-record.interface.d.ts +11 -1
  28. package/package.json +3 -4
  29. package/rule-engine/rule-engine.service.d.ts +2 -1
  30. package/rule-engine/rule-regex.d.ts +0 -2
  31. package/rule-engine/rule-values.d.ts +4 -1
  32. package/rule-engine/rule.interface.d.ts +2 -3
  33. package/services/definition-bundle.diff.d.ts +6 -0
  34. package/services/definition-bundle.service.d.ts +10 -2
  35. package/services/entity-flow-scaffold.d.ts +2 -1
  36. package/services/entity-permission.service.d.ts +1 -0
  37. package/services/flow-definition.service.d.ts +1 -1
  38. package/services/flow-runtime.service.d.ts +1 -0
  39. package/services/generic-entity.service.d.ts +5 -0
  40. package/services/schema-change-executor.service.d.ts +1 -0
  41. package/services/schema-dialect-adapter.service.d.ts +2 -0
@@ -1,24 +1,79 @@
1
- import { RE2JS } from "re2js";
2
1
  import * as __rspack_external__flusys_nestjs_shared_interfaces_413f2706 from "@flusys/nestjs-shared/interfaces";
3
2
  import * as __rspack_external__flusys_nestjs_shared_modules_24702bee from "@flusys/nestjs-shared/modules";
4
3
  import * as __rspack_external__flusys_nestjs_shared_utils_9125c1f1 from "@flusys/nestjs-shared/utils";
5
4
  import * as __rspack_external__nestjs_common_a04939da from "@nestjs/common";
6
5
  import * as __rspack_external_node_net_5ed819e1 from "node:net";
7
- export const __rspack_esm_id = 582;
8
- export const __rspack_esm_ids = [582];
6
+ export const __rspack_esm_id = 857;
7
+ export const __rspack_esm_ids = [857];
9
8
  export const __webpack_modules__ = {
10
9
  3372(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
11
10
  const RECORD_FILTER_OPS = [
12
11
  'eq',
13
12
  'ne',
13
+ 'ieq',
14
14
  'gt',
15
15
  'gte',
16
16
  'lt',
17
17
  'lte',
18
+ 'between',
19
+ 'not_between',
18
20
  'in',
21
+ 'not_in',
22
+ 'contains',
23
+ 'not_contains',
24
+ 'starts_with',
25
+ 'ends_with',
26
+ 'has_any',
27
+ 'has_all',
28
+ 'has_none',
29
+ 'is_empty',
30
+ 'not_empty',
19
31
  'is_null',
20
32
  'not_null'
21
33
  ];
34
+ const FILTER_OP_VALUE_KIND = {
35
+ eq: 'single',
36
+ ne: 'single',
37
+ ieq: 'single',
38
+ gt: 'single',
39
+ gte: 'single',
40
+ lt: 'single',
41
+ lte: 'single',
42
+ between: 'range',
43
+ not_between: 'range',
44
+ in: 'list',
45
+ not_in: 'list',
46
+ contains: 'single',
47
+ not_contains: 'single',
48
+ starts_with: 'single',
49
+ ends_with: 'single',
50
+ has_any: 'list',
51
+ has_all: 'list',
52
+ has_none: 'list',
53
+ is_empty: 'none',
54
+ not_empty: 'none',
55
+ is_null: 'none',
56
+ not_null: 'none'
57
+ };
58
+ /** Case-insensitive text operators: text, long text, email and single-select fields only. */ const TEXT_FILTER_OPS = [
59
+ 'ieq',
60
+ 'contains',
61
+ 'not_contains',
62
+ 'starts_with',
63
+ 'ends_with'
64
+ ];
65
+ /** Multi-select operators: whether the stored list holds any / all / none of the given values. */ const LIST_FIELD_FILTER_OPS = [
66
+ 'has_any',
67
+ 'has_all',
68
+ 'has_none'
69
+ ];
70
+ /** Blank checks: no value, an empty text or an empty multi-select. */ const EMPTY_FILTER_OPS = [
71
+ 'is_empty',
72
+ 'not_empty'
73
+ ];
74
+ function isFilterRange(value) {
75
+ return !!value && typeof value === 'object' && !Array.isArray(value) && 'from' in value && 'to' in value && Object.keys(value).length === 2;
76
+ }
22
77
  const RECORD_FILTER_LIMITS = {
23
78
  MAX_IN_VALUES: 100
24
79
  };
@@ -37,15 +92,20 @@ const FILTER_CONDITION_KEYS = new Set([
37
92
  }
38
93
 
39
94
  __webpack_require__.d(__webpack_exports__, {
95
+ iA: () => (isFilterRange),
40
96
  t1: () => (isRecordFilterCondition)
41
97
  }, {
42
98
  M5: RECORD_FILTER_LIMITS,
43
- ox: RECORD_FILTER_OPS
99
+ Oh: EMPTY_FILTER_OPS,
100
+ ox: RECORD_FILTER_OPS,
101
+ w9: FILTER_OP_VALUE_KIND,
102
+ wk: TEXT_FILTER_OPS,
103
+ yV: LIST_FIELD_FILTER_OPS
44
104
  });
45
105
 
46
106
 
47
107
  },
48
- 8429(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
108
+ 8552(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
49
109
 
50
110
  // EXPORTS
51
111
  __webpack_require__.d(__webpack_exports__, {
@@ -74,14 +134,87 @@ var common_ = __webpack_require__(6157);
74
134
  var external_node_crypto_ = __webpack_require__(2561);
75
135
  // EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/config/message-keys.ts
76
136
  var message_keys = __webpack_require__(5732);
77
- // EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/interfaces/generic-record.interface.ts
78
- var generic_record_interface = __webpack_require__(3372);
79
137
  // EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/rule-engine/rule-ip.ts
80
138
  var rule_ip = __webpack_require__(809);
81
139
  // EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/rule-engine/rule-permission.ts
82
140
  var rule_permission = __webpack_require__(5191);
83
- // EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/rule-engine/rule-regex.ts + 1 modules
84
- var rule_regex = __webpack_require__(6308);
141
+ ;// CONCATENATED MODULE: ./projects/nestjs-entity-builder/src/rule-engine/rule-regex.ts
142
+
143
+
144
+
145
+
146
+ /** RE2 (linear-time) search: true when the pattern matches anywhere in the input. */ function matchesPattern(input, pattern) {
147
+ const prepared = prepare(input, pattern);
148
+ return prepared ? prepared.regex.matcher(prepared.text).find() : false;
149
+ }
150
+ /**
151
+ * The first match's capture `group` (default: the first group when the pattern has one, else the
152
+ * whole match); null when nothing matches or the group does not exist.
153
+ */ function extractPattern(input, pattern, group) {
154
+ const prepared = prepare(input, pattern);
155
+ if (!prepared) return null;
156
+ const index = group === undefined || group === null || group === '' ? prepared.regex.groupCount() > 0 ? 1 : 0 : Number(group);
157
+ if (!Number.isInteger(index) || index < 0 || index > prepared.regex.groupCount()) return null;
158
+ const matcher = prepared.regex.matcher(prepared.text);
159
+ return matcher.find() ? matcher.group(index) ?? null : null;
160
+ }
161
+ function prepare(input, pattern) {
162
+ if (typeof pattern !== 'string') {
163
+ throw new common_.BadRequestException({
164
+ message: 'A regular expression pattern must be text.',
165
+ messageKey: message_keys/* .RULE_ENGINE_MESSAGES.REGEX_INVALID */.x3.REGEX_INVALID,
166
+ messageVariables: {
167
+ pattern: JSON.stringify(pattern ?? null)
168
+ }
169
+ });
170
+ }
171
+ const problem = (0,utils_.safeRegexProblem)(pattern);
172
+ if (problem) throw patternError(problem, pattern);
173
+ const text = typeof input === 'string' ? input : typeof input === 'number' || typeof input === 'boolean' ? String(input) : null;
174
+ if (text === null) return null;
175
+ if (text.length > rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_INPUT_LENGTH */.bw.MAX_REGEX_INPUT_LENGTH) {
176
+ throw new common_.BadRequestException({
177
+ message: `Text matched against a regular expression can be at most ${rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_INPUT_LENGTH */.bw.MAX_REGEX_INPUT_LENGTH} characters.`,
178
+ messageKey: message_keys/* .RULE_ENGINE_MESSAGES.REGEX_INPUT_TOO_LONG */.x3.REGEX_INPUT_TOO_LONG,
179
+ messageVariables: {
180
+ max: rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_INPUT_LENGTH */.bw.MAX_REGEX_INPUT_LENGTH
181
+ }
182
+ });
183
+ }
184
+ return {
185
+ regex: (0,utils_.compileSafeRegex)(pattern),
186
+ text
187
+ };
188
+ }
189
+ function patternError(problem, pattern) {
190
+ switch(problem){
191
+ case 'too_long':
192
+ return new common_.BadRequestException({
193
+ message: `A regular expression pattern can be at most ${rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_PATTERN_LENGTH */.bw.MAX_REGEX_PATTERN_LENGTH} characters.`,
194
+ messageKey: message_keys/* .RULE_ENGINE_MESSAGES.REGEX_PATTERN_TOO_LONG */.x3.REGEX_PATTERN_TOO_LONG,
195
+ messageVariables: {
196
+ max: rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_PATTERN_LENGTH */.bw.MAX_REGEX_PATTERN_LENGTH
197
+ }
198
+ });
199
+ case 'too_complex':
200
+ return new common_.BadRequestException({
201
+ message: `A regular expression can repeat a part at most ${rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_REPEAT */.bw.MAX_REGEX_REPEAT} times, nested repeats included.`,
202
+ messageKey: message_keys/* .RULE_ENGINE_MESSAGES.REGEX_TOO_COMPLEX */.x3.REGEX_TOO_COMPLEX,
203
+ messageVariables: {
204
+ max: rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_REPEAT */.bw.MAX_REGEX_REPEAT
205
+ }
206
+ });
207
+ case 'invalid':
208
+ return new common_.BadRequestException({
209
+ message: `'${pattern}' is not a valid regular expression.`,
210
+ messageKey: message_keys/* .RULE_ENGINE_MESSAGES.REGEX_INVALID */.x3.REGEX_INVALID,
211
+ messageVariables: {
212
+ pattern
213
+ }
214
+ });
215
+ }
216
+ }
217
+
85
218
  // EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/rule-engine/rule-values.ts
86
219
  var rule_values = __webpack_require__(6622);
87
220
  ;// CONCATENATED MODULE: ./projects/nestjs-entity-builder/src/rule-engine/rule-engine.service.ts
@@ -119,7 +252,6 @@ function _ts_param(paramIndex, decorator) {
119
252
 
120
253
 
121
254
 
122
-
123
255
  const FORBIDDEN_PATH_KEYS = new Set([
124
256
  '__proto__',
125
257
  'constructor',
@@ -145,6 +277,12 @@ class RuleEngineService {
145
277
  cache: this.permissionCache
146
278
  });
147
279
  }
280
+ /** Any user's codes in any company / branch - another user, or the caller outside their current scope. */ permissionCodes(scope) {
281
+ return (0,utils_.loadPermissionCodes)(scope, {
282
+ resolver: this.permissionResolver,
283
+ cache: this.permissionCache
284
+ });
285
+ }
148
286
  async evaluateGroup(group, ctx, depth = 0, budget = {}) {
149
287
  this.assertWithinLimits(group, depth);
150
288
  const evaluate = (node)=>(0,rule_interface/* .isRuleGroup */.GD)(node) ? this.evaluateGroup(node, ctx, depth + 1, budget) : this.evaluateCondition(node, ctx, budget);
@@ -221,9 +359,9 @@ class RuleEngineService {
221
359
  case 'is_false':
222
360
  return actual === false;
223
361
  case 'matches':
224
- return (0,rule_regex/* .matchesPattern */.MT)(actual, expected);
362
+ return matchesPattern(actual, expected);
225
363
  case 'not_matches':
226
- return !(0,rule_regex/* .matchesPattern */.MT)(actual, expected);
364
+ return !matchesPattern(actual, expected);
227
365
  }
228
366
  }
229
367
  async resolveConditionLeft(condition, ctx, budget) {
@@ -290,17 +428,7 @@ class RuleEngineService {
290
428
  }
291
429
  const filter = {};
292
430
  for (const [key, item] of Object.entries(expression.filter ?? {})){
293
- if ((0,generic_record_interface/* .isRecordFilterCondition */.t1)(item)) {
294
- const value = item.value === undefined ? undefined : await this.resolveExpression(item.value, ctx, budget);
295
- filter[key] = value === undefined ? {
296
- op: item.op
297
- } : {
298
- op: item.op,
299
- value
300
- };
301
- } else {
302
- filter[key] = (0,rule_values/* .equalsOperand */.$b)(await this.resolveExpression(item, ctx, budget));
303
- }
431
+ filter[key] = await (0,rule_values/* .resolveFilterEntry */.vY)(item, (value)=>this.resolveExpression(value, ctx, budget));
304
432
  }
305
433
  const { rows, total } = await ctx.lookupResolver.find(expression.entity, {
306
434
  filter,
@@ -469,14 +597,15 @@ class RuleEngineService {
469
597
  return part === undefined ? null : part.trim();
470
598
  }
471
599
  case 'REGEX_EXTRACT':
472
- return (0,rule_regex/* .extractPattern */.Ax)(resolvedArgs[0], resolvedArgs[1], resolvedArgs[2]);
600
+ return extractPattern(resolvedArgs[0], resolvedArgs[1], resolvedArgs[2]);
473
601
  case 'REPLACE':
474
602
  {
475
603
  const [value, search, replacement] = resolvedArgs;
476
604
  const text = this.toText(value);
477
605
  if (text === null) return null;
478
606
  const needle = this.toText(search) ?? '';
479
- return needle ? text.replaceAll(needle, this.toText(replacement) ?? '') : text;
607
+ const replacementText = this.toText(replacement) ?? '';
608
+ return needle ? text.replaceAll(needle, ()=>replacementText) : text;
480
609
  }
481
610
  case 'TO_NUMBER':
482
611
  {
@@ -824,235 +953,10 @@ __webpack_require__.d(__webpack_exports__, {
824
953
  });
825
954
 
826
955
 
827
- },
828
- 6308(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
829
-
830
- // EXPORTS
831
- __webpack_require__.d(__webpack_exports__, {
832
- Ax: () => (/* binding */ extractPattern),
833
- MT: () => (/* binding */ matchesPattern),
834
- _V: () => (/* binding */ rulePatternProblem)
835
- });
836
-
837
- // EXTERNAL MODULE: external "@nestjs/common"
838
- var common_ = __webpack_require__(6157);
839
- ;// CONCATENATED MODULE: external "re2js"
840
-
841
- // EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/config/message-keys.ts
842
- var message_keys = __webpack_require__(5732);
843
- // EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/rule-engine/rule.interface.ts
844
- var rule_interface = __webpack_require__(2354);
845
- ;// CONCATENATED MODULE: ./projects/nestjs-entity-builder/src/rule-engine/rule-regex.ts
846
-
847
-
848
-
849
-
850
- const MAX_CACHED_PATTERNS = 200;
851
- const compiled = new Map();
852
- const tooComplex = new Map();
853
- function remember(cache, pattern, make) {
854
- if (cache.has(pattern)) return cache.get(pattern);
855
- const value = make(pattern);
856
- if (cache.size >= MAX_CACHED_PATTERNS) cache.delete(cache.keys().next().value);
857
- cache.set(pattern, value);
858
- return value;
859
- }
860
- /** Why a pattern cannot be used, or null when it compiles within the limits. */ function rulePatternProblem(pattern) {
861
- if (pattern.length > rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_PATTERN_LENGTH */.bw.MAX_REGEX_PATTERN_LENGTH) return 'too_long';
862
- if (remember(tooComplex, pattern, isTooComplex)) return 'too_complex';
863
- try {
864
- compile(pattern);
865
- return null;
866
- } catch {
867
- return 'invalid';
868
- }
869
- }
870
- const newFrame = ()=>({
871
- size: 0,
872
- last: 0,
873
- lastProduct: 1,
874
- maxProduct: 1
875
- });
876
- /**
877
- * RE2 unrolls counted repeats (`x{2,50}` becomes 50 copies of x), so match time grows with the
878
- * product of nested counts. Rejects a count above MAX_REGEX_REPEAT, nested counts whose product
879
- * is above it, and a pattern whose unrolled size grows by more than MAX_REGEX_REPEAT_EXPANSION.
880
- * `*`, `+` and `?` do not unroll and stay allowed, nested or not.
881
- */ function isTooComplex(pattern) {
882
- const { MAX_REGEX_REPEAT, MAX_REGEX_REPEAT_EXPANSION } = rule_interface/* .RULE_ENGINE_LIMITS */.bw;
883
- const stack = [
884
- newFrame()
885
- ];
886
- const top = ()=>stack[stack.length - 1];
887
- let atoms = 0;
888
- const atom = (size, product)=>{
889
- const frame = top();
890
- frame.size += size;
891
- frame.last = size;
892
- frame.lastProduct = product;
893
- frame.maxProduct = Math.max(frame.maxProduct, product);
894
- };
895
- let i = 0;
896
- while(i < pattern.length){
897
- const c = pattern[i];
898
- if (c === '\\') {
899
- const next = pattern[i + 1];
900
- i += 2;
901
- if ((next === 'p' || next === 'P' || next === 'x') && pattern[i] === '{') i = closing(pattern, i, '}');
902
- atoms++;
903
- atom(1, 1);
904
- } else if (c === '[') {
905
- i = classEnd(pattern, i);
906
- atoms++;
907
- atom(1, 1);
908
- } else if (c === '(') {
909
- i++;
910
- if (pattern[i] === '?') {
911
- const flagsOnly = /^\?[a-zA-Z-]*\)/.exec(pattern.slice(i));
912
- if (flagsOnly) {
913
- i += flagsOnly[0].length;
914
- continue;
915
- }
916
- const marker = /^\?(?:P?<[^>]*>|[a-zA-Z-]*:)/.exec(pattern.slice(i));
917
- i += marker ? marker[0].length : 1;
918
- }
919
- stack.push(newFrame());
920
- } else if (c === ')') {
921
- i++;
922
- if (stack.length === 1) continue;
923
- const group = stack.pop();
924
- atom(group.size, group.maxProduct);
925
- } else if (c === '|') {
926
- i++;
927
- top().last = 0;
928
- top().lastProduct = 1;
929
- } else if (c === '{') {
930
- const repeat = /^\{(\d+)(,(\d*))?\}\??/.exec(pattern.slice(i));
931
- if (!repeat) {
932
- i++;
933
- atoms++;
934
- atom(1, 1);
935
- continue;
936
- }
937
- i += repeat[0].length;
938
- const min = Number(repeat[1]);
939
- const max = repeat[2] === undefined ? min : repeat[3] ? Number(repeat[3]) : min + 1;
940
- if (min > MAX_REGEX_REPEAT || max > MAX_REGEX_REPEAT) return true;
941
- const frame = top();
942
- const product = frame.lastProduct * Math.max(max, 1);
943
- if (product > MAX_REGEX_REPEAT) return true;
944
- const extra = frame.last * (Math.max(max, 1) - 1);
945
- frame.size += extra;
946
- frame.last += extra;
947
- frame.lastProduct = product;
948
- frame.maxProduct = Math.max(frame.maxProduct, product);
949
- } else {
950
- i++;
951
- if (c !== '*' && c !== '+' && c !== '?') {
952
- atoms++;
953
- atom(1, 1);
954
- }
955
- }
956
- }
957
- while(stack.length > 1){
958
- const group = stack.pop();
959
- atom(group.size, group.maxProduct);
960
- }
961
- return stack[0].size - atoms > MAX_REGEX_REPEAT_EXPANSION;
962
- }
963
- function closing(pattern, from, char) {
964
- const end = pattern.indexOf(char, from);
965
- return end < 0 ? pattern.length : end + 1;
966
- }
967
- function classEnd(pattern, start) {
968
- let j = start + 1;
969
- if (pattern[j] === '^') j++;
970
- if (pattern[j] === ']') j++;
971
- while(j < pattern.length && pattern[j] !== ']'){
972
- if (pattern[j] === '\\') j += 2;
973
- else if (pattern.startsWith('[:', j)) j = closing(pattern, j + 2, ']');
974
- else j++;
975
- }
976
- return j + 1;
977
- }
978
- /** RE2 (linear-time) search: true when the pattern matches anywhere in the input. */ function matchesPattern(input, pattern) {
979
- const prepared = prepare(input, pattern);
980
- return prepared ? prepared.regex.matcher(prepared.text).find() : false;
981
- }
982
- /**
983
- * The first match's capture `group` (default: the first group when the pattern has one, else the
984
- * whole match); null when nothing matches or the group does not exist.
985
- */ function extractPattern(input, pattern, group) {
986
- const prepared = prepare(input, pattern);
987
- if (!prepared) return null;
988
- const index = group === undefined || group === null || group === '' ? prepared.regex.groupCount() > 0 ? 1 : 0 : Number(group);
989
- if (!Number.isInteger(index) || index < 0 || index > prepared.regex.groupCount()) return null;
990
- const matcher = prepared.regex.matcher(prepared.text);
991
- return matcher.find() ? matcher.group(index) ?? null : null;
992
- }
993
- function prepare(input, pattern) {
994
- if (typeof pattern !== 'string') {
995
- throw new common_.BadRequestException({
996
- message: 'A regular expression pattern must be text.',
997
- messageKey: message_keys/* .RULE_ENGINE_MESSAGES.REGEX_INVALID */.x3.REGEX_INVALID,
998
- messageVariables: {
999
- pattern: JSON.stringify(pattern ?? null)
1000
- }
1001
- });
1002
- }
1003
- const problem = rulePatternProblem(pattern);
1004
- if (problem) throw patternError(problem, pattern);
1005
- const text = typeof input === 'string' ? input : typeof input === 'number' || typeof input === 'boolean' ? String(input) : null;
1006
- if (text === null) return null;
1007
- if (text.length > rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_INPUT_LENGTH */.bw.MAX_REGEX_INPUT_LENGTH) {
1008
- throw new common_.BadRequestException({
1009
- message: `Text matched against a regular expression can be at most ${rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_INPUT_LENGTH */.bw.MAX_REGEX_INPUT_LENGTH} characters.`,
1010
- messageKey: message_keys/* .RULE_ENGINE_MESSAGES.REGEX_INPUT_TOO_LONG */.x3.REGEX_INPUT_TOO_LONG,
1011
- messageVariables: {
1012
- max: rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_INPUT_LENGTH */.bw.MAX_REGEX_INPUT_LENGTH
1013
- }
1014
- });
1015
- }
1016
- return {
1017
- regex: compile(pattern),
1018
- text
1019
- };
1020
- }
1021
- function patternError(problem, pattern) {
1022
- switch(problem){
1023
- case 'too_long':
1024
- return new common_.BadRequestException({
1025
- message: `A regular expression pattern can be at most ${rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_PATTERN_LENGTH */.bw.MAX_REGEX_PATTERN_LENGTH} characters.`,
1026
- messageKey: message_keys/* .RULE_ENGINE_MESSAGES.REGEX_PATTERN_TOO_LONG */.x3.REGEX_PATTERN_TOO_LONG,
1027
- messageVariables: {
1028
- max: rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_PATTERN_LENGTH */.bw.MAX_REGEX_PATTERN_LENGTH
1029
- }
1030
- });
1031
- case 'too_complex':
1032
- return new common_.BadRequestException({
1033
- message: `A regular expression can repeat a part at most ${rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_REPEAT */.bw.MAX_REGEX_REPEAT} times, nested repeats included.`,
1034
- messageKey: message_keys/* .RULE_ENGINE_MESSAGES.REGEX_TOO_COMPLEX */.x3.REGEX_TOO_COMPLEX,
1035
- messageVariables: {
1036
- max: rule_interface/* .RULE_ENGINE_LIMITS.MAX_REGEX_REPEAT */.bw.MAX_REGEX_REPEAT
1037
- }
1038
- });
1039
- case 'invalid':
1040
- return new common_.BadRequestException({
1041
- message: `'${pattern}' is not a valid regular expression.`,
1042
- messageKey: message_keys/* .RULE_ENGINE_MESSAGES.REGEX_INVALID */.x3.REGEX_INVALID,
1043
- messageVariables: {
1044
- pattern
1045
- }
1046
- });
1047
- }
1048
- }
1049
- function compile(pattern) {
1050
- return remember(compiled, pattern, (p)=>RE2JS.compile(p));
1051
- }
1052
-
1053
-
1054
956
  },
1055
957
  6622(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
958
+ /* import */ var _interfaces_generic_record_interface_js__rspack_import_0 = __webpack_require__(3372);
959
+
1056
960
  const ISO_DATE_PREFIX = /^\s*\d{4}-\d{2}-\d{2}/;
1057
961
  const ISO_DATE_TIME = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:[.,](\d{1,9}))?)?)?\s*(Z|[+-]\d{2}(?::?\d{2})?)?$/i;
1058
962
  const EXPLICIT_ZONE = /(?:\bZ|\bGMT|\bUTC|[+-]\d{2}:?\d{2})$/i;
@@ -1103,21 +1007,54 @@ function instant(value) {
1103
1007
  }
1104
1008
  const includesValue = (list, value)=>list.some((item)=>valuesEqual(item, value));
1105
1009
  /**
1106
- * A resolved filter value is only ever an operand: an object or a list (e.g. `{ "op": "not_null" }`
1107
- * sent as input) is wrapped as the operand of `eq`, which the entity service refuses as not a single
1108
- * value, so it never becomes an operator. Only authored `{ op, value }` entries are operators.
1109
- */ const equalsOperand = (value)=>value !== null && typeof value === 'object' ? {
1010
+ * A filter entry with its expressions resolved, as the entity service takes it: a plain expression
1011
+ * is `eq`, a `range` becomes `[from, to]`. `value` is undefined when a value it needs resolves to
1012
+ * undefined. A resolved value is only ever an operand, so an object or list sent as input (e.g.
1013
+ * `{ "op": "not_null" }`) never becomes an operator: the entity service refuses it as not a value.
1014
+ */ async function resolveFilterEntry(item, resolve) {
1015
+ if (!(0,_interfaces_generic_record_interface_js__rspack_import_0/* .isRecordFilterCondition */.t1)(item)) return {
1110
1016
  op: 'eq',
1111
- value
1112
- } : value;
1017
+ value: await resolve(item)
1018
+ };
1019
+ const { op, value } = item;
1020
+ switch(_interfaces_generic_record_interface_js__rspack_import_0/* .FILTER_OP_VALUE_KIND */.w9[op]){
1021
+ case 'none':
1022
+ return {
1023
+ op
1024
+ };
1025
+ case 'range':
1026
+ {
1027
+ if (!(0,_interfaces_generic_record_interface_js__rspack_import_0/* .isFilterRange */.iA)(value)) return {
1028
+ op,
1029
+ value: undefined
1030
+ };
1031
+ const from = await resolve(value.from);
1032
+ const to = await resolve(value.to);
1033
+ return {
1034
+ op,
1035
+ value: from === undefined || to === undefined ? undefined : [
1036
+ from,
1037
+ to
1038
+ ]
1039
+ };
1040
+ }
1041
+ default:
1042
+ return {
1043
+ op,
1044
+ value: value === undefined ? undefined : await resolve(value)
1045
+ };
1046
+ }
1047
+ }
1048
+ /** Whether a resolved entry is missing the value its operator needs. */ const isFilterValueMissing = (entry)=>_interfaces_generic_record_interface_js__rspack_import_0/* .FILTER_OP_VALUE_KIND */.w9[entry.op] !== 'none' && entry.value === undefined;
1113
1049
 
1114
1050
  __webpack_require__.d(__webpack_exports__, {
1115
1051
  hz: () => (parseDateText),
1116
- lu: () => (valuesEqual)
1052
+ lu: () => (valuesEqual),
1053
+ vY: () => (resolveFilterEntry)
1117
1054
  }, {
1118
- $b: equalsOperand,
1119
1055
  XL: includesValue,
1120
- YN: ISO_DATE_PREFIX
1056
+ YN: ISO_DATE_PREFIX,
1057
+ kp: isFilterValueMissing
1121
1058
  });
1122
1059
 
1123
1060
 
@@ -1174,10 +1111,9 @@ const RULE_ENGINE_LIMITS = {
1174
1111
  MAX_GROUP_DEPTH: 8,
1175
1112
  MAX_CONDITIONS_PER_GROUP: 100,
1176
1113
  MAX_LOOKUPS: 10,
1177
- MAX_REGEX_PATTERN_LENGTH: 500,
1178
- MAX_REGEX_INPUT_LENGTH: 10_000,
1179
- /** Largest `{n,m}` count, also for the product of nested counts. */ MAX_REGEX_REPEAT: 100,
1180
- /** How much larger counted repeats may make the unrolled pattern than the pattern itself. */ MAX_REGEX_REPEAT_EXPANSION: 300,
1114
+ MAX_REGEX_PATTERN_LENGTH: _flusys_nestjs_shared_utils__rspack_import_0.SAFE_REGEX_LIMITS.MAX_PATTERN_LENGTH,
1115
+ MAX_REGEX_INPUT_LENGTH: _flusys_nestjs_shared_utils__rspack_import_0.SAFE_REGEX_LIMITS.MAX_INPUT_LENGTH,
1116
+ /** Largest `{n,m}` count, also for the product of nested counts. */ MAX_REGEX_REPEAT: _flusys_nestjs_shared_utils__rspack_import_0.SAFE_REGEX_LIMITS.MAX_REPEAT,
1181
1117
  /** Largest `offsetMinutes` accepted by START_OF_DAY / END_OF_DAY (UTC+14 / UTC-12). */ MAX_UTC_OFFSET_MINUTES: 840,
1182
1118
  MAX_PERMISSION_CODES: _flusys_nestjs_shared_utils__rspack_import_0.MAX_PERMISSION_LOGIC_CODES,
1183
1119
  MAX_IP_RANGES: 100