dequel-editor 0.7.0 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,162 +1,231 @@
1
- import { syntaxTree as P, LRLanguage as O, indentNodeProp as I, foldNodeProp as V, foldInside as w, HighlightStyle as A, LanguageSupport as E, syntaxHighlighting as D } from "@codemirror/language";
2
- import { Tag as m, tags as i, styleTags as L } from "@lezer/highlight";
3
- import { buildParser as Q } from "@lezer/generator";
4
- import { Facet as T, StateEffect as k, StateField as q } from "@codemirror/state";
5
- const j = Q(`
1
+ import { syntaxTree as N, LRLanguage as I, indentNodeProp as v, foldNodeProp as F, foldInside as P, HighlightStyle as A, LanguageSupport as L, syntaxHighlighting as k } from "@codemirror/language";
2
+ import { tags as i, Tag as f, styleTags as E } from "@lezer/highlight";
3
+ import { buildParser as W } from "@lezer/generator";
4
+ import { Facet as B, StateEffect as j, StateField as w } from "@codemirror/state";
5
+ const Q = W(`
6
6
  @top QueryList { Query }
7
- @skip { "
7
+ @skip { " " | " " | "
8
8
  " | Comment }
9
+ @detectDelim
9
10
 
10
11
  Query {
11
- anyCondition ((" " | " ")+ anyCondition)*
12
+ queryElement+
12
13
  }
13
14
 
14
- anyCondition { Condition | ExcludeCondition }
15
- Condition { Field ":" Predicate }
16
- ExcludeCondition { "-" Field ":" Predicate }
15
+ queryElement {
16
+ logicalOp | Condition | ExcludeCondition | Group | ObjectBlock
17
+ }
18
+
19
+ logicalOp { And | Or }
20
+
21
+ And { "&&" | andWord }
22
+ Or { "||" | orWord }
23
+ andWord[@name=And] { @specialize<Identifier, "AND"> | @specialize<Identifier, "and"> }
24
+ orWord[@name=Or] { @specialize<Identifier, "OR"> | @specialize<Identifier, "or"> }
25
+
26
+ Group { "(" Query ")" }
27
+
28
+ ObjectBlock { Identifier "{" Query "}" }
29
+
30
+ Condition { field ":" Predicate }
31
+ ExcludeCondition { "-" field ":" Predicate }
32
+
33
+ field[@name=Field] { Identifier }
34
+
35
+ Predicate {
36
+ NegatedPredicate |
37
+ RangePredicate |
38
+ ComparisonPredicate |
39
+ BracketPredicate |
40
+ ShorthandPredicate |
41
+ Command |
42
+ SimplePredicate
43
+ }
44
+
45
+ NegatedPredicate { Not (ComparisonPredicate | ShorthandPredicate | SimplePredicate) }
46
+ ComparisonPredicate { CompareOp Value }
47
+ RangePredicate { Value RangeSep Value }
48
+ BracketPredicate { "[" Value ("," Value)* "]" }
49
+ ShorthandPredicate { (Contains | StartsWith | EndsWith) Value }
50
+ SimplePredicate { Value }
51
+
52
+ Command { Identifier ~ambig "(" ArgList? ")" }
53
+ ArgList { Argument ("," Argument)* }
54
+ Argument { Identifier | Number | String | DateLiteral | DynamicValue }
17
55
 
18
- Predicate { Value | Command }
19
- Command { Identifier "(" Argument ("," Argument)* ")" }
20
- Argument { Identifier | Number | String }
21
- Value { Identifier | Number | String }
56
+ Value { DynamicValue | DateLiteral | Number | String | Identifier ~ambig }
22
57
 
23
58
  @tokens {
59
+ CompareOp { ">=" | "<=" | ">" | "<" }
60
+ RangeSep { ".." }
61
+
62
+ Contains { "*" }
63
+ StartsWith { "^" }
64
+ EndsWith { "$" }
65
+ Not { "!" }
66
+
67
+ DynamicValue { "@" ("today" | "tomorrow" | "yesterday" | "this-year" | "this-month-start" | "this-month-end" | "this-month") }
68
+ DateLiteral { std.digit std.digit std.digit std.digit "-" std.digit std.digit ("-" std.digit std.digit)? }
69
+
70
+ Number { "-"? std.digit+ ("." std.digit+)? }
71
+ String { '"' !["]* '"' }
72
+
24
73
  ":"
25
- Field { Identifier }
74
+
75
+ @precedence { DynamicValue, DateLiteral, Number, Identifier }
76
+
26
77
  Identifier { $[a-zA-Z_]+ ("." $[a-zA-Z_]+)* }
27
- Number { std.digit+ }
28
- String { '"' !["]* '"' }
78
+
29
79
  Comment { "#" (![
30
80
  ])* }
81
+
82
+ "(" ")" "{" "}" "[" "]" "," "-" "&&" "||"
31
83
  }
32
- `), n = {
33
- Condition: m.define(i.keyword),
34
- Field: m.define(i.propertyName),
84
+ `), t = {
85
+ Condition: f.define(i.keyword),
86
+ Field: f.define(i.propertyName),
35
87
  Command: i.function(i.variableName),
36
- Predicate: m.define(i.variableName),
37
- Value: m.define(i.attributeValue),
38
- Operator: m.define(i.operator)
39
- }, B = T.define(), H = (e, o) => {
40
- for (; o.parent; ) {
41
- if (o.parent.name === e)
42
- return o.parent;
43
- o = o.parent;
88
+ Predicate: f.define(i.variableName),
89
+ Value: f.define(i.attributeValue),
90
+ Operator: f.define(i.operator),
91
+ DynamicValue: i.special(i.variableName)
92
+ }, R = B.define(), q = (e, n) => {
93
+ for (; n.parent; ) {
94
+ if (n.parent.name === e)
95
+ return n.parent;
96
+ n = n.parent;
44
97
  }
45
98
  return null;
46
99
  };
47
- async function $(e, o, t) {
48
- let r = o;
49
- for (const s of e) {
50
- const a = r.fields[s];
51
- if (a?.type !== "relationship" || !a.schema)
100
+ async function z(e, n, a) {
101
+ let o = n;
102
+ for (const d of e) {
103
+ const r = o.fields[d];
104
+ if (r?.type !== "relationship" || !r.schema)
52
105
  return null;
53
- r = await t.get(a.schema);
106
+ o = await a.get(r.schema);
54
107
  }
55
- return r;
108
+ return o;
56
109
  }
57
- const z = k.define(), Z = q.define({
110
+ const T = j.define(), $ = w.define({
58
111
  create: () => ({ fields: {} }),
59
- update: (e, o) => {
60
- for (const t of o.effects)
61
- if (t.is(z))
62
- return t.value;
112
+ update: (e, n) => {
113
+ for (const a of n.effects)
114
+ if (a.is(T))
115
+ return a.value;
63
116
  return e;
64
117
  }
65
- }), _ = b.data.of({
118
+ }), H = b.data.of({
66
119
  autocomplete: async (e) => {
67
- const t = P(e.state).resolveInner(e.pos, -1), r = e.state.sliceDoc(t.from, e.pos), s = /[\w.]*$/.exec(r);
68
- if (!s && !e.explicit) return null;
69
- const a = s ? t.from + s.index : e.pos, l = e.state.field(Z, !1), h = e.state.facet(B)[0]?.schemaCache, C = H("Condition", t), u = C?.getChild("Field"), y = C?.getChild(":");
70
- if (u && y && e.pos > y.to) {
71
- const p = e.state.doc.sliceString(u.from, u.to), d = l?.fields[p]?.values;
72
- if (d?.length) {
73
- const g = d.map((c) => ({
120
+ const a = N(e.state).resolveInner(e.pos, -1), o = e.state.sliceDoc(a.from, e.pos), d = /[\w.]*$/.exec(o);
121
+ if (!d && !e.explicit) return null;
122
+ const r = d ? a.from + d.index : e.pos, s = e.state.field($, !1), h = e.state.facet(R)[0]?.schemaCache, y = q("Condition", a), u = y?.getChild("Field"), C = y?.getChild(":");
123
+ if (u && C && e.pos > C.to) {
124
+ const p = e.state.doc.sliceString(u.from, u.to), l = s?.fields[p]?.values;
125
+ if (l?.length) {
126
+ const g = l.map((c) => ({
74
127
  label: c,
75
128
  type: "value"
76
129
  }));
77
130
  return {
78
- from: a,
131
+ from: r,
79
132
  options: g
80
133
  };
81
134
  }
82
135
  }
83
- if (t.name === "Field" && l && Object.keys(l.fields).length) {
84
- const p = e.state.doc.sliceString(t.from, e.pos), d = p.split(".");
85
- if (d.length > 1 && h) {
86
- const c = d.slice(0, -1), f = t.from + p.lastIndexOf(".") + 1, F = await $(
136
+ if (a.name === "Field" && s && Object.keys(s.fields).length) {
137
+ const p = e.state.doc.sliceString(a.from, e.pos), l = p.split(".");
138
+ if (l.length > 1 && h) {
139
+ const c = l.slice(0, -1), m = a.from + p.lastIndexOf(".") + 1, O = await z(
87
140
  c,
88
- l,
141
+ s,
89
142
  h
90
143
  );
91
- if (F) {
92
- const v = Object.entries(F.fields).map(([N, S]) => ({
93
- label: N,
144
+ if (O) {
145
+ const V = Object.entries(O.fields).map(([D, S]) => ({
146
+ label: D,
94
147
  type: S.type,
95
148
  info: S.info
96
149
  }));
97
150
  return {
98
- from: f,
99
- options: v
151
+ from: m,
152
+ options: V
100
153
  };
101
154
  }
102
155
  return {
103
- from: f,
156
+ from: m,
104
157
  options: []
105
158
  };
106
159
  }
107
- const g = Object.entries(l.fields).map(([c, f]) => ({
160
+ const g = Object.entries(s.fields).map(([c, m]) => ({
108
161
  label: c,
109
- type: f.type,
110
- info: f.info
162
+ type: m.type,
163
+ info: m.info
111
164
  }));
112
165
  return {
113
- from: a,
166
+ from: r,
114
167
  options: g
115
168
  };
116
169
  }
117
- return t.name === "Field" ? {
118
- from: a,
170
+ return a.name === "Field" ? {
171
+ from: r,
119
172
  options: []
120
173
  } : null;
121
174
  }
122
- }), M = A.define([
123
- { tag: n.Condition, class: "cnd" },
124
- { tag: n.Operator, class: "cnd-op" },
125
- { tag: n.Value, class: "cnd-val" },
126
- { tag: n.Command, class: "cnd-val cnd-cmd" },
127
- { tag: n.Field, class: "cnd-fld" },
175
+ }), G = A.define([
176
+ { tag: t.Condition, class: "cnd" },
177
+ { tag: t.Operator, class: "cnd-op" },
178
+ { tag: t.Value, class: "cnd-val" },
179
+ { tag: t.Command, class: "cnd-val cnd-cmd" },
180
+ { tag: t.Field, class: "cnd-fld" },
181
+ { tag: t.DynamicValue, class: "cnd-val cnd-dynamic" },
128
182
  { tag: i.string, class: "string" },
183
+ { tag: i.number, class: "cnd-val" },
129
184
  { tag: i.lineComment, class: "comment" }
130
- ]), R = j.configure({
185
+ ]), Z = Q.configure({
131
186
  props: [
132
- L({
133
- "Condition/:": n.Operator,
134
- "ExcludeCondition/:": n.Operator,
135
- "Condition/Field/...": n.Field,
136
- "Command!": n.Command,
137
- "Separator!": n.Operator,
138
- Comment: i.lineComment,
139
- Field: n.Field,
140
- "Value!": n.Value
187
+ E({
188
+ // Condition structure
189
+ "Condition/:": t.Operator,
190
+ "ExcludeCondition/:": t.Operator,
191
+ "Condition/Field/...": t.Field,
192
+ Field: t.Field,
193
+ // Command and values
194
+ "Command!": t.Command,
195
+ "Value!": t.Value,
196
+ "Separator!": t.Operator,
197
+ // Logical operators
198
+ "And Or": t.Operator,
199
+ // Comparison and range operators
200
+ "CompareOp Contains StartsWith EndsWith Not RangeSep": t.Operator,
201
+ // Special value types
202
+ DynamicValue: t.DynamicValue,
203
+ DateLiteral: i.number,
204
+ // Object blocks
205
+ "ObjectBlock/Identifier": t.Field,
206
+ // Comments
207
+ Comment: i.lineComment
141
208
  }),
142
- I.add({
143
- Query: (e) => e.column(e.node.from) + e.unit
209
+ v.add({
210
+ Query: (e) => e.column(e.node.from) + e.unit,
211
+ ObjectBlock: (e) => e.column(e.node.from) + e.unit
144
212
  }),
145
- V.add({
146
- Query: w
213
+ F.add({
214
+ Query: P,
215
+ ObjectBlock: P
147
216
  })
148
217
  ]
149
- }), b = O.define({
150
- parser: R,
218
+ }), b = I.define({
219
+ parser: Z,
151
220
  languageData: {}
152
221
  });
153
- function U() {
154
- return new E(b, [
155
- D(M),
156
- _
222
+ function X() {
223
+ return new L(b, [
224
+ k(G),
225
+ H
157
226
  ]);
158
227
  }
159
228
  export {
160
- U as DequelLang,
229
+ X as DequelLang,
161
230
  b as dequelParser
162
231
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dequel-editor",
3
- "version": "0.7.0",
3
+ "version": "0.8.5",
4
4
  "description": "CodeMirror-based editor for Dequel query language",
5
5
  "type": "module",
6
6
  "main": "./dist/dequel-editor.js",