dequel-editor 0.7.0 → 0.9.2

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,232 @@
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 {
24
- ":"
25
- Field { Identifier }
26
- Identifier { $[a-zA-Z_]+ ("." $[a-zA-Z_]+)* }
27
- Number { std.digit+ }
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+)? }
28
71
  String { '"' !["]* '"' }
72
+
73
+ ":"
74
+
75
+ @precedence { DynamicValue, DateLiteral, Number, Identifier }
76
+
77
+ identSegment { $[a-zA-Z_] $[a-zA-Z_0-9-]* }
78
+ Identifier { "/"? identSegment ($[./] identSegment)* }
79
+
29
80
  Comment { "#" (![
30
81
  ])* }
82
+
83
+ "(" ")" "{" "}" "[" "]" "," "-" "&&" "||"
31
84
  }
32
- `), n = {
33
- Condition: m.define(i.keyword),
34
- Field: m.define(i.propertyName),
85
+ `), t = {
86
+ Condition: f.define(i.keyword),
87
+ Field: f.define(i.propertyName),
35
88
  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;
89
+ Predicate: f.define(i.variableName),
90
+ Value: f.define(i.attributeValue),
91
+ Operator: f.define(i.operator),
92
+ DynamicValue: i.special(i.variableName)
93
+ }, R = B.define(), q = (e, n) => {
94
+ for (; n.parent; ) {
95
+ if (n.parent.name === e)
96
+ return n.parent;
97
+ n = n.parent;
44
98
  }
45
99
  return null;
46
100
  };
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)
101
+ async function z(e, n, a) {
102
+ let o = n;
103
+ for (const d of e) {
104
+ const r = o.fields[d];
105
+ if (r?.type !== "relationship" || !r.schema)
52
106
  return null;
53
- r = await t.get(a.schema);
107
+ o = await a.get(r.schema);
54
108
  }
55
- return r;
109
+ return o;
56
110
  }
57
- const z = k.define(), Z = q.define({
111
+ const T = j.define(), $ = w.define({
58
112
  create: () => ({ fields: {} }),
59
- update: (e, o) => {
60
- for (const t of o.effects)
61
- if (t.is(z))
62
- return t.value;
113
+ update: (e, n) => {
114
+ for (const a of n.effects)
115
+ if (a.is(T))
116
+ return a.value;
63
117
  return e;
64
118
  }
65
- }), _ = b.data.of({
119
+ }), H = b.data.of({
66
120
  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) => ({
121
+ const a = N(e.state).resolveInner(e.pos, -1), o = e.state.sliceDoc(a.from, e.pos), d = /[\w.]*$/.exec(o);
122
+ if (!d && !e.explicit) return null;
123
+ 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(":");
124
+ if (u && C && e.pos > C.to) {
125
+ const p = e.state.doc.sliceString(u.from, u.to), l = s?.fields[p]?.values;
126
+ if (l?.length) {
127
+ const g = l.map((c) => ({
74
128
  label: c,
75
129
  type: "value"
76
130
  }));
77
131
  return {
78
- from: a,
132
+ from: r,
79
133
  options: g
80
134
  };
81
135
  }
82
136
  }
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 $(
137
+ if (a.name === "Field" && s && Object.keys(s.fields).length) {
138
+ const p = e.state.doc.sliceString(a.from, e.pos), l = p.split(".");
139
+ if (l.length > 1 && h) {
140
+ const c = l.slice(0, -1), m = a.from + p.lastIndexOf(".") + 1, S = await z(
87
141
  c,
88
- l,
142
+ s,
89
143
  h
90
144
  );
91
- if (F) {
92
- const v = Object.entries(F.fields).map(([N, S]) => ({
93
- label: N,
94
- type: S.type,
95
- info: S.info
145
+ if (S) {
146
+ const V = Object.entries(S.fields).map(([D, O]) => ({
147
+ label: D,
148
+ type: O.type,
149
+ info: O.info
96
150
  }));
97
151
  return {
98
- from: f,
99
- options: v
152
+ from: m,
153
+ options: V
100
154
  };
101
155
  }
102
156
  return {
103
- from: f,
157
+ from: m,
104
158
  options: []
105
159
  };
106
160
  }
107
- const g = Object.entries(l.fields).map(([c, f]) => ({
161
+ const g = Object.entries(s.fields).map(([c, m]) => ({
108
162
  label: c,
109
- type: f.type,
110
- info: f.info
163
+ type: m.type,
164
+ info: m.info
111
165
  }));
112
166
  return {
113
- from: a,
167
+ from: r,
114
168
  options: g
115
169
  };
116
170
  }
117
- return t.name === "Field" ? {
118
- from: a,
171
+ return a.name === "Field" ? {
172
+ from: r,
119
173
  options: []
120
174
  } : null;
121
175
  }
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" },
176
+ }), G = A.define([
177
+ { tag: t.Condition, class: "cnd" },
178
+ { tag: t.Operator, class: "cnd-op" },
179
+ { tag: t.Value, class: "cnd-val" },
180
+ { tag: t.Command, class: "cnd-val cnd-cmd" },
181
+ { tag: t.Field, class: "cnd-fld" },
182
+ { tag: t.DynamicValue, class: "cnd-val cnd-dynamic" },
128
183
  { tag: i.string, class: "string" },
184
+ { tag: i.number, class: "cnd-val" },
129
185
  { tag: i.lineComment, class: "comment" }
130
- ]), R = j.configure({
186
+ ]), Z = Q.configure({
131
187
  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
188
+ E({
189
+ // Condition structure
190
+ "Condition/:": t.Operator,
191
+ "ExcludeCondition/:": t.Operator,
192
+ "Condition/Field/...": t.Field,
193
+ Field: t.Field,
194
+ // Command and values
195
+ "Command!": t.Command,
196
+ "Value!": t.Value,
197
+ "Separator!": t.Operator,
198
+ // Logical operators
199
+ "And Or": t.Operator,
200
+ // Comparison and range operators
201
+ "CompareOp Contains StartsWith EndsWith Not RangeSep": t.Operator,
202
+ // Special value types
203
+ DynamicValue: t.DynamicValue,
204
+ DateLiteral: i.number,
205
+ // Object blocks
206
+ "ObjectBlock/Identifier": t.Field,
207
+ // Comments
208
+ Comment: i.lineComment
141
209
  }),
142
- I.add({
143
- Query: (e) => e.column(e.node.from) + e.unit
210
+ v.add({
211
+ Query: (e) => e.column(e.node.from) + e.unit,
212
+ ObjectBlock: (e) => e.column(e.node.from) + e.unit
144
213
  }),
145
- V.add({
146
- Query: w
214
+ F.add({
215
+ Query: P,
216
+ ObjectBlock: P
147
217
  })
148
218
  ]
149
- }), b = O.define({
150
- parser: R,
219
+ }), b = I.define({
220
+ parser: Z,
151
221
  languageData: {}
152
222
  });
153
- function U() {
154
- return new E(b, [
155
- D(M),
156
- _
223
+ function X() {
224
+ return new L(b, [
225
+ k(G),
226
+ H
157
227
  ]);
158
228
  }
159
229
  export {
160
- U as DequelLang,
230
+ X as DequelLang,
161
231
  b as dequelParser
162
232
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dequel-editor",
3
- "version": "0.7.0",
3
+ "version": "0.9.2",
4
4
  "description": "CodeMirror-based editor for Dequel query language",
5
5
  "type": "module",
6
6
  "main": "./dist/dequel-editor.js",