@tellaro/tql 0.1.18 → 0.2.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.
@@ -1,30 +1,30 @@
1
- import { defineComponent as $, computed as v, ref as D, openBlock as i, createElementBlock as o, normalizeClass as f, createElementVNode as s, Fragment as h, toDisplayString as a, createCommentVNode as u, renderList as q, createVNode as P, unref as j } from "vue";
2
- import { generatePreview as A } from "../../src/semanticPreview.js";
3
- const F = {
1
+ import { defineComponent as E, computed as v, ref as B, openBlock as i, createElementBlock as o, normalizeClass as f, createElementVNode as s, Fragment as h, toDisplayString as a, createCommentVNode as u, renderList as q, createVNode as D, unref as P } from "vue";
2
+ import { generatePreview as j } from "../../src/semanticPreview.js";
3
+ const A = {
4
4
  key: 0,
5
5
  class: "tql-preview__empty"
6
- }, O = {
6
+ }, F = {
7
7
  key: 0,
8
8
  class: "tql-preview__complexity"
9
- }, V = { class: "tql-preview__field-count" }, K = {
9
+ }, O = { class: "tql-preview__field-count" }, V = {
10
10
  key: 1,
11
11
  class: "tql-preview__warnings"
12
- }, U = { class: "tql-preview__warning-icon" }, I = { class: "tql-preview__warning-text" }, M = {
12
+ }, K = { class: "tql-preview__warning-icon" }, U = { class: "tql-preview__warning-text" }, I = {
13
13
  key: 2,
14
14
  class: "tql-preview__suggestions"
15
- }, z = { class: "tql-preview__suggestions-list" }, H = {
15
+ }, M = { class: "tql-preview__suggestions-list" }, z = {
16
16
  key: 3,
17
17
  class: "tql-preview__tree"
18
- }, Q = { class: "tql-preview__tree-content" }, G = {
18
+ }, H = { class: "tql-preview__tree-content" }, Q = {
19
19
  key: 4,
20
20
  class: "tql-preview__fields"
21
- }, J = { class: "tql-preview__fields-list" }, R = ["onClick"], W = { class: "tql-preview__field-name" }, X = {
21
+ }, G = { class: "tql-preview__fields-list" }, J = ["onClick"], R = { class: "tql-preview__field-name" }, W = {
22
22
  key: 0,
23
23
  class: "tql-preview__field-mutators"
24
- }, Y = { class: "tql-preview__field-operator" }, Z = { class: "tql-preview__field-value" }, ee = ["title"], te = {
24
+ }, X = { class: "tql-preview__field-operator" }, Y = { class: "tql-preview__field-value" }, Z = ["title"], ee = {
25
25
  key: 5,
26
26
  class: "tql-preview__operators"
27
- }, ne = { class: "tql-preview__operators-list" }, le = $({
27
+ }, te = { class: "tql-preview__operators-list" }, ne = E({
28
28
  name: "TqlPreviewNode",
29
29
  props: {
30
30
  node: {
@@ -51,10 +51,9 @@ const F = {
51
51
  emits: ["toggle", "node-click"],
52
52
  setup(t, { emit: m }) {
53
53
  const _ = v(() => t.node.children && t.node.children.length > 0), y = v(() => {
54
- var r;
55
54
  if (t.node.type === "comparison") {
56
- const k = (r = t.node.mutators) != null && r.length ? ` | ${t.node.mutators.join(" | ")}` : "", C = n(t.node.value);
57
- return `${t.node.field}${k} ${t.node.operator} ${C}`;
55
+ const r = t.node.mutators?.length ? ` | ${t.node.mutators.join(" | ")}` : "", k = n(t.node.value);
56
+ return `${t.node.field}${r} ${t.node.operator} ${k}`;
58
57
  }
59
58
  return t.node.type;
60
59
  });
@@ -119,7 +118,7 @@ const F = {
119
118
  </div>
120
119
  </div>
121
120
  `
122
- }), re = /* @__PURE__ */ $({
121
+ }), se = /* @__PURE__ */ E({
123
122
  __name: "TqlPreview",
124
123
  props: {
125
124
  query: {},
@@ -132,7 +131,7 @@ const F = {
132
131
  },
133
132
  emits: ["field-click", "node-click"],
134
133
  setup(t, { emit: m }) {
135
- const _ = t, y = m, n = v(() => A(_.query)), g = v(() => !_.query.trim() || !n.value.logicTree), w = v(() => {
134
+ const _ = t, y = m, n = v(() => j(_.query)), g = v(() => !_.query.trim() || !n.value.logicTree), w = v(() => {
136
135
  const e = n.value.complexity.score;
137
136
  return {
138
137
  "tql-preview--low": e === "low",
@@ -143,20 +142,20 @@ const F = {
143
142
  low: "Low complexity",
144
143
  medium: "Medium complexity",
145
144
  high: "High complexity"
146
- })[n.value.complexity.score] || "Unknown"), p = D(/* @__PURE__ */ new Set());
145
+ })[n.value.complexity.score] || "Unknown"), p = B(/* @__PURE__ */ new Set());
147
146
  function r(e) {
148
147
  return p.value.has(e);
149
148
  }
150
149
  function k(e) {
151
150
  p.value.has(e) ? p.value.delete(e) : p.value.add(e);
152
151
  }
153
- function C(e) {
152
+ function T(e) {
154
153
  return e < _.maxExpandedDepth;
155
154
  }
156
- function E(e) {
157
- return e === null ? "null" : e === void 0 ? "" : typeof e == "string" ? `"${e}"` : Array.isArray(e) ? `[${e.map(E).join(", ")}]` : String(e);
155
+ function C(e) {
156
+ return e === null ? "null" : e === void 0 ? "" : typeof e == "string" ? `"${e}"` : Array.isArray(e) ? `[${e.map(C).join(", ")}]` : String(e);
158
157
  }
159
- function b(e) {
158
+ function $(e) {
160
159
  return {
161
160
  exact: "=",
162
161
  wildcard: "*",
@@ -167,87 +166,84 @@ const F = {
167
166
  cidr: "IP"
168
167
  }[e] || "?";
169
168
  }
170
- function N(e) {
169
+ function b(e) {
171
170
  return `tql-preview__match-type--${e}`;
172
171
  }
173
- function S(e) {
172
+ function N(e) {
174
173
  return `tql-preview__warning--${e}`;
175
174
  }
176
- function L(e) {
175
+ function S(e) {
177
176
  y("field-click", e);
178
177
  }
179
- function B(e) {
178
+ function L(e) {
180
179
  y("node-click", e);
181
180
  }
182
181
  return (e, d) => (i(), o("div", {
183
182
  class: f(["tql-preview", [w.value, { "tql-preview--compact": t.compact, "tql-preview--empty": g.value }]])
184
183
  }, [
185
- g.value ? (i(), o("div", F, [...d[0] || (d[0] = [
184
+ g.value ? (i(), o("div", A, [...d[0] || (d[0] = [
186
185
  s("span", { class: "tql-preview__empty-text" }, "Enter a query to see preview", -1)
187
186
  ])])) : (i(), o(h, { key: 1 }, [
188
- t.showComplexity ? (i(), o("div", O, [
187
+ t.showComplexity ? (i(), o("div", F, [
189
188
  s("span", {
190
189
  class: f(["tql-preview__complexity-badge", w.value])
191
190
  }, a(x.value), 3),
192
- s("span", V, a(n.value.fieldCount) + " field" + a(n.value.fieldCount !== 1 ? "s" : ""), 1)
191
+ s("span", O, a(n.value.fieldCount) + " field" + a(n.value.fieldCount !== 1 ? "s" : ""), 1)
193
192
  ])) : u("", !0),
194
- t.showComplexity && n.value.complexity.warnings.length > 0 ? (i(), o("div", K, [
193
+ t.showComplexity && n.value.complexity.warnings.length > 0 ? (i(), o("div", V, [
195
194
  (i(!0), o(h, null, q(n.value.complexity.warnings, (l, c) => (i(), o("div", {
196
195
  key: c,
197
- class: f(["tql-preview__warning", S(l.severity)])
196
+ class: f(["tql-preview__warning", N(l.severity)])
198
197
  }, [
199
- s("span", U, a(l.severity === "error" || l.severity === "warning" ? "!" : "i"), 1),
200
- s("span", I, a(l.message), 1)
198
+ s("span", K, a(l.severity === "error" || l.severity === "warning" ? "!" : "i"), 1),
199
+ s("span", U, a(l.message), 1)
201
200
  ], 2))), 128))
202
201
  ])) : u("", !0),
203
- t.showComplexity && n.value.complexity.suggestions.length > 0 ? (i(), o("div", M, [
202
+ t.showComplexity && n.value.complexity.suggestions.length > 0 ? (i(), o("div", I, [
204
203
  d[1] || (d[1] = s("div", { class: "tql-preview__suggestions-header" }, "Suggestions:", -1)),
205
- s("ul", z, [
204
+ s("ul", M, [
206
205
  (i(!0), o(h, null, q(n.value.complexity.suggestions, (l, c) => (i(), o("li", {
207
206
  key: c,
208
207
  class: "tql-preview__suggestion"
209
208
  }, a(l), 1))), 128))
210
209
  ])
211
210
  ])) : u("", !0),
212
- t.showLogicTree && n.value.logicTree ? (i(), o("div", H, [
211
+ t.showLogicTree && n.value.logicTree ? (i(), o("div", z, [
213
212
  d[2] || (d[2] = s("div", { class: "tql-preview__tree-header" }, "Query Structure", -1)),
214
- s("div", Q, [
215
- P(j(le), {
213
+ s("div", H, [
214
+ D(P(ne), {
216
215
  node: n.value.logicTree,
217
216
  depth: 0,
218
217
  "node-key": "root",
219
- "is-expanded": C(0) || r("root"),
218
+ "is-expanded": T(0) || r("root"),
220
219
  "auto-expand-depth": t.maxExpandedDepth,
221
220
  onToggle: k,
222
- onNodeClick: B
221
+ onNodeClick: L
223
222
  }, null, 8, ["node", "is-expanded", "auto-expand-depth"])
224
223
  ])
225
224
  ])) : u("", !0),
226
- t.showFieldUsage && n.value.fields.length > 0 ? (i(), o("div", G, [
225
+ t.showFieldUsage && n.value.fields.length > 0 ? (i(), o("div", Q, [
227
226
  d[3] || (d[3] = s("div", { class: "tql-preview__fields-header" }, "Fields Used", -1)),
228
- s("div", J, [
229
- (i(!0), o(h, null, q(n.value.fields, (l, c) => {
230
- var T;
231
- return i(), o("div", {
232
- key: c,
233
- class: "tql-preview__field",
234
- onClick: (ie) => L(l)
235
- }, [
236
- s("span", W, a(l.name), 1),
237
- (T = l.mutators) != null && T.length ? (i(), o("span", X, " | " + a(l.mutators.join(" | ")), 1)) : u("", !0),
238
- s("span", Y, a(l.operator), 1),
239
- s("span", Z, a(E(l.value)), 1),
240
- s("span", {
241
- class: f(["tql-preview__match-type", N(l.matchType)]),
242
- title: l.matchType
243
- }, a(b(l.matchType)), 11, ee)
244
- ], 8, R);
245
- }), 128))
227
+ s("div", G, [
228
+ (i(!0), o(h, null, q(n.value.fields, (l, c) => (i(), o("div", {
229
+ key: c,
230
+ class: "tql-preview__field",
231
+ onClick: (le) => S(l)
232
+ }, [
233
+ s("span", R, a(l.name), 1),
234
+ l.mutators?.length ? (i(), o("span", W, " | " + a(l.mutators.join(" | ")), 1)) : u("", !0),
235
+ s("span", X, a(l.operator), 1),
236
+ s("span", Y, a(C(l.value)), 1),
237
+ s("span", {
238
+ class: f(["tql-preview__match-type", b(l.matchType)]),
239
+ title: l.matchType
240
+ }, a($(l.matchType)), 11, Z)
241
+ ], 8, J))), 128))
246
242
  ])
247
243
  ])) : u("", !0),
248
- t.showOperatorSummary && Object.keys(n.value.operatorSummary).length > 0 ? (i(), o("div", te, [
244
+ t.showOperatorSummary && Object.keys(n.value.operatorSummary).length > 0 ? (i(), o("div", ee, [
249
245
  d[4] || (d[4] = s("div", { class: "tql-preview__operators-header" }, "Operators", -1)),
250
- s("div", ne, [
246
+ s("div", te, [
251
247
  (i(!0), o(h, null, q(n.value.operatorSummary, (l, c) => (i(), o("span", {
252
248
  key: c,
253
249
  class: "tql-preview__operator"
@@ -259,6 +255,6 @@ const F = {
259
255
  }
260
256
  });
261
257
  export {
262
- le as TqlPreviewNode,
263
- re as default
258
+ ne as TqlPreviewNode,
259
+ se as default
264
260
  };
@@ -1,6 +1,5 @@
1
1
  import { Ref, ComputedRef } from 'vue';
2
2
  import { QueryHistoryEntry, UseQueryHistoryOptions } from '../../src/types';
3
-
4
3
  export interface UseQueryHistoryReturn {
5
4
  /** Reactive array of all history entries */
6
5
  history: Ref<QueryHistoryEntry[]>;
@@ -106,10 +106,7 @@ function L(y) {
106
106
  if (!e.trim())
107
107
  return [...r.value];
108
108
  const t = e.toLowerCase();
109
- return r.value.filter((i) => {
110
- var a;
111
- return !!(i.query.toLowerCase().includes(t) || (a = i.label) != null && a.toLowerCase().includes(t));
112
- });
109
+ return r.value.filter((i) => !!(i.query.toLowerCase().includes(t) || i.label?.toLowerCase().includes(t)));
113
110
  }
114
111
  function E(e = 10, t = !1) {
115
112
  let i = [...r.value];
@@ -1,168 +1,158 @@
1
- import { useDebounceFn as O } from "@vueuse/core";
2
- import { ref as p, computed as T, watch as oe } from "vue";
3
- import { getCompletions as re, shouldTriggerCompletion as ue } from "../src/completionProvider.js";
4
- import { parseTql as le } from "../src/parser.js";
5
- import { findTokenAtPosition as R, tokenizeTql as ae } from "../src/tokenizer.js";
1
+ import { useDebounceFn as E } from "@vueuse/core";
2
+ import { ref as i, computed as m, watch as se } from "vue";
3
+ import { getCompletions as le, shouldTriggerCompletion as re } from "../src/completionProvider.js";
4
+ import { parseTql as ue } from "../src/parser.js";
5
+ import { findTokenAtPosition as W, tokenizeTql as ae } from "../src/tokenizer.js";
6
6
  import { validateTql as ie } from "../src/validator.js";
7
- function he(V) {
7
+ function ge(z) {
8
8
  const {
9
- modelValue: i,
10
- fieldSchema: u,
9
+ modelValue: u,
10
+ fieldSchema: I,
11
11
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
12
12
  snippets: ce,
13
13
  // Reserved for future snippet support
14
- fieldValues: y,
15
- validateOnInput: j = !0,
16
- debounceMs: Q = 300,
17
- completionDebounceMs: U = 50,
14
+ fieldValues: D,
15
+ validateOnInput: F = !0,
16
+ debounceMs: O = 300,
17
+ completionDebounceMs: R = 50,
18
18
  // Faster debounce for completions
19
- autocomplete: A = !0,
20
- onValidation: C,
21
- onParse: k
22
- } = V, v = p([]), w = p(null), m = p(null), c = p(0), g = p([]), f = p(!1), q = p(!1), _ = T(() => {
23
- var e;
24
- return ((e = m.value) == null ? void 0 : e.valid) ?? !0;
25
- }), b = T(() => {
26
- var e;
27
- return ((e = m.value) == null ? void 0 : e.errors) ?? [];
28
- }), P = T(() => {
29
- var e;
30
- return ((e = m.value) == null ? void 0 : e.warnings) ?? [];
31
- }), $ = T(() => b.value.length > 0), B = T(() => P.value.length > 0);
32
- function M() {
33
- return v.value = ae(i.value), v.value;
19
+ autocomplete: C = !0,
20
+ onValidation: j,
21
+ onParse: Q
22
+ } = z, c = i([]), k = i(null), p = i(null), a = i(0), f = i([]), d = i(!1), x = i(!1), U = m(() => p.value?.valid ?? !0), h = m(() => p.value?.errors ?? []), q = m(() => p.value?.warnings ?? []), _ = m(() => h.value.length > 0), $ = m(() => q.value.length > 0);
23
+ function A() {
24
+ return c.value = ae(u.value), c.value;
34
25
  }
35
- function G() {
36
- const e = le(i.value);
37
- return w.value = e, k == null || k(e), e;
26
+ function B() {
27
+ const e = ue(u.value);
28
+ return k.value = e, Q?.(e), e;
38
29
  }
39
- function E() {
40
- var s, r;
41
- q.value = !0;
42
- const e = (s = u == null ? void 0 : u.value) == null ? void 0 : s.map((l) => l.name), t = (r = u == null ? void 0 : u.value) == null ? void 0 : r.reduce(
43
- (l, d) => (l[d.name] = d.type, l),
30
+ function P() {
31
+ x.value = !0;
32
+ const e = I?.value?.map((t) => t.name), n = I?.value?.reduce(
33
+ (t, l) => (t[l.name] = l.type, t),
44
34
  {}
45
- ), n = ie(i.value, {
35
+ ), o = ie(u.value, {
46
36
  availableFields: e,
47
- fieldTypes: t,
37
+ fieldTypes: n,
48
38
  strictMode: !1
49
39
  });
50
- return m.value = n, q.value = !1, C == null || C(n), n;
40
+ return p.value = o, x.value = !1, j?.(o), o;
51
41
  }
52
- const H = O(E, Q), J = O(I, U);
53
- function I() {
54
- if (!A) {
55
- g.value = [], f.value = !1;
42
+ const G = E(P, O), H = E(g, R);
43
+ function g() {
44
+ if (!C) {
45
+ f.value = [], d.value = !1;
56
46
  return;
57
47
  }
58
- const e = re(
48
+ const e = le(
59
49
  {
60
- query: i.value,
61
- cursorPosition: c.value
50
+ query: u.value,
51
+ cursorPosition: a.value
62
52
  },
63
53
  {
64
- fields: u == null ? void 0 : u.value,
65
- fieldValues: y == null ? void 0 : y.value,
54
+ fields: I?.value,
55
+ fieldValues: D?.value,
66
56
  includeSnippets: !0,
67
57
  maxItems: 15
68
58
  }
69
59
  );
70
- g.value = e, f.value = e.length > 0;
60
+ f.value = e, d.value = e.length > 0;
71
61
  }
72
- function K() {
73
- I(), f.value = g.value.length > 0;
62
+ function J() {
63
+ g(), d.value = f.value.length > 0;
74
64
  }
75
- function W() {
76
- f.value = !1;
65
+ function w() {
66
+ d.value = !1;
77
67
  }
78
- function z(e) {
79
- M(), j && H(), A && ue(e, c.value) && (J(), g.value.length > 0 && (f.value = !0));
68
+ function V(e) {
69
+ A(), F && G(), C && re(e, a.value) && (H(), f.value.length > 0 && (d.value = !0));
80
70
  }
81
- function L(e) {
82
- c.value = e, I();
71
+ function K(e) {
72
+ a.value = e, g();
83
73
  }
84
- function N(e) {
85
- const t = i.value, n = c.value, s = R(v.value, n);
86
- let r = n, l = n;
87
- if (s && s.type !== "whitespace")
88
- r = s.start, l = s.end;
74
+ function L(e) {
75
+ const n = u.value, o = a.value, t = W(c.value, o);
76
+ let l = o, T = o;
77
+ if (t && t.type !== "whitespace")
78
+ l = t.start, T = t.end;
89
79
  else {
90
- const a = v.value.filter((o) => o.end <= n && o.type !== "whitespace");
91
- if (a.length > 0) {
92
- const o = a[a.length - 1];
93
- o.end === n && (r = o.start, l = o.end);
80
+ const r = c.value.filter((s) => s.end <= o && s.type !== "whitespace");
81
+ if (r.length > 0) {
82
+ const s = r[r.length - 1];
83
+ s.end === o && (l = s.start, T = s.end);
94
84
  }
95
85
  }
96
- const d = t.substring(0, r), ee = t.substring(l), x = [];
97
- let h = e.insertText;
86
+ const y = n.substring(0, l), ee = n.substring(T), b = [];
87
+ let v = e.insertText;
98
88
  const te = [...e.insertText.matchAll(/\$(\d+)/g)].sort(
99
- (a, o) => parseInt(a[1]) - parseInt(o[1])
89
+ (r, s) => parseInt(r[1]) - parseInt(s[1])
100
90
  );
101
- let D = 0;
102
- for (const a of te) {
103
- const o = h.indexOf(a[0]);
104
- if (o !== -1) {
105
- const F = r + o - D;
106
- x.push({
107
- start: F,
108
- end: F
91
+ let S = 0;
92
+ for (const r of te) {
93
+ const s = v.indexOf(r[0]);
94
+ if (s !== -1) {
95
+ const M = l + s - S;
96
+ b.push({
97
+ start: M,
98
+ end: M
109
99
  // Zero-width cursor position
110
- }), h = h.replace(a[0], ""), D += a[0].length;
100
+ }), v = v.replace(r[0], ""), S += r[0].length;
111
101
  }
112
102
  }
113
- const ne = d + h + ee, se = x.length > 0 ? x[0].start : r + h.length;
114
- return W(), { query: ne, newCursorPosition: se, placeholders: x };
103
+ const ne = y + v + ee, oe = b.length > 0 ? b[0].start : l + v.length;
104
+ return w(), { query: ne, newCursorPosition: oe, placeholders: b };
115
105
  }
116
- function X(e) {
117
- const t = i.value, n = c.value, s = t.substring(0, n), r = t.substring(n), d = s.length > 0 && !s.endsWith(" ") && !s.endsWith("(") ? " " : "";
118
- return s + d + e.insertText + r;
106
+ function N(e) {
107
+ const n = u.value, o = a.value, t = n.substring(0, o), l = n.substring(o), y = t.length > 0 && !t.endsWith(" ") && !t.endsWith("(") ? " " : "";
108
+ return t + y + e.insertText + l;
119
109
  }
120
- function Y() {
121
- return R(v.value, c.value);
110
+ function X() {
111
+ return W(c.value, a.value);
122
112
  }
123
- function Z(e) {
124
- return b.value.some((t) => e >= t.start && e < t.end);
113
+ function Y(e) {
114
+ return h.value.some((n) => e >= n.start && e < n.end);
125
115
  }
126
- function S(e) {
127
- return b.value.filter((t) => e >= t.start && e < t.end);
116
+ function Z(e) {
117
+ return h.value.filter((n) => e >= n.start && e < n.end);
128
118
  }
129
- return oe(
130
- i,
119
+ return se(
120
+ u,
131
121
  (e) => {
132
- e !== void 0 && z(e);
122
+ e !== void 0 && V(e);
133
123
  },
134
124
  { immediate: !0 }
135
125
  ), {
136
126
  // State
137
- tokens: v,
138
- parseResult: w,
139
- validationResult: m,
140
- cursorPosition: c,
141
- completionItems: g,
142
- showAutocomplete: f,
143
- isValidating: q,
127
+ tokens: c,
128
+ parseResult: k,
129
+ validationResult: p,
130
+ cursorPosition: a,
131
+ completionItems: f,
132
+ showAutocomplete: d,
133
+ isValidating: x,
144
134
  // Computed
145
- isValid: _,
146
- errors: b,
147
- warnings: P,
148
- hasErrors: $,
149
- hasWarnings: B,
135
+ isValid: U,
136
+ errors: h,
137
+ warnings: q,
138
+ hasErrors: _,
139
+ hasWarnings: $,
150
140
  // Methods
151
- tokenize: M,
152
- parse: G,
153
- validate: E,
154
- updateCompletions: I,
155
- triggerAutocomplete: K,
156
- hideAutocomplete: W,
157
- handleInput: z,
158
- handleCursorChange: L,
159
- insertCompletion: N,
160
- insertSnippet: X,
161
- getTokenAtCursor: Y,
162
- isPositionInError: Z,
163
- getErrorsAtPosition: S
141
+ tokenize: A,
142
+ parse: B,
143
+ validate: P,
144
+ updateCompletions: g,
145
+ triggerAutocomplete: J,
146
+ hideAutocomplete: w,
147
+ handleInput: V,
148
+ handleCursorChange: K,
149
+ insertCompletion: L,
150
+ insertSnippet: N,
151
+ getTokenAtCursor: X,
152
+ isPositionInError: Y,
153
+ getErrorsAtPosition: Z
164
154
  };
165
155
  }
166
156
  export {
167
- he as useTqlInput
157
+ ge as useTqlInput
168
158
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tellaro/tql",
3
- "version": "0.1.18",
3
+ "version": "0.2.0",
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,11 +23,17 @@
23
23
  "README.md"
24
24
  ],
25
25
  "scripts": {
26
+ "build": "vite build",
26
27
  "test": "vitest run",
27
28
  "test:watch": "vitest",
28
29
  "test:shared": "vitest run --grep 'shared-fixtures'",
29
30
  "test:e2e": "playwright test",
30
- "test:e2e:ui": "playwright test --ui"
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"
31
37
  },
32
38
  "repository": {
33
39
  "type": "git",
@@ -70,9 +76,9 @@
70
76
  "js-yaml": "^4.1.0",
71
77
  "jsdom": "^24.0.0",
72
78
  "typescript": "^5.3.0",
73
- "vite": "^5.0.0",
74
- "vite-plugin-dts": "^3.7.0",
75
- "vitest": "^1.0.0",
79
+ "vite": "^7.3.1",
80
+ "vite-plugin-dts": "^4.5.4",
81
+ "vitest": "^4.0.18",
76
82
  "vue": "^3.4.0",
77
83
  "vue-tsc": "^3.2.4"
78
84
  },
package/dist/style.css DELETED
@@ -1 +0,0 @@
1
- .tql-autocomplete-dropdown[data-v-e29dd6a7]{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-e29dd6a7]{overflow-y:auto;max-height:calc(var(--dropdown-max-height) - 60px)}.tql-completion-item[data-v-e29dd6a7]{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;cursor:pointer;transition:background-color .15s}.tql-completion-item[data-v-e29dd6a7]:hover,.tql-completion-item.selected[data-v-e29dd6a7]{background:var(--highlight-bg, #f0f0f0)}.tql-completion-icon[data-v-e29dd6a7]{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-e29dd6a7]{background:var(--blue-100, #e3f2fd);color:var(--blue-600, #1e88e5)}.tql-completion-icon.tql-completion-kind-operator[data-v-e29dd6a7]{background:var(--pink-100, #fce4ec);color:var(--pink-600, #d81b60)}.tql-completion-icon.tql-completion-kind-value[data-v-e29dd6a7]{background:var(--green-100, #e8f5e9);color:var(--green-600, #43a047)}.tql-completion-icon.tql-completion-kind-keyword[data-v-e29dd6a7]{background:var(--purple-100, #f3e5f5);color:var(--purple-600, #8e24aa)}.tql-completion-icon.tql-completion-kind-snippet[data-v-e29dd6a7]{background:var(--orange-100, #fff3e0);color:var(--orange-600, #fb8c00)}.tql-completion-icon.tql-completion-kind-mutator[data-v-e29dd6a7]{background:var(--cyan-100, #e0f7fa);color:var(--cyan-600, #00acc1)}.tql-completion-icon.tql-completion-kind-aggregation[data-v-e29dd6a7]{background:var(--indigo-100, #e8eaf6);color:var(--indigo-600, #3949ab)}.tql-completion-icon.tql-completion-kind-logicalOp[data-v-e29dd6a7]{background:var(--yellow-100, #fffde7);color:var(--yellow-700, #fbc02d)}.tql-completion-icon.tql-completion-kind-typeHint[data-v-e29dd6a7]{background:var(--teal-100, #e0f2f1);color:var(--teal-600, #00897b)}.tql-completion-icon.tql-completion-kind-visualization[data-v-e29dd6a7]{background:var(--red-100, #ffebee);color:var(--red-600, #e53935)}.tql-completion-content[data-v-e29dd6a7]{flex:1;display:flex;flex-direction:column;min-width:0}.tql-completion-label[data-v-e29dd6a7]{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-e29dd6a7]{font-size:.75rem;color:var(--text-color-secondary, #666);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tql-completion-kind-badge[data-v-e29dd6a7]{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-e29dd6a7]{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-preview[data-v-bae811e6]{font-family:ui-monospace,monospace;font-size:13px;line-height:1.5;padding:12px;border:1px solid var(--tql-preview-border, #e0e0e0);border-radius:6px;background:var(--tql-preview-bg, #fafafa)}.tql-preview--compact[data-v-bae811e6]{padding:8px;font-size:12px}.tql-preview--empty[data-v-bae811e6]{color:var(--tql-preview-muted, #888)}.tql-preview__empty[data-v-bae811e6]{text-align:center;padding:20px}.tql-preview__complexity[data-v-bae811e6]{display:flex;align-items:center;gap:12px;margin-bottom:12px}.tql-preview__complexity-badge[data-v-bae811e6]{padding:2px 8px;border-radius:4px;font-size:11px;font-weight:600;text-transform:uppercase}.tql-preview--low .tql-preview__complexity-badge[data-v-bae811e6]{background:var(--tql-preview-low-bg, #e8f5e9);color:var(--tql-preview-low-text, #2e7d32)}.tql-preview--medium .tql-preview__complexity-badge[data-v-bae811e6]{background:var(--tql-preview-medium-bg, #fff3e0);color:var(--tql-preview-medium-text, #e65100)}.tql-preview--high .tql-preview__complexity-badge[data-v-bae811e6]{background:var(--tql-preview-high-bg, #ffebee);color:var(--tql-preview-high-text, #c62828)}.tql-preview__field-count[data-v-bae811e6]{color:var(--tql-preview-muted, #666);font-size:12px}.tql-preview__warnings[data-v-bae811e6]{margin-bottom:12px}.tql-preview__warning[data-v-bae811e6]{display:flex;align-items:flex-start;gap:8px;padding:6px 8px;border-radius:4px;margin-bottom:4px}.tql-preview__warning--info[data-v-bae811e6]{background:var(--tql-preview-info-bg, #e3f2fd);color:var(--tql-preview-info-text, #1565c0)}.tql-preview__warning--warning[data-v-bae811e6]{background:var(--tql-preview-warning-bg, #fff3e0);color:var(--tql-preview-warning-text, #e65100)}.tql-preview__warning--error[data-v-bae811e6]{background:var(--tql-preview-error-bg, #ffebee);color:var(--tql-preview-error-text, #c62828)}.tql-preview__warning-icon[data-v-bae811e6]{font-weight:700;width:16px;text-align:center}.tql-preview__warning-text[data-v-bae811e6]{flex:1}.tql-preview__suggestions[data-v-bae811e6]{margin-bottom:12px;padding:8px;background:var(--tql-preview-suggestion-bg, #f5f5f5);border-radius:4px}.tql-preview__suggestions-header[data-v-bae811e6]{font-weight:600;margin-bottom:4px;color:var(--tql-preview-header, #333)}.tql-preview__suggestions-list[data-v-bae811e6]{margin:0;padding-left:20px}.tql-preview__suggestion[data-v-bae811e6]{color:var(--tql-preview-muted, #666);margin:2px 0}.tql-preview__tree[data-v-bae811e6]{margin-bottom:12px}.tql-preview__tree-header[data-v-bae811e6],.tql-preview__fields-header[data-v-bae811e6],.tql-preview__operators-header[data-v-bae811e6]{font-weight:600;margin-bottom:8px;color:var(--tql-preview-header, #333);font-size:12px;text-transform:uppercase;letter-spacing:.5px}.tql-preview__tree-content[data-v-bae811e6]{border:1px solid var(--tql-preview-tree-border, #e0e0e0);border-radius:4px;background:var(--tql-preview-tree-bg, #fff);padding:8px}.tql-preview__node[data-v-bae811e6]{margin:2px 0}.tql-preview__node-content[data-v-bae811e6]{display:flex;align-items:center;gap:4px;padding:2px 4px;border-radius:3px;cursor:pointer}.tql-preview__node-content[data-v-bae811e6]:hover{background:var(--tql-preview-node-hover, #f0f0f0)}.tql-preview__node-toggle[data-v-bae811e6]{width:16px;height:16px;border:none;background:var(--tql-preview-toggle-bg, #e0e0e0);border-radius:3px;cursor:pointer;font-size:12px;line-height:1;display:flex;align-items:center;justify-content:center}.tql-preview__node-toggle[data-v-bae811e6]:hover{background:var(--tql-preview-toggle-hover, #d0d0d0)}.tql-preview__node-toggle--leaf[data-v-bae811e6]{visibility:hidden}.tql-preview__node-type[data-v-bae811e6]{font-weight:600;color:var(--tql-preview-node-type, #666)}.tql-preview__node--and .tql-preview__node-type[data-v-bae811e6]{color:var(--tql-preview-and, #1976d2)}.tql-preview__node--or .tql-preview__node-type[data-v-bae811e6]{color:var(--tql-preview-or, #7b1fa2)}.tql-preview__node--not .tql-preview__node-type[data-v-bae811e6]{color:var(--tql-preview-not, #c62828)}.tql-preview__node--group .tql-preview__node-type[data-v-bae811e6]{color:var(--tql-preview-group, #666)}.tql-preview__node-label[data-v-bae811e6]{flex:1}.tql-preview__fields-list[data-v-bae811e6]{display:flex;flex-direction:column;gap:4px}.tql-preview__field[data-v-bae811e6]{display:flex;align-items:center;gap:6px;padding:4px 8px;background:var(--tql-preview-field-bg, #fff);border:1px solid var(--tql-preview-field-border, #e0e0e0);border-radius:4px;cursor:pointer}.tql-preview__field[data-v-bae811e6]:hover{background:var(--tql-preview-field-hover, #f5f5f5)}.tql-preview__field-name[data-v-bae811e6]{font-weight:600;color:var(--tql-preview-field-name, #1976d2)}.tql-preview__field-mutators[data-v-bae811e6]{color:var(--tql-preview-mutator, #7b1fa2)}.tql-preview__field-operator[data-v-bae811e6]{color:var(--tql-preview-operator, #666)}.tql-preview__field-value[data-v-bae811e6]{color:var(--tql-preview-value, #2e7d32)}.tql-preview__match-type[data-v-bae811e6]{margin-left:auto;padding:1px 4px;border-radius:3px;font-size:10px;font-weight:600;background:var(--tql-preview-match-bg, #f0f0f0)}.tql-preview__match-type--exact[data-v-bae811e6]{background:var(--tql-preview-match-exact-bg, #e8f5e9);color:var(--tql-preview-match-exact, #2e7d32)}.tql-preview__match-type--wildcard[data-v-bae811e6]{background:var(--tql-preview-match-wildcard-bg, #fff3e0);color:var(--tql-preview-match-wildcard, #e65100)}.tql-preview__match-type--regex[data-v-bae811e6]{background:var(--tql-preview-match-regex-bg, #fce4ec);color:var(--tql-preview-match-regex, #c2185b)}.tql-preview__match-type--range[data-v-bae811e6]{background:var(--tql-preview-match-range-bg, #e3f2fd);color:var(--tql-preview-match-range, #1565c0)}.tql-preview__match-type--cidr[data-v-bae811e6]{background:var(--tql-preview-match-cidr-bg, #f3e5f5);color:var(--tql-preview-match-cidr, #7b1fa2)}.tql-preview__operators-list[data-v-bae811e6]{display:flex;flex-wrap:wrap;gap:8px}.tql-preview__operator[data-v-bae811e6]{padding:2px 6px;background:var(--tql-preview-op-bg, #f0f0f0);border-radius:3px;font-size:11px}.tql-input-wrapper[data-v-c7135df3]{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-has-min-height[data-v-c7135df3],.tql-input-wrapper.tql-input-has-min-height .tql-input[data-v-c7135df3]{min-height:var(--tql-min-height)}.tql-input-wrapper.tql-input-focused[data-v-c7135df3]{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-c7135df3]{border-color:var(--red-500, #ef4444)}.tql-input-wrapper.tql-input-invalid.tql-input-focused[data-v-c7135df3]{box-shadow:0 0 0 2px var(--red-100, rgba(239, 68, 68, .2))}.tql-input-wrapper.tql-input-valid[data-v-c7135df3]{border-color:var(--tql-valid-color, var(--green-500, #22c55e))}.tql-input-wrapper.tql-input-valid.tql-input-focused[data-v-c7135df3]{box-shadow:0 0 0 2px var(--green-100, rgba(34, 197, 94, .2))}.tql-input-wrapper.tql-input-slow[data-v-c7135df3]{border-color:var(--tql-slow-color, var(--yellow-500, #eab308))}.tql-input-wrapper.tql-input-slow.tql-input-focused[data-v-c7135df3]{box-shadow:0 0 0 2px var(--yellow-100, rgba(234, 179, 8, .2))}.tql-slow-indicator[data-v-c7135df3]{color:var(--tql-slow-color, var(--yellow-500, #eab308));margin-left:4px;cursor:help}.tql-input-wrapper.tql-input-disabled[data-v-c7135df3]{opacity:.6;cursor:not-allowed}.tql-highlight-layer[data-v-c7135df3]{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-c7135df3]{overflow-y:auto}.tql-input[data-v-c7135df3]{flex:1;width:100%;padding:.5rem 8rem .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-c7135df3]{color:transparent;caret-color:var(--text-color, #333)}.tql-input[data-v-c7135df3]::placeholder{color:var(--text-color-secondary, #666);opacity:.7}.tql-input[data-v-c7135df3]:disabled{cursor:not-allowed}.tql-token-field[data-v-c7135df3]{color:var(--tql-field-color, var(--blue-600, #2563eb))}.tql-token-operator[data-v-c7135df3]{color:var(--tql-operator-color, var(--pink-600, #db2777));font-weight:500}.tql-token-logicalOp[data-v-c7135df3]{color:var(--tql-logical-color, var(--purple-600, #9333ea));font-weight:600}.tql-token-collectionOp[data-v-c7135df3]{color:var(--tql-collection-color, var(--indigo-600, #4f46e5));font-weight:600}.tql-token-string[data-v-c7135df3]{color:var(--tql-string-color, var(--green-600, #16a34a))}.tql-token-number[data-v-c7135df3]{color:var(--tql-number-color, var(--orange-600, #ea580c))}.tql-token-boolean[data-v-c7135df3]{color:var(--tql-boolean-color, var(--cyan-600, #0891b2))}.tql-token-null[data-v-c7135df3]{color:var(--tql-null-color, var(--gray-500, #6b7280));font-style:italic}.tql-token-mutator[data-v-c7135df3]{color:var(--tql-mutator-color, var(--teal-600, #0d9488));font-style:italic}.tql-token-aggregation[data-v-c7135df3]{color:var(--tql-aggregation-color, var(--indigo-600, #4f46e5))}.tql-token-keyword[data-v-c7135df3]{color:var(--tql-keyword-color, var(--purple-500, #a855f7))}.tql-token-typeHint[data-v-c7135df3]{color:var(--tql-typehint-color, var(--teal-500, #14b8a6))}.tql-token-visualization[data-v-c7135df3]{color:var(--tql-viz-color, var(--red-500, #ef4444))}.tql-token-arrow[data-v-c7135df3]{color:var(--tql-arrow-color, var(--gray-600, #4b5563));font-weight:600}.tql-token-doubleColon[data-v-c7135df3]{color:var(--tql-colon-color, var(--gray-500, #6b7280))}.tql-token-paren[data-v-c7135df3],.tql-token-bracket[data-v-c7135df3]{color:var(--tql-bracket-color, var(--gray-600, #4b5563))}.tql-token-error[data-v-c7135df3]{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-c7135df3]{background-color:var(--red-50, #fef2f2)}.tql-token-unknown[data-v-c7135df3]{color:var(--text-color-secondary, #666)}.tql-validation-icon[data-v-c7135df3]{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-c7135df3]{top:.75rem;transform:none}.tql-icon-valid[data-v-c7135df3]{color:var(--green-500, #22c55e)}.tql-icon-invalid[data-v-c7135df3]{color:var(--red-500, #ef4444)}.tql-icon-clickable[data-v-c7135df3]{cursor:pointer;transition:transform .2s}.tql-icon-clickable[data-v-c7135df3]:hover{transform:scale(1.2)}.tql-icon-clickable[data-v-c7135df3]:focus{outline:2px solid var(--primary-color, #3b82f6);outline-offset:2px;border-radius:50%}.tql-snippet-button[data-v-c7135df3]{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-c7135df3]:hover{color:var(--primary-color, #3b82f6);background:var(--surface-100, #f5f5f5)}.tql-input-multiline .tql-snippet-button[data-v-c7135df3]{top:.75rem;transform:none}.tql-input-resizable-textarea[data-v-c7135df3]{resize:vertical;min-height:80px}.tql-input-wrapper.tql-input-resizable[data-v-c7135df3]{height:auto}.tql-input-wrapper.tql-input-resizable .tql-highlight-layer[data-v-c7135df3]{height:100%}.tql-validation-messages[data-v-c7135df3]{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-input-autocomplete-active .tql-validation-messages[data-v-c7135df3],.tql-input-autocomplete-active .tql-complexity-warnings[data-v-c7135df3],.tql-input-autocomplete-active .tql-history-dropdown[data-v-c7135df3],.tql-input-autocomplete-active .tql-preview-panel[data-v-c7135df3]{display:none!important}.tql-error-message[data-v-c7135df3]{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-c7135df3]{margin-top:.125rem;font-size:.75rem}.tql-error-suggestion[data-v-c7135df3]{display:block;color:var(--text-color-secondary, #666);font-style:italic;margin-left:1.25rem}.sr-only[data-v-c7135df3]{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.tql-toolbar[data-v-c7135df3]{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:.25rem}.tql-input-multiline .tql-toolbar[data-v-c7135df3]{top:.5rem;transform:none}.tql-toolbar-button[data-v-c7135df3]{padding:.25rem;border:none;background:transparent;color:var(--text-color-secondary, #666);cursor:pointer;border-radius:var(--border-radius, 4px);transition:color .2s,background-color .2s;display:flex;align-items:center;justify-content:center}.tql-toolbar-button[data-v-c7135df3]:hover{color:var(--primary-color, #3b82f6);background:var(--surface-100, #f5f5f5)}.tql-toolbar-button--active[data-v-c7135df3]{color:var(--primary-color, #3b82f6);background:var(--primary-100, rgba(59, 130, 246, .1))}.tql-validation-status[data-v-c7135df3]{display:flex;align-items:center}.tql-complexity-badge[data-v-c7135df3]{display:flex;align-items:center;gap:.25rem;padding:.125rem .5rem;border-radius:9999px;font-size:.625rem;font-weight:600;text-transform:uppercase;letter-spacing:.025em}.tql-complexity-low[data-v-c7135df3]{background:var(--green-100, #dcfce7);color:var(--green-700, #15803d)}.tql-complexity-medium[data-v-c7135df3]{background:var(--yellow-100, #fef9c3);color:var(--yellow-700, #a16207)}.tql-complexity-high[data-v-c7135df3]{background:var(--red-100, #fee2e2);color:var(--red-700, #b91c1c)}.tql-complexity-count[data-v-c7135df3]{display:inline-flex;align-items:center;justify-content:center;min-width:1rem;height:1rem;padding:0 .25rem;border-radius:9999px;background:currentColor;color:#fff;font-size:.5rem}.tql-complexity-low .tql-complexity-count[data-v-c7135df3]{background:var(--green-600, #16a34a)}.tql-complexity-medium .tql-complexity-count[data-v-c7135df3]{background:var(--yellow-600, #ca8a04)}.tql-complexity-high .tql-complexity-count[data-v-c7135df3]{background:var(--red-600, #dc2626)}.tql-complexity-warnings[data-v-c7135df3]{position:absolute;top:100%;left:0;right:0;margin-top:.25rem;background:var(--surface-overlay, #fff);border:1px solid var(--surface-border, #e0e0e0);border-radius:var(--border-radius, 6px);padding:.5rem;z-index:9;box-shadow:0 2px 8px #0000001a}.tql-complexity-warning[data-v-c7135df3]{display:flex;align-items:flex-start;gap:.5rem;padding:.25rem 0;font-size:.75rem}.tql-complexity-warning i[data-v-c7135df3]{margin-top:.125rem;font-size:.75rem}.tql-complexity-warning--info[data-v-c7135df3]{color:var(--blue-600, #2563eb)}.tql-complexity-warning--warning[data-v-c7135df3]{color:var(--yellow-600, #ca8a04)}.tql-complexity-warning--error[data-v-c7135df3]{color:var(--red-600, #dc2626)}.tql-complexity-suggestions[data-v-c7135df3]{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--surface-border, #e0e0e0)}.tql-complexity-suggestion[data-v-c7135df3]{display:flex;align-items:flex-start;gap:.5rem;padding:.25rem 0;font-size:.75rem;color:var(--text-color-secondary, #666)}.tql-complexity-suggestion i[data-v-c7135df3]{color:var(--yellow-500, #eab308)}.tql-history-dropdown[data-v-c7135df3]{position:absolute;top:100%;left:0;right:0;margin-top:.25rem;background:var(--surface-overlay, #fff);border:1px solid var(--surface-border, #e0e0e0);border-radius:var(--border-radius, 6px);z-index:20;box-shadow:0 4px 12px #00000026;max-height:300px;overflow:hidden;display:flex;flex-direction:column}.tql-history-header[data-v-c7135df3]{padding:.5rem;border-bottom:1px solid var(--surface-border, #e0e0e0)}.tql-history-search[data-v-c7135df3]{width:100%;padding:.375rem .5rem;border:1px solid var(--surface-border, #e0e0e0);border-radius:var(--border-radius, 4px);font-size:.75rem;outline:none}.tql-history-search[data-v-c7135df3]:focus{border-color:var(--primary-color, #3b82f6)}.tql-history-list[data-v-c7135df3]{overflow-y:auto;flex:1}.tql-history-item[data-v-c7135df3]{display:flex;align-items:flex-start;gap:.5rem;padding:.5rem;cursor:pointer;border-bottom:1px solid var(--surface-50, #f9fafb);transition:background-color .15s}.tql-history-item[data-v-c7135df3]:hover{background:var(--surface-100, #f5f5f5)}.tql-history-item--favorite[data-v-c7135df3]{background:var(--yellow-50, #fefce8)}.tql-history-item--favorite[data-v-c7135df3]:hover{background:var(--yellow-100, #fef9c3)}.tql-history-favorite[data-v-c7135df3]{padding:.125rem;border:none;background:transparent;color:var(--text-color-secondary, #999);cursor:pointer;flex-shrink:0}.tql-history-favorite[data-v-c7135df3]:hover,.tql-history-item--favorite .tql-history-favorite[data-v-c7135df3]{color:var(--yellow-500, #eab308)}.tql-history-content[data-v-c7135df3]{flex:1;min-width:0}.tql-history-label[data-v-c7135df3]{font-size:.6875rem;font-weight:600;color:var(--text-color, #333);margin-bottom:.125rem}.tql-history-query[data-v-c7135df3]{font-family:Courier New,monospace;font-size:.6875rem;color:var(--text-color-secondary, #666);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tql-history-time[data-v-c7135df3]{font-size:.625rem;color:var(--text-color-secondary, #999);flex-shrink:0}.tql-history-empty[data-v-c7135df3]{padding:1rem;text-align:center;color:var(--text-color-secondary, #666);font-size:.75rem}.tql-preview-panel[data-v-c7135df3]{position:absolute;top:100%;left:0;right:0;margin-top:.25rem;background:var(--surface-overlay, #fff);border:1px solid var(--surface-border, #e0e0e0);border-radius:var(--border-radius, 6px);z-index:15;box-shadow:0 4px 12px #00000026;max-height:400px;overflow:hidden;display:flex;flex-direction:column}.tql-preview-header[data-v-c7135df3]{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;border-bottom:1px solid var(--surface-border, #e0e0e0);font-size:.75rem;font-weight:600;color:var(--text-color, #333)}.tql-preview-close[data-v-c7135df3]{padding:.125rem;border:none;background:transparent;color:var(--text-color-secondary, #666);cursor:pointer;border-radius:var(--border-radius, 4px)}.tql-preview-close[data-v-c7135df3]:hover{background:var(--surface-100, #f5f5f5);color:var(--text-color, #333)}.tql-preview-panel[data-v-c7135df3] .tql-preview{border:none;border-radius:0;max-height:350px;overflow-y:auto}.tql-validation-messages-portal{position:fixed;top:var(--tql-msg-top, 0);left:var(--tql-msg-left, 0);width:var(--tql-msg-width, auto);z-index:9998;background:var(--surface-overlay, #fff);border:2px solid var(--red-500, #ef4444);border-radius:var(--border-radius, 6px);padding:.5rem;box-shadow:0 4px 12px #00000026}.tql-validation-messages-portal .tql-error-message{display:flex;align-items:flex-start;gap:.5rem;padding:.25rem 0;font-size:.75rem;color:var(--red-600, #dc2626)}.tql-validation-messages-portal .tql-error-message i{margin-top:.125rem;font-size:.75rem}.tql-validation-messages-portal .tql-error-suggestion{display:block;color:var(--text-color-secondary, #6b7280);font-style:italic;margin-left:1.25rem}