@halleyassist/rule-templater 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -5
- package/dist/rule-templater.browser.js +32 -7
- package/index.d.ts +27 -0
- package/package.json +1 -1
- package/src/RuleTemplate.ebnf.js +2 -0
- package/src/RuleTemplate.production.ebnf.js +1 -1
- package/src/RuleTemplater.js +31 -6
- package/src/RuleTemplater.production.js +31 -6
package/README.md
CHANGED
|
@@ -27,8 +27,8 @@ const parsed = RuleTemplate.parse(template);
|
|
|
27
27
|
const variables = parsed.extractVariables();
|
|
28
28
|
console.log(variables);
|
|
29
29
|
// [
|
|
30
|
-
// { name: 'EVENT_TYPE', filters: [] },
|
|
31
|
-
// { name: 'THRESHOLD', filters: [] }
|
|
30
|
+
// { name: 'EVENT_TYPE', filters: [], positions: [{ start: 8, end: 21 }] },
|
|
31
|
+
// { name: 'THRESHOLD', filters: [], positions: [{ start: 36, end: 48 }] }
|
|
32
32
|
// ]
|
|
33
33
|
|
|
34
34
|
// Validate that variables are provided correctly
|
|
@@ -57,8 +57,8 @@ const parsed = RuleTemplate.parse(template);
|
|
|
57
57
|
// Extract variables
|
|
58
58
|
const variables = parsed.extractVariables();
|
|
59
59
|
// [
|
|
60
|
-
// { name: 'ACTION', filters: [] },
|
|
61
|
-
// { name: 'TIME', filters: [] }
|
|
60
|
+
// { name: 'ACTION', filters: [], positions: [{ start: 48, end: 57 }] },
|
|
61
|
+
// { name: 'TIME', filters: [], positions: [{ start: 142, end: 149 }] }
|
|
62
62
|
// ]
|
|
63
63
|
|
|
64
64
|
// Prepare with values
|
|
@@ -79,7 +79,7 @@ const template = 'EventIs(${EVENT_TYPE|upper})';
|
|
|
79
79
|
|
|
80
80
|
const parsed = RuleTemplate.parse(template);
|
|
81
81
|
const variables = parsed.extractVariables();
|
|
82
|
-
// [{ name: 'EVENT_TYPE', filters: ['upper'] }]
|
|
82
|
+
// [{ name: 'EVENT_TYPE', filters: ['upper'], positions: [{ start: 8, end: 27 }] }]
|
|
83
83
|
|
|
84
84
|
// Prepare with filters applied
|
|
85
85
|
const prepared = parsed.prepare({
|
|
@@ -154,6 +154,11 @@ Extracts all variables from the template using the AST.
|
|
|
154
154
|
**Returns:** Array of objects with:
|
|
155
155
|
- `name` (string): The variable name
|
|
156
156
|
- `filters` (array): Array of filter names applied to the variable
|
|
157
|
+
- `positions` (array): Array of position objects, each with:
|
|
158
|
+
- `start` (number): Zero-based start index of the variable in the template string
|
|
159
|
+
- `end` (number): Zero-based end index of the variable in the template string
|
|
160
|
+
|
|
161
|
+
Note: If a variable appears multiple times in the template, all occurrences will be recorded in the `positions` array.
|
|
157
162
|
|
|
158
163
|
### `ruleTemplate.validate(variables)`
|
|
159
164
|
|
|
@@ -2032,7 +2032,7 @@ Object.defineProperty(exports, "ParsingError", { enumerable: true, get: function
|
|
|
2032
2032
|
exports.Grammars = require("./Grammars");
|
|
2033
2033
|
|
|
2034
2034
|
},{"./Grammars":5,"./Parser":6,"./ParsingError":7,"./TokenError":9}],11:[function(require,module,exports){
|
|
2035
|
-
module.exports=[{"name":"TEMPLATE_BEGIN","bnf":[["\"${\""]]},{"name":"TEMPLATE_END","bnf":[["\"}\""]]},{"name":"PIPE","bnf":[["\"|\""]]},{"name":"%IDENT[2]","bnf":[[/[A-Za-z0-9_]/]]},{"name":"IDENT","bnf":[[/[A-Za-z_]/,"%IDENT[2]*"]]},{"name":"DOT","bnf":[["\".\""]]},{"name":"template_value","bnf":[["TEMPLATE_BEGIN","WS*","template_expr","WS*","TEMPLATE_END"]]},{"name":"%template_expr[2]","bnf":[["WS*","template_pipe","WS*","template_filter_call"]],"fragment":true},{"name":"template_expr","bnf":[["template_path","%template_expr[2]*"]]},{"name":"template_pipe","bnf":[["PIPE"]]},{"name":"%template_path[2]","bnf":[["WS*","DOT","WS*","IDENT"]],"fragment":true},{"name":"template_path","bnf":[["IDENT","%template_path[2]*"]]},{"name":"%template_filter_call[2]","bnf":[["WS*","BEGIN_ARGUMENT","WS*","template_filter_args?","WS*","END_ARGUMENT"]],"fragment":true},{"name":"template_filter_call","bnf":[["template_filter_name","%template_filter_call[2]?"]]},{"name":"template_filter_name","bnf":[["IDENT"]]},{"name":"%template_filter_args[2]","bnf":[["WS*","\",\"","WS*","template_filter_arg"]],"fragment":true},{"name":"template_filter_args","bnf":[["template_filter_arg","%template_filter_args[2]*"]]},{"name":"template_filter_arg","bnf":[["value"],["template_value"]]},{"name":"number_atom","bnf":[["number"],["template_value"]]},{"name":"number_time_atom","bnf":[["number_time"],["template_value"]]},{"name":"tod_atom","bnf":[["number_tod"],["template_value"]]},{"name":"dow_atom","bnf":[["dow"],["template_value"]]}]
|
|
2035
|
+
module.exports=[{"name":"TEMPLATE_BEGIN","bnf":[["\"${\""]]},{"name":"TEMPLATE_END","bnf":[["\"}\""]]},{"name":"PIPE","bnf":[["\"|\""]]},{"name":"%IDENT[2]","bnf":[[/[A-Za-z0-9_]/]]},{"name":"IDENT","bnf":[[/[A-Za-z_]/,"%IDENT[2]*"]]},{"name":"DOT","bnf":[["\".\""]]},{"name":"template_value","bnf":[["TEMPLATE_BEGIN","WS*","template_expr","WS*","TEMPLATE_END"]]},{"name":"%template_expr[2]","bnf":[["WS*","template_pipe","WS*","template_filter_call"]],"fragment":true},{"name":"template_expr","bnf":[["template_path","%template_expr[2]*"]]},{"name":"template_pipe","bnf":[["PIPE"]]},{"name":"%template_path[2]","bnf":[["WS*","DOT","WS*","IDENT"]],"fragment":true},{"name":"template_path","bnf":[["IDENT","%template_path[2]*"]]},{"name":"%template_filter_call[2]","bnf":[["WS*","BEGIN_ARGUMENT","WS*","template_filter_args?","WS*","END_ARGUMENT"]],"fragment":true},{"name":"template_filter_call","bnf":[["template_filter_name","%template_filter_call[2]?"]]},{"name":"template_filter_name","bnf":[["IDENT"]]},{"name":"%template_filter_args[2]","bnf":[["WS*","\",\"","WS*","template_filter_arg"]],"fragment":true},{"name":"template_filter_args","bnf":[["template_filter_arg","%template_filter_args[2]*"]]},{"name":"template_filter_arg","bnf":[["value"],["template_value"]]},{"name":"number_atom","bnf":[["number"],["template_value"]]},{"name":"number_time_atom","bnf":[["number_time"],["template_value"]]},{"name":"tod_atom","bnf":[["number_tod"],["template_value"]]},{"name":"dow_atom","bnf":[["dow"],["template_value"]]},{"name":"between_time_only_atom","bnf":[["between_time_only"],["template_value"]]},{"name":"between_tod_only_atom","bnf":[["between_tod_only"],["template_value"]]}]
|
|
2036
2036
|
},{}],12:[function(require,module,exports){
|
|
2037
2037
|
module.exports = require('./RuleTemplater.production.js');
|
|
2038
2038
|
},{"./RuleTemplater.production.js":13}],13:[function(require,module,exports){
|
|
@@ -2113,11 +2113,11 @@ class RuleTemplate {
|
|
|
2113
2113
|
|
|
2114
2114
|
/**
|
|
2115
2115
|
* Extract variables from the template using the AST
|
|
2116
|
-
* @returns {Array} Array of {name, filters: []} objects
|
|
2116
|
+
* @returns {Array} Array of {name, filters: [], positions: [{start, end}]} objects
|
|
2117
2117
|
*/
|
|
2118
2118
|
extractVariables(){
|
|
2119
2119
|
const variables = [];
|
|
2120
|
-
const
|
|
2120
|
+
const variableMap = new Map();
|
|
2121
2121
|
|
|
2122
2122
|
const traverse = (node) => {
|
|
2123
2123
|
if (!node) return;
|
|
@@ -2126,9 +2126,24 @@ class RuleTemplate {
|
|
|
2126
2126
|
if (node.type === 'template_value') {
|
|
2127
2127
|
// Extract the variable information
|
|
2128
2128
|
const varInfo = this._extractVariableFromNode(node);
|
|
2129
|
-
if (varInfo
|
|
2130
|
-
|
|
2131
|
-
|
|
2129
|
+
if (varInfo) {
|
|
2130
|
+
// Add position to existing variable or create new entry
|
|
2131
|
+
if (variableMap.has(varInfo.name)) {
|
|
2132
|
+
const existing = variableMap.get(varInfo.name);
|
|
2133
|
+
existing.positions.push({
|
|
2134
|
+
start: varInfo.start,
|
|
2135
|
+
end: varInfo.end
|
|
2136
|
+
});
|
|
2137
|
+
} else {
|
|
2138
|
+
variableMap.set(varInfo.name, {
|
|
2139
|
+
name: varInfo.name,
|
|
2140
|
+
filters: varInfo.filters,
|
|
2141
|
+
positions: [{
|
|
2142
|
+
start: varInfo.start,
|
|
2143
|
+
end: varInfo.end
|
|
2144
|
+
}]
|
|
2145
|
+
});
|
|
2146
|
+
}
|
|
2132
2147
|
}
|
|
2133
2148
|
}
|
|
2134
2149
|
|
|
@@ -2141,6 +2156,12 @@ class RuleTemplate {
|
|
|
2141
2156
|
};
|
|
2142
2157
|
|
|
2143
2158
|
traverse(this.ast);
|
|
2159
|
+
|
|
2160
|
+
// Convert map to array
|
|
2161
|
+
for (const variable of variableMap.values()) {
|
|
2162
|
+
variables.push(variable);
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2144
2165
|
return variables;
|
|
2145
2166
|
}
|
|
2146
2167
|
|
|
@@ -2172,7 +2193,11 @@ class RuleTemplate {
|
|
|
2172
2193
|
}
|
|
2173
2194
|
}
|
|
2174
2195
|
|
|
2175
|
-
|
|
2196
|
+
// Extract position information from the node
|
|
2197
|
+
const start = node.start;
|
|
2198
|
+
const end = node.end;
|
|
2199
|
+
|
|
2200
|
+
return { name, filters, start, end };
|
|
2176
2201
|
}
|
|
2177
2202
|
|
|
2178
2203
|
/**
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
export interface VariablePosition {
|
|
2
|
+
start: number;
|
|
3
|
+
end: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
1
6
|
export interface VariableInfo {
|
|
2
7
|
name: string;
|
|
3
8
|
filters: string[];
|
|
9
|
+
positions: VariablePosition[];
|
|
4
10
|
}
|
|
5
11
|
|
|
6
12
|
export interface VariableValue {
|
|
@@ -89,3 +95,24 @@ export default class RuleTemplate {
|
|
|
89
95
|
export const ParserRules: any[];
|
|
90
96
|
export const VariableTypes: string[];
|
|
91
97
|
export const TemplateFilters: TemplateFiltersType;
|
|
98
|
+
|
|
99
|
+
export interface IParsingErrorPosition {
|
|
100
|
+
offset: number;
|
|
101
|
+
line: number;
|
|
102
|
+
column: number;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface IFailureTreeNode {
|
|
106
|
+
name: string;
|
|
107
|
+
expected?: string | RegExp;
|
|
108
|
+
children?: IFailureTreeNode[];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export class ParsingError extends Error {
|
|
112
|
+
readonly position: IParsingErrorPosition;
|
|
113
|
+
readonly expected: string[];
|
|
114
|
+
readonly found: string;
|
|
115
|
+
readonly failureTree?: IFailureTreeNode[];
|
|
116
|
+
constructor(message: string, position: IParsingErrorPosition, expected: string[], found: string, failureTree?: IFailureTreeNode[]);
|
|
117
|
+
toString(): string;
|
|
118
|
+
}
|
package/package.json
CHANGED
package/src/RuleTemplate.ebnf.js
CHANGED
|
@@ -27,6 +27,8 @@ const grammar = `
|
|
|
27
27
|
number_time_atom ::= number_time | template_value
|
|
28
28
|
tod_atom ::= number_tod | template_value
|
|
29
29
|
dow_atom ::= dow | template_value
|
|
30
|
+
between_time_only_atom ::= between_time_only | template_value
|
|
31
|
+
between_tod_only_atom ::= between_tod_only | template_value
|
|
30
32
|
`
|
|
31
33
|
|
|
32
34
|
module.exports = Grammars.W3C.getRules(grammar);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports=[{"name":"TEMPLATE_BEGIN","bnf":[["\"${\""]]},{"name":"TEMPLATE_END","bnf":[["\"}\""]]},{"name":"PIPE","bnf":[["\"|\""]]},{"name":"%IDENT[2]","bnf":[[/[A-Za-z0-9_]/]]},{"name":"IDENT","bnf":[[/[A-Za-z_]/,"%IDENT[2]*"]]},{"name":"DOT","bnf":[["\".\""]]},{"name":"template_value","bnf":[["TEMPLATE_BEGIN","WS*","template_expr","WS*","TEMPLATE_END"]]},{"name":"%template_expr[2]","bnf":[["WS*","template_pipe","WS*","template_filter_call"]],"fragment":true},{"name":"template_expr","bnf":[["template_path","%template_expr[2]*"]]},{"name":"template_pipe","bnf":[["PIPE"]]},{"name":"%template_path[2]","bnf":[["WS*","DOT","WS*","IDENT"]],"fragment":true},{"name":"template_path","bnf":[["IDENT","%template_path[2]*"]]},{"name":"%template_filter_call[2]","bnf":[["WS*","BEGIN_ARGUMENT","WS*","template_filter_args?","WS*","END_ARGUMENT"]],"fragment":true},{"name":"template_filter_call","bnf":[["template_filter_name","%template_filter_call[2]?"]]},{"name":"template_filter_name","bnf":[["IDENT"]]},{"name":"%template_filter_args[2]","bnf":[["WS*","\",\"","WS*","template_filter_arg"]],"fragment":true},{"name":"template_filter_args","bnf":[["template_filter_arg","%template_filter_args[2]*"]]},{"name":"template_filter_arg","bnf":[["value"],["template_value"]]},{"name":"number_atom","bnf":[["number"],["template_value"]]},{"name":"number_time_atom","bnf":[["number_time"],["template_value"]]},{"name":"tod_atom","bnf":[["number_tod"],["template_value"]]},{"name":"dow_atom","bnf":[["dow"],["template_value"]]}]
|
|
1
|
+
module.exports=[{"name":"TEMPLATE_BEGIN","bnf":[["\"${\""]]},{"name":"TEMPLATE_END","bnf":[["\"}\""]]},{"name":"PIPE","bnf":[["\"|\""]]},{"name":"%IDENT[2]","bnf":[[/[A-Za-z0-9_]/]]},{"name":"IDENT","bnf":[[/[A-Za-z_]/,"%IDENT[2]*"]]},{"name":"DOT","bnf":[["\".\""]]},{"name":"template_value","bnf":[["TEMPLATE_BEGIN","WS*","template_expr","WS*","TEMPLATE_END"]]},{"name":"%template_expr[2]","bnf":[["WS*","template_pipe","WS*","template_filter_call"]],"fragment":true},{"name":"template_expr","bnf":[["template_path","%template_expr[2]*"]]},{"name":"template_pipe","bnf":[["PIPE"]]},{"name":"%template_path[2]","bnf":[["WS*","DOT","WS*","IDENT"]],"fragment":true},{"name":"template_path","bnf":[["IDENT","%template_path[2]*"]]},{"name":"%template_filter_call[2]","bnf":[["WS*","BEGIN_ARGUMENT","WS*","template_filter_args?","WS*","END_ARGUMENT"]],"fragment":true},{"name":"template_filter_call","bnf":[["template_filter_name","%template_filter_call[2]?"]]},{"name":"template_filter_name","bnf":[["IDENT"]]},{"name":"%template_filter_args[2]","bnf":[["WS*","\",\"","WS*","template_filter_arg"]],"fragment":true},{"name":"template_filter_args","bnf":[["template_filter_arg","%template_filter_args[2]*"]]},{"name":"template_filter_arg","bnf":[["value"],["template_value"]]},{"name":"number_atom","bnf":[["number"],["template_value"]]},{"name":"number_time_atom","bnf":[["number_time"],["template_value"]]},{"name":"tod_atom","bnf":[["number_tod"],["template_value"]]},{"name":"dow_atom","bnf":[["dow"],["template_value"]]},{"name":"between_time_only_atom","bnf":[["between_time_only"],["template_value"]]},{"name":"between_tod_only_atom","bnf":[["between_tod_only"],["template_value"]]}]
|
package/src/RuleTemplater.js
CHANGED
|
@@ -75,11 +75,11 @@ class RuleTemplate {
|
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* Extract variables from the template using the AST
|
|
78
|
-
* @returns {Array} Array of {name, filters: []} objects
|
|
78
|
+
* @returns {Array} Array of {name, filters: [], positions: [{start, end}]} objects
|
|
79
79
|
*/
|
|
80
80
|
extractVariables(){
|
|
81
81
|
const variables = [];
|
|
82
|
-
const
|
|
82
|
+
const variableMap = new Map();
|
|
83
83
|
|
|
84
84
|
const traverse = (node) => {
|
|
85
85
|
if (!node) return;
|
|
@@ -88,9 +88,24 @@ class RuleTemplate {
|
|
|
88
88
|
if (node.type === 'template_value') {
|
|
89
89
|
// Extract the variable information
|
|
90
90
|
const varInfo = this._extractVariableFromNode(node);
|
|
91
|
-
if (varInfo
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
if (varInfo) {
|
|
92
|
+
// Add position to existing variable or create new entry
|
|
93
|
+
if (variableMap.has(varInfo.name)) {
|
|
94
|
+
const existing = variableMap.get(varInfo.name);
|
|
95
|
+
existing.positions.push({
|
|
96
|
+
start: varInfo.start,
|
|
97
|
+
end: varInfo.end
|
|
98
|
+
});
|
|
99
|
+
} else {
|
|
100
|
+
variableMap.set(varInfo.name, {
|
|
101
|
+
name: varInfo.name,
|
|
102
|
+
filters: varInfo.filters,
|
|
103
|
+
positions: [{
|
|
104
|
+
start: varInfo.start,
|
|
105
|
+
end: varInfo.end
|
|
106
|
+
}]
|
|
107
|
+
});
|
|
108
|
+
}
|
|
94
109
|
}
|
|
95
110
|
}
|
|
96
111
|
|
|
@@ -103,6 +118,12 @@ class RuleTemplate {
|
|
|
103
118
|
};
|
|
104
119
|
|
|
105
120
|
traverse(this.ast);
|
|
121
|
+
|
|
122
|
+
// Convert map to array
|
|
123
|
+
for (const variable of variableMap.values()) {
|
|
124
|
+
variables.push(variable);
|
|
125
|
+
}
|
|
126
|
+
|
|
106
127
|
return variables;
|
|
107
128
|
}
|
|
108
129
|
|
|
@@ -134,7 +155,11 @@ class RuleTemplate {
|
|
|
134
155
|
}
|
|
135
156
|
}
|
|
136
157
|
|
|
137
|
-
|
|
158
|
+
// Extract position information from the node
|
|
159
|
+
const start = node.start;
|
|
160
|
+
const end = node.end;
|
|
161
|
+
|
|
162
|
+
return { name, filters, start, end };
|
|
138
163
|
}
|
|
139
164
|
|
|
140
165
|
/**
|
|
@@ -75,11 +75,11 @@ class RuleTemplate {
|
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* Extract variables from the template using the AST
|
|
78
|
-
* @returns {Array} Array of {name, filters: []} objects
|
|
78
|
+
* @returns {Array} Array of {name, filters: [], positions: [{start, end}]} objects
|
|
79
79
|
*/
|
|
80
80
|
extractVariables(){
|
|
81
81
|
const variables = [];
|
|
82
|
-
const
|
|
82
|
+
const variableMap = new Map();
|
|
83
83
|
|
|
84
84
|
const traverse = (node) => {
|
|
85
85
|
if (!node) return;
|
|
@@ -88,9 +88,24 @@ class RuleTemplate {
|
|
|
88
88
|
if (node.type === 'template_value') {
|
|
89
89
|
// Extract the variable information
|
|
90
90
|
const varInfo = this._extractVariableFromNode(node);
|
|
91
|
-
if (varInfo
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
if (varInfo) {
|
|
92
|
+
// Add position to existing variable or create new entry
|
|
93
|
+
if (variableMap.has(varInfo.name)) {
|
|
94
|
+
const existing = variableMap.get(varInfo.name);
|
|
95
|
+
existing.positions.push({
|
|
96
|
+
start: varInfo.start,
|
|
97
|
+
end: varInfo.end
|
|
98
|
+
});
|
|
99
|
+
} else {
|
|
100
|
+
variableMap.set(varInfo.name, {
|
|
101
|
+
name: varInfo.name,
|
|
102
|
+
filters: varInfo.filters,
|
|
103
|
+
positions: [{
|
|
104
|
+
start: varInfo.start,
|
|
105
|
+
end: varInfo.end
|
|
106
|
+
}]
|
|
107
|
+
});
|
|
108
|
+
}
|
|
94
109
|
}
|
|
95
110
|
}
|
|
96
111
|
|
|
@@ -103,6 +118,12 @@ class RuleTemplate {
|
|
|
103
118
|
};
|
|
104
119
|
|
|
105
120
|
traverse(this.ast);
|
|
121
|
+
|
|
122
|
+
// Convert map to array
|
|
123
|
+
for (const variable of variableMap.values()) {
|
|
124
|
+
variables.push(variable);
|
|
125
|
+
}
|
|
126
|
+
|
|
106
127
|
return variables;
|
|
107
128
|
}
|
|
108
129
|
|
|
@@ -134,7 +155,11 @@ class RuleTemplate {
|
|
|
134
155
|
}
|
|
135
156
|
}
|
|
136
157
|
|
|
137
|
-
|
|
158
|
+
// Extract position information from the node
|
|
159
|
+
const start = node.start;
|
|
160
|
+
const end = node.end;
|
|
161
|
+
|
|
162
|
+
return { name, filters, start, end };
|
|
138
163
|
}
|
|
139
164
|
|
|
140
165
|
/**
|