@tellaro/tql 0.1.11 → 0.1.12
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 +66 -3
- package/dist/src/parser.js +17 -1
- package/dist/src/tokenizer.d.ts +14 -0
- package/dist/src/tokenizer.js +48 -0
- package/package.json +2 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var I = Object.defineProperty;
|
|
2
2
|
var S = (e, t, a) => t in e ? I(e, t, { enumerable: !0, configurable: !0, writable: !0, value: a }) : e[t] = a;
|
|
3
3
|
var p = (e, t, a) => S(e, typeof t != "symbol" ? t + "" : t, a);
|
|
4
|
-
import { tokenizeTql as b, COMPARISON_OPERATORS as A, LOGICAL_OPERATORS as L, AGGREGATION_FUNCTIONS as R, VISUALIZATION_TYPES as $, TYPE_HINTS as P, MUTATORS as D } from "./tokenizer.js";
|
|
4
|
+
import { tokenizeTql as b, COMPARISON_OPERATORS as A, LOGICAL_OPERATORS as L, AGGREGATION_FUNCTIONS as R, VISUALIZATION_TYPES as $, TYPE_HINTS as P, MUTATORS as D, ENRICHMENT_MUTATORS as ENRICHMENT_MUTATORS, MUTATOR_PARAMETERS as MUTATOR_PARAMETERS } from "./tokenizer.js";
|
|
5
5
|
import { fuzzyMatch as _ } from "./fuzzyMatcher.js";
|
|
6
6
|
import { getSchemaCache as M } from "./schemaCache.js";
|
|
7
7
|
const E = [
|
|
@@ -281,8 +281,14 @@ function G(e, t, a) {
|
|
|
281
281
|
const n = o[o.length - 1], r = o.length > 1 ? o[o.length - 2] : null, d = n.end === t && !((u = e[t - 1]) != null && u.match(/\s/)), s = d ? n.value : void 0;
|
|
282
282
|
if (n.type === "logicalOp")
|
|
283
283
|
return { type: "start" };
|
|
284
|
-
if (n.type === "paren" && n.value === "(")
|
|
284
|
+
if (n.type === "paren" && n.value === "(") {
|
|
285
|
+
// Check if previous token is a mutator - we're inside mutator params
|
|
286
|
+
if (r && r.type === "mutator") {
|
|
287
|
+
const mutatorName = r.value.toLowerCase();
|
|
288
|
+
return { type: "mutator_params", mutatorName: mutatorName, usedParams: [], partialText: s };
|
|
289
|
+
}
|
|
285
290
|
return { type: "after_paren" };
|
|
291
|
+
}
|
|
286
292
|
if (n.type === "arrow")
|
|
287
293
|
return { type: "after_arrow", partialText: s };
|
|
288
294
|
if (n.type === "doubleColon")
|
|
@@ -358,7 +364,15 @@ function ae(e, t = {}) {
|
|
|
358
364
|
n.push(...x(o.partialText, o.fieldType)), n.push(H());
|
|
359
365
|
break;
|
|
360
366
|
case "after_mutator":
|
|
361
|
-
|
|
367
|
+
// Check if this is an enrichment mutator (geo, nslookup, etc.)
|
|
368
|
+
// Enrichment mutators don't need operators - they transform the field into enriched data
|
|
369
|
+
if (o.mutatorName && ENRICHMENT_MUTATORS.includes(o.mutatorName)) {
|
|
370
|
+
// Suggest logical operators (AND, OR) or pipe for chaining
|
|
371
|
+
n.push(...C());
|
|
372
|
+
n.push(H());
|
|
373
|
+
} else {
|
|
374
|
+
n.push(...x(o.partialText, o.mutatorOutputType));
|
|
375
|
+
}
|
|
362
376
|
break;
|
|
363
377
|
case "after_operator":
|
|
364
378
|
n.push(...Y(o.fieldName, t));
|
|
@@ -383,6 +397,9 @@ function ae(e, t = {}) {
|
|
|
383
397
|
case "after_by":
|
|
384
398
|
n.push(...y(t.fields, o.partialText));
|
|
385
399
|
break;
|
|
400
|
+
case "mutator_params":
|
|
401
|
+
n.push(...getMutatorParameterCompletions(o.mutatorName, o.usedParams, o.partialText));
|
|
402
|
+
break;
|
|
386
403
|
default:
|
|
387
404
|
n.push(...y(t.fields, o.partialText)), n.push(...x(o.partialText)), n.push(...C());
|
|
388
405
|
}
|
|
@@ -674,6 +691,52 @@ function ie(e, t, a) {
|
|
|
674
691
|
const i = b(e.substring(0, t)), o = i[i.length - 1];
|
|
675
692
|
return !!(o && o.type === "field" && o.value.length >= 2);
|
|
676
693
|
}
|
|
694
|
+
/**
|
|
695
|
+
* Get mutator parameter completions
|
|
696
|
+
* @param mutatorName - The mutator name (e.g., "geo", "nslookup")
|
|
697
|
+
* @param usedParams - Parameters already used in the current call
|
|
698
|
+
* @param partialText - Partial text for filtering
|
|
699
|
+
*/
|
|
700
|
+
function getMutatorParameterCompletions(mutatorName, usedParams = [], partialText) {
|
|
701
|
+
const params = MUTATOR_PARAMETERS[mutatorName];
|
|
702
|
+
if (!params || params.length === 0) {
|
|
703
|
+
return [];
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// Filter out already used parameters
|
|
707
|
+
const usedSet = new Set(usedParams.map(p => p.toLowerCase()));
|
|
708
|
+
const availableParams = params.filter(p => !usedSet.has(p.name.toLowerCase()));
|
|
709
|
+
|
|
710
|
+
// Filter by partial text if provided
|
|
711
|
+
let filteredParams = availableParams;
|
|
712
|
+
if (partialText) {
|
|
713
|
+
const searchText = partialText.toLowerCase();
|
|
714
|
+
filteredParams = availableParams.filter(p =>
|
|
715
|
+
p.name.toLowerCase().includes(searchText)
|
|
716
|
+
);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
return filteredParams.map((param, idx) => {
|
|
720
|
+
// Generate insert text based on parameter type
|
|
721
|
+
let insertText = `${param.name}=`;
|
|
722
|
+
if (param.type === "boolean") {
|
|
723
|
+
insertText = `${param.name}=true`;
|
|
724
|
+
} else if (param.type === "string") {
|
|
725
|
+
insertText = `${param.name}="$1"`;
|
|
726
|
+
} else if (param.type === "number") {
|
|
727
|
+
insertText = `${param.name}=$1`;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
return {
|
|
731
|
+
label: param.name,
|
|
732
|
+
insertText: insertText,
|
|
733
|
+
kind: "property",
|
|
734
|
+
detail: `${param.type} - ${param.description}`,
|
|
735
|
+
documentation: param.description,
|
|
736
|
+
sortOrder: 100 + idx
|
|
737
|
+
};
|
|
738
|
+
});
|
|
739
|
+
}
|
|
677
740
|
export {
|
|
678
741
|
oe as getCompletionTriggerCharacters,
|
|
679
742
|
ae as getCompletions,
|
package/dist/src/parser.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var c = Object.defineProperty;
|
|
2
2
|
var d = (r, e, t) => e in r ? c(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
|
|
3
3
|
var o = (r, e, t) => d(r, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import { tokenizeTql as p, COMPARISON_OPERATORS as v } from "./tokenizer.js";
|
|
4
|
+
import { tokenizeTql as p, COMPARISON_OPERATORS as v, ENRICHMENT_MUTATORS as ENRICHMENT_MUTATORS } from "./tokenizer.js";
|
|
5
5
|
const f = 50, k = /* @__PURE__ */ new Set(["logicalOp", "paren"]);
|
|
6
6
|
class y {
|
|
7
7
|
constructor(e) {
|
|
@@ -220,6 +220,22 @@ class y {
|
|
|
220
220
|
mutators: n,
|
|
221
221
|
end: this.previous().end
|
|
222
222
|
}), !this.check("operator")) {
|
|
223
|
+
// Check if the last mutator is an enrichment mutator (geo, nslookup, etc.)
|
|
224
|
+
// Enrichment mutators don't require an operator - they transform the field into enriched data
|
|
225
|
+
const lastMutator = n.length > 0 ? n[n.length - 1] : null;
|
|
226
|
+
const isEnrichmentMutator = lastMutator && ENRICHMENT_MUTATORS.includes(lastMutator);
|
|
227
|
+
|
|
228
|
+
if (isEnrichmentMutator) {
|
|
229
|
+
// Return a valid enrichment expression without error
|
|
230
|
+
return {
|
|
231
|
+
type: "enrichment",
|
|
232
|
+
field: t,
|
|
233
|
+
mutator: lastMutator,
|
|
234
|
+
start: t.start,
|
|
235
|
+
end: t.end
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
223
239
|
const s = this.isAtEnd() ? this.previous() : this.peek(), h = n.length > 0 ? `'${e.value}' with mutator` : `'${e.value}'`;
|
|
224
240
|
return this.addError(
|
|
225
241
|
`Expected operator after field ${h}`,
|
package/dist/src/tokenizer.d.ts
CHANGED
|
@@ -20,6 +20,20 @@ export declare const COLLECTION_OPERATORS: TqlCollectionOperator[];
|
|
|
20
20
|
* Synchronized with Python/Rust implementations.
|
|
21
21
|
*/
|
|
22
22
|
export declare const MUTATORS: TqlMutator[];
|
|
23
|
+
/**
|
|
24
|
+
* Enrichment mutators that don't require an operator after them.
|
|
25
|
+
* These mutators transform the field into an enriched object/value that stands alone.
|
|
26
|
+
*/
|
|
27
|
+
export declare const ENRICHMENT_MUTATORS: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Parameters available for mutators that support function call syntax.
|
|
30
|
+
*/
|
|
31
|
+
export interface MutatorParameter {
|
|
32
|
+
name: string;
|
|
33
|
+
type: 'boolean' | 'string' | 'number';
|
|
34
|
+
description: string;
|
|
35
|
+
}
|
|
36
|
+
export declare const MUTATOR_PARAMETERS: Record<string, MutatorParameter[]>;
|
|
23
37
|
/**
|
|
24
38
|
* All aggregation functions supported by TQL.
|
|
25
39
|
* Synchronized with Python/Rust implementations.
|
package/dist/src/tokenizer.js
CHANGED
|
@@ -1,6 +1,52 @@
|
|
|
1
1
|
var l = Object.defineProperty;
|
|
2
2
|
var u = (o, e, n) => e in o ? l(o, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : o[e] = n;
|
|
3
3
|
var a = (o, e, n) => u(o, typeof e != "symbol" ? e + "" : e, n);
|
|
4
|
+
// Enrichment mutators that don't require an operator after them
|
|
5
|
+
// These mutators transform the field into an enriched object/value that stands alone
|
|
6
|
+
const ENRICHMENT_MUTATORS = [
|
|
7
|
+
"geo",
|
|
8
|
+
"geoip",
|
|
9
|
+
"geoip_lookup",
|
|
10
|
+
"nslookup"
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
// Parameters available for mutators that support function call syntax
|
|
14
|
+
// e.g., geo(force=true, save=true)
|
|
15
|
+
const MUTATOR_PARAMETERS = {
|
|
16
|
+
geo: [
|
|
17
|
+
{ name: "force", type: "boolean", description: "Force lookup even if geo data already exists" },
|
|
18
|
+
{ name: "save", type: "boolean", description: "Save results to the record" },
|
|
19
|
+
{ name: "field", type: "string", description: "Field name to save results to" },
|
|
20
|
+
{ name: "cache", type: "boolean", description: "Enable caching of lookup results" },
|
|
21
|
+
{ name: "cache_ttl", type: "number", description: "Cache TTL in seconds" }
|
|
22
|
+
],
|
|
23
|
+
geoip: [
|
|
24
|
+
{ name: "force", type: "boolean", description: "Force lookup even if geo data already exists" },
|
|
25
|
+
{ name: "save", type: "boolean", description: "Save results to the record" },
|
|
26
|
+
{ name: "field", type: "string", description: "Field name to save results to" },
|
|
27
|
+
{ name: "cache", type: "boolean", description: "Enable caching of lookup results" },
|
|
28
|
+
{ name: "cache_ttl", type: "number", description: "Cache TTL in seconds" }
|
|
29
|
+
],
|
|
30
|
+
geoip_lookup: [
|
|
31
|
+
{ name: "force", type: "boolean", description: "Force lookup even if geo data already exists" },
|
|
32
|
+
{ name: "save", type: "boolean", description: "Save results to the record" },
|
|
33
|
+
{ name: "field", type: "string", description: "Field name to save results to" },
|
|
34
|
+
{ name: "cache", type: "boolean", description: "Enable caching of lookup results" },
|
|
35
|
+
{ 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
|
+
]
|
|
49
|
+
};
|
|
4
50
|
const p = [
|
|
5
51
|
// Equality
|
|
6
52
|
"eq",
|
|
@@ -413,9 +459,11 @@ export {
|
|
|
413
459
|
_ as AGGREGATION_FUNCTIONS,
|
|
414
460
|
f as COLLECTION_OPERATORS,
|
|
415
461
|
p as COMPARISON_OPERATORS,
|
|
462
|
+
ENRICHMENT_MUTATORS,
|
|
416
463
|
w as KEYWORDS,
|
|
417
464
|
k as LOGICAL_OPERATORS,
|
|
418
465
|
m as MUTATORS,
|
|
466
|
+
MUTATOR_PARAMETERS,
|
|
419
467
|
d as NEGATION_SYMBOL_OPERATORS,
|
|
420
468
|
c as SYMBOL_OPERATORS,
|
|
421
469
|
g as TYPE_HINTS,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tellaro/tql",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "Tellaro Query Language (TQL) parser, validator, and autocomplete for JavaScript/TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -23,17 +23,11 @@
|
|
|
23
23
|
"README.md"
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
|
-
"build": "vite build",
|
|
27
26
|
"test": "vitest run",
|
|
28
27
|
"test:watch": "vitest",
|
|
29
28
|
"test:shared": "vitest run --grep 'shared-fixtures'",
|
|
30
29
|
"test:e2e": "playwright test",
|
|
31
|
-
"test:e2e:ui": "playwright test --ui"
|
|
32
|
-
"playground:serve": "vite --config vite.playground.config.ts --port 5174",
|
|
33
|
-
"playground:dev": "vite --config vite.playground.config.ts",
|
|
34
|
-
"lint": "eslint src vue tests --ext .ts,.vue",
|
|
35
|
-
"typecheck": "vue-tsc --noEmit",
|
|
36
|
-
"prepublishOnly": "npm run build"
|
|
30
|
+
"test:e2e:ui": "playwright test --ui"
|
|
37
31
|
},
|
|
38
32
|
"repository": {
|
|
39
33
|
"type": "git",
|