dequel-editor 0.4.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.
- package/README.md +127 -0
- package/dist/de-ChXK8h97.js +24 -0
- package/dist/dequel-editor.js +21070 -0
- package/dist/dequel-lang.js +215 -0
- package/dist/vite.svg +1 -0
- package/package.json +113 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { syntaxTree as u, LRLanguage as N, indentNodeProp as P, foldNodeProp as k, foldInside as D, HighlightStyle as E, LanguageSupport as O, syntaxHighlighting as w } from "@codemirror/language";
|
|
2
|
+
import { Tag as l, tags as r, styleTags as V } from "@lezer/highlight";
|
|
3
|
+
import { ViewPlugin as q, Decoration as m } from "@codemirror/view";
|
|
4
|
+
import { buildParser as A } from "@lezer/generator";
|
|
5
|
+
import { Facet as L, StateEffect as Q, StateField as T } from "@codemirror/state";
|
|
6
|
+
const B = A(`
|
|
7
|
+
@top QueryList { Query }
|
|
8
|
+
@skip { "
|
|
9
|
+
" | Comment }
|
|
10
|
+
|
|
11
|
+
Query {
|
|
12
|
+
anyCondition ((" " | " ")+ anyCondition)*
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
anyCondition { Condition | ExcludeCondition | IgnoredCondition }
|
|
16
|
+
Condition { Field ":" Predicate }
|
|
17
|
+
ExcludeCondition { "-" Field ":" Predicate }
|
|
18
|
+
IgnoredCondition { "!" Field ":" Predicate }
|
|
19
|
+
|
|
20
|
+
Predicate { Regex | Value | Command }
|
|
21
|
+
Command { Identifier "(" Argument ("," Argument)* ")" }
|
|
22
|
+
Argument { Identifier | Number | String }
|
|
23
|
+
Value { Identifier | Number | String }
|
|
24
|
+
|
|
25
|
+
@tokens {
|
|
26
|
+
":"
|
|
27
|
+
Field { Identifier }
|
|
28
|
+
Function { Identifier }
|
|
29
|
+
Identifier { $[a-zA-Z_]+ ("." $[a-zA-Z_]+)* }
|
|
30
|
+
Number { std.digit+ }
|
|
31
|
+
String { '"' !["]* '"' }
|
|
32
|
+
Regex { RegexContent (RegexFlag)* }
|
|
33
|
+
RegexFlag { std.asciiLetter+ }
|
|
34
|
+
RegexContent { "/" (![/] | "\\/")* "/" }
|
|
35
|
+
Comment { "#" (![
|
|
36
|
+
])* }
|
|
37
|
+
}
|
|
38
|
+
`), n = {
|
|
39
|
+
Condition: l.define(r.keyword),
|
|
40
|
+
Field: l.define(r.propertyName),
|
|
41
|
+
Command: r.function(r.variableName),
|
|
42
|
+
Predicate: l.define(r.variableName),
|
|
43
|
+
Value: l.define(r.attributeValue),
|
|
44
|
+
Operator: l.define(r.operator),
|
|
45
|
+
Regex: l.define(r.regexp),
|
|
46
|
+
RegexContent: l.define(r.regexp)
|
|
47
|
+
}, H = [
|
|
48
|
+
"IgnoredCondition",
|
|
49
|
+
"ExcludeCondition",
|
|
50
|
+
"Condition"
|
|
51
|
+
], _ = (e) => H.includes(e), $ = L.define(), z = (e, t) => {
|
|
52
|
+
for (; t.parent; ) {
|
|
53
|
+
if (t.parent.name === e)
|
|
54
|
+
return t.parent;
|
|
55
|
+
t = t.parent;
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
};
|
|
59
|
+
async function Z(e, t, o) {
|
|
60
|
+
let a = t;
|
|
61
|
+
for (const i of e) {
|
|
62
|
+
const s = a.fields.find((c) => c.label === i);
|
|
63
|
+
if (s?.type !== "relationship" || !s.target)
|
|
64
|
+
return null;
|
|
65
|
+
a = await o.get(s.target);
|
|
66
|
+
}
|
|
67
|
+
return a;
|
|
68
|
+
}
|
|
69
|
+
const M = Q.define(), W = T.define({
|
|
70
|
+
create: () => ({ fields: [] }),
|
|
71
|
+
update: (e, t) => {
|
|
72
|
+
for (const o of t.effects)
|
|
73
|
+
if (o.is(M))
|
|
74
|
+
return o.value;
|
|
75
|
+
return e;
|
|
76
|
+
}
|
|
77
|
+
}), Y = b.data.of({
|
|
78
|
+
autocomplete: async (e) => {
|
|
79
|
+
const o = u(e.state).resolveInner(e.pos, -1), a = e.state.sliceDoc(o.from, e.pos), i = /[\w.]*$/.exec(a);
|
|
80
|
+
if (!i && !e.explicit) return null;
|
|
81
|
+
const s = i ? o.from + i.index : e.pos, c = e.state.field(W, !1), y = e.state.facet($)[0]?.schemaCache, x = z("Condition", o), p = x?.getChild("Field"), F = x?.getChild(":");
|
|
82
|
+
if (p && F && e.pos > F.to) {
|
|
83
|
+
const g = e.state.doc.sliceString(p.from, p.to), f = c?.values?.[g];
|
|
84
|
+
if (f?.length) {
|
|
85
|
+
const C = f.map((d) => ({
|
|
86
|
+
label: d,
|
|
87
|
+
type: "value"
|
|
88
|
+
}));
|
|
89
|
+
return {
|
|
90
|
+
from: s,
|
|
91
|
+
options: C
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (o.name === "Field" && c?.fields?.length) {
|
|
96
|
+
const g = e.state.doc.sliceString(o.from, e.pos), f = g.split(".");
|
|
97
|
+
if (f.length > 1 && y) {
|
|
98
|
+
const d = f.slice(0, -1), S = o.from + g.lastIndexOf(".") + 1, I = await Z(
|
|
99
|
+
d,
|
|
100
|
+
c,
|
|
101
|
+
y
|
|
102
|
+
);
|
|
103
|
+
if (I) {
|
|
104
|
+
const v = I.fields.map((h) => ({
|
|
105
|
+
label: h.label,
|
|
106
|
+
type: h.type,
|
|
107
|
+
info: h.info
|
|
108
|
+
}));
|
|
109
|
+
return {
|
|
110
|
+
from: S,
|
|
111
|
+
options: v
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
from: S,
|
|
116
|
+
options: []
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const C = c.fields.map((d) => ({
|
|
120
|
+
label: d.label,
|
|
121
|
+
type: d.type,
|
|
122
|
+
info: d.info
|
|
123
|
+
}));
|
|
124
|
+
return {
|
|
125
|
+
from: s,
|
|
126
|
+
options: C
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return o.name === "Field" ? {
|
|
130
|
+
from: s,
|
|
131
|
+
options: []
|
|
132
|
+
} : null;
|
|
133
|
+
}
|
|
134
|
+
}), j = E.define([
|
|
135
|
+
{ tag: n.Condition, class: "cnd" },
|
|
136
|
+
{ tag: n.Operator, class: "cnd-op" },
|
|
137
|
+
{ tag: n.Value, class: "cnd-val" },
|
|
138
|
+
{ tag: n.Command, class: "cnd-val cnd-cmd" },
|
|
139
|
+
{ tag: n.Field, class: "cnd-fld" },
|
|
140
|
+
{ tag: n.Regex, class: "cnd-val cnd-rgx cnd-rgx-f" },
|
|
141
|
+
{ tag: r.string, class: "string" },
|
|
142
|
+
{ tag: r.lineComment, class: "comment" }
|
|
143
|
+
]), G = (e) => {
|
|
144
|
+
let t;
|
|
145
|
+
return e === "ExcludeCondition" && (t = m.mark({ class: "condition condition--exclude" })), e === "IgnoredCondition" && (t = m.mark({ class: "condition condition--ignored" })), t = t || m.mark({
|
|
146
|
+
class: "condition"
|
|
147
|
+
}), t;
|
|
148
|
+
}, J = () => m.mark({
|
|
149
|
+
class: "query"
|
|
150
|
+
}), R = (e) => {
|
|
151
|
+
const t = [];
|
|
152
|
+
for (const { from: o, to: a } of e.visibleRanges)
|
|
153
|
+
u(e.state).iterate({
|
|
154
|
+
from: o,
|
|
155
|
+
to: a,
|
|
156
|
+
enter: (i) => {
|
|
157
|
+
i.name === "Query" && t.push(J().range(i.from, i.to)), _(i.name) && t.push(G(i.name).range(i.from, i.to));
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
return m.set(t);
|
|
161
|
+
}, ie = q.fromClass(
|
|
162
|
+
class {
|
|
163
|
+
decorations;
|
|
164
|
+
constructor(e) {
|
|
165
|
+
this.decorations = R(e);
|
|
166
|
+
}
|
|
167
|
+
update(e) {
|
|
168
|
+
(e.docChanged || e.viewportChanged || u(e.startState) != u(e.state)) && (this.decorations = R(e.view));
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
decorations: (e) => e.decorations
|
|
173
|
+
}
|
|
174
|
+
), K = B.configure({
|
|
175
|
+
props: [
|
|
176
|
+
V({
|
|
177
|
+
"Condition/:": n.Operator,
|
|
178
|
+
"ExcludeCondition/:": n.Operator,
|
|
179
|
+
"Condition/Field/...": n.Field,
|
|
180
|
+
"Condition/Predicate/RegexContent!": n.RegexContent,
|
|
181
|
+
"Command!": n.Command,
|
|
182
|
+
"Separator!": n.Operator,
|
|
183
|
+
Regex: n.Regex,
|
|
184
|
+
// "Condition/Predicate/...": condition.Predicate,
|
|
185
|
+
Comment: r.lineComment,
|
|
186
|
+
Field: n.Field,
|
|
187
|
+
"Value!": n.Value
|
|
188
|
+
}),
|
|
189
|
+
P.add({
|
|
190
|
+
Query: (e) => e.column(e.node.from) + e.unit
|
|
191
|
+
}),
|
|
192
|
+
k.add({
|
|
193
|
+
Query: D
|
|
194
|
+
})
|
|
195
|
+
]
|
|
196
|
+
}), b = N.define({
|
|
197
|
+
parser: K,
|
|
198
|
+
languageData: {
|
|
199
|
+
// commentTokens: { line: "" },
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
function re() {
|
|
203
|
+
return new O(b, [
|
|
204
|
+
w(j),
|
|
205
|
+
Y
|
|
206
|
+
// linter(lintExample),
|
|
207
|
+
]);
|
|
208
|
+
}
|
|
209
|
+
export {
|
|
210
|
+
ie as DequelConditionDecoration,
|
|
211
|
+
re as DequelLang,
|
|
212
|
+
j as EdkQLHighlights,
|
|
213
|
+
b as dequelParser,
|
|
214
|
+
K as parserWithMetadata
|
|
215
|
+
};
|
package/dist/vite.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dequel-editor",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "CodeMirror-based editor for Dequel query language",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/dequel-editor.js",
|
|
7
|
+
"module": "./dist/dequel-editor.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/dequel-editor.js",
|
|
10
|
+
"./lang": {
|
|
11
|
+
"import": "./dist/dequel-lang.js",
|
|
12
|
+
"types": "./dist/dequel-lang.d.ts"
|
|
13
|
+
},
|
|
14
|
+
"./style.css": "./dist/style.css"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist/"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"codemirror",
|
|
21
|
+
"editor",
|
|
22
|
+
"query-language",
|
|
23
|
+
"dequel",
|
|
24
|
+
"phoenix",
|
|
25
|
+
"elixir"
|
|
26
|
+
],
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/nocksock/dequel.git",
|
|
30
|
+
"directory": "editor"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"scripts": {
|
|
34
|
+
"dev": "vite",
|
|
35
|
+
"dev:build": "pnpm i18n:build && pnpm build:full --watch",
|
|
36
|
+
"build": "pnpm i18n:build && pnpm build:full && pnpm build:lang",
|
|
37
|
+
"build:full": "BUILD_MODE=full vite build",
|
|
38
|
+
"build:lang": "BUILD_MODE=lang vite build",
|
|
39
|
+
"build:types": "tsc --declaration --emitDeclarationOnly --outDir dist",
|
|
40
|
+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
41
|
+
"preview": "vite preview",
|
|
42
|
+
"test": "vitest",
|
|
43
|
+
"test:wtr": "web-test-runner test/**/*.test.{js,ts}",
|
|
44
|
+
"prepublishOnly": "pnpm build",
|
|
45
|
+
"i18n:build": "tsx scripts/po2json.ts"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@codemirror/autocomplete": "^6.20.0",
|
|
49
|
+
"@codemirror/commands": "^6.10.1",
|
|
50
|
+
"@codemirror/lang-markdown": "^6.5.0",
|
|
51
|
+
"@codemirror/language": "^6.12.1",
|
|
52
|
+
"@codemirror/lint": "^6.9.3",
|
|
53
|
+
"@codemirror/search": "^6.6.0",
|
|
54
|
+
"@codemirror/state": "^6.5.4",
|
|
55
|
+
"@codemirror/view": "^6.39.12",
|
|
56
|
+
"@lezer/common": "^1.5.0",
|
|
57
|
+
"@lezer/generator": "^1.8.0",
|
|
58
|
+
"@lezer/highlight": "^1.2.3",
|
|
59
|
+
"@lezer/lr": "^1.4.8",
|
|
60
|
+
"@preact/preset-vite": "^2.10.3",
|
|
61
|
+
"@preact/signals": "^1.3.3",
|
|
62
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
63
|
+
"@tanstack/react-query": "^5.90.20",
|
|
64
|
+
"@types/lodash-es": "^4.17.12",
|
|
65
|
+
"@uidotdev/usehooks": "^2.4.1",
|
|
66
|
+
"axios": "^1.13.4",
|
|
67
|
+
"codemirror": "^6.0.2",
|
|
68
|
+
"htm": "^3.1.1",
|
|
69
|
+
"lodash-es": "^4.17.23",
|
|
70
|
+
"lucide-react": "^0.396.0",
|
|
71
|
+
"preact": "^10.28.3",
|
|
72
|
+
"preact-custom-element": "^4.6.0",
|
|
73
|
+
"react": "^18.3.1",
|
|
74
|
+
"react-dom": "^18.3.1",
|
|
75
|
+
"vite-plugin-inspect": "^0.8.9"
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@esm-bundle/chai": "4.3.4-fix.0",
|
|
79
|
+
"@open-wc/testing": "^4.0.0",
|
|
80
|
+
"@types/axios": "^0.14.4",
|
|
81
|
+
"@types/mocha": "^10.0.10",
|
|
82
|
+
"@types/node": "^20.19.31",
|
|
83
|
+
"@types/preact-custom-element": "^4.0.4",
|
|
84
|
+
"@types/react": "^18.3.27",
|
|
85
|
+
"@types/react-dom": "^18.3.7",
|
|
86
|
+
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
87
|
+
"@typescript-eslint/parser": "^7.18.0",
|
|
88
|
+
"@web/dev-server-esbuild": "^1.0.5",
|
|
89
|
+
"@web/test-runner": "^0.20.2",
|
|
90
|
+
"autoprefixer": "^10.4.24",
|
|
91
|
+
"daisyui": "^5.5.17",
|
|
92
|
+
"eslint": "^8.57.1",
|
|
93
|
+
"gettext-parser": "^8.0.0",
|
|
94
|
+
"http-proxy-middleware": "^3.0.5",
|
|
95
|
+
"tailwindcss": "^4.1.18",
|
|
96
|
+
"tsx": "^4.19.4",
|
|
97
|
+
"typescript": "^5.9.3",
|
|
98
|
+
"vite": "^5.4.21",
|
|
99
|
+
"vitest": "^1.6.1"
|
|
100
|
+
},
|
|
101
|
+
"peerDependencies": {
|
|
102
|
+
"@codemirror/state": "^6.0.0",
|
|
103
|
+
"@codemirror/view": "^6.0.0"
|
|
104
|
+
},
|
|
105
|
+
"peerDependenciesMeta": {
|
|
106
|
+
"@codemirror/state": {
|
|
107
|
+
"optional": true
|
|
108
|
+
},
|
|
109
|
+
"@codemirror/view": {
|
|
110
|
+
"optional": true
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|