@visactor/vbi 0.4.12 → 0.4.13
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/dist/builder/sub-builders/havingFilters/having-builder.d.ts +33 -20
- package/dist/builder/sub-builders/havingFilters/having-group-builder.d.ts +48 -0
- package/dist/builder/sub-builders/havingFilters/having-node-builder.d.ts +8 -0
- package/dist/builder/sub-builders/havingFilters/index.d.ts +1 -0
- package/dist/builder/sub-builders/index.d.ts +1 -1
- package/dist/builder/sub-builders/whereFilters/index.d.ts +1 -0
- package/dist/builder/sub-builders/whereFilters/where-builder.d.ts +30 -17
- package/dist/builder/sub-builders/whereFilters/where-group-builder.d.ts +48 -0
- package/dist/builder/sub-builders/whereFilters/where-node-builder.d.ts +8 -0
- package/dist/index.cjs +424 -129
- package/dist/index.js +406 -120
- package/dist/pipeline/index.d.ts +1 -1
- package/dist/pipeline/vqueryDSL/buildGroupBy.d.ts +2 -0
- package/dist/pipeline/vqueryDSL/buildHaving.d.ts +2 -0
- package/dist/pipeline/vqueryDSL/buildLimit.d.ts +2 -0
- package/dist/pipeline/vqueryDSL/buildSelect.d.ts +2 -0
- package/dist/pipeline/vqueryDSL/buildWhere.d.ts +2 -0
- package/dist/pipeline/vqueryDSL/index.d.ts +4 -1
- package/dist/pipeline/vqueryDSL/types.d.ts +7 -0
- package/dist/types/dsl/havingFilters/having.d.ts +12 -7
- package/dist/types/dsl/index.d.ts +4 -2
- package/dist/types/dsl/vbi/vbi.d.ts +2 -10
- package/dist/types/dsl/whereFilters/filters.d.ts +12 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/utils/id.d.ts +3 -0
- package/dist/utils/index.d.ts +1 -0
- package/package.json +12 -10
- package/dist/pipeline/vqueryDSL/buildVQuery.d.ts +0 -4
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Array as external_yjs_Array, Doc, Map as external_yjs_Map, UndoManager, applyUpdate, encodeStateAsUpdate } from "yjs";
|
|
2
2
|
import { ChartTypeEnum, findTreeNodesBy, preorderTraverse } from "@visactor/vseed";
|
|
3
|
-
import {
|
|
3
|
+
import { v4 } from "uuid";
|
|
4
4
|
import { pipe } from "remeda";
|
|
5
|
+
import { z } from "zod";
|
|
5
6
|
class DimensionNodeBuilder {
|
|
6
7
|
yMap;
|
|
7
8
|
constructor(yMap){
|
|
@@ -166,20 +167,88 @@ class MeasuresBuilder {
|
|
|
166
167
|
return 'children' in node;
|
|
167
168
|
}
|
|
168
169
|
}
|
|
170
|
+
const id_id = {
|
|
171
|
+
uuid: ()=>v4()
|
|
172
|
+
};
|
|
169
173
|
class HavingFiltersNodeBuilder {
|
|
170
174
|
yMap;
|
|
171
175
|
constructor(yMap){
|
|
172
176
|
this.yMap = yMap;
|
|
173
177
|
}
|
|
178
|
+
getId() {
|
|
179
|
+
return this.yMap.get('id');
|
|
180
|
+
}
|
|
174
181
|
getField() {
|
|
175
182
|
return this.yMap.get('field');
|
|
176
183
|
}
|
|
184
|
+
getOperator() {
|
|
185
|
+
return this.yMap.get('op');
|
|
186
|
+
}
|
|
177
187
|
setValue(value) {
|
|
178
188
|
this.yMap.set('value', value);
|
|
179
189
|
return this;
|
|
180
190
|
}
|
|
181
191
|
setOperator(operator) {
|
|
182
|
-
this.yMap.set('
|
|
192
|
+
this.yMap.set('op', operator);
|
|
193
|
+
return this;
|
|
194
|
+
}
|
|
195
|
+
toJson() {
|
|
196
|
+
return this.yMap.toJSON();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
class HavingGroupBuilder {
|
|
200
|
+
yMap;
|
|
201
|
+
constructor(yMap){
|
|
202
|
+
this.yMap = yMap;
|
|
203
|
+
}
|
|
204
|
+
getId() {
|
|
205
|
+
return this.yMap.get('id');
|
|
206
|
+
}
|
|
207
|
+
getOperator() {
|
|
208
|
+
return this.yMap.get('op');
|
|
209
|
+
}
|
|
210
|
+
setOperator(op) {
|
|
211
|
+
this.yMap.set('op', op);
|
|
212
|
+
return this;
|
|
213
|
+
}
|
|
214
|
+
add(field, callback) {
|
|
215
|
+
const yMap = new external_yjs_Map();
|
|
216
|
+
yMap.set('id', id_id.uuid());
|
|
217
|
+
yMap.set('field', field);
|
|
218
|
+
const conditions = this.yMap.get('conditions');
|
|
219
|
+
conditions.push([
|
|
220
|
+
yMap
|
|
221
|
+
]);
|
|
222
|
+
const node = new HavingFiltersNodeBuilder(yMap);
|
|
223
|
+
callback(node);
|
|
224
|
+
return this;
|
|
225
|
+
}
|
|
226
|
+
addGroup(op, callback) {
|
|
227
|
+
const yMap = new external_yjs_Map();
|
|
228
|
+
yMap.set('id', id_id.uuid());
|
|
229
|
+
yMap.set('op', op);
|
|
230
|
+
yMap.set('conditions', new external_yjs_Array());
|
|
231
|
+
const conditions = this.yMap.get('conditions');
|
|
232
|
+
conditions.push([
|
|
233
|
+
yMap
|
|
234
|
+
]);
|
|
235
|
+
const group = new HavingGroupBuilder(yMap);
|
|
236
|
+
callback(group);
|
|
237
|
+
return this;
|
|
238
|
+
}
|
|
239
|
+
remove(idOrIndex) {
|
|
240
|
+
const conditions = this.yMap.get('conditions');
|
|
241
|
+
if ('number' == typeof idOrIndex) {
|
|
242
|
+
if (idOrIndex >= 0 && idOrIndex < conditions.length) conditions.delete(idOrIndex, 1);
|
|
243
|
+
} else {
|
|
244
|
+
const index = conditions.toArray().findIndex((item)=>item.get('id') === idOrIndex);
|
|
245
|
+
if (-1 !== index) conditions.delete(index, 1);
|
|
246
|
+
}
|
|
247
|
+
return this;
|
|
248
|
+
}
|
|
249
|
+
clear() {
|
|
250
|
+
const conditions = this.yMap.get('conditions');
|
|
251
|
+
conditions.delete(0, conditions.length);
|
|
183
252
|
return this;
|
|
184
253
|
}
|
|
185
254
|
toJson() {
|
|
@@ -188,54 +257,76 @@ class HavingFiltersNodeBuilder {
|
|
|
188
257
|
}
|
|
189
258
|
class HavingFiltersBuilder {
|
|
190
259
|
dsl;
|
|
191
|
-
|
|
260
|
+
doc;
|
|
261
|
+
constructor(doc, dsl){
|
|
262
|
+
this.doc = doc;
|
|
192
263
|
this.dsl = dsl;
|
|
264
|
+
if (!this.dsl.get('havingFilters')) this.doc.transact(()=>{
|
|
265
|
+
this.dsl.set('havingFilters', new external_yjs_Array());
|
|
266
|
+
});
|
|
193
267
|
}
|
|
194
268
|
add(field, callback) {
|
|
195
|
-
if (!field || 'string' != typeof field) throw new Error('Field is required and must be a string');
|
|
196
|
-
const defaultFilter = {
|
|
197
|
-
field,
|
|
198
|
-
operator: 'eq',
|
|
199
|
-
value: null
|
|
200
|
-
};
|
|
201
269
|
const yMap = new external_yjs_Map();
|
|
202
|
-
|
|
270
|
+
yMap.set('id', id_id.uuid());
|
|
271
|
+
yMap.set('field', field);
|
|
203
272
|
this.dsl.get('havingFilters').push([
|
|
204
273
|
yMap
|
|
205
274
|
]);
|
|
206
|
-
const
|
|
207
|
-
callback(
|
|
275
|
+
const node = new HavingFiltersNodeBuilder(yMap);
|
|
276
|
+
callback(node);
|
|
208
277
|
return this;
|
|
209
278
|
}
|
|
210
|
-
|
|
279
|
+
addGroup(op, callback) {
|
|
280
|
+
const yMap = new external_yjs_Map();
|
|
281
|
+
yMap.set('id', id_id.uuid());
|
|
282
|
+
yMap.set('op', op);
|
|
283
|
+
yMap.set('conditions', new external_yjs_Array());
|
|
284
|
+
this.dsl.get('havingFilters').push([
|
|
285
|
+
yMap
|
|
286
|
+
]);
|
|
287
|
+
const group = new HavingGroupBuilder(yMap);
|
|
288
|
+
callback(group);
|
|
289
|
+
return this;
|
|
290
|
+
}
|
|
291
|
+
update(id, callback) {
|
|
211
292
|
const havingFilters = this.dsl.get('havingFilters');
|
|
212
|
-
const index = havingFilters.toArray().findIndex((item)=>item.get('
|
|
213
|
-
if (-1 === index) throw new Error(`Having filter with
|
|
293
|
+
const index = havingFilters.toArray().findIndex((item)=>item.get('id') === id);
|
|
294
|
+
if (-1 === index) throw new Error(`Having filter with id ${id} not found`);
|
|
214
295
|
const filterYMap = havingFilters.get(index);
|
|
215
296
|
const node = new HavingFiltersNodeBuilder(filterYMap);
|
|
216
297
|
callback(node);
|
|
217
298
|
return this;
|
|
218
299
|
}
|
|
219
|
-
|
|
220
|
-
if (!field || 'string' != typeof field) console.error('[HavingFiltersBuilder] Invalid field name:', field);
|
|
300
|
+
updateGroup(id, callback) {
|
|
221
301
|
const havingFilters = this.dsl.get('havingFilters');
|
|
222
|
-
const index = havingFilters.toArray().findIndex((item)=>item.get('
|
|
223
|
-
if (-1
|
|
302
|
+
const index = havingFilters.toArray().findIndex((item)=>item.get('id') === id);
|
|
303
|
+
if (-1 === index) throw new Error(`Having group with id ${id} not found`);
|
|
304
|
+
const yMap = havingFilters.get(index);
|
|
305
|
+
if (!HavingFiltersBuilder.isGroup(yMap)) throw new Error(`Item with id ${id} is not a group`);
|
|
306
|
+
const group = new HavingGroupBuilder(yMap);
|
|
307
|
+
callback(group);
|
|
224
308
|
return this;
|
|
225
309
|
}
|
|
226
|
-
|
|
310
|
+
remove(idOrIndex) {
|
|
227
311
|
const havingFilters = this.dsl.get('havingFilters');
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
312
|
+
if ('number' == typeof idOrIndex) {
|
|
313
|
+
if (idOrIndex >= 0 && idOrIndex < havingFilters.length) havingFilters.delete(idOrIndex, 1);
|
|
314
|
+
} else {
|
|
315
|
+
const index = havingFilters.toArray().findIndex((item)=>item.get('id') === idOrIndex);
|
|
316
|
+
if (-1 !== index) havingFilters.delete(index, 1);
|
|
317
|
+
}
|
|
318
|
+
return this;
|
|
231
319
|
}
|
|
232
|
-
|
|
320
|
+
find(id) {
|
|
233
321
|
const havingFilters = this.dsl.get('havingFilters');
|
|
234
|
-
|
|
322
|
+
const yMap = havingFilters.toArray().find((item)=>item.get('id') === id);
|
|
323
|
+
if (!yMap) return;
|
|
324
|
+
if (HavingFiltersBuilder.isGroup(yMap)) return new HavingGroupBuilder(yMap);
|
|
325
|
+
return new HavingFiltersNodeBuilder(yMap);
|
|
235
326
|
}
|
|
236
327
|
clear() {
|
|
237
328
|
const havingFilters = this.dsl.get('havingFilters');
|
|
238
|
-
|
|
329
|
+
havingFilters.delete(0, havingFilters.length);
|
|
239
330
|
return this;
|
|
240
331
|
}
|
|
241
332
|
toJson() {
|
|
@@ -247,6 +338,12 @@ class HavingFiltersBuilder {
|
|
|
247
338
|
this.dsl.get('havingFilters').unobserve(callback);
|
|
248
339
|
};
|
|
249
340
|
}
|
|
341
|
+
static isGroup(yMap) {
|
|
342
|
+
return void 0 !== yMap.get('op') && void 0 !== yMap.get('conditions');
|
|
343
|
+
}
|
|
344
|
+
static isNode(yMap) {
|
|
345
|
+
return void 0 !== yMap.get('field');
|
|
346
|
+
}
|
|
250
347
|
}
|
|
251
348
|
class ChartTypeBuilder {
|
|
252
349
|
dsl;
|
|
@@ -302,11 +399,17 @@ class WhereFilterNodeBuilder {
|
|
|
302
399
|
constructor(yMap){
|
|
303
400
|
this.yMap = yMap;
|
|
304
401
|
}
|
|
402
|
+
getId() {
|
|
403
|
+
return this.yMap.get('id');
|
|
404
|
+
}
|
|
305
405
|
getField() {
|
|
306
406
|
return this.yMap.get('field');
|
|
307
407
|
}
|
|
408
|
+
getOperator() {
|
|
409
|
+
return this.yMap.get('op');
|
|
410
|
+
}
|
|
308
411
|
setOperator(operator) {
|
|
309
|
-
this.yMap.set('
|
|
412
|
+
this.yMap.set('op', operator);
|
|
310
413
|
return this;
|
|
311
414
|
}
|
|
312
415
|
setValue(value) {
|
|
@@ -317,6 +420,65 @@ class WhereFilterNodeBuilder {
|
|
|
317
420
|
return this.yMap.toJSON();
|
|
318
421
|
}
|
|
319
422
|
}
|
|
423
|
+
class WhereGroupBuilder {
|
|
424
|
+
yMap;
|
|
425
|
+
constructor(yMap){
|
|
426
|
+
this.yMap = yMap;
|
|
427
|
+
}
|
|
428
|
+
getId() {
|
|
429
|
+
return this.yMap.get('id');
|
|
430
|
+
}
|
|
431
|
+
getOperator() {
|
|
432
|
+
return this.yMap.get('op');
|
|
433
|
+
}
|
|
434
|
+
setOperator(op) {
|
|
435
|
+
this.yMap.set('op', op);
|
|
436
|
+
return this;
|
|
437
|
+
}
|
|
438
|
+
add(field, callback) {
|
|
439
|
+
const yMap = new external_yjs_Map();
|
|
440
|
+
yMap.set('id', id_id.uuid());
|
|
441
|
+
yMap.set('field', field);
|
|
442
|
+
const conditions = this.yMap.get('conditions');
|
|
443
|
+
conditions.push([
|
|
444
|
+
yMap
|
|
445
|
+
]);
|
|
446
|
+
const node = new WhereFilterNodeBuilder(yMap);
|
|
447
|
+
callback(node);
|
|
448
|
+
return this;
|
|
449
|
+
}
|
|
450
|
+
addGroup(op, callback) {
|
|
451
|
+
const yMap = new external_yjs_Map();
|
|
452
|
+
yMap.set('id', id_id.uuid());
|
|
453
|
+
yMap.set('op', op);
|
|
454
|
+
yMap.set('conditions', new external_yjs_Array());
|
|
455
|
+
const conditions = this.yMap.get('conditions');
|
|
456
|
+
conditions.push([
|
|
457
|
+
yMap
|
|
458
|
+
]);
|
|
459
|
+
const group = new WhereGroupBuilder(yMap);
|
|
460
|
+
callback(group);
|
|
461
|
+
return this;
|
|
462
|
+
}
|
|
463
|
+
remove(idOrIndex) {
|
|
464
|
+
const conditions = this.yMap.get('conditions');
|
|
465
|
+
if ('number' == typeof idOrIndex) {
|
|
466
|
+
if (idOrIndex >= 0 && idOrIndex < conditions.length) conditions.delete(idOrIndex, 1);
|
|
467
|
+
} else {
|
|
468
|
+
const index = conditions.toArray().findIndex((item)=>item.get('id') === idOrIndex);
|
|
469
|
+
if (-1 !== index) conditions.delete(index, 1);
|
|
470
|
+
}
|
|
471
|
+
return this;
|
|
472
|
+
}
|
|
473
|
+
clear() {
|
|
474
|
+
const conditions = this.yMap.get('conditions');
|
|
475
|
+
conditions.delete(0, conditions.length);
|
|
476
|
+
return this;
|
|
477
|
+
}
|
|
478
|
+
toJson() {
|
|
479
|
+
return this.yMap.toJSON();
|
|
480
|
+
}
|
|
481
|
+
}
|
|
320
482
|
class WhereFiltersBuilder {
|
|
321
483
|
dsl;
|
|
322
484
|
doc;
|
|
@@ -328,11 +490,9 @@ class WhereFiltersBuilder {
|
|
|
328
490
|
});
|
|
329
491
|
}
|
|
330
492
|
add(field, callback) {
|
|
331
|
-
const filter = {
|
|
332
|
-
field
|
|
333
|
-
};
|
|
334
493
|
const yMap = new external_yjs_Map();
|
|
335
|
-
|
|
494
|
+
yMap.set('id', id_id.uuid());
|
|
495
|
+
yMap.set('field', field);
|
|
336
496
|
this.dsl.get('whereFilters').push([
|
|
337
497
|
yMap
|
|
338
498
|
]);
|
|
@@ -340,31 +500,53 @@ class WhereFiltersBuilder {
|
|
|
340
500
|
callback(node);
|
|
341
501
|
return this;
|
|
342
502
|
}
|
|
343
|
-
|
|
503
|
+
addGroup(op, callback) {
|
|
504
|
+
const yMap = new external_yjs_Map();
|
|
505
|
+
yMap.set('id', id_id.uuid());
|
|
506
|
+
yMap.set('op', op);
|
|
507
|
+
yMap.set('conditions', new external_yjs_Array());
|
|
508
|
+
this.dsl.get('whereFilters').push([
|
|
509
|
+
yMap
|
|
510
|
+
]);
|
|
511
|
+
const group = new WhereGroupBuilder(yMap);
|
|
512
|
+
callback(group);
|
|
513
|
+
return this;
|
|
514
|
+
}
|
|
515
|
+
update(id, callback) {
|
|
344
516
|
const whereFilters = this.dsl.get('whereFilters');
|
|
345
|
-
const index = whereFilters.toArray().findIndex((item)=>item.get('
|
|
346
|
-
if (-1 === index) throw new Error(`Where filter with
|
|
517
|
+
const index = whereFilters.toArray().findIndex((item)=>item.get('id') === id);
|
|
518
|
+
if (-1 === index) throw new Error(`Where filter with id ${id} not found`);
|
|
347
519
|
const filterYMap = whereFilters.get(index);
|
|
348
520
|
const node = new WhereFilterNodeBuilder(filterYMap);
|
|
349
521
|
callback(node);
|
|
350
522
|
return this;
|
|
351
523
|
}
|
|
352
|
-
|
|
524
|
+
updateGroup(id, callback) {
|
|
353
525
|
const whereFilters = this.dsl.get('whereFilters');
|
|
354
|
-
const index = whereFilters.toArray().findIndex((item)=>item.get('
|
|
355
|
-
if (-1 === index)
|
|
356
|
-
whereFilters.
|
|
526
|
+
const index = whereFilters.toArray().findIndex((item)=>item.get('id') === id);
|
|
527
|
+
if (-1 === index) throw new Error(`Where group with id ${id} not found`);
|
|
528
|
+
const yMap = whereFilters.get(index);
|
|
529
|
+
if (!WhereFiltersBuilder.isGroup(yMap)) throw new Error(`Item with id ${id} is not a group`);
|
|
530
|
+
const group = new WhereGroupBuilder(yMap);
|
|
531
|
+
callback(group);
|
|
357
532
|
return this;
|
|
358
533
|
}
|
|
359
|
-
|
|
534
|
+
remove(idOrIndex) {
|
|
360
535
|
const whereFilters = this.dsl.get('whereFilters');
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
536
|
+
if ('number' == typeof idOrIndex) {
|
|
537
|
+
if (idOrIndex >= 0 && idOrIndex < whereFilters.length) whereFilters.delete(idOrIndex, 1);
|
|
538
|
+
} else {
|
|
539
|
+
const index = whereFilters.toArray().findIndex((item)=>item.get('id') === idOrIndex);
|
|
540
|
+
if (-1 !== index) whereFilters.delete(index, 1);
|
|
541
|
+
}
|
|
542
|
+
return this;
|
|
364
543
|
}
|
|
365
|
-
|
|
544
|
+
find(id) {
|
|
366
545
|
const whereFilters = this.dsl.get('whereFilters');
|
|
367
|
-
|
|
546
|
+
const yMap = whereFilters.toArray().find((item)=>item.get('id') === id);
|
|
547
|
+
if (!yMap) return;
|
|
548
|
+
if (WhereFiltersBuilder.isGroup(yMap)) return new WhereGroupBuilder(yMap);
|
|
549
|
+
return new WhereFilterNodeBuilder(yMap);
|
|
368
550
|
}
|
|
369
551
|
clear() {
|
|
370
552
|
const whereFilters = this.dsl.get('whereFilters');
|
|
@@ -380,61 +562,13 @@ class WhereFiltersBuilder {
|
|
|
380
562
|
this.dsl.get('whereFilters').unobserve(callback);
|
|
381
563
|
};
|
|
382
564
|
}
|
|
565
|
+
static isGroup(yMap) {
|
|
566
|
+
return void 0 !== yMap.get('op') && void 0 !== yMap.get('conditions');
|
|
567
|
+
}
|
|
568
|
+
static isNode(yMap) {
|
|
569
|
+
return void 0 !== yMap.get('field');
|
|
570
|
+
}
|
|
383
571
|
}
|
|
384
|
-
const zVBIHavingFilter = z.object({
|
|
385
|
-
field: z.string(),
|
|
386
|
-
operator: z.string().optional(),
|
|
387
|
-
value: z.any().optional()
|
|
388
|
-
});
|
|
389
|
-
const zVBIHavingArray = z.array(zVBIHavingFilter);
|
|
390
|
-
const buildVQuery = (vbiDSL, builder)=>{
|
|
391
|
-
const wrapper = (processor)=>(queryDSL)=>processor(queryDSL, {
|
|
392
|
-
vbiDSL,
|
|
393
|
-
builder
|
|
394
|
-
});
|
|
395
|
-
return pipe({}, wrapper(buildSelect), wrapper(buildGroupBy), wrapper(buildWhere), wrapper(buildHaving), wrapper(buildOrderBy), wrapper(buildLimit));
|
|
396
|
-
};
|
|
397
|
-
const buildWhere = (queryDSL, context)=>{
|
|
398
|
-
const { vbiDSL } = context;
|
|
399
|
-
const whereFilters = vbiDSL.whereFilters || [];
|
|
400
|
-
if (0 === whereFilters.length) return queryDSL;
|
|
401
|
-
const result = {
|
|
402
|
-
...queryDSL
|
|
403
|
-
};
|
|
404
|
-
result.where = {
|
|
405
|
-
op: 'and',
|
|
406
|
-
conditions: whereFilters.flatMap((filter)=>{
|
|
407
|
-
if ('between' === filter.operator && filter.value && 'object' == typeof filter.value && !Array.isArray(filter.value)) {
|
|
408
|
-
const conditions = [];
|
|
409
|
-
if (void 0 !== filter.value.min && null !== filter.value.min && '' !== filter.value.min) conditions.push({
|
|
410
|
-
field: filter.field,
|
|
411
|
-
op: '<' === filter.value.leftOp ? '>' : '>=',
|
|
412
|
-
value: filter.value.min
|
|
413
|
-
});
|
|
414
|
-
if (void 0 !== filter.value.max && null !== filter.value.max && '' !== filter.value.max) conditions.push({
|
|
415
|
-
field: filter.field,
|
|
416
|
-
op: '<' === filter.value.rightOp ? '<' : '<=',
|
|
417
|
-
value: filter.value.max
|
|
418
|
-
});
|
|
419
|
-
return conditions;
|
|
420
|
-
}
|
|
421
|
-
let mappedOp = filter.operator ?? '=';
|
|
422
|
-
if (Array.isArray(filter.value)) {
|
|
423
|
-
if ('=' === mappedOp) mappedOp = 'in';
|
|
424
|
-
if ('!=' === mappedOp) mappedOp = 'not in';
|
|
425
|
-
}
|
|
426
|
-
return [
|
|
427
|
-
{
|
|
428
|
-
field: filter.field,
|
|
429
|
-
op: mappedOp,
|
|
430
|
-
value: filter.value
|
|
431
|
-
}
|
|
432
|
-
];
|
|
433
|
-
})
|
|
434
|
-
};
|
|
435
|
-
return result;
|
|
436
|
-
};
|
|
437
|
-
const buildOrderBy = (queryDSL, context)=>queryDSL;
|
|
438
572
|
const buildSelect = (queryDSL, context)=>{
|
|
439
573
|
const { vbiDSL } = context;
|
|
440
574
|
const measures = vbiDSL.measures;
|
|
@@ -466,14 +600,68 @@ const buildGroupBy = (queryDSL, context)=>{
|
|
|
466
600
|
result.groupBy = dimensionNodes.map((dimension)=>dimension.field);
|
|
467
601
|
return result;
|
|
468
602
|
};
|
|
469
|
-
const
|
|
603
|
+
const buildWhere = (queryDSL, context)=>{
|
|
604
|
+
const { vbiDSL } = context;
|
|
605
|
+
const whereFilters = vbiDSL.whereFilters || [];
|
|
606
|
+
if (0 === whereFilters.length) return queryDSL;
|
|
470
607
|
const result = {
|
|
471
608
|
...queryDSL
|
|
472
609
|
};
|
|
473
|
-
|
|
474
|
-
|
|
610
|
+
result.where = {
|
|
611
|
+
op: 'and',
|
|
612
|
+
conditions: whereFilters.flatMap(mapClauseToCondition)
|
|
613
|
+
};
|
|
475
614
|
return result;
|
|
476
615
|
};
|
|
616
|
+
function isWhereGroup(clause) {
|
|
617
|
+
return 'op' in clause && 'conditions' in clause;
|
|
618
|
+
}
|
|
619
|
+
function mapClauseToCondition(clause) {
|
|
620
|
+
if (isWhereGroup(clause)) return [
|
|
621
|
+
mapGroupToCondition(clause)
|
|
622
|
+
];
|
|
623
|
+
return mapFilterToCondition(clause);
|
|
624
|
+
}
|
|
625
|
+
function mapGroupToCondition(group) {
|
|
626
|
+
return {
|
|
627
|
+
op: group.op,
|
|
628
|
+
conditions: group.conditions.flatMap(mapClauseToCondition)
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
function mapFilterToCondition(filter) {
|
|
632
|
+
if ('between' === filter.op) return handleBetweenFilter(filter);
|
|
633
|
+
return handleSimpleFilter(filter);
|
|
634
|
+
}
|
|
635
|
+
function handleBetweenFilter(filter) {
|
|
636
|
+
const conditions = [];
|
|
637
|
+
const value = filter.value;
|
|
638
|
+
if (void 0 !== value.min && null !== value.min && '' !== value.min) conditions.push({
|
|
639
|
+
field: filter.field,
|
|
640
|
+
op: '<' === value.leftOp ? '>' : '>=',
|
|
641
|
+
value: value.min
|
|
642
|
+
});
|
|
643
|
+
if (void 0 !== value.max && null !== value.max && '' !== value.max) conditions.push({
|
|
644
|
+
field: filter.field,
|
|
645
|
+
op: '<' === value.rightOp ? '<' : '<=',
|
|
646
|
+
value: value.max
|
|
647
|
+
});
|
|
648
|
+
return conditions;
|
|
649
|
+
}
|
|
650
|
+
function handleSimpleFilter(filter) {
|
|
651
|
+
let mappedOp = filter.op ?? '=';
|
|
652
|
+
const value = filter.value;
|
|
653
|
+
if (Array.isArray(value)) {
|
|
654
|
+
if ('=' === mappedOp) mappedOp = 'in';
|
|
655
|
+
if ('!=' === mappedOp) mappedOp = 'not in';
|
|
656
|
+
}
|
|
657
|
+
return [
|
|
658
|
+
{
|
|
659
|
+
field: filter.field,
|
|
660
|
+
op: mappedOp,
|
|
661
|
+
value
|
|
662
|
+
}
|
|
663
|
+
];
|
|
664
|
+
}
|
|
477
665
|
const buildHaving = (queryDSL, context)=>{
|
|
478
666
|
const { vbiDSL } = context;
|
|
479
667
|
const havingFilters = vbiDSL.havingFilters || [];
|
|
@@ -483,17 +671,50 @@ const buildHaving = (queryDSL, context)=>{
|
|
|
483
671
|
};
|
|
484
672
|
result.having = {
|
|
485
673
|
op: 'and',
|
|
486
|
-
conditions: havingFilters.
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
674
|
+
conditions: havingFilters.flatMap(buildHaving_mapClauseToCondition)
|
|
675
|
+
};
|
|
676
|
+
return result;
|
|
677
|
+
};
|
|
678
|
+
function isHavingGroup(clause) {
|
|
679
|
+
return 'op' in clause && 'conditions' in clause;
|
|
680
|
+
}
|
|
681
|
+
function buildHaving_mapClauseToCondition(clause) {
|
|
682
|
+
if (isHavingGroup(clause)) return [
|
|
683
|
+
buildHaving_mapGroupToCondition(clause)
|
|
684
|
+
];
|
|
685
|
+
return buildHaving_mapFilterToCondition(clause);
|
|
686
|
+
}
|
|
687
|
+
function buildHaving_mapGroupToCondition(group) {
|
|
688
|
+
return {
|
|
689
|
+
op: group.op,
|
|
690
|
+
conditions: group.conditions.flatMap(buildHaving_mapClauseToCondition)
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
function buildHaving_mapFilterToCondition(filter) {
|
|
694
|
+
const mappedOp = filter.op ?? '=';
|
|
695
|
+
return [
|
|
696
|
+
{
|
|
697
|
+
field: filter.field,
|
|
698
|
+
op: mappedOp,
|
|
699
|
+
value: filter.value
|
|
700
|
+
}
|
|
701
|
+
];
|
|
702
|
+
}
|
|
703
|
+
const buildLimit = (queryDSL, context)=>{
|
|
704
|
+
const result = {
|
|
705
|
+
...queryDSL
|
|
494
706
|
};
|
|
707
|
+
const limit = context.vbiDSL.limit ?? 1000;
|
|
708
|
+
result.limit = limit;
|
|
495
709
|
return result;
|
|
496
710
|
};
|
|
711
|
+
const buildVQuery = (vbiDSL, builder)=>{
|
|
712
|
+
const wrapper = (processor)=>(queryDSL)=>processor(queryDSL, {
|
|
713
|
+
vbiDSL,
|
|
714
|
+
builder
|
|
715
|
+
});
|
|
716
|
+
return pipe({}, wrapper(buildSelect), wrapper(buildGroupBy), wrapper(buildWhere), wrapper(buildHaving), wrapper(buildLimit));
|
|
717
|
+
};
|
|
497
718
|
const connectorMap = new Map();
|
|
498
719
|
const registerConnector = (id, connector)=>{
|
|
499
720
|
connectorMap.set(id, connector);
|
|
@@ -596,7 +817,27 @@ const createVBI = ()=>({
|
|
|
596
817
|
if (vbi.limit) dsl.set('limit', vbi.limit);
|
|
597
818
|
if (vbi.locale) dsl.set('locale', vbi.locale);
|
|
598
819
|
if (vbi.version) dsl.set('version', vbi.version);
|
|
599
|
-
const
|
|
820
|
+
const toYMap = (obj, ensureId = false)=>{
|
|
821
|
+
const yMap = new external_yjs_Map();
|
|
822
|
+
if (ensureId && !obj.id) yMap.set('id', id_id.uuid());
|
|
823
|
+
for (const [key, value] of Object.entries(obj))if ('conditions' === key && Array.isArray(value)) {
|
|
824
|
+
const yArr = new external_yjs_Array();
|
|
825
|
+
value.forEach((child)=>{
|
|
826
|
+
if (child instanceof external_yjs_Map) yArr.push([
|
|
827
|
+
child
|
|
828
|
+
]);
|
|
829
|
+
else if ('object' == typeof child && null !== child) yArr.push([
|
|
830
|
+
toYMap(child, true)
|
|
831
|
+
]);
|
|
832
|
+
else yArr.push([
|
|
833
|
+
child
|
|
834
|
+
]);
|
|
835
|
+
});
|
|
836
|
+
yMap.set(key, yArr);
|
|
837
|
+
} else yMap.set(key, value);
|
|
838
|
+
return yMap;
|
|
839
|
+
};
|
|
840
|
+
const ensureYArray = (arr, ensureId = false)=>{
|
|
600
841
|
if (!arr) return new external_yjs_Array();
|
|
601
842
|
if (arr instanceof external_yjs_Array) return arr;
|
|
602
843
|
const yArr = new external_yjs_Array();
|
|
@@ -604,20 +845,17 @@ const createVBI = ()=>({
|
|
|
604
845
|
if (item instanceof external_yjs_Map) yArr.push([
|
|
605
846
|
item
|
|
606
847
|
]);
|
|
607
|
-
else if ('object' == typeof item && null !== item)
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
yMap
|
|
612
|
-
]);
|
|
613
|
-
} else yArr.push([
|
|
848
|
+
else if ('object' == typeof item && null !== item) yArr.push([
|
|
849
|
+
toYMap(item, ensureId)
|
|
850
|
+
]);
|
|
851
|
+
else yArr.push([
|
|
614
852
|
item
|
|
615
853
|
]);
|
|
616
854
|
});
|
|
617
855
|
return yArr;
|
|
618
856
|
};
|
|
619
|
-
dsl.set('whereFilters', ensureYArray(vbi.whereFilters));
|
|
620
|
-
dsl.set('havingFilters', ensureYArray(vbi.havingFilters));
|
|
857
|
+
dsl.set('whereFilters', ensureYArray(vbi.whereFilters, true));
|
|
858
|
+
dsl.set('havingFilters', ensureYArray(vbi.havingFilters, true));
|
|
621
859
|
dsl.set('measures', ensureYArray(vbi.measures));
|
|
622
860
|
dsl.set('dimensions', ensureYArray(vbi.dimensions));
|
|
623
861
|
});
|
|
@@ -625,4 +863,52 @@ const createVBI = ()=>({
|
|
|
625
863
|
}
|
|
626
864
|
});
|
|
627
865
|
const VBI = createVBI();
|
|
628
|
-
|
|
866
|
+
const zVBIFilter = z.object({
|
|
867
|
+
id: z.string(),
|
|
868
|
+
field: z.string(),
|
|
869
|
+
op: z.string().optional(),
|
|
870
|
+
value: z.any().optional()
|
|
871
|
+
});
|
|
872
|
+
const zVBIWhereGroup = z.lazy(()=>z.object({
|
|
873
|
+
id: z.string(),
|
|
874
|
+
op: z["enum"]([
|
|
875
|
+
'and',
|
|
876
|
+
'or'
|
|
877
|
+
]),
|
|
878
|
+
conditions: z.array(zVBIWhereClause)
|
|
879
|
+
}));
|
|
880
|
+
const zVBIWhereClause = z.lazy(()=>z.union([
|
|
881
|
+
zVBIFilter,
|
|
882
|
+
zVBIWhereGroup
|
|
883
|
+
]));
|
|
884
|
+
function isVBIFilter(clause) {
|
|
885
|
+
return 'field' in clause;
|
|
886
|
+
}
|
|
887
|
+
function isVBIWhereGroup(clause) {
|
|
888
|
+
return 'conditions' in clause;
|
|
889
|
+
}
|
|
890
|
+
const zVBIHavingFilter = z.object({
|
|
891
|
+
id: z.string(),
|
|
892
|
+
field: z.string(),
|
|
893
|
+
op: z.string().optional(),
|
|
894
|
+
value: z.any().optional()
|
|
895
|
+
});
|
|
896
|
+
const zVBIHavingGroup = z.lazy(()=>z.object({
|
|
897
|
+
id: z.string(),
|
|
898
|
+
op: z["enum"]([
|
|
899
|
+
'and',
|
|
900
|
+
'or'
|
|
901
|
+
]),
|
|
902
|
+
conditions: z.array(zVBIHavingClause)
|
|
903
|
+
}));
|
|
904
|
+
const zVBIHavingClause = z.lazy(()=>z.union([
|
|
905
|
+
zVBIHavingFilter,
|
|
906
|
+
zVBIHavingGroup
|
|
907
|
+
]));
|
|
908
|
+
function isVBIHavingFilter(clause) {
|
|
909
|
+
return 'field' in clause;
|
|
910
|
+
}
|
|
911
|
+
function isVBIHavingGroup(clause) {
|
|
912
|
+
return 'conditions' in clause;
|
|
913
|
+
}
|
|
914
|
+
export { ChartTypeBuilder, DimensionsBuilder, MeasuresBuilder, VBI, VBIBuilder, buildVQuery, findTreeNodesBy, id_id as id, isVBIFilter, isVBIHavingFilter, isVBIHavingGroup, isVBIWhereGroup, preorderTraverse };
|
package/dist/pipeline/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { buildVQuery } from './vqueryDSL';
|
|
1
|
+
export { buildVQuery } from './vqueryDSL/index';
|