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.
@@ -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
+ }