@halleyassist/rule-parser 1.0.25 → 1.0.26

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.
@@ -1949,6 +1949,31 @@ const LogicalOperators = {
1949
1949
  '||': 'Or',
1950
1950
  'OR': 'Or'
1951
1951
  };
1952
+ const ILReservedNames = new Set([
1953
+ 'Value',
1954
+ 'Array',
1955
+ 'ArrayIn',
1956
+ 'Between',
1957
+ 'Not',
1958
+ 'And',
1959
+ 'Or',
1960
+ 'Gt',
1961
+ 'Lt',
1962
+ 'Gte',
1963
+ 'Lte',
1964
+ 'Eq',
1965
+ 'Neq',
1966
+ 'MathAdd',
1967
+ 'MathSub',
1968
+ 'MathDiv',
1969
+ 'MathMul',
1970
+ 'MathMod',
1971
+ 'Default',
1972
+ 'TimePeriodConst',
1973
+ 'TimePeriodConstAgo',
1974
+ 'TimePeriodBetween',
1975
+ 'TimePeriodBetweenAgo'
1976
+ ]);
1952
1977
  const DOW_MAP = {
1953
1978
  'MON': 'MONDAY',
1954
1979
  'TUE': 'TUESDAY',
@@ -2609,6 +2634,29 @@ class RuleParser {
2609
2634
  throw new Error(`unknown type of expression ${ eInner.type }`);
2610
2635
  }
2611
2636
  }
2637
+ static _collectFunctions(il, names) {
2638
+ if (!Array.isArray(il) || il.length === 0) {
2639
+ return;
2640
+ }
2641
+ const [head, ...tail] = il;
2642
+ if (typeof head === 'string') {
2643
+ if (!ILReservedNames.has(head)) {
2644
+ names.add(head);
2645
+ }
2646
+ for (const child of tail) {
2647
+ RuleParser._collectFunctions(child, names);
2648
+ }
2649
+ return;
2650
+ }
2651
+ for (const child of il) {
2652
+ RuleParser._collectFunctions(child, names);
2653
+ }
2654
+ }
2655
+ static getFunctions(il) {
2656
+ const names = new Set();
2657
+ RuleParser._collectFunctions(il, names);
2658
+ return [...names];
2659
+ }
2612
2660
  static toIL(txt) {
2613
2661
  try {
2614
2662
  const ast = RuleParser.toAst(txt);
package/index.d.ts CHANGED
@@ -127,12 +127,24 @@ export type TimePeriodExpression =
127
127
  | TimePeriodBetween
128
128
  | TimePeriodBetweenAgo;
129
129
 
130
+ /**
131
+ * Array expression used for dynamic `IN (...)` arguments
132
+ */
133
+ export type ArrayExpression = ['Array', ...ILExpression[]];
134
+
135
+ /**
136
+ * Array membership expression
137
+ */
138
+ export type ArrayInExpression = ['ArrayIn', ILExpression, ILExpression];
139
+
130
140
  /**
131
141
  * Forward declaration for ILExpression to handle recursive types
132
142
  */
133
143
  export type ILExpression =
134
144
  | ValueExpression
135
145
  | TimePeriodExpression
146
+ | ArrayExpression
147
+ | ArrayInExpression
136
148
  | FunctionCall
137
149
  | ComparisonExpression
138
150
  | LogicalExpression
@@ -207,6 +219,13 @@ declare class RuleParser {
207
219
  * @throws {RuleParseError} If the rule string is invalid
208
220
  */
209
221
  static toIL(txt: string): ILExpression;
222
+
223
+ /**
224
+ * Collect unique function names referenced in an IL expression
225
+ * @param il - The IL expression to inspect
226
+ * @returns Unique function names in first-seen order
227
+ */
228
+ static getFunctions(il: ILExpression): string[];
210
229
  }
211
230
 
212
231
  export default RuleParser;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@halleyassist/rule-parser",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "The grammar for HalleyAssist rules",
5
5
  "main": "src/RuleParser.production.js",
6
6
  "browser": "./dist/rule-parser.browser.js",
package/src/RuleParser.js CHANGED
@@ -34,6 +34,32 @@ const LogicalOperators = {
34
34
  "OR": 'Or',
35
35
  }
36
36
 
37
+ const ILReservedNames = new Set([
38
+ 'Value',
39
+ 'Array',
40
+ 'ArrayIn',
41
+ 'Between',
42
+ 'Not',
43
+ 'And',
44
+ 'Or',
45
+ 'Gt',
46
+ 'Lt',
47
+ 'Gte',
48
+ 'Lte',
49
+ 'Eq',
50
+ 'Neq',
51
+ 'MathAdd',
52
+ 'MathSub',
53
+ 'MathDiv',
54
+ 'MathMul',
55
+ 'MathMod',
56
+ 'Default',
57
+ 'TimePeriodConst',
58
+ 'TimePeriodConstAgo',
59
+ 'TimePeriodBetween',
60
+ 'TimePeriodBetweenAgo'
61
+ ])
62
+
37
63
  // Map abbreviations to canonical uppercase full form
38
64
  const DOW_MAP = {
39
65
  'MON': 'MONDAY',
@@ -623,6 +649,32 @@ class RuleParser {
623
649
  throw new Error(`unknown type of expression ${eInner.type}`)
624
650
  }
625
651
  }
652
+ static _collectFunctions(il, names){
653
+ if(!Array.isArray(il) || il.length === 0){
654
+ return
655
+ }
656
+
657
+ const [head, ...tail] = il
658
+
659
+ if(typeof head === 'string'){
660
+ if(!ILReservedNames.has(head)){
661
+ names.add(head)
662
+ }
663
+ for(const child of tail){
664
+ RuleParser._collectFunctions(child, names)
665
+ }
666
+ return
667
+ }
668
+
669
+ for(const child of il){
670
+ RuleParser._collectFunctions(child, names)
671
+ }
672
+ }
673
+ static getFunctions(il){
674
+ const names = new Set()
675
+ RuleParser._collectFunctions(il, names)
676
+ return [...names]
677
+ }
626
678
  static toIL(txt){
627
679
  try {
628
680
  const ast = RuleParser.toAst(txt)
@@ -34,6 +34,32 @@ const LogicalOperators = {
34
34
  "OR": 'Or',
35
35
  }
36
36
 
37
+ const ILReservedNames = new Set([
38
+ 'Value',
39
+ 'Array',
40
+ 'ArrayIn',
41
+ 'Between',
42
+ 'Not',
43
+ 'And',
44
+ 'Or',
45
+ 'Gt',
46
+ 'Lt',
47
+ 'Gte',
48
+ 'Lte',
49
+ 'Eq',
50
+ 'Neq',
51
+ 'MathAdd',
52
+ 'MathSub',
53
+ 'MathDiv',
54
+ 'MathMul',
55
+ 'MathMod',
56
+ 'Default',
57
+ 'TimePeriodConst',
58
+ 'TimePeriodConstAgo',
59
+ 'TimePeriodBetween',
60
+ 'TimePeriodBetweenAgo'
61
+ ])
62
+
37
63
  // Map abbreviations to canonical uppercase full form
38
64
  const DOW_MAP = {
39
65
  'MON': 'MONDAY',
@@ -623,6 +649,32 @@ class RuleParser {
623
649
  throw new Error(`unknown type of expression ${eInner.type}`)
624
650
  }
625
651
  }
652
+ static _collectFunctions(il, names){
653
+ if(!Array.isArray(il) || il.length === 0){
654
+ return
655
+ }
656
+
657
+ const [head, ...tail] = il
658
+
659
+ if(typeof head === 'string'){
660
+ if(!ILReservedNames.has(head)){
661
+ names.add(head)
662
+ }
663
+ for(const child of tail){
664
+ RuleParser._collectFunctions(child, names)
665
+ }
666
+ return
667
+ }
668
+
669
+ for(const child of il){
670
+ RuleParser._collectFunctions(child, names)
671
+ }
672
+ }
673
+ static getFunctions(il){
674
+ const names = new Set()
675
+ RuleParser._collectFunctions(il, names)
676
+ return [...names]
677
+ }
626
678
  static toIL(txt){
627
679
  try {
628
680
  const ast = RuleParser.toAst(txt)