@dxos/echo-query 0.8.4-main.ead640a → 0.8.4-main.f466a3d56e

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.
Files changed (42) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/neutral/index.mjs +917 -0
  4. package/dist/lib/neutral/index.mjs.map +7 -0
  5. package/dist/lib/neutral/meta.json +1 -0
  6. package/dist/query-lite/index.d.ts +10022 -0
  7. package/dist/query-lite/index.d.ts.map +1 -0
  8. package/dist/query-lite/index.js +545 -375
  9. package/dist/query-lite/index.js.map +1 -0
  10. package/dist/types/src/index.d.ts +1 -0
  11. package/dist/types/src/index.d.ts.map +1 -1
  12. package/dist/types/src/parser/gen/index.d.ts.map +1 -1
  13. package/dist/types/src/parser/gen/query.terms.d.ts +1 -1
  14. package/dist/types/src/parser/gen/query.terms.d.ts.map +1 -1
  15. package/dist/types/src/parser/query-builder.d.ts +18 -3
  16. package/dist/types/src/parser/query-builder.d.ts.map +1 -1
  17. package/dist/types/src/query-lite/query-lite.d.ts +4 -4
  18. package/dist/types/src/query-lite/query-lite.d.ts.map +1 -1
  19. package/dist/types/src/sandbox/index.d.ts +2 -0
  20. package/dist/types/src/sandbox/index.d.ts.map +1 -0
  21. package/dist/types/src/sandbox/query-sandbox.d.ts +1 -1
  22. package/dist/types/src/sandbox/query-sandbox.d.ts.map +1 -1
  23. package/dist/types/src/sandbox/quickjs.d.ts.map +1 -1
  24. package/dist/types/tsconfig.tsbuildinfo +1 -1
  25. package/package.json +22 -20
  26. package/src/index.ts +1 -0
  27. package/src/parser/gen/query.terms.ts +24 -23
  28. package/src/parser/gen/query.ts +8 -8
  29. package/src/parser/query-builder.ts +333 -20
  30. package/src/parser/query.grammar +8 -2
  31. package/src/parser/query.test.ts +207 -41
  32. package/src/query-lite/query-lite.ts +360 -73
  33. package/src/sandbox/index.ts +5 -0
  34. package/src/sandbox/query-sandbox.test.ts +15 -14
  35. package/src/sandbox/query-sandbox.ts +1 -1
  36. package/src/sandbox/quickjs.ts +1 -2
  37. package/dist/lib/browser/index.mjs +0 -530
  38. package/dist/lib/browser/index.mjs.map +0 -7
  39. package/dist/lib/browser/meta.json +0 -1
  40. package/dist/lib/node-esm/index.mjs +0 -530
  41. package/dist/lib/node-esm/index.mjs.map +0 -7
  42. package/dist/lib/node-esm/meta.json +0 -1
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './query-sandbox';
@@ -5,6 +5,7 @@
5
5
  import { afterAll, beforeAll, describe, expect, test } from 'vitest';
6
6
 
7
7
  import { Filter, Order, Query } from '@dxos/echo';
8
+ import { trim } from '@dxos/util';
8
9
 
9
10
  import { QuerySandbox } from './query-sandbox';
10
11
 
@@ -14,38 +15,38 @@ describe('QuerySandbox', () => {
14
15
  afterAll(() => sandbox.close());
15
16
 
16
17
  test('works', { timeout: 10_000 }, async () => {
17
- const ast = sandbox.eval(`
18
- Query.select(Filter.typename('dxos.org/type/Person'))
18
+ const ast = sandbox.eval(trim`
19
+ Query.select(Filter.typename('org.dxos.type.person'))
19
20
  `);
20
- expect(ast).toEqual(Query.select(Filter.typename('dxos.org/type/Person')).ast);
21
+ expect(ast).toEqual(Query.select(Filter.typename('org.dxos.type.person')).ast);
21
22
  });
22
23
 
23
24
  test('works with just Filter passed in', () => {
24
- const ast = sandbox.eval(`
25
- Filter.typename('dxos.org/type/Person')
25
+ const ast = sandbox.eval(trim`
26
+ Filter.typename('org.dxos.type.person')
26
27
  `);
27
- expect(ast).toEqual(Query.select(Filter.typename('dxos.org/type/Person')).ast);
28
+ expect(ast).toEqual(Query.select(Filter.typename('org.dxos.type.person')).ast);
28
29
  });
29
30
 
30
31
  test('Order', () => {
31
- const ast = sandbox.eval(`
32
- Query.type('dxos.org/type/Person').orderBy(Order.property('name', 'desc'))
32
+ const ast = sandbox.eval(trim`
33
+ Query.type('org.dxos.type.person').orderBy(Order.property('name', 'desc'))
33
34
  `);
34
- expect(ast).toEqual(Query.type('dxos.org/type/Person').orderBy(Order.property('name', 'desc')).ast);
35
+ expect(ast).toEqual(Query.type('org.dxos.type.person').orderBy(Order.property('name', 'desc')).ast);
35
36
  });
36
37
 
37
38
  test('traversal', () => {
38
- const ast = sandbox.eval(`
39
- Query.select(Filter.type('example.com/type/Person', { jobTitle: 'investor' }))
39
+ const ast = sandbox.eval(trim`
40
+ Query.select(Filter.type('org.dxos.type.person', { jobTitle: 'investor' }))
40
41
  .reference('organization')
41
- .targetOf('example.com/relation/ResearchOn')
42
+ .targetOf('org.dxos.relation.hasSubject')
42
43
  .source()
43
44
  `);
44
45
 
45
46
  expect(ast).toEqual(
46
- Query.select(Filter.type('example.com/type/Person', { jobTitle: 'investor' }))
47
+ Query.select(Filter.type('org.dxos.type.person', { jobTitle: 'investor' }))
47
48
  .reference('organization')
48
- .targetOf('example.com/relation/ResearchOn')
49
+ .targetOf('org.dxos.relation.hasSubject')
49
50
  .source().ast,
50
51
  );
51
52
  });
@@ -49,7 +49,7 @@ export class QuerySandbox extends Resource {
49
49
 
50
50
  /**
51
51
  * Evaluates the query code.
52
- * @param queryCode Example: `Query.select(Filter.typename('dxos.org/type/Person'))`
52
+ * @param queryCode Example: `Query.select(Filter.typename('org.dxos.type.person'))`
53
53
  */
54
54
  eval(queryCode: string): QueryAST.Query {
55
55
  using context = this.#runtime.newContext();
@@ -17,8 +17,7 @@ export const unwrapResult = <T>(context: QuickJSContext, result: SuccessOrFail<T
17
17
  if (
18
18
  typeof contextError === 'object' &&
19
19
  typeof contextError.name === 'string' &&
20
- typeof contextError.message === 'string' &&
21
- typeof contextError.stack === 'string'
20
+ typeof contextError.message === 'string'
22
21
  ) {
23
22
  const error = new Error(contextError.message);
24
23
  Object.defineProperty(error, 'name', { value: contextError.name });
@@ -1,530 +0,0 @@
1
- import "@dxos/node-std/globals";
2
- var __defProp = Object.defineProperty;
3
- var __export = (target, all) => {
4
- for (var name in all)
5
- __defProp(target, name, { get: all[name], enumerable: true });
6
- };
7
-
8
- // src/parser/gen/query.ts
9
- import { LRParser } from "@lezer/lr";
10
- var spec_Identifier = {
11
- __proto__: null,
12
- type: 18,
13
- NOT: 82,
14
- not: 82,
15
- "!": 82,
16
- AND: 84,
17
- and: 84,
18
- OR: 86,
19
- or: 86
20
- };
21
- var parser = LRParser.deserialize({
22
- version: 14,
23
- states: "(QOVQPOOOOQO'#C_'#C_OOQO'#Ca'#CaOnQPO'#CcOsQPO'#ChO{QPO'#CnO!TQPO'#CgOOQO'#C^'#C^OOQO'#Cv'#CvOOQO'#DU'#DUOVQPO'#DUQ!YQPOOOVQPO'#DUO!jQPO,58}O!oQPO'#DOO!tQPO,59SO!|QPO'#CpOOQO,59Y,59YO#RQPO,59YO#ZQQO,59RO#oQPO,59pOOQO'#Cw'#CwOOQO'#Cx'#CxOOQO'#Cy'#CyOVQPO,59pOVQPO,59pOVQPO,59pO$jQPO,59pOOQO1G.i1G.iOOQO,59j,59jOOQO-E6|-E6|O#ZQQO,59[O$}QPO'#DPO%SQPO1G.tOOQO1G.t1G.tO%[QQO'#CsOOQO'#Cj'#CjOOQO1G.m1G.mO%cQPO1G/[O%yQPO1G/[O&aQPO1G/[OOQO1G/[1G/[OOQO1G.v1G.vOOQO,59k,59kOOQO-E6}-E6}OOQO7+$`7+$`OOQO,59_,59_O&wQPO,59_O#ZQQO'#DQO'PQPO1G.yOOQO1G.y1G.yOOQO,59l,59lOOQO-E7O-E7OOOQO7+$e7+$e",
24
- stateData: "'X~OwOS~OSPOUQOWSOXROcTOp[OyWO~OY]O~O]^OY[X~OW`OfaO~OYcO~OngOogOzeO{fO~PVOWlO~OWmO~O]^OY[a~OYoO~OepOfrO~OUtO_tO`tOatOcTOhsO~OyWOSxaUxaWxaXxacxanxaoxapxauxazxa{xaqxa~OngOogOqyOzeO{fO~PVOW`O~OepOf}O~Oi!OO~P#ZOnxioxiuxizxi{xiqxi~PVOzeOnxioxiuxi{xiqxi~PVOzeO{fOnxioxiuxiqxi~PVOe!QOi!SO~Oe!QOi!VO~O",
25
- goto: "%TyPPz!XP!XP!XPPP!X!fP!sPPP#PP#dPP#^PP#j#x$O$TPPPP$X$_$ePPP$kgXOYZ[hijkvwxgVOYZ[hijkvwxgUOYZ[hijkvwxQucQzoQ!PsR!T!QfVOYZ[hijkvwxXtcos!QQbTR{piYOYZ[dhijkvwxXhZkwxViZkxTjZkQ_SRn_QqbR|qQ!R!PR!U!RQZO^dYZdkvwxQk[QvhQwiRxj",
26
- nodeNames: "\u26A0 Query Filter TagFilter Tag TextFilter String TypeFilter Identifier TypeKeyword : PropertyFilter PropertyPath . Value Number Boolean Null ObjectLiteral { ObjectProperty , } ArrayLiteral [ ] Not And Or Relation ArrowRight ArrowLeft ( )",
27
- maxTerm: 43,
28
- skippedNodes: [
29
- 0
30
- ],
31
- repeatNodeCount: 3,
32
- tokenData: "2w~RrX^#]pq#]rs$Qst%nwx&fxy'}yz(S|}(X}!O(^!O!P)}!Q![(g![!]*S!^!_*X!c!}*d!}#O+O#P#Q+T#R#S*d#T#Y*d#Y#Z+Y#Z#b*d#b#c.i#c#h*d#h#i1Z#i#o*d#o#p2m#q#r2r#y#z#]$f$g#]#BY#BZ#]$IS$I_#]$I|$JO#]$JT$JU#]$KV$KW#]&FU&FV#]~#bYw~X^#]pq#]#y#z#]$f$g#]#BY#BZ#]$IS$I_#]$I|$JO#]$JT$JU#]$KV$KW#]&FU&FV#]~$TVOr$Qrs$js#O$Q#O#P$o#P;'S$Q;'S;=`%h<%lO$Q~$oOU~~$rRO;'S$Q;'S;=`${;=`O$Q~%OWOr$Qrs$js#O$Q#O#P$o#P;'S$Q;'S;=`%h;=`<%l$Q<%lO$Q~%kP;=`<%l$Q~%qT}!O&Q!Q![&Q!c!}&Q#R#S&Q#T#o&Q~&VTS~}!O&Q!Q![&Q!c!}&Q#R#S&Q#T#o&Q~&iVOw&fwx$jx#O&f#O#P'O#P;'S&f;'S;=`'w<%lO&f~'RRO;'S&f;'S;=`'[;=`O&f~'_WOw&fwx$jx#O&f#O#P'O#P;'S&f;'S;=`'w;=`<%l&f<%lO&f~'zP;=`<%l&f~(SOp~~(XOq~~(^Oe~~(aQ!Q![(g!`!a)x~(lS_~!O!P(x!Q![(g!g!h)^#X#Y)^~({P!Q![)O~)TR_~!Q![)O!g!h)^#X#Y)^~)aR{|)j}!O)j!Q![)p~)mP!Q![)p~)uP_~!Q![)p~)}On~~*SO]~~*XOY~~*[P}!O*_~*dOo~P*iVWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#o*d~+TOh~~+YOi~R+_WWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#U+w#U#o*dR+|XWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#`*d#`#a,i#a#o*dR,nXWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#g*d#g#h-Z#h#o*dR-`XWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#X*d#X#Y-{#Y#o*dR.SV`QWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#o*dR.nXWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#i*d#i#j/Z#j#o*dR/`XWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#`*d#`#a/{#a#o*dR0QXWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#`*d#`#a0m#a#o*dR0tVWPaQ}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#o*dR1`XWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#f*d#f#g1{#g#o*dR2QXWP}!O*d!O!P*d!P!Q*d!Q![*d!c!}*d#R#S*d#T#i*d#i#j-Z#j#o*d~2rOc~~2wOf~",
33
- tokenizers: [
34
- 0,
35
- 1
36
- ],
37
- topRules: {
38
- "Query": [
39
- 0,
40
- 1
41
- ]
42
- },
43
- specialized: [
44
- {
45
- term: 8,
46
- get: (value) => spec_Identifier[value] || -1
47
- }
48
- ],
49
- tokenPrec: 0
50
- });
51
-
52
- // src/parser/gen/query.terms.ts
53
- var query_terms_exports = {};
54
- __export(query_terms_exports, {
55
- And: () => And,
56
- ArrayLiteral: () => ArrayLiteral,
57
- ArrowLeft: () => ArrowLeft,
58
- ArrowRight: () => ArrowRight,
59
- Boolean: () => Boolean,
60
- Filter: () => Filter,
61
- Identifier: () => Identifier,
62
- Not: () => Not,
63
- Null: () => Null,
64
- Number: () => Number2,
65
- ObjectLiteral: () => ObjectLiteral,
66
- ObjectProperty: () => ObjectProperty,
67
- Or: () => Or,
68
- PropertyFilter: () => PropertyFilter,
69
- PropertyPath: () => PropertyPath,
70
- Query: () => Query,
71
- Relation: () => Relation,
72
- String: () => String,
73
- Tag: () => Tag,
74
- TagFilter: () => TagFilter,
75
- TextFilter: () => TextFilter,
76
- TypeFilter: () => TypeFilter,
77
- TypeKeyword: () => TypeKeyword,
78
- Value: () => Value
79
- });
80
- var Query = 1;
81
- var Filter = 2;
82
- var TagFilter = 3;
83
- var Tag = 4;
84
- var TextFilter = 5;
85
- var String = 6;
86
- var TypeFilter = 7;
87
- var Identifier = 8;
88
- var TypeKeyword = 9;
89
- var PropertyFilter = 11;
90
- var PropertyPath = 12;
91
- var Value = 14;
92
- var Number2 = 15;
93
- var Boolean = 16;
94
- var Null = 17;
95
- var ObjectLiteral = 18;
96
- var ObjectProperty = 20;
97
- var ArrayLiteral = 23;
98
- var Not = 26;
99
- var And = 27;
100
- var Or = 28;
101
- var Relation = 29;
102
- var ArrowRight = 30;
103
- var ArrowLeft = 31;
104
-
105
- // src/parser/gen/index.ts
106
- (function(QueryDSL2) {
107
- QueryDSL2.Parser = parser;
108
- QueryDSL2.Node = query_terms_exports;
109
- QueryDSL2.Tokens = [
110
- "type:",
111
- "AND",
112
- "OR",
113
- "NOT"
114
- ];
115
- })(QueryDSL || (QueryDSL = {}));
116
- var QueryDSL;
117
-
118
- // src/parser/query-builder.ts
119
- import { Filter as Filter2 } from "@dxos/echo";
120
- import { invariant } from "@dxos/invariant";
121
- function _define_property(obj, key, value) {
122
- if (key in obj) {
123
- Object.defineProperty(obj, key, {
124
- value,
125
- enumerable: true,
126
- configurable: true,
127
- writable: true
128
- });
129
- } else {
130
- obj[key] = value;
131
- }
132
- return obj;
133
- }
134
- var __dxlog_file = "/__w/dxos/dxos/packages/core/echo/echo-query/src/parser/query-builder.ts";
135
- var QueryBuilder = class {
136
- /**
137
- * Check valid input.
138
- */
139
- validate(input) {
140
- try {
141
- const tree = this._parser.parse(input);
142
- return tree.cursor().node.name === "Query";
143
- } catch {
144
- return false;
145
- }
146
- }
147
- /**
148
- * Build a query from the input string.
149
- */
150
- build(input) {
151
- try {
152
- const tree = this._parser.parse(input);
153
- return this.buildQuery(tree, input);
154
- } catch {
155
- return void 0;
156
- }
157
- }
158
- /**
159
- * Build a query from a parsed DSL tree.
160
- */
161
- buildQuery(tree, input) {
162
- const cursor = tree.cursor();
163
- if (cursor.node.name !== "Query") {
164
- return void 0;
165
- }
166
- const children = [];
167
- if (cursor.firstChild()) {
168
- do {
169
- children.push({
170
- name: cursor.node.name,
171
- from: cursor.from,
172
- to: cursor.to
173
- });
174
- } while (cursor.nextSibling());
175
- cursor.parent();
176
- }
177
- const hasOperator = children.some((child) => child.name === "And" || child.name === "Or");
178
- const hasMultipleExpressions = children.filter((child) => child.name === "Filter" || child.name === "Not" || child.name === "(").length > 1;
179
- if (hasOperator || hasMultipleExpressions) {
180
- return this._parseBinaryExpression(cursor, input);
181
- }
182
- if (!cursor.firstChild()) {
183
- return Filter2.nothing();
184
- }
185
- return this._parseExpression(cursor, input);
186
- }
187
- /**
188
- * Parse an expression node.
189
- */
190
- _parseExpression(cursor, input) {
191
- const nodeName = cursor.node.name;
192
- switch (nodeName) {
193
- case "Filter":
194
- return this._parseFilter(cursor, input);
195
- case "Not": {
196
- cursor.nextSibling();
197
- const notFilter = this._parseExpression(cursor, input);
198
- return notFilter ? Filter2.not(notFilter) : void 0;
199
- }
200
- case "And":
201
- case "Or":
202
- cursor.parent();
203
- return this._parseBinaryExpression(cursor, input);
204
- case "(": {
205
- cursor.nextSibling();
206
- const parenFilter = this._parseExpression(cursor, input);
207
- cursor.nextSibling();
208
- return parenFilter;
209
- }
210
- default: {
211
- const savedPos = cursor.from;
212
- if (cursor.firstChild()) {
213
- let hasOperator = false;
214
- let expressionCount = 0;
215
- do {
216
- if (cursor.node.name === "And" || cursor.node.name === "Or") {
217
- hasOperator = true;
218
- break;
219
- }
220
- if (cursor.node.name === "Filter" || cursor.node.name === "Not" || cursor.node.name === "(") {
221
- expressionCount++;
222
- }
223
- } while (cursor.nextSibling());
224
- hasOperator = hasOperator || expressionCount > 1;
225
- cursor.parent();
226
- cursor.firstChild();
227
- while (cursor.from !== savedPos && cursor.nextSibling()) {
228
- }
229
- if (hasOperator) {
230
- cursor.parent();
231
- return this._parseBinaryExpression(cursor, input);
232
- } else {
233
- const result = this._parseExpression(cursor, input);
234
- cursor.parent();
235
- return result;
236
- }
237
- }
238
- return Filter2.nothing();
239
- }
240
- }
241
- }
242
- /**
243
- * Parse a binary expression (AND/OR).
244
- */
245
- _parseBinaryExpression(cursor, input) {
246
- const filters = [];
247
- let operator = null;
248
- if (cursor.firstChild()) {
249
- do {
250
- const nodeName = cursor.node.name;
251
- if (nodeName === "And" || nodeName === "Or") {
252
- operator = nodeName.toLowerCase();
253
- } else if (nodeName === "(") {
254
- const savedPos = cursor.from;
255
- cursor.nextSibling();
256
- let hasBinaryOp = false;
257
- do {
258
- if (cursor.node.name === "And" || cursor.node.name === "Or") {
259
- hasBinaryOp = true;
260
- break;
261
- }
262
- } while (cursor.nextSibling() && cursor.node.name !== ")");
263
- cursor.parent();
264
- cursor.firstChild();
265
- while (cursor.from !== savedPos && cursor.nextSibling()) {
266
- }
267
- cursor.nextSibling();
268
- if (hasBinaryOp) {
269
- let depth = 1;
270
- const exprStart = cursor.from;
271
- let exprEnd = cursor.to;
272
- while (cursor.nextSibling() && depth > 0) {
273
- if (cursor.node.name === "(") depth++;
274
- else if (cursor.node.name === ")") {
275
- depth--;
276
- if (depth === 0) {
277
- exprEnd = cursor.from;
278
- }
279
- }
280
- }
281
- const subInput = input.slice(exprStart, exprEnd);
282
- const subTree = this._parser.parse(subInput);
283
- const subFilter = this.buildQuery(subTree, subInput);
284
- if (subFilter) {
285
- filters.push(subFilter);
286
- }
287
- } else {
288
- const subFilter = this._parseExpression(cursor, input);
289
- if (subFilter) {
290
- filters.push(subFilter);
291
- }
292
- while (cursor.nextSibling() && cursor.node.name !== ")") {
293
- }
294
- }
295
- } else if (nodeName !== ")") {
296
- const subFilter = this._parseExpression(cursor, input);
297
- if (subFilter) {
298
- filters.push(subFilter);
299
- }
300
- }
301
- } while (cursor.nextSibling());
302
- cursor.parent();
303
- }
304
- if (filters.length === 0) {
305
- return Filter2.nothing();
306
- }
307
- if (filters.length === 1) {
308
- return filters[0];
309
- }
310
- return operator === "or" ? Filter2.or(...filters) : Filter2.and(...filters);
311
- }
312
- /**
313
- * Parse a Filter node.
314
- */
315
- _parseFilter(cursor, input) {
316
- if (!cursor.firstChild()) {
317
- return Filter2.nothing();
318
- }
319
- let result = void 0;
320
- const filterType = cursor.node.name;
321
- switch (filterType) {
322
- case "TagFilter":
323
- if (this._tags) {
324
- result = this._parseTagFilter(cursor, input);
325
- }
326
- break;
327
- case "TextFilter":
328
- result = this._parseTextFilter(cursor, input);
329
- break;
330
- case "TypeFilter":
331
- result = this._parseTypeFilter(cursor, input);
332
- break;
333
- case "ObjectLiteral":
334
- result = this._parseObjectLiteral(cursor, input);
335
- break;
336
- case "PropertyFilter":
337
- result = this._parsePropertyFilter(cursor, input);
338
- break;
339
- default:
340
- result = Filter2.nothing();
341
- }
342
- cursor.parent();
343
- return result;
344
- }
345
- /**
346
- * Parse a TypeFilter node (type:typename).
347
- */
348
- _parseTypeFilter(cursor, input) {
349
- cursor.firstChild();
350
- cursor.nextSibling();
351
- cursor.nextSibling();
352
- const typename = this._getNodeText(cursor, input);
353
- cursor.parent();
354
- return Filter2.typename(typename);
355
- }
356
- /**
357
- * Parse a TextFilter node (quoted string).
358
- */
359
- _parseTextFilter(cursor, input) {
360
- cursor.firstChild();
361
- const text = this._getNodeText(cursor, input);
362
- cursor.parent();
363
- return Filter2.text(text.slice(1, -1));
364
- }
365
- /**
366
- * Parse an ObjectLiteral node.
367
- */
368
- _parseObjectLiteral(cursor, input) {
369
- const props = {};
370
- if (cursor.firstChild()) {
371
- do {
372
- if (cursor.node.name === "ObjectProperty") {
373
- const { key, value } = this._parseObjectProperty(cursor, input);
374
- if (key) {
375
- props[key] = Filter2.eq(value);
376
- }
377
- }
378
- } while (cursor.nextSibling());
379
- cursor.parent();
380
- }
381
- return Filter2.props(props);
382
- }
383
- /**
384
- * Parse an ObjectProperty node.
385
- */
386
- _parseObjectProperty(cursor, input) {
387
- let key = null;
388
- let value = null;
389
- if (cursor.firstChild()) {
390
- if (cursor.node.name === "Identifier") {
391
- key = this._getNodeText(cursor, input);
392
- }
393
- cursor.nextSibling();
394
- cursor.nextSibling();
395
- if (cursor.node.name === "Value" && cursor.firstChild()) {
396
- value = this._parseValue(cursor, input);
397
- cursor.parent();
398
- }
399
- cursor.parent();
400
- }
401
- return {
402
- key,
403
- value
404
- };
405
- }
406
- /**
407
- * Parse a PropertyFilter node (property:value).
408
- */
409
- _parsePropertyFilter(cursor, input) {
410
- let path = null;
411
- let value = null;
412
- if (cursor.firstChild()) {
413
- if (cursor.node.name === "PropertyPath") {
414
- path = this._parsePropertyPath(cursor, input);
415
- }
416
- cursor.nextSibling();
417
- cursor.nextSibling();
418
- if (cursor.node.name === "Value" && cursor.firstChild()) {
419
- value = this._parseValue(cursor, input);
420
- cursor.parent();
421
- }
422
- cursor.parent();
423
- }
424
- if (!path) {
425
- return Filter2.nothing();
426
- }
427
- return Filter2.props({
428
- [path]: value
429
- });
430
- }
431
- /**
432
- * Parse a PropertyPath node (supports dot notation).
433
- */
434
- _parsePropertyPath(cursor, input) {
435
- const parts = [];
436
- if (cursor.firstChild()) {
437
- do {
438
- if (cursor.node.name === "Identifier") {
439
- parts.push(this._getNodeText(cursor, input));
440
- }
441
- } while (cursor.nextSibling());
442
- cursor.parent();
443
- }
444
- return parts.join(".");
445
- }
446
- /**
447
- * Parse a TagFilter node (#tag).
448
- */
449
- _parseTagFilter(cursor, input) {
450
- invariant(this._tags, void 0, {
451
- F: __dxlog_file,
452
- L: 415,
453
- S: this,
454
- A: [
455
- "this._tags",
456
- ""
457
- ]
458
- });
459
- const str = this._getNodeText(cursor, input).slice(1).toLowerCase();
460
- const [key] = Object.entries(this._tags).find(([, value]) => value.label.toLowerCase() === str) ?? [];
461
- return key ? Filter2.tag(key) : void 0;
462
- }
463
- /**
464
- * Parse a Value node.
465
- */
466
- _parseValue(cursor, input) {
467
- const valueType = cursor.node.name;
468
- switch (valueType) {
469
- case "String": {
470
- const str = this._getNodeText(cursor, input);
471
- return str.slice(1, -1);
472
- }
473
- case "Number":
474
- return Number(this._getNodeText(cursor, input));
475
- case "Boolean":
476
- return this._getNodeText(cursor, input) === "true";
477
- case "Null":
478
- return null;
479
- case "ObjectLiteral": {
480
- const props = {};
481
- if (cursor.firstChild()) {
482
- do {
483
- if (cursor.node.name === "ObjectProperty") {
484
- const { key, value } = this._parseObjectProperty(cursor, input);
485
- if (key) {
486
- props[key] = value;
487
- }
488
- }
489
- } while (cursor.nextSibling());
490
- cursor.parent();
491
- }
492
- return props;
493
- }
494
- case "ArrayLiteral": {
495
- const array = [];
496
- if (cursor.firstChild()) {
497
- do {
498
- if (cursor.node.name === "Value" && cursor.firstChild()) {
499
- array.push(this._parseValue(cursor, input));
500
- cursor.parent();
501
- }
502
- } while (cursor.nextSibling());
503
- cursor.parent();
504
- }
505
- return array;
506
- }
507
- default:
508
- return null;
509
- }
510
- }
511
- /**
512
- * Get the text content of the current node.
513
- */
514
- _getNodeText(cursor, input) {
515
- return input.slice(cursor.from, cursor.to);
516
- }
517
- constructor(_tags) {
518
- _define_property(this, "_tags", void 0);
519
- _define_property(this, "_parser", void 0);
520
- this._tags = _tags;
521
- this._parser = QueryDSL.Parser.configure({
522
- strict: true
523
- });
524
- }
525
- };
526
- export {
527
- QueryBuilder,
528
- QueryDSL
529
- };
530
- //# sourceMappingURL=index.mjs.map