@tellaro/tql 0.1.14 → 0.1.15
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/dist/src/completionProvider.js +178 -69
- package/dist/src/tokenizer.js +56 -12
- package/package.json +1 -1
|
@@ -108,68 +108,167 @@ const E = [
|
|
|
108
108
|
category: "Stats"
|
|
109
109
|
}
|
|
110
110
|
], U = {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
111
|
+
// Equality operators
|
|
112
|
+
eq: { detail: "Equals", documentation: "Exact match comparison. Case-sensitive for strings.\n\nExamples:\n- status eq 'active'\n- severity eq 3\n- enabled eq true\n\nWorks with: strings, numbers, booleans, dates, IPs" },
|
|
113
|
+
ne: { detail: "Not equals", documentation: "Match any value except the specified one.\n\nExamples:\n- status ne 'error'\n- severity ne 0\n\nUseful for filtering out specific values." },
|
|
114
|
+
// Comparison operators
|
|
115
|
+
gt: { detail: "Greater than", documentation: "Compare if field value is greater than the specified value.\n\nExamples:\n- severity gt 3\n- bytes gt 1000000\n- @timestamp gt '2024-01-01'\n\nWorks with: numbers, dates" },
|
|
116
|
+
gte: { detail: "Greater than or equal", documentation: "Compare if field value is greater than or equal to the specified value.\n\nExamples:\n- risk_score gte 70\n- attempts gte 5\n\nWorks with: numbers, dates" },
|
|
117
|
+
lt: { detail: "Less than", documentation: "Compare if field value is less than the specified value.\n\nExamples:\n- response_time lt 100\n- @timestamp lt 'now-1d'\n\nWorks with: numbers, dates" },
|
|
118
|
+
lte: { detail: "Less than or equal", documentation: "Compare if field value is less than or equal to the specified value.\n\nExamples:\n- confidence lte 50\n- age lte 30\n\nWorks with: numbers, dates" },
|
|
119
|
+
// String operators
|
|
120
|
+
contains: { detail: "Contains substring", documentation: "Check if field contains the specified substring. Case-insensitive.\n\nExamples:\n- message contains 'error'\n- url contains 'admin'\n\nUseful for searching within text fields." },
|
|
121
|
+
not_contains: { detail: "Does not contain", documentation: "Check if field does NOT contain the specified substring.\n\nExamples:\n- message not_contains 'debug'\n- path not_contains 'test'\n\nUseful for excluding noise from results." },
|
|
122
|
+
startswith: { detail: "Starts with", documentation: "Check if field value starts with the specified prefix.\n\nExamples:\n- hostname startswith 'web-'\n- url startswith 'https://'\n\nFaster than contains for prefix matching." },
|
|
123
|
+
not_startswith: { detail: "Does not start with", documentation: "Check if field value does NOT start with the specified prefix.\n\nExamples:\n- hostname not_startswith 'test-'\n- email not_startswith 'noreply'" },
|
|
124
|
+
endswith: { detail: "Ends with", documentation: "Check if field value ends with the specified suffix.\n\nExamples:\n- file.name endswith '.exe'\n- email endswith '@company.com'\n\nUseful for file extension matching." },
|
|
125
|
+
not_endswith: { detail: "Does not end with", documentation: "Check if field value does NOT end with the specified suffix.\n\nExamples:\n- file.name not_endswith '.log'\n- url not_endswith '.jpg'" },
|
|
126
|
+
regexp: { detail: "Regular expression", documentation: "Match field value against a regular expression pattern.\n\nExamples:\n- ip regexp '^192\\\\.168\\\\..*'\n- email regexp '.*@(gmail|yahoo)\\\\.com$'\n\nUses standard regex syntax." },
|
|
127
|
+
regex: { detail: "Regular expression", documentation: "Alias for regexp. Match using regex pattern.\n\nExamples:\n- user.name regex '^admin.*'" },
|
|
128
|
+
not_regexp: { detail: "Not matching regex", documentation: "Match if field value does NOT match the regex.\n\nExamples:\n- file.path not_regexp '.*\\\\.tmp$'\n- message not_regexp 'DEBUG|TRACE'" },
|
|
129
|
+
matches: { detail: "Pattern match", documentation: "Alias for regexp. Match using regex pattern.\n\nExamples:\n- hostname matches 'server[0-9]+'" },
|
|
130
|
+
not_matches: { detail: "Not matching pattern", documentation: "Alias for not_regexp. Does NOT match the pattern." },
|
|
131
|
+
// Range operators
|
|
132
|
+
between: { detail: "Between range", documentation: "Check if field value is within a range (inclusive).\n\nExamples:\n- port between 1024 AND 65535\n- severity between 1 AND 5\n\nIncludes both boundary values." },
|
|
133
|
+
not_between: { detail: "Not between range", documentation: "Check if field value is outside a range.\n\nExamples:\n- port not_between 80 AND 443\n\nExcludes values in the range." },
|
|
134
|
+
// List operators
|
|
135
|
+
in: { detail: "In list", documentation: "Check if field value matches any value in the list.\n\nExamples:\n- status in ['active', 'pending']\n- severity in [3, 4, 5]\n\nMore efficient than multiple OR conditions." },
|
|
136
|
+
not_in: { detail: "Not in list", documentation: "Check if field value does NOT match any value in the list.\n\nExamples:\n- status not_in ['deleted', 'archived']\n\nUseful for exclusion lists." },
|
|
137
|
+
// Existence operators
|
|
138
|
+
exists: { detail: "Field exists", documentation: "Check if field exists and has a non-null value.\n\nExamples:\n- user.email exists\n- threat.indicator exists\n\nReturns false for null values or missing fields." },
|
|
139
|
+
not_exists: { detail: "Field not exists", documentation: "Check if field is missing or has a null value.\n\nExamples:\n- error.code not_exists\n\nTrue when field is missing or explicitly null." },
|
|
140
|
+
is: { detail: "Is null check", documentation: "Check if field value is explicitly null.\n\nExamples:\n- user.phone is null\n\nDifferent from not_exists: returns false for missing fields." },
|
|
141
|
+
is_not: { detail: "Is not null check", documentation: "Check if field exists and is not null.\n\nExamples:\n- user.email is_not null\n\nField must exist and have a non-null value." },
|
|
142
|
+
// Network operators
|
|
143
|
+
cidr: { detail: "CIDR match", documentation: "Match IP addresses within a CIDR range.\n\nExamples:\n- source.ip cidr '192.168.0.0/16'\n- destination.ip cidr '10.0.0.0/8'\n\nWorks with IPv4 and IPv6." },
|
|
144
|
+
not_cidr: { detail: "Not in CIDR", documentation: "Match IP addresses NOT within a CIDR range.\n\nExamples:\n- source.ip not_cidr '192.168.0.0/16'\n\nUseful for identifying external IPs." },
|
|
145
|
+
// Collection operators
|
|
146
|
+
any: { detail: "Any element matches", documentation: "True if ANY element in an array matches the condition.\n\nExamples:\n- tags any eq 'critical'\n- ports any between 1 AND 1024\n\nUseful for searching within array fields." },
|
|
147
|
+
all: { detail: "All elements match", documentation: "True if ALL elements in an array match the condition.\n\nExamples:\n- scores all gte 70\n\nUseful for validation across arrays." },
|
|
148
|
+
none: { detail: "No elements match", documentation: "True if NO elements in an array match the condition.\n\nExamples:\n- tags none eq 'deprecated'\n\nUseful for ensuring no bad values exist." },
|
|
149
|
+
not_any: { detail: "Not any matches", documentation: "Negation of any - equivalent to none.\n\nTrue when no elements match." },
|
|
150
|
+
not_all: { detail: "Not all match", documentation: "Negation of all - at least one element doesn't match.\n\nTrue when at least one element fails." },
|
|
151
|
+
not_none: { detail: "Not none match", documentation: "Negation of none - equivalent to any.\n\nTrue when at least one element matches." }
|
|
144
152
|
}, z = {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
153
|
+
// String mutators
|
|
154
|
+
lowercase: {
|
|
155
|
+
detail: "Convert to lowercase",
|
|
156
|
+
documentation: "Transforms the field value to lowercase.\n\nExample: hostname | lowercase eq 'server01'\n\nUseful for case-insensitive comparisons."
|
|
157
|
+
},
|
|
158
|
+
uppercase: {
|
|
159
|
+
detail: "Convert to uppercase",
|
|
160
|
+
documentation: "Transforms the field value to uppercase.\n\nExample: status | uppercase eq 'ERROR'\n\nUseful for normalizing status codes."
|
|
161
|
+
},
|
|
162
|
+
trim: {
|
|
163
|
+
detail: "Trim whitespace",
|
|
164
|
+
documentation: "Removes leading and trailing whitespace from the field value.\n\nExample: message | trim contains 'error'\n\nUseful for cleaning user input or log messages."
|
|
165
|
+
},
|
|
166
|
+
split: {
|
|
167
|
+
detail: "Split string into array",
|
|
168
|
+
documentation: "Splits a string into an array using a delimiter.\n\nExample: tags | split(delimiter=',') any eq 'critical'\n\nParameters:\n- delimiter: Character(s) to split on (default: ',')\n- field: Field name to save results to"
|
|
169
|
+
},
|
|
170
|
+
length: {
|
|
171
|
+
detail: "Get string/array length",
|
|
172
|
+
documentation: "Returns the length of a string or array as a number.\n\nExample: password | length gte 8\n\nUseful for validation checks."
|
|
173
|
+
},
|
|
174
|
+
replace: {
|
|
175
|
+
detail: "Replace text in string",
|
|
176
|
+
documentation: "Replaces occurrences of a substring with another string.\n\nExample: url | replace(find='http://', replace='https://') startswith 'https'\n\nParameters:\n- find: Text to search for (required)\n- replace: Text to replace with (required)\n- field: Field name to save results to"
|
|
177
|
+
},
|
|
178
|
+
// Encoding mutators
|
|
179
|
+
b64encode: {
|
|
180
|
+
detail: "Base64 encode",
|
|
181
|
+
documentation: "Encodes the field value to Base64.\n\nExample: payload | b64encode eq 'SGVsbG8gV29ybGQ='\n\nParameters:\n- field: Field name to save encoded result"
|
|
182
|
+
},
|
|
183
|
+
b64decode: {
|
|
184
|
+
detail: "Base64 decode",
|
|
185
|
+
documentation: "Decodes a Base64-encoded field value.\n\nExample: encoded_data | b64decode contains 'password'\n\nParameters:\n- field: Field name to save decoded result"
|
|
186
|
+
},
|
|
187
|
+
urldecode: {
|
|
188
|
+
detail: "URL decode",
|
|
189
|
+
documentation: "Decodes URL-encoded (percent-encoded) strings.\n\nExample: query_string | urldecode contains 'SELECT'\n\nUseful for analyzing web requests."
|
|
190
|
+
},
|
|
191
|
+
hexencode: {
|
|
192
|
+
detail: "Hex encode",
|
|
193
|
+
documentation: "Encodes the field value to hexadecimal.\n\nExample: data | hexencode eq '48656c6c6f'\n\nParameters:\n- field: Field name to save encoded result"
|
|
194
|
+
},
|
|
195
|
+
hexdecode: {
|
|
196
|
+
detail: "Hex decode",
|
|
197
|
+
documentation: "Decodes a hexadecimal-encoded field value.\n\nExample: hex_payload | hexdecode contains 'malware'\n\nParameters:\n- field: Field name to save decoded result"
|
|
198
|
+
},
|
|
199
|
+
md5: {
|
|
200
|
+
detail: "MD5 hash",
|
|
201
|
+
documentation: "Calculates the MD5 hash of the field value.\n\nExample: file_content | md5 eq 'd41d8cd98f00b204e9800998ecf8427e'\n\nUseful for file integrity checks."
|
|
202
|
+
},
|
|
203
|
+
sha256: {
|
|
204
|
+
detail: "SHA256 hash",
|
|
205
|
+
documentation: "Calculates the SHA256 hash of the field value.\n\nExample: file_content | sha256 in ['hash1', 'hash2']\n\nUseful for malware signature matching."
|
|
206
|
+
},
|
|
207
|
+
// Security mutators
|
|
208
|
+
refang: {
|
|
209
|
+
detail: "Refang IOC",
|
|
210
|
+
documentation: "Converts defanged indicators back to their original form.\n\nExample: ioc | refang eq '192.168.1.1'\n\nConverts 'hxxp://evil[.]com' to 'http://evil.com'"
|
|
211
|
+
},
|
|
212
|
+
defang: {
|
|
213
|
+
detail: "Defang IOC",
|
|
214
|
+
documentation: "Converts URLs/IPs to a safe defanged form for sharing.\n\nExample: url | defang\n\nConverts 'http://evil.com' to 'hxxp://evil[.]com'"
|
|
215
|
+
},
|
|
216
|
+
// Network mutators
|
|
217
|
+
is_private: {
|
|
218
|
+
detail: "Check if IP is private",
|
|
219
|
+
documentation: "Returns true if the IP address is in a private range (RFC1918).\n\nExample: source.ip | is_private eq true\n\nPrivate ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16"
|
|
220
|
+
},
|
|
221
|
+
is_global: {
|
|
222
|
+
detail: "Check if IP is globally routable",
|
|
223
|
+
documentation: "Returns true if the IP address is globally routable (not private/reserved).\n\nExample: destination.ip | is_global eq true\n\nUseful for filtering external connections."
|
|
224
|
+
},
|
|
225
|
+
// DNS mutator
|
|
226
|
+
nslookup: {
|
|
227
|
+
detail: "DNS lookup",
|
|
228
|
+
documentation: "Performs DNS lookup on a hostname or reverse lookup on an IP.\n\nExample: hostname | nslookup(types=['A', 'AAAA'])\n\nParameters:\n- servers: DNS servers to query (e.g., ['1.1.1.1'])\n- types: Record types to query (A, AAAA, MX, TXT, etc.)\n- force: Force lookup even if data exists\n- save: Save results to record\n- field: Field name to save results"
|
|
229
|
+
},
|
|
230
|
+
// GeoIP mutators
|
|
231
|
+
geoip_lookup: {
|
|
232
|
+
detail: "GeoIP enrichment",
|
|
233
|
+
documentation: "Enriches IP address with geolocation data (country, city, ASN, etc.).\n\nExample: source.ip | geoip_lookup(force=true)\n\nParameters:\n- db_path: Path to MaxMind database\n- force: Force lookup even if geo data exists\n- save: Save results to record\n- cache: Enable result caching\n- cache_ttl: Cache TTL in seconds"
|
|
234
|
+
},
|
|
235
|
+
geoip: {
|
|
236
|
+
detail: "GeoIP enrichment",
|
|
237
|
+
documentation: "Alias for geoip_lookup. Enriches IP with geolocation data.\n\nExample: destination.ip | geoip"
|
|
238
|
+
},
|
|
239
|
+
geo: {
|
|
240
|
+
detail: "GeoIP enrichment",
|
|
241
|
+
documentation: "Alias for geoip_lookup. Enriches IP with geolocation data.\n\nExample: source.ip | geo(save=true)\n\nAdds: country, city, region, coordinates, ASN info"
|
|
242
|
+
},
|
|
243
|
+
// List mutators
|
|
244
|
+
any: {
|
|
245
|
+
detail: "Any element matches",
|
|
246
|
+
documentation: "Returns true if any element in an array matches the condition.\n\nExample: tags | any eq 'critical'\n\nUseful for checking array fields."
|
|
247
|
+
},
|
|
248
|
+
all: {
|
|
249
|
+
detail: "All elements match",
|
|
250
|
+
documentation: "Returns true if all elements in an array match the condition.\n\nExample: scores | all gte 70\n\nUseful for validation across arrays."
|
|
251
|
+
},
|
|
252
|
+
avg: {
|
|
253
|
+
detail: "Average of array",
|
|
254
|
+
documentation: "Calculates the average of numeric array elements.\n\nExample: response_times | avg lt 100\n\nUseful for performance analysis."
|
|
255
|
+
},
|
|
256
|
+
average: {
|
|
257
|
+
detail: "Average of array",
|
|
258
|
+
documentation: "Alias for avg. Calculates the average of numeric array elements."
|
|
259
|
+
},
|
|
260
|
+
sum: {
|
|
261
|
+
detail: "Sum of array",
|
|
262
|
+
documentation: "Calculates the sum of numeric array elements.\n\nExample: byte_counts | sum gt 1000000\n\nUseful for aggregate analysis."
|
|
263
|
+
},
|
|
264
|
+
min: {
|
|
265
|
+
detail: "Minimum value in array",
|
|
266
|
+
documentation: "Returns the minimum value from a numeric array.\n\nExample: temperatures | min lt 0\n\nUseful for threshold detection."
|
|
267
|
+
},
|
|
268
|
+
max: {
|
|
269
|
+
detail: "Maximum value in array",
|
|
270
|
+
documentation: "Returns the maximum value from a numeric array.\n\nExample: cpu_usage | max gt 90\n\nUseful for peak detection."
|
|
271
|
+
}
|
|
173
272
|
}, h = {
|
|
174
273
|
// String outputs
|
|
175
274
|
lowercase: "keyword",
|
|
@@ -661,23 +760,33 @@ function W(e) {
|
|
|
661
760
|
return D.filter((t) => !e || t.toLowerCase().includes(e.toLowerCase())).map(
|
|
662
761
|
(t, a) => {
|
|
663
762
|
const i = z[t] || { detail: "Field mutator", documentation: "" };
|
|
664
|
-
// Check if this
|
|
665
|
-
const isEnrichment = ENRICHMENT_MUTATORS.includes(t);
|
|
763
|
+
// Check if this mutator has parameters defined
|
|
666
764
|
const hasParams = MUTATOR_PARAMETERS[t] && MUTATOR_PARAMETERS[t].length > 0;
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
//
|
|
765
|
+
const isEnrichment = ENRICHMENT_MUTATORS.includes(t);
|
|
766
|
+
|
|
767
|
+
// Build label and insertText
|
|
768
|
+
let label = t;
|
|
670
769
|
let insertText = t;
|
|
671
|
-
|
|
770
|
+
let detail = i.detail;
|
|
771
|
+
|
|
772
|
+
if (hasParams) {
|
|
773
|
+
// Mutators with parameters show () in label and insert with cursor inside
|
|
774
|
+
label = `${t}()`;
|
|
672
775
|
insertText = `${t}($1)`;
|
|
776
|
+
// Add param hint to detail
|
|
777
|
+
const paramNames = MUTATOR_PARAMETERS[t].map(p => p.name).join(", ");
|
|
778
|
+
detail = `${i.detail} - params: ${paramNames}`;
|
|
673
779
|
} else if (isEnrichment) {
|
|
780
|
+
// Enrichment mutators without params still get () for consistency
|
|
781
|
+
label = `${t}()`;
|
|
674
782
|
insertText = `${t}()`;
|
|
675
783
|
}
|
|
784
|
+
|
|
676
785
|
return {
|
|
677
|
-
label:
|
|
786
|
+
label: label,
|
|
678
787
|
insertText: insertText,
|
|
679
788
|
kind: "mutator",
|
|
680
|
-
detail:
|
|
789
|
+
detail: detail,
|
|
681
790
|
documentation: i.documentation,
|
|
682
791
|
sortOrder: 60 + a
|
|
683
792
|
};
|
package/dist/src/tokenizer.js
CHANGED
|
@@ -12,8 +12,62 @@ const ENRICHMENT_MUTATORS = [
|
|
|
12
12
|
|
|
13
13
|
// Parameters available for mutators that support function call syntax
|
|
14
14
|
// e.g., geo(force=true, save=true)
|
|
15
|
+
// Synced with Python TQL ALLOWED_MUTATORS definition
|
|
15
16
|
const MUTATOR_PARAMETERS = {
|
|
17
|
+
// String mutators
|
|
18
|
+
split: [
|
|
19
|
+
{ name: "delimiter", type: "string", description: "Delimiter to split on (default: comma)" },
|
|
20
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
21
|
+
],
|
|
22
|
+
length: [
|
|
23
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
24
|
+
],
|
|
25
|
+
replace: [
|
|
26
|
+
{ name: "find", type: "string", description: "Text to find (required)" },
|
|
27
|
+
{ name: "replace", type: "string", description: "Text to replace with (required)" },
|
|
28
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
29
|
+
],
|
|
30
|
+
// Security mutators
|
|
31
|
+
refang: [
|
|
32
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
33
|
+
],
|
|
34
|
+
defang: [
|
|
35
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
36
|
+
],
|
|
37
|
+
// Encoding mutators
|
|
38
|
+
b64encode: [
|
|
39
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
40
|
+
],
|
|
41
|
+
b64decode: [
|
|
42
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
43
|
+
],
|
|
44
|
+
urldecode: [
|
|
45
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
46
|
+
],
|
|
47
|
+
hexencode: [
|
|
48
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
49
|
+
],
|
|
50
|
+
hexdecode: [
|
|
51
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
52
|
+
],
|
|
53
|
+
md5: [
|
|
54
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
55
|
+
],
|
|
56
|
+
sha256: [
|
|
57
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
58
|
+
],
|
|
59
|
+
// DNS mutator
|
|
60
|
+
nslookup: [
|
|
61
|
+
{ name: "servers", type: "array", description: "DNS servers to query (e.g., ['1.1.1.1', '8.8.8.8'])" },
|
|
62
|
+
{ name: "types", type: "array", description: "DNS record types to query (e.g., ['A', 'AAAA', 'MX'])" },
|
|
63
|
+
{ name: "append_field", type: "string", description: "Field name to append results to" },
|
|
64
|
+
{ name: "force", type: "boolean", description: "Force lookup even if DNS data already exists" },
|
|
65
|
+
{ name: "save", type: "boolean", description: "Save results to the record" },
|
|
66
|
+
{ name: "field", type: "string", description: "Field name to save results to" }
|
|
67
|
+
],
|
|
68
|
+
// GeoIP mutators
|
|
16
69
|
geo: [
|
|
70
|
+
{ name: "db_path", type: "string", description: "Path to MaxMind GeoIP database" },
|
|
17
71
|
{ name: "force", type: "boolean", description: "Force lookup even if geo data already exists" },
|
|
18
72
|
{ name: "save", type: "boolean", description: "Save results to the record" },
|
|
19
73
|
{ name: "field", type: "string", description: "Field name to save results to" },
|
|
@@ -21,6 +75,7 @@ const MUTATOR_PARAMETERS = {
|
|
|
21
75
|
{ name: "cache_ttl", type: "number", description: "Cache TTL in seconds" }
|
|
22
76
|
],
|
|
23
77
|
geoip: [
|
|
78
|
+
{ name: "db_path", type: "string", description: "Path to MaxMind GeoIP database" },
|
|
24
79
|
{ name: "force", type: "boolean", description: "Force lookup even if geo data already exists" },
|
|
25
80
|
{ name: "save", type: "boolean", description: "Save results to the record" },
|
|
26
81
|
{ name: "field", type: "string", description: "Field name to save results to" },
|
|
@@ -28,23 +83,12 @@ const MUTATOR_PARAMETERS = {
|
|
|
28
83
|
{ name: "cache_ttl", type: "number", description: "Cache TTL in seconds" }
|
|
29
84
|
],
|
|
30
85
|
geoip_lookup: [
|
|
86
|
+
{ name: "db_path", type: "string", description: "Path to MaxMind GeoIP database" },
|
|
31
87
|
{ name: "force", type: "boolean", description: "Force lookup even if geo data already exists" },
|
|
32
88
|
{ name: "save", type: "boolean", description: "Save results to the record" },
|
|
33
89
|
{ name: "field", type: "string", description: "Field name to save results to" },
|
|
34
90
|
{ name: "cache", type: "boolean", description: "Enable caching of lookup results" },
|
|
35
91
|
{ name: "cache_ttl", type: "number", description: "Cache TTL in seconds" }
|
|
36
|
-
],
|
|
37
|
-
nslookup: [
|
|
38
|
-
{ name: "record_type", type: "string", description: "DNS record type (A, AAAA, MX, etc.)" },
|
|
39
|
-
{ name: "cache", type: "boolean", description: "Enable caching of lookup results" },
|
|
40
|
-
{ name: "cache_ttl", type: "number", description: "Cache TTL in seconds" }
|
|
41
|
-
],
|
|
42
|
-
split: [
|
|
43
|
-
{ name: "delimiter", type: "string", description: "Delimiter to split on (default: comma)" }
|
|
44
|
-
],
|
|
45
|
-
replace: [
|
|
46
|
-
{ name: "find", type: "string", description: "Text to find" },
|
|
47
|
-
{ name: "replace", type: "string", description: "Text to replace with" }
|
|
48
92
|
]
|
|
49
93
|
};
|
|
50
94
|
const p = [
|