@tellaro/tql 0.1.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.
@@ -0,0 +1,221 @@
1
+ /**
2
+ * TQL (Tellaro Query Language) Type Definitions
3
+ *
4
+ * Comprehensive type system for TQL parsing, validation, and autocomplete.
5
+ * Synchronized with tellaro-query-language Python/Rust implementations.
6
+ */
7
+ export type TqlTokenType = "field" | "operator" | "logicalOp" | "collectionOp" | "string" | "number" | "boolean" | "null" | "paren" | "bracket" | "comma" | "pipe" | "arrow" | "doubleColon" | "mutator" | "aggregation" | "keyword" | "typeHint" | "visualization" | "whitespace" | "unknown" | "error";
8
+ export interface TqlToken {
9
+ type: TqlTokenType;
10
+ value: string;
11
+ start: number;
12
+ end: number;
13
+ line: number;
14
+ column: number;
15
+ raw?: string;
16
+ }
17
+ export type TqlExpression = TqlBinaryExpression | TqlUnaryExpression | TqlComparisonExpression | TqlCollectionExpression | TqlMutatorExpression | TqlAggregationExpression | TqlStatsExpression | TqlGroupExpression | TqlLiteral | TqlFieldReference;
18
+ export interface TqlBinaryExpression {
19
+ type: "binary";
20
+ operator: "AND" | "OR";
21
+ left: TqlExpression;
22
+ right: TqlExpression;
23
+ start: number;
24
+ end: number;
25
+ }
26
+ export interface TqlUnaryExpression {
27
+ type: "unary";
28
+ operator: "NOT";
29
+ operand: TqlExpression;
30
+ start: number;
31
+ end: number;
32
+ }
33
+ export interface TqlComparisonExpression {
34
+ type: "comparison";
35
+ field: TqlFieldReference | TqlMutatorExpression;
36
+ operator: TqlComparisonOperator;
37
+ value: TqlLiteral | TqlLiteral[];
38
+ start: number;
39
+ end: number;
40
+ }
41
+ export interface TqlCollectionExpression {
42
+ type: "collection";
43
+ operator: "ANY" | "ALL" | "NONE";
44
+ field: TqlFieldReference;
45
+ condition: TqlExpression;
46
+ start: number;
47
+ end: number;
48
+ }
49
+ export interface TqlMutatorExpression {
50
+ type: "mutator";
51
+ mutator: TqlMutator;
52
+ field: TqlFieldReference | TqlMutatorExpression;
53
+ args?: TqlLiteral[];
54
+ start: number;
55
+ end: number;
56
+ }
57
+ export interface TqlAggregationExpression {
58
+ type: "aggregation";
59
+ function: TqlAggregationFunction;
60
+ field?: TqlFieldReference;
61
+ args?: (string | number)[];
62
+ alias?: string;
63
+ start: number;
64
+ end: number;
65
+ }
66
+ export interface TqlStatsExpression {
67
+ type: "stats";
68
+ aggregations: TqlAggregationExpression[];
69
+ groupBy?: TqlFieldReference[];
70
+ topN?: number;
71
+ bottomN?: number;
72
+ visualization?: TqlVisualizationType;
73
+ start: number;
74
+ end: number;
75
+ }
76
+ export interface TqlGroupExpression {
77
+ type: "group";
78
+ expression: TqlExpression;
79
+ start: number;
80
+ end: number;
81
+ }
82
+ export interface TqlLiteral {
83
+ type: "literal";
84
+ valueType: "string" | "number" | "boolean" | "null";
85
+ value: string | number | boolean | null;
86
+ start: number;
87
+ end: number;
88
+ }
89
+ export interface TqlFieldReference {
90
+ type: "field";
91
+ name: string;
92
+ path: string[];
93
+ mutators?: string[];
94
+ typeHint?: TqlTypeHint;
95
+ start: number;
96
+ end: number;
97
+ }
98
+ export type TqlComparisonOperator = "eq" | "ne" | "=" | "!=" | "==" | "gt" | "gte" | "lt" | "lte" | ">" | ">=" | "<" | "<=" | "contains" | "not_contains" | "!contains" | "startswith" | "not_startswith" | "!startswith" | "endswith" | "not_endswith" | "!endswith" | "regexp" | "regex" | "not_regexp" | "!regexp" | "matches" | "not_matches" | "!matches" | "between" | "not_between" | "!between" | "in" | "not_in" | "!in" | "exists" | "not_exists" | "!exists" | "is" | "is_not" | "!is" | "cidr" | "not_cidr" | "!cidr" | "any" | "all" | "none" | "not_any" | "not_all" | "not_none" | "!any" | "!all" | "!none";
99
+ export type TqlLogicalOperator = "AND" | "OR" | "NOT";
100
+ export type TqlCollectionOperator = "ANY" | "ALL" | "NONE";
101
+ export type TqlMutator = "lowercase" | "uppercase" | "trim" | "split" | "length" | "replace" | "b64encode" | "b64decode" | "urldecode" | "hexencode" | "hexdecode" | "md5" | "sha256" | "refang" | "defang" | "is_private" | "is_global" | "nslookup" | "geoip_lookup" | "geoip" | "geo" | "any" | "all" | "avg" | "average" | "sum" | "min" | "max";
102
+ export type TqlAggregationFunction = "count" | "sum" | "avg" | "average" | "mean" | "median" | "med" | "min" | "max" | "percentile" | "percentiles" | "p" | "pct" | "percentile_rank" | "percentile_ranks" | "pct_rank" | "pct_ranks" | "std" | "standard_deviation" | "unique_count" | "cardinality" | "values" | "unique" | "distinct";
103
+ export type TqlTypeHint = "string" | "str" | "number" | "int" | "integer" | "float" | "double" | "decimal" | "date" | "bool" | "boolean" | "array" | "list" | "object" | "geo";
104
+ export type TqlVisualizationType = "bar" | "barchart" | "line" | "area" | "pie" | "donut" | "scatter" | "heatmap" | "treemap" | "sunburst" | "table" | "number" | "gauge" | "map" | "grouped_bar" | "stacked_bar" | "nested_pie" | "nested_donut" | "chord";
105
+ export interface TqlParseResult {
106
+ ast: TqlExpression | null;
107
+ tokens: TqlToken[];
108
+ errors: TqlParseError[];
109
+ warnings: TqlParseWarning[];
110
+ success: boolean;
111
+ }
112
+ export interface TqlParseError {
113
+ message: string;
114
+ start: number;
115
+ end: number;
116
+ line: number;
117
+ column: number;
118
+ severity: "error";
119
+ code: TqlErrorCode;
120
+ suggestion?: string;
121
+ }
122
+ export interface TqlParseWarning {
123
+ message: string;
124
+ start: number;
125
+ end: number;
126
+ line: number;
127
+ column: number;
128
+ severity: "warning";
129
+ code: TqlWarningCode;
130
+ suggestion?: string;
131
+ }
132
+ export type TqlErrorCode = "UNEXPECTED_TOKEN" | "UNEXPECTED_END" | "UNBALANCED_PARENS" | "UNBALANCED_BRACKETS" | "UNTERMINATED_STRING" | "INVALID_OPERATOR" | "INVALID_MUTATOR" | "INVALID_VALUE" | "MISSING_OPERAND" | "MISSING_OPERATOR" | "MISSING_VALUE" | "MISSING_FIELD" | "MISSING_MUTATOR" | "INVALID_SYNTAX" | "MAX_DEPTH_EXCEEDED" | "TYPE_MISMATCH";
133
+ export type TqlWarningCode = "UNKNOWN_FIELD" | "TYPE_MISMATCH" | "DEPRECATED_OPERATOR" | "REDUNDANT_PARENS";
134
+ export interface TqlValidationResult {
135
+ valid: boolean;
136
+ errors: TqlParseError[];
137
+ warnings: TqlParseWarning[];
138
+ }
139
+ export interface TqlValidationOptions {
140
+ availableFields?: string[];
141
+ fieldTypes?: Record<string, TqlFieldType>;
142
+ strictMode?: boolean;
143
+ allowAggregations?: boolean;
144
+ allowMutators?: boolean;
145
+ maxDepth?: number;
146
+ }
147
+ export type TqlFieldType = "text" | "keyword" | "long" | "integer" | "short" | "byte" | "double" | "float" | "half_float" | "scaled_float" | "unsigned_long" | "date" | "boolean" | "ip" | "nested" | "object" | "geo_point";
148
+ export interface TqlCompletionItem {
149
+ label: string;
150
+ insertText: string;
151
+ kind: TqlCompletionKind;
152
+ detail?: string;
153
+ documentation?: string;
154
+ sortOrder: number;
155
+ filterText?: string;
156
+ commitCharacters?: string[];
157
+ }
158
+ export type TqlCompletionKind = "field" | "operator" | "value" | "keyword" | "snippet" | "mutator" | "aggregation" | "logicalOp" | "typeHint" | "visualization";
159
+ export interface TqlCompletionContext {
160
+ query: string;
161
+ cursorPosition: number;
162
+ triggerKind: "invoked" | "character" | "automatic";
163
+ triggerCharacter?: string;
164
+ }
165
+ export interface TqlCompletionOptions {
166
+ fields?: TqlFieldSchema[];
167
+ includeSnippets?: boolean;
168
+ includeMutators?: boolean;
169
+ includeAggregations?: boolean;
170
+ includeTypeHints?: boolean;
171
+ includeVisualizations?: boolean;
172
+ maxItems?: number;
173
+ fieldValues?: Record<string, string[]>;
174
+ }
175
+ export interface TqlFieldSchema {
176
+ name: string;
177
+ type: TqlFieldType;
178
+ description?: string;
179
+ examples?: string[];
180
+ path?: string[];
181
+ nested?: TqlFieldSchema[];
182
+ }
183
+ export interface TqlSnippet {
184
+ label: string;
185
+ insertText: string;
186
+ description?: string;
187
+ category?: string;
188
+ }
189
+ export interface TqlInputProps {
190
+ modelValue: string;
191
+ placeholder?: string;
192
+ disabled?: boolean;
193
+ readonly?: boolean;
194
+ rows?: number;
195
+ multiline?: boolean;
196
+ showValidation?: boolean;
197
+ validateOnInput?: boolean;
198
+ debounceMs?: number;
199
+ fieldSchema?: TqlFieldSchema[];
200
+ modelName?: string;
201
+ snippets?: TqlSnippet[];
202
+ showSnippetButton?: boolean;
203
+ autocomplete?: boolean;
204
+ syntaxHighlighting?: boolean;
205
+ }
206
+ export interface TqlInputEmits {
207
+ (e: "update:modelValue", value: string): void;
208
+ (e: "validation", result: TqlValidationResult): void;
209
+ (e: "parse", result: TqlParseResult): void;
210
+ (e: "submit", value: string): void;
211
+ }
212
+ export interface TqlInputExpose {
213
+ focus(): void;
214
+ blur(): void;
215
+ validate(): TqlValidationResult;
216
+ insertText(text: string): void;
217
+ insertSnippet(snippet: TqlSnippet): void;
218
+ getTokenAtPosition(pos: number): TqlToken | null;
219
+ getCursorPosition(): number;
220
+ setCursorPosition(pos: number): void;
221
+ }
@@ -0,0 +1,46 @@
1
+ import { TqlParseError, TqlParseWarning, TqlValidationOptions, TqlValidationResult } from './types';
2
+
3
+ export declare class TqlValidator {
4
+ private options;
5
+ private errors;
6
+ private warnings;
7
+ constructor(options?: TqlValidationOptions);
8
+ /**
9
+ * Validate a TQL query
10
+ */
11
+ validate(query: string): TqlValidationResult;
12
+ /**
13
+ * Validate an expression recursively
14
+ */
15
+ private validateExpression;
16
+ /**
17
+ * Validate a comparison expression
18
+ */
19
+ private validateComparison;
20
+ /**
21
+ * Suggest a similar field name using Levenshtein distance
22
+ */
23
+ private suggestField;
24
+ /**
25
+ * Calculate Levenshtein distance between two strings
26
+ */
27
+ private levenshteinDistance;
28
+ private addError;
29
+ private addWarning;
30
+ }
31
+ /**
32
+ * Validate a TQL query with options
33
+ */
34
+ export declare function validateTql(query: string, options?: TqlValidationOptions): TqlValidationResult;
35
+ /**
36
+ * Quick check if TQL is valid (syntax only)
37
+ */
38
+ export declare function isValidTqlSyntax(query: string): boolean;
39
+ /**
40
+ * Get all validation issues (errors + warnings)
41
+ */
42
+ export declare function getTqlIssues(query: string, options?: TqlValidationOptions): (TqlParseError | TqlParseWarning)[];
43
+ /**
44
+ * Format validation result for display
45
+ */
46
+ export declare function formatValidationResult(result: TqlValidationResult): string;
@@ -0,0 +1,315 @@
1
+ var b = Object.defineProperty;
2
+ var u = (s, e, t) => e in s ? b(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
+ var r = (s, e, t) => u(s, typeof e != "symbol" ? e + "" : e, t);
4
+ import { parseTql as c } from "./parser.js";
5
+ const f = {
6
+ // Equality (all types)
7
+ eq: ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
8
+ ne: ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
9
+ "=": ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
10
+ "==": ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
11
+ "!=": ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
12
+ // Comparison (numeric and dates)
13
+ gt: ["long", "integer", "double", "float", "date"],
14
+ gte: ["long", "integer", "double", "float", "date"],
15
+ lt: ["long", "integer", "double", "float", "date"],
16
+ lte: ["long", "integer", "double", "float", "date"],
17
+ ">": ["long", "integer", "double", "float", "date"],
18
+ ">=": ["long", "integer", "double", "float", "date"],
19
+ "<": ["long", "integer", "double", "float", "date"],
20
+ "<=": ["long", "integer", "double", "float", "date"],
21
+ // String operations
22
+ contains: ["text", "keyword"],
23
+ not_contains: ["text", "keyword"],
24
+ "!contains": ["text", "keyword"],
25
+ startswith: ["text", "keyword"],
26
+ not_startswith: ["text", "keyword"],
27
+ "!startswith": ["text", "keyword"],
28
+ endswith: ["text", "keyword"],
29
+ not_endswith: ["text", "keyword"],
30
+ "!endswith": ["text", "keyword"],
31
+ regexp: ["text", "keyword"],
32
+ regex: ["text", "keyword"],
33
+ not_regexp: ["text", "keyword"],
34
+ "!regexp": ["text", "keyword"],
35
+ matches: ["text", "keyword"],
36
+ not_matches: ["text", "keyword"],
37
+ "!matches": ["text", "keyword"],
38
+ // Range
39
+ between: ["long", "integer", "double", "float", "date"],
40
+ not_between: ["long", "integer", "double", "float", "date"],
41
+ "!between": ["long", "integer", "double", "float", "date"],
42
+ in: ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip"],
43
+ not_in: ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip"],
44
+ "!in": ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip"],
45
+ // Existence (all types)
46
+ exists: ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
47
+ not_exists: ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
48
+ "!exists": ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
49
+ // Null checks (all types)
50
+ is: ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
51
+ is_not: ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
52
+ "!is": ["text", "keyword", "long", "integer", "double", "float", "date", "boolean", "ip", "nested", "object", "geo_point"],
53
+ // IP-specific operators
54
+ cidr: ["ip"],
55
+ not_cidr: ["ip"],
56
+ "!cidr": ["ip"],
57
+ // Collection operators
58
+ any: ["nested", "object", "keyword", "text"],
59
+ all: ["nested", "object", "keyword", "text"],
60
+ none: ["nested", "object", "keyword", "text"],
61
+ not_any: ["nested", "object", "keyword", "text"],
62
+ not_all: ["nested", "object", "keyword", "text"],
63
+ not_none: ["nested", "object", "keyword", "text"],
64
+ "!any": ["nested", "object", "keyword", "text"],
65
+ "!all": ["nested", "object", "keyword", "text"],
66
+ "!none": ["nested", "object", "keyword", "text"]
67
+ }, d = {
68
+ cidr: ["ip"],
69
+ not_cidr: ["ip"],
70
+ "!cidr": ["ip"]
71
+ }, h = {
72
+ eq: ["string", "number", "boolean"],
73
+ ne: ["string", "number", "boolean"],
74
+ "=": ["string", "number", "boolean"],
75
+ "==": ["string", "number", "boolean"],
76
+ "!=": ["string", "number", "boolean"],
77
+ gt: ["number", "string"],
78
+ gte: ["number", "string"],
79
+ lt: ["number", "string"],
80
+ lte: ["number", "string"],
81
+ ">": ["number", "string"],
82
+ ">=": ["number", "string"],
83
+ "<": ["number", "string"],
84
+ "<=": ["number", "string"],
85
+ contains: ["string"],
86
+ not_contains: ["string"],
87
+ "!contains": ["string"],
88
+ startswith: ["string"],
89
+ not_startswith: ["string"],
90
+ "!startswith": ["string"],
91
+ endswith: ["string"],
92
+ not_endswith: ["string"],
93
+ "!endswith": ["string"],
94
+ regexp: ["string"],
95
+ regex: ["string"],
96
+ not_regexp: ["string"],
97
+ "!regexp": ["string"],
98
+ matches: ["string"],
99
+ not_matches: ["string"],
100
+ "!matches": ["string"],
101
+ between: ["number", "string"],
102
+ not_between: ["number", "string"],
103
+ "!between": ["number", "string"],
104
+ in: ["string", "number", "boolean"],
105
+ not_in: ["string", "number", "boolean"],
106
+ "!in": ["string", "number", "boolean"],
107
+ exists: ["boolean"],
108
+ not_exists: ["boolean"],
109
+ "!exists": ["boolean"],
110
+ is: ["null"],
111
+ is_not: ["null"],
112
+ "!is": ["null"],
113
+ cidr: ["string"],
114
+ not_cidr: ["string"],
115
+ "!cidr": ["string"],
116
+ any: ["string", "number", "boolean"],
117
+ all: ["string", "number", "boolean"],
118
+ none: ["string", "number", "boolean"],
119
+ not_any: ["string", "number", "boolean"],
120
+ not_all: ["string", "number", "boolean"],
121
+ not_none: ["string", "number", "boolean"],
122
+ "!any": ["string", "number", "boolean"],
123
+ "!all": ["string", "number", "boolean"],
124
+ "!none": ["string", "number", "boolean"]
125
+ };
126
+ class y {
127
+ constructor(e = {}) {
128
+ r(this, "options");
129
+ r(this, "errors");
130
+ r(this, "warnings");
131
+ this.options = e, this.errors = [], this.warnings = [];
132
+ }
133
+ /**
134
+ * Validate a TQL query
135
+ */
136
+ validate(e) {
137
+ this.errors = [], this.warnings = [];
138
+ const t = c(e);
139
+ return this.errors.push(...t.errors), this.warnings.push(...t.warnings), t.ast && this.validateExpression(t.ast), {
140
+ valid: this.errors.length === 0,
141
+ errors: this.errors,
142
+ warnings: this.warnings
143
+ };
144
+ }
145
+ /**
146
+ * Validate an expression recursively
147
+ */
148
+ validateExpression(e) {
149
+ switch (e.type) {
150
+ case "binary":
151
+ this.validateExpression(e.left), this.validateExpression(e.right);
152
+ break;
153
+ case "unary":
154
+ this.validateExpression(e.operand);
155
+ break;
156
+ case "group":
157
+ this.validateExpression(e.expression);
158
+ break;
159
+ case "comparison":
160
+ this.validateComparison(e);
161
+ break;
162
+ }
163
+ }
164
+ /**
165
+ * Validate a comparison expression
166
+ */
167
+ validateComparison(e) {
168
+ const t = e.field.type === "field" ? e.field.name : "computed";
169
+ if (this.options.availableFields && this.options.strictMode && !this.options.availableFields.includes(t) && e.field.type === "field" && this.addWarning(
170
+ `Unknown field '${t}'`,
171
+ e.field.start,
172
+ e.field.end,
173
+ (e.field.type === "field", 1),
174
+ 1,
175
+ "UNKNOWN_FIELD",
176
+ `Did you mean: ${this.suggestField(t)}`
177
+ ), this.options.fieldTypes && e.field.type === "field") {
178
+ const o = this.options.fieldTypes[t];
179
+ if (o) {
180
+ const n = d[e.operator];
181
+ n && !n.includes(o) && this.addError(
182
+ `Operator '${e.operator}' requires field type ${n.join(" or ")}, but '${t}' is type '${o}'`,
183
+ e.start,
184
+ e.end,
185
+ 1,
186
+ 1,
187
+ "TYPE_MISMATCH",
188
+ `Use '${e.operator}' only with ${n.join(" or ")} fields`
189
+ );
190
+ }
191
+ }
192
+ if (this.options.fieldTypes && e.field.type === "field") {
193
+ const o = this.options.fieldTypes[t];
194
+ if (o) {
195
+ const n = f[e.operator];
196
+ !d[e.operator] && n && !n.includes(o) && this.addWarning(
197
+ `Operator '${e.operator}' may not work well with field type '${o}'`,
198
+ e.start,
199
+ e.end,
200
+ 1,
201
+ 1,
202
+ "TYPE_MISMATCH",
203
+ `Consider using a different operator for ${o} fields`
204
+ );
205
+ }
206
+ }
207
+ if (!Array.isArray(e.value) && e.value.type === "literal") {
208
+ const o = h[e.operator];
209
+ o && !o.includes(e.value.valueType) && this.addWarning(
210
+ `Operator '${e.operator}' expects ${o.join(" or ")} value`,
211
+ e.value.start,
212
+ e.value.end,
213
+ 1,
214
+ 1,
215
+ "TYPE_MISMATCH"
216
+ );
217
+ }
218
+ if ((e.operator === "regexp" || e.operator === "regex" || e.operator === "not_regexp" || e.operator === "matches" || e.operator === "not_matches") && !Array.isArray(e.value) && e.value.valueType === "string" && typeof e.value.value == "string")
219
+ try {
220
+ new RegExp(e.value.value);
221
+ } catch {
222
+ this.addError(
223
+ `Invalid regular expression: ${e.value.value}`,
224
+ e.value.start,
225
+ e.value.end,
226
+ 1,
227
+ 1,
228
+ "INVALID_VALUE",
229
+ "Check the regex syntax"
230
+ );
231
+ }
232
+ }
233
+ /**
234
+ * Suggest a similar field name using Levenshtein distance
235
+ */
236
+ suggestField(e) {
237
+ if (!this.options.availableFields || this.options.availableFields.length === 0)
238
+ return "check available fields";
239
+ let t = this.options.availableFields[0], o = this.levenshteinDistance(e, t);
240
+ for (const n of this.options.availableFields) {
241
+ const i = this.levenshteinDistance(e, n);
242
+ i < o && (o = i, t = n);
243
+ }
244
+ return t;
245
+ }
246
+ /**
247
+ * Calculate Levenshtein distance between two strings
248
+ */
249
+ levenshteinDistance(e, t) {
250
+ const o = [];
251
+ for (let n = 0; n <= t.length; n++)
252
+ o[n] = [n];
253
+ for (let n = 0; n <= e.length; n++)
254
+ o[0][n] = n;
255
+ for (let n = 1; n <= t.length; n++)
256
+ for (let i = 1; i <= e.length; i++)
257
+ t.charAt(n - 1) === e.charAt(i - 1) ? o[n][i] = o[n - 1][i - 1] : o[n][i] = Math.min(
258
+ o[n - 1][i - 1] + 1,
259
+ o[n][i - 1] + 1,
260
+ o[n - 1][i] + 1
261
+ );
262
+ return o[t.length][e.length];
263
+ }
264
+ addError(e, t, o, n, i, a, l) {
265
+ this.errors.push({
266
+ message: e,
267
+ start: t,
268
+ end: o,
269
+ line: n,
270
+ column: i,
271
+ severity: "error",
272
+ code: a,
273
+ suggestion: l
274
+ });
275
+ }
276
+ addWarning(e, t, o, n, i, a, l) {
277
+ this.warnings.push({
278
+ message: e,
279
+ start: t,
280
+ end: o,
281
+ line: n,
282
+ column: i,
283
+ severity: "warning",
284
+ code: a,
285
+ suggestion: l
286
+ });
287
+ }
288
+ }
289
+ function g(s, e) {
290
+ return new y(e).validate(s);
291
+ }
292
+ function _(s) {
293
+ return g(s).valid;
294
+ }
295
+ function m(s, e) {
296
+ const t = g(s, e);
297
+ return [...t.errors, ...t.warnings];
298
+ }
299
+ function v(s) {
300
+ const e = [];
301
+ s.valid ? e.push("Query is valid") : e.push("Query has errors:");
302
+ for (const t of s.errors)
303
+ e.push(` Error: ${t.message}`), t.suggestion && e.push(` Suggestion: ${t.suggestion}`);
304
+ for (const t of s.warnings)
305
+ e.push(` Warning: ${t.message}`), t.suggestion && e.push(` Suggestion: ${t.suggestion}`);
306
+ return e.join(`
307
+ `);
308
+ }
309
+ export {
310
+ y as TqlValidator,
311
+ v as formatValidationResult,
312
+ m as getTqlIssues,
313
+ _ as isValidTqlSyntax,
314
+ g as validateTql
315
+ };
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .tql-autocomplete-dropdown[data-v-6381bbdd]{position:fixed;top:var(--dropdown-top);left:var(--dropdown-left);z-index:9999;min-width:280px;max-width:450px;max-height:var(--dropdown-max-height);background:var(--surface-overlay, #fff);border:1px solid var(--surface-border, #ddd);border-radius:var(--border-radius, 6px);box-shadow:0 4px 16px #00000026;overflow:hidden;display:flex;flex-direction:column}.tql-completion-list[data-v-6381bbdd]{overflow-y:auto;max-height:calc(var(--dropdown-max-height) - 60px)}.tql-completion-item[data-v-6381bbdd]{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;cursor:pointer;transition:background-color .15s}.tql-completion-item[data-v-6381bbdd]:hover,.tql-completion-item.selected[data-v-6381bbdd]{background:var(--highlight-bg, #f0f0f0)}.tql-completion-icon[data-v-6381bbdd]{display:flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:4px;font-size:.75rem}.tql-completion-icon.tql-completion-kind-field[data-v-6381bbdd]{background:var(--blue-100, #e3f2fd);color:var(--blue-600, #1e88e5)}.tql-completion-icon.tql-completion-kind-operator[data-v-6381bbdd]{background:var(--pink-100, #fce4ec);color:var(--pink-600, #d81b60)}.tql-completion-icon.tql-completion-kind-value[data-v-6381bbdd]{background:var(--green-100, #e8f5e9);color:var(--green-600, #43a047)}.tql-completion-icon.tql-completion-kind-keyword[data-v-6381bbdd]{background:var(--purple-100, #f3e5f5);color:var(--purple-600, #8e24aa)}.tql-completion-icon.tql-completion-kind-snippet[data-v-6381bbdd]{background:var(--orange-100, #fff3e0);color:var(--orange-600, #fb8c00)}.tql-completion-icon.tql-completion-kind-mutator[data-v-6381bbdd]{background:var(--cyan-100, #e0f7fa);color:var(--cyan-600, #00acc1)}.tql-completion-icon.tql-completion-kind-aggregation[data-v-6381bbdd]{background:var(--indigo-100, #e8eaf6);color:var(--indigo-600, #3949ab)}.tql-completion-icon.tql-completion-kind-logicalOp[data-v-6381bbdd]{background:var(--yellow-100, #fffde7);color:var(--yellow-700, #fbc02d)}.tql-completion-icon.tql-completion-kind-typeHint[data-v-6381bbdd]{background:var(--teal-100, #e0f2f1);color:var(--teal-600, #00897b)}.tql-completion-icon.tql-completion-kind-visualization[data-v-6381bbdd]{background:var(--red-100, #ffebee);color:var(--red-600, #e53935)}.tql-completion-content[data-v-6381bbdd]{flex:1;display:flex;flex-direction:column;min-width:0}.tql-completion-label[data-v-6381bbdd]{font-family:Courier New,monospace;font-size:.875rem;font-weight:500;color:var(--text-color, #333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tql-completion-detail[data-v-6381bbdd]{font-size:.75rem;color:var(--text-color-secondary, #666);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tql-completion-kind-badge[data-v-6381bbdd]{font-size:.625rem;padding:.125rem .375rem;background:var(--surface-100, #f5f5f5);border-radius:3px;color:var(--text-color-secondary, #666);text-transform:uppercase;letter-spacing:.025em}.tql-completion-docs[data-v-6381bbdd]{padding:.5rem .75rem;border-top:1px solid var(--surface-border, #ddd);background:var(--surface-50, #fafafa);font-size:.75rem;color:var(--text-color-secondary, #666);max-height:60px;overflow-y:auto}.tql-input-wrapper[data-v-c0e226bb]{position:relative;display:flex;align-items:flex-start;border:1px solid var(--surface-border, #ddd);border-radius:var(--border-radius, 6px);background:var(--surface-ground, #fff);transition:border-color .2s,box-shadow .2s}.tql-input-wrapper.tql-input-focused[data-v-c0e226bb]{border-color:var(--primary-color, #3b82f6);box-shadow:0 0 0 2px var(--primary-100, rgba(59, 130, 246, .2))}.tql-input-wrapper.tql-input-invalid[data-v-c0e226bb]{border-color:var(--red-500, #ef4444)}.tql-input-wrapper.tql-input-invalid.tql-input-focused[data-v-c0e226bb]{box-shadow:0 0 0 2px var(--red-100, rgba(239, 68, 68, .2))}.tql-input-wrapper.tql-input-disabled[data-v-c0e226bb]{opacity:.6;cursor:not-allowed}.tql-highlight-layer[data-v-c0e226bb]{position:absolute;top:0;left:0;right:0;bottom:0;padding:.5rem .75rem;pointer-events:none;white-space:pre-wrap;word-wrap:break-word;font-family:Courier New,monospace;font-size:.875rem;line-height:1.5;overflow:hidden}.tql-input-multiline .tql-highlight-layer[data-v-c0e226bb]{overflow-y:auto}.tql-input[data-v-c0e226bb]{flex:1;width:100%;padding:.5rem 2.5rem .5rem .75rem;border:none;background:transparent;font-family:Courier New,monospace;font-size:.875rem;line-height:1.5;color:var(--text-color, #333);outline:none;resize:none}.tql-input.tql-input-highlighted[data-v-c0e226bb]{color:transparent;caret-color:var(--text-color, #333)}.tql-input[data-v-c0e226bb]::placeholder{color:var(--text-color-secondary, #666);opacity:.7}.tql-input[data-v-c0e226bb]:disabled{cursor:not-allowed}.tql-token-field[data-v-c0e226bb]{color:var(--tql-field-color, var(--blue-600, #2563eb))}.tql-token-operator[data-v-c0e226bb]{color:var(--tql-operator-color, var(--pink-600, #db2777));font-weight:500}.tql-token-logicalOp[data-v-c0e226bb]{color:var(--tql-logical-color, var(--purple-600, #9333ea));font-weight:600}.tql-token-collectionOp[data-v-c0e226bb]{color:var(--tql-collection-color, var(--indigo-600, #4f46e5));font-weight:600}.tql-token-string[data-v-c0e226bb]{color:var(--tql-string-color, var(--green-600, #16a34a))}.tql-token-number[data-v-c0e226bb]{color:var(--tql-number-color, var(--orange-600, #ea580c))}.tql-token-boolean[data-v-c0e226bb]{color:var(--tql-boolean-color, var(--cyan-600, #0891b2))}.tql-token-null[data-v-c0e226bb]{color:var(--tql-null-color, var(--gray-500, #6b7280));font-style:italic}.tql-token-mutator[data-v-c0e226bb]{color:var(--tql-mutator-color, var(--teal-600, #0d9488));font-style:italic}.tql-token-aggregation[data-v-c0e226bb]{color:var(--tql-aggregation-color, var(--indigo-600, #4f46e5))}.tql-token-keyword[data-v-c0e226bb]{color:var(--tql-keyword-color, var(--purple-500, #a855f7))}.tql-token-typeHint[data-v-c0e226bb]{color:var(--tql-typehint-color, var(--teal-500, #14b8a6))}.tql-token-visualization[data-v-c0e226bb]{color:var(--tql-viz-color, var(--red-500, #ef4444))}.tql-token-arrow[data-v-c0e226bb]{color:var(--tql-arrow-color, var(--gray-600, #4b5563));font-weight:600}.tql-token-doubleColon[data-v-c0e226bb]{color:var(--tql-colon-color, var(--gray-500, #6b7280))}.tql-token-paren[data-v-c0e226bb],.tql-token-bracket[data-v-c0e226bb]{color:var(--tql-bracket-color, var(--gray-600, #4b5563))}.tql-token-error[data-v-c0e226bb]{color:var(--tql-error-color, var(--red-600, #dc2626));text-decoration:wavy underline;text-decoration-color:var(--red-400, #f87171)}.tql-token-error-range[data-v-c0e226bb]{background-color:var(--red-50, #fef2f2)}.tql-token-unknown[data-v-c0e226bb]{color:var(--text-color-secondary, #666)}.tql-validation-icon[data-v-c0e226bb]{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);display:flex;align-items:center;justify-content:center}.tql-input-multiline .tql-validation-icon[data-v-c0e226bb]{top:.75rem;transform:none}.tql-icon-valid[data-v-c0e226bb]{color:var(--green-500, #22c55e)}.tql-icon-invalid[data-v-c0e226bb]{color:var(--red-500, #ef4444)}.tql-icon-clickable[data-v-c0e226bb]{cursor:pointer;transition:transform .2s}.tql-icon-clickable[data-v-c0e226bb]:hover{transform:scale(1.2)}.tql-icon-clickable[data-v-c0e226bb]:focus{outline:2px solid var(--primary-color, #3b82f6);outline-offset:2px;border-radius:50%}.tql-snippet-button[data-v-c0e226bb]{position:absolute;right:2rem;top:50%;transform:translateY(-50%);padding:.25rem;border:none;background:transparent;color:var(--text-color-secondary, #666);cursor:pointer;border-radius:var(--border-radius, 6px);transition:color .2s,background-color .2s}.tql-snippet-button[data-v-c0e226bb]:hover{color:var(--primary-color, #3b82f6);background:var(--surface-100, #f5f5f5)}.tql-input-multiline .tql-snippet-button[data-v-c0e226bb]{top:.75rem;transform:none}.tql-validation-messages[data-v-c0e226bb]{position:absolute;top:100%;left:0;right:0;margin-top:.25rem;background:var(--surface-overlay, #fff);border:1px solid var(--red-200, #fecaca);border-radius:var(--border-radius, 6px);padding:.5rem;z-index:10;box-shadow:0 2px 8px #0000001a}.tql-error-message[data-v-c0e226bb]{display:flex;align-items:flex-start;gap:.5rem;padding:.25rem 0;font-size:.75rem;color:var(--red-600, #dc2626)}.tql-error-message i[data-v-c0e226bb]{margin-top:.125rem;font-size:.75rem}.tql-error-suggestion[data-v-c0e226bb]{display:block;color:var(--text-color-secondary, #666);font-style:italic;margin-left:1.25rem}
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import o from "./TqlAutocomplete.vue2.js";
2
+ /* empty css */
3
+ import t from "../_virtual/_plugin-vue_export-helper.js";
4
+ const e = /* @__PURE__ */ t(o, [["__scopeId", "data-v-6381bbdd"]]);
5
+ export {
6
+ e as default
7
+ };