@visactor/vbi 0.4.12 → 0.4.14

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 (32) hide show
  1. package/dist/builder/index.d.ts +1 -0
  2. package/dist/builder/sub-builders/havingFilters/having-builder.d.ts +33 -20
  3. package/dist/builder/sub-builders/havingFilters/having-group-builder.d.ts +48 -0
  4. package/dist/builder/sub-builders/havingFilters/having-node-builder.d.ts +8 -0
  5. package/dist/builder/sub-builders/havingFilters/index.d.ts +1 -0
  6. package/dist/builder/sub-builders/index.d.ts +1 -1
  7. package/dist/builder/sub-builders/whereFilters/index.d.ts +1 -0
  8. package/dist/builder/sub-builders/whereFilters/where-builder.d.ts +30 -17
  9. package/dist/builder/sub-builders/whereFilters/where-group-builder.d.ts +48 -0
  10. package/dist/builder/sub-builders/whereFilters/where-node-builder.d.ts +8 -0
  11. package/dist/builder/undo-manager.d.ts +37 -0
  12. package/dist/builder/vbi-builder.d.ts +2 -1
  13. package/dist/index.cjs +446 -130
  14. package/dist/index.js +428 -121
  15. package/dist/pipeline/index.d.ts +1 -1
  16. package/dist/pipeline/vqueryDSL/buildGroupBy.d.ts +2 -0
  17. package/dist/pipeline/vqueryDSL/buildHaving.d.ts +2 -0
  18. package/dist/pipeline/vqueryDSL/buildLimit.d.ts +2 -0
  19. package/dist/pipeline/vqueryDSL/buildSelect.d.ts +2 -0
  20. package/dist/pipeline/vqueryDSL/buildWhere.d.ts +2 -0
  21. package/dist/pipeline/vqueryDSL/index.d.ts +4 -1
  22. package/dist/pipeline/vqueryDSL/types.d.ts +7 -0
  23. package/dist/types/builder/VBIInterface.d.ts +2 -1
  24. package/dist/types/dsl/havingFilters/having.d.ts +12 -7
  25. package/dist/types/dsl/index.d.ts +4 -2
  26. package/dist/types/dsl/vbi/vbi.d.ts +2 -10
  27. package/dist/types/dsl/whereFilters/filters.d.ts +12 -1
  28. package/dist/types/index.d.ts +0 -1
  29. package/dist/utils/id.d.ts +3 -0
  30. package/dist/utils/index.d.ts +1 -0
  31. package/package.json +12 -10
  32. package/dist/pipeline/vqueryDSL/buildVQuery.d.ts +0 -4
package/dist/index.cjs CHANGED
@@ -24,16 +24,19 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- zVBIHavingFilter: ()=>zVBIHavingFilter,
28
- zVBIHavingArray: ()=>zVBIHavingArray,
27
+ preorderTraverse: ()=>vseed_namespaceObject.preorderTraverse,
28
+ isVBIHavingGroup: ()=>isVBIHavingGroup,
29
29
  MeasuresBuilder: ()=>MeasuresBuilder,
30
30
  DimensionsBuilder: ()=>DimensionsBuilder,
31
31
  VBIBuilder: ()=>VBIBuilder,
32
32
  ChartTypeBuilder: ()=>ChartTypeBuilder,
33
+ isVBIFilter: ()=>isVBIFilter,
33
34
  VBI: ()=>VBI,
34
- preorderTraverse: ()=>vseed_namespaceObject.preorderTraverse,
35
+ isVBIWhereGroup: ()=>isVBIWhereGroup,
36
+ isVBIHavingFilter: ()=>isVBIHavingFilter,
35
37
  buildVQuery: ()=>buildVQuery,
36
- findTreeNodesBy: ()=>vseed_namespaceObject.findTreeNodesBy
38
+ findTreeNodesBy: ()=>vseed_namespaceObject.findTreeNodesBy,
39
+ id: ()=>id_id
37
40
  });
38
41
  const external_yjs_namespaceObject = require("yjs");
39
42
  class DimensionNodeBuilder {
@@ -200,20 +203,90 @@ class MeasuresBuilder {
200
203
  return 'children' in node;
201
204
  }
202
205
  }
206
+ const vseed_namespaceObject = require("@visactor/vseed");
207
+ const external_uuid_namespaceObject = require("uuid");
208
+ const id_id = {
209
+ uuid: ()=>(0, external_uuid_namespaceObject.v4)()
210
+ };
203
211
  class HavingFiltersNodeBuilder {
204
212
  yMap;
205
213
  constructor(yMap){
206
214
  this.yMap = yMap;
207
215
  }
216
+ getId() {
217
+ return this.yMap.get('id');
218
+ }
208
219
  getField() {
209
220
  return this.yMap.get('field');
210
221
  }
222
+ getOperator() {
223
+ return this.yMap.get('op');
224
+ }
211
225
  setValue(value) {
212
226
  this.yMap.set('value', value);
213
227
  return this;
214
228
  }
215
229
  setOperator(operator) {
216
- this.yMap.set('operator', operator);
230
+ this.yMap.set('op', operator);
231
+ return this;
232
+ }
233
+ toJson() {
234
+ return this.yMap.toJSON();
235
+ }
236
+ }
237
+ class HavingGroupBuilder {
238
+ yMap;
239
+ constructor(yMap){
240
+ this.yMap = yMap;
241
+ }
242
+ getId() {
243
+ return this.yMap.get('id');
244
+ }
245
+ getOperator() {
246
+ return this.yMap.get('op');
247
+ }
248
+ setOperator(op) {
249
+ this.yMap.set('op', op);
250
+ return this;
251
+ }
252
+ add(field, callback) {
253
+ const yMap = new external_yjs_namespaceObject.Map();
254
+ yMap.set('id', id_id.uuid());
255
+ yMap.set('field', field);
256
+ const conditions = this.yMap.get('conditions');
257
+ conditions.push([
258
+ yMap
259
+ ]);
260
+ const node = new HavingFiltersNodeBuilder(yMap);
261
+ callback(node);
262
+ return this;
263
+ }
264
+ addGroup(op, callback) {
265
+ const yMap = new external_yjs_namespaceObject.Map();
266
+ yMap.set('id', id_id.uuid());
267
+ yMap.set('op', op);
268
+ yMap.set('conditions', new external_yjs_namespaceObject.Array());
269
+ const conditions = this.yMap.get('conditions');
270
+ conditions.push([
271
+ yMap
272
+ ]);
273
+ const group = new HavingGroupBuilder(yMap);
274
+ callback(group);
275
+ return this;
276
+ }
277
+ remove(idOrIndex) {
278
+ const conditions = this.yMap.get('conditions');
279
+ if ('number' == typeof idOrIndex) {
280
+ if (idOrIndex >= 0 && idOrIndex < conditions.length) conditions.delete(idOrIndex, 1);
281
+ } else {
282
+ const index = conditions.toArray().findIndex((item)=>item.get('id') === idOrIndex);
283
+ if (-1 !== index) conditions.delete(index, 1);
284
+ }
285
+ return this;
286
+ }
287
+ clear() {
288
+ const conditions = this.yMap.get('conditions');
289
+ conditions.delete(0, conditions.length);
217
290
  return this;
218
291
  }
219
292
  toJson() {
@@ -222,54 +295,76 @@ class HavingFiltersNodeBuilder {
222
295
  }
223
296
  class HavingFiltersBuilder {
224
297
  dsl;
225
- constructor(_doc, dsl){
298
+ doc;
299
+ constructor(doc, dsl){
300
+ this.doc = doc;
226
301
  this.dsl = dsl;
302
+ if (!this.dsl.get('havingFilters')) this.doc.transact(()=>{
303
+ this.dsl.set('havingFilters', new external_yjs_namespaceObject.Array());
304
+ });
227
305
  }
228
306
  add(field, callback) {
229
- if (!field || 'string' != typeof field) throw new Error('Field is required and must be a string');
230
- const defaultFilter = {
231
- field,
232
- operator: 'eq',
233
- value: null
234
- };
235
307
  const yMap = new external_yjs_namespaceObject.Map();
236
- for (const [key, value] of Object.entries(defaultFilter))yMap.set(key, value);
308
+ yMap.set('id', id_id.uuid());
309
+ yMap.set('field', field);
237
310
  this.dsl.get('havingFilters').push([
238
311
  yMap
239
312
  ]);
240
- const filterNode = new HavingFiltersNodeBuilder(yMap);
241
- callback(filterNode);
313
+ const node = new HavingFiltersNodeBuilder(yMap);
314
+ callback(node);
242
315
  return this;
243
316
  }
244
- update(field, callback) {
317
+ addGroup(op, callback) {
318
+ const yMap = new external_yjs_namespaceObject.Map();
319
+ yMap.set('id', id_id.uuid());
320
+ yMap.set('op', op);
321
+ yMap.set('conditions', new external_yjs_namespaceObject.Array());
322
+ this.dsl.get('havingFilters').push([
323
+ yMap
324
+ ]);
325
+ const group = new HavingGroupBuilder(yMap);
326
+ callback(group);
327
+ return this;
328
+ }
329
+ update(id, callback) {
245
330
  const havingFilters = this.dsl.get('havingFilters');
246
- const index = havingFilters.toArray().findIndex((item)=>item.get('field') === field);
247
- if (-1 === index) throw new Error(`Having filter with field "${field}" not found`);
331
+ const index = havingFilters.toArray().findIndex((item)=>item.get('id') === id);
332
+ if (-1 === index) throw new Error(`Having filter with id ${id} not found`);
248
333
  const filterYMap = havingFilters.get(index);
249
334
  const node = new HavingFiltersNodeBuilder(filterYMap);
250
335
  callback(node);
251
336
  return this;
252
337
  }
253
- remove(field) {
254
- if (!field || 'string' != typeof field) console.error('[HavingFiltersBuilder] Invalid field name:', field);
338
+ updateGroup(id, callback) {
255
339
  const havingFilters = this.dsl.get('havingFilters');
256
- const index = havingFilters.toArray().findIndex((item)=>item.get('field') === field);
257
- if (-1 !== index) this.dsl.get('havingFilters').delete(index, 1);
340
+ const index = havingFilters.toArray().findIndex((item)=>item.get('id') === id);
341
+ if (-1 === index) throw new Error(`Having group with id ${id} not found`);
342
+ const yMap = havingFilters.get(index);
343
+ if (!HavingFiltersBuilder.isGroup(yMap)) throw new Error(`Item with id ${id} is not a group`);
344
+ const group = new HavingGroupBuilder(yMap);
345
+ callback(group);
258
346
  return this;
259
347
  }
260
- find(field) {
348
+ remove(idOrIndex) {
261
349
  const havingFilters = this.dsl.get('havingFilters');
262
- const index = havingFilters.toArray().findIndex((item)=>item.get('field') === field);
263
- if (-1 === index) return;
264
- return new HavingFiltersNodeBuilder(havingFilters.get(index));
350
+ if ('number' == typeof idOrIndex) {
351
+ if (idOrIndex >= 0 && idOrIndex < havingFilters.length) havingFilters.delete(idOrIndex, 1);
352
+ } else {
353
+ const index = havingFilters.toArray().findIndex((item)=>item.get('id') === idOrIndex);
354
+ if (-1 !== index) havingFilters.delete(index, 1);
355
+ }
356
+ return this;
265
357
  }
266
- findAll() {
358
+ find(id) {
267
359
  const havingFilters = this.dsl.get('havingFilters');
268
- return havingFilters.toArray().map((yMap)=>new HavingFiltersNodeBuilder(yMap));
360
+ const yMap = havingFilters.toArray().find((item)=>item.get('id') === id);
361
+ if (!yMap) return;
362
+ if (HavingFiltersBuilder.isGroup(yMap)) return new HavingGroupBuilder(yMap);
363
+ return new HavingFiltersNodeBuilder(yMap);
269
364
  }
270
365
  clear() {
271
366
  const havingFilters = this.dsl.get('havingFilters');
272
- if (havingFilters.length > 0) havingFilters.delete(0, havingFilters.length);
367
+ havingFilters.delete(0, havingFilters.length);
273
368
  return this;
274
369
  }
275
370
  toJson() {
@@ -281,8 +376,13 @@ class HavingFiltersBuilder {
281
376
  this.dsl.get('havingFilters').unobserve(callback);
282
377
  };
283
378
  }
379
+ static isGroup(yMap) {
380
+ return void 0 !== yMap.get('op') && void 0 !== yMap.get('conditions');
381
+ }
382
+ static isNode(yMap) {
383
+ return void 0 !== yMap.get('field');
384
+ }
284
385
  }
285
- const vseed_namespaceObject = require("@visactor/vseed");
286
386
  class ChartTypeBuilder {
287
387
  dsl;
288
388
  constructor(_doc, dsl){
@@ -337,11 +437,17 @@ class WhereFilterNodeBuilder {
337
437
  constructor(yMap){
338
438
  this.yMap = yMap;
339
439
  }
440
+ getId() {
441
+ return this.yMap.get('id');
442
+ }
340
443
  getField() {
341
444
  return this.yMap.get('field');
342
445
  }
446
+ getOperator() {
447
+ return this.yMap.get('op');
448
+ }
343
449
  setOperator(operator) {
344
- this.yMap.set('operator', operator);
450
+ this.yMap.set('op', operator);
345
451
  return this;
346
452
  }
347
453
  setValue(value) {
@@ -352,6 +458,65 @@ class WhereFilterNodeBuilder {
352
458
  return this.yMap.toJSON();
353
459
  }
354
460
  }
461
+ class WhereGroupBuilder {
462
+ yMap;
463
+ constructor(yMap){
464
+ this.yMap = yMap;
465
+ }
466
+ getId() {
467
+ return this.yMap.get('id');
468
+ }
469
+ getOperator() {
470
+ return this.yMap.get('op');
471
+ }
472
+ setOperator(op) {
473
+ this.yMap.set('op', op);
474
+ return this;
475
+ }
476
+ add(field, callback) {
477
+ const yMap = new external_yjs_namespaceObject.Map();
478
+ yMap.set('id', id_id.uuid());
479
+ yMap.set('field', field);
480
+ const conditions = this.yMap.get('conditions');
481
+ conditions.push([
482
+ yMap
483
+ ]);
484
+ const node = new WhereFilterNodeBuilder(yMap);
485
+ callback(node);
486
+ return this;
487
+ }
488
+ addGroup(op, callback) {
489
+ const yMap = new external_yjs_namespaceObject.Map();
490
+ yMap.set('id', id_id.uuid());
491
+ yMap.set('op', op);
492
+ yMap.set('conditions', new external_yjs_namespaceObject.Array());
493
+ const conditions = this.yMap.get('conditions');
494
+ conditions.push([
495
+ yMap
496
+ ]);
497
+ const group = new WhereGroupBuilder(yMap);
498
+ callback(group);
499
+ return this;
500
+ }
501
+ remove(idOrIndex) {
502
+ const conditions = this.yMap.get('conditions');
503
+ if ('number' == typeof idOrIndex) {
504
+ if (idOrIndex >= 0 && idOrIndex < conditions.length) conditions.delete(idOrIndex, 1);
505
+ } else {
506
+ const index = conditions.toArray().findIndex((item)=>item.get('id') === idOrIndex);
507
+ if (-1 !== index) conditions.delete(index, 1);
508
+ }
509
+ return this;
510
+ }
511
+ clear() {
512
+ const conditions = this.yMap.get('conditions');
513
+ conditions.delete(0, conditions.length);
514
+ return this;
515
+ }
516
+ toJson() {
517
+ return this.yMap.toJSON();
518
+ }
519
+ }
355
520
  class WhereFiltersBuilder {
356
521
  dsl;
357
522
  doc;
@@ -363,11 +528,9 @@ class WhereFiltersBuilder {
363
528
  });
364
529
  }
365
530
  add(field, callback) {
366
- const filter = {
367
- field
368
- };
369
531
  const yMap = new external_yjs_namespaceObject.Map();
370
- for (const [key, value] of Object.entries(filter))yMap.set(key, value);
532
+ yMap.set('id', id_id.uuid());
533
+ yMap.set('field', field);
371
534
  this.dsl.get('whereFilters').push([
372
535
  yMap
373
536
  ]);
@@ -375,31 +538,53 @@ class WhereFiltersBuilder {
375
538
  callback(node);
376
539
  return this;
377
540
  }
378
- update(field, callback) {
541
+ addGroup(op, callback) {
542
+ const yMap = new external_yjs_namespaceObject.Map();
543
+ yMap.set('id', id_id.uuid());
544
+ yMap.set('op', op);
545
+ yMap.set('conditions', new external_yjs_namespaceObject.Array());
546
+ this.dsl.get('whereFilters').push([
547
+ yMap
548
+ ]);
549
+ const group = new WhereGroupBuilder(yMap);
550
+ callback(group);
551
+ return this;
552
+ }
553
+ update(id, callback) {
379
554
  const whereFilters = this.dsl.get('whereFilters');
380
- const index = whereFilters.toArray().findIndex((item)=>item.get('field') === field);
381
- if (-1 === index) throw new Error(`Where filter with field ${field} not found`);
555
+ const index = whereFilters.toArray().findIndex((item)=>item.get('id') === id);
556
+ if (-1 === index) throw new Error(`Where filter with id ${id} not found`);
382
557
  const filterYMap = whereFilters.get(index);
383
558
  const node = new WhereFilterNodeBuilder(filterYMap);
384
559
  callback(node);
385
560
  return this;
386
561
  }
387
- remove(field) {
562
+ updateGroup(id, callback) {
388
563
  const whereFilters = this.dsl.get('whereFilters');
389
- const index = whereFilters.toArray().findIndex((item)=>item.get('field') === field);
390
- if (-1 === index) return this;
391
- whereFilters.delete(index, 1);
564
+ const index = whereFilters.toArray().findIndex((item)=>item.get('id') === id);
565
+ if (-1 === index) throw new Error(`Where group with id ${id} not found`);
566
+ const yMap = whereFilters.get(index);
567
+ if (!WhereFiltersBuilder.isGroup(yMap)) throw new Error(`Item with id ${id} is not a group`);
568
+ const group = new WhereGroupBuilder(yMap);
569
+ callback(group);
392
570
  return this;
393
571
  }
394
- find(field) {
572
+ remove(idOrIndex) {
395
573
  const whereFilters = this.dsl.get('whereFilters');
396
- const index = whereFilters.toArray().findIndex((item)=>item.get('field') === field);
397
- if (-1 === index) return;
398
- return new WhereFilterNodeBuilder(whereFilters.get(index));
574
+ if ('number' == typeof idOrIndex) {
575
+ if (idOrIndex >= 0 && idOrIndex < whereFilters.length) whereFilters.delete(idOrIndex, 1);
576
+ } else {
577
+ const index = whereFilters.toArray().findIndex((item)=>item.get('id') === idOrIndex);
578
+ if (-1 !== index) whereFilters.delete(index, 1);
579
+ }
580
+ return this;
399
581
  }
400
- findAll() {
582
+ find(id) {
401
583
  const whereFilters = this.dsl.get('whereFilters');
402
- return whereFilters.toArray().map((yMap)=>new WhereFilterNodeBuilder(yMap));
584
+ const yMap = whereFilters.toArray().find((item)=>item.get('id') === id);
585
+ if (!yMap) return;
586
+ if (WhereFiltersBuilder.isGroup(yMap)) return new WhereGroupBuilder(yMap);
587
+ return new WhereFilterNodeBuilder(yMap);
403
588
  }
404
589
  clear() {
405
590
  const whereFilters = this.dsl.get('whereFilters');
@@ -415,63 +600,35 @@ class WhereFiltersBuilder {
415
600
  this.dsl.get('whereFilters').unobserve(callback);
416
601
  };
417
602
  }
603
+ static isGroup(yMap) {
604
+ return void 0 !== yMap.get('op') && void 0 !== yMap.get('conditions');
605
+ }
606
+ static isNode(yMap) {
607
+ return void 0 !== yMap.get('field');
608
+ }
609
+ }
610
+ class UndoManager {
611
+ manager;
612
+ constructor(scope){
613
+ this.manager = new external_yjs_namespaceObject.UndoManager(scope);
614
+ }
615
+ undo() {
616
+ return null !== this.manager.undo();
617
+ }
618
+ redo() {
619
+ return null !== this.manager.redo();
620
+ }
621
+ canUndo() {
622
+ return this.manager.canUndo();
623
+ }
624
+ canRedo() {
625
+ return this.manager.canRedo();
626
+ }
627
+ clear(clearUndoStack, clearRedoStack) {
628
+ this.manager.clear(clearUndoStack, clearRedoStack);
629
+ }
418
630
  }
419
- const external_zod_namespaceObject = require("zod");
420
- const zVBIHavingFilter = external_zod_namespaceObject.z.object({
421
- field: external_zod_namespaceObject.z.string(),
422
- operator: external_zod_namespaceObject.z.string().optional(),
423
- value: external_zod_namespaceObject.z.any().optional()
424
- });
425
- const zVBIHavingArray = external_zod_namespaceObject.z.array(zVBIHavingFilter);
426
631
  const external_remeda_namespaceObject = require("remeda");
427
- const buildVQuery = (vbiDSL, builder)=>{
428
- const wrapper = (processor)=>(queryDSL)=>processor(queryDSL, {
429
- vbiDSL,
430
- builder
431
- });
432
- return (0, external_remeda_namespaceObject.pipe)({}, wrapper(buildSelect), wrapper(buildGroupBy), wrapper(buildWhere), wrapper(buildHaving), wrapper(buildOrderBy), wrapper(buildLimit));
433
- };
434
- const buildWhere = (queryDSL, context)=>{
435
- const { vbiDSL } = context;
436
- const whereFilters = vbiDSL.whereFilters || [];
437
- if (0 === whereFilters.length) return queryDSL;
438
- const result = {
439
- ...queryDSL
440
- };
441
- result.where = {
442
- op: 'and',
443
- conditions: whereFilters.flatMap((filter)=>{
444
- if ('between' === filter.operator && filter.value && 'object' == typeof filter.value && !Array.isArray(filter.value)) {
445
- const conditions = [];
446
- if (void 0 !== filter.value.min && null !== filter.value.min && '' !== filter.value.min) conditions.push({
447
- field: filter.field,
448
- op: '<' === filter.value.leftOp ? '>' : '>=',
449
- value: filter.value.min
450
- });
451
- if (void 0 !== filter.value.max && null !== filter.value.max && '' !== filter.value.max) conditions.push({
452
- field: filter.field,
453
- op: '<' === filter.value.rightOp ? '<' : '<=',
454
- value: filter.value.max
455
- });
456
- return conditions;
457
- }
458
- let mappedOp = filter.operator ?? '=';
459
- if (Array.isArray(filter.value)) {
460
- if ('=' === mappedOp) mappedOp = 'in';
461
- if ('!=' === mappedOp) mappedOp = 'not in';
462
- }
463
- return [
464
- {
465
- field: filter.field,
466
- op: mappedOp,
467
- value: filter.value
468
- }
469
- ];
470
- })
471
- };
472
- return result;
473
- };
474
- const buildOrderBy = (queryDSL, context)=>queryDSL;
475
632
  const buildSelect = (queryDSL, context)=>{
476
633
  const { vbiDSL } = context;
477
634
  const measures = vbiDSL.measures;
@@ -503,14 +660,68 @@ const buildGroupBy = (queryDSL, context)=>{
503
660
  result.groupBy = dimensionNodes.map((dimension)=>dimension.field);
504
661
  return result;
505
662
  };
506
- const buildLimit = (queryDSL, context)=>{
663
+ const buildWhere = (queryDSL, context)=>{
664
+ const { vbiDSL } = context;
665
+ const whereFilters = vbiDSL.whereFilters || [];
666
+ if (0 === whereFilters.length) return queryDSL;
507
667
  const result = {
508
668
  ...queryDSL
509
669
  };
510
- const limit = context.vbiDSL.limit ?? 1000;
511
- result.limit = limit;
670
+ result.where = {
671
+ op: 'and',
672
+ conditions: whereFilters.flatMap(mapClauseToCondition)
673
+ };
512
674
  return result;
513
675
  };
676
+ function isWhereGroup(clause) {
677
+ return 'op' in clause && 'conditions' in clause;
678
+ }
679
+ function mapClauseToCondition(clause) {
680
+ if (isWhereGroup(clause)) return [
681
+ mapGroupToCondition(clause)
682
+ ];
683
+ return mapFilterToCondition(clause);
684
+ }
685
+ function mapGroupToCondition(group) {
686
+ return {
687
+ op: group.op,
688
+ conditions: group.conditions.flatMap(mapClauseToCondition)
689
+ };
690
+ }
691
+ function mapFilterToCondition(filter) {
692
+ if ('between' === filter.op) return handleBetweenFilter(filter);
693
+ return handleSimpleFilter(filter);
694
+ }
695
+ function handleBetweenFilter(filter) {
696
+ const conditions = [];
697
+ const value = filter.value;
698
+ if (void 0 !== value.min && null !== value.min && '' !== value.min) conditions.push({
699
+ field: filter.field,
700
+ op: '<' === value.leftOp ? '>' : '>=',
701
+ value: value.min
702
+ });
703
+ if (void 0 !== value.max && null !== value.max && '' !== value.max) conditions.push({
704
+ field: filter.field,
705
+ op: '<' === value.rightOp ? '<' : '<=',
706
+ value: value.max
707
+ });
708
+ return conditions;
709
+ }
710
+ function handleSimpleFilter(filter) {
711
+ let mappedOp = filter.op ?? '=';
712
+ const value = filter.value;
713
+ if (Array.isArray(value)) {
714
+ if ('=' === mappedOp) mappedOp = 'in';
715
+ if ('!=' === mappedOp) mappedOp = 'not in';
716
+ }
717
+ return [
718
+ {
719
+ field: filter.field,
720
+ op: mappedOp,
721
+ value
722
+ }
723
+ ];
724
+ }
514
725
  const buildHaving = (queryDSL, context)=>{
515
726
  const { vbiDSL } = context;
516
727
  const havingFilters = vbiDSL.havingFilters || [];
@@ -520,17 +731,50 @@ const buildHaving = (queryDSL, context)=>{
520
731
  };
521
732
  result.having = {
522
733
  op: 'and',
523
- conditions: havingFilters.map((filter)=>{
524
- const mappedOp = filter.operator ?? '=';
525
- return {
526
- field: filter.field,
527
- op: mappedOp,
528
- value: filter.value
529
- };
530
- })
734
+ conditions: havingFilters.flatMap(buildHaving_mapClauseToCondition)
531
735
  };
532
736
  return result;
533
737
  };
738
+ function isHavingGroup(clause) {
739
+ return 'op' in clause && 'conditions' in clause;
740
+ }
741
+ function buildHaving_mapClauseToCondition(clause) {
742
+ if (isHavingGroup(clause)) return [
743
+ buildHaving_mapGroupToCondition(clause)
744
+ ];
745
+ return buildHaving_mapFilterToCondition(clause);
746
+ }
747
+ function buildHaving_mapGroupToCondition(group) {
748
+ return {
749
+ op: group.op,
750
+ conditions: group.conditions.flatMap(buildHaving_mapClauseToCondition)
751
+ };
752
+ }
753
+ function buildHaving_mapFilterToCondition(filter) {
754
+ const mappedOp = filter.op ?? '=';
755
+ return [
756
+ {
757
+ field: filter.field,
758
+ op: mappedOp,
759
+ value: filter.value
760
+ }
761
+ ];
762
+ }
763
+ const buildLimit = (queryDSL, context)=>{
764
+ const result = {
765
+ ...queryDSL
766
+ };
767
+ const limit = context.vbiDSL.limit ?? 1000;
768
+ result.limit = limit;
769
+ return result;
770
+ };
771
+ const buildVQuery = (vbiDSL, builder)=>{
772
+ const wrapper = (processor)=>(queryDSL)=>processor(queryDSL, {
773
+ vbiDSL,
774
+ builder
775
+ });
776
+ return (0, external_remeda_namespaceObject.pipe)({}, wrapper(buildSelect), wrapper(buildGroupBy), wrapper(buildWhere), wrapper(buildHaving), wrapper(buildLimit));
777
+ };
534
778
  const connectorMap = new Map();
535
779
  const registerConnector = (id, connector)=>{
536
780
  connectorMap.set(id, connector);
@@ -553,7 +797,7 @@ class VBIBuilder {
553
797
  constructor(doc){
554
798
  this.doc = doc;
555
799
  this.dsl = doc.getMap('dsl');
556
- this.undoManager = new external_yjs_namespaceObject.UndoManager(this.dsl);
800
+ this.undoManager = new UndoManager(this.dsl);
557
801
  this.chartType = new ChartTypeBuilder(doc, this.dsl);
558
802
  this.measures = new MeasuresBuilder(doc, this.dsl);
559
803
  this.dimensions = new DimensionsBuilder(doc, this.dsl);
@@ -633,7 +877,27 @@ const createVBI = ()=>({
633
877
  if (vbi.limit) dsl.set('limit', vbi.limit);
634
878
  if (vbi.locale) dsl.set('locale', vbi.locale);
635
879
  if (vbi.version) dsl.set('version', vbi.version);
636
- const ensureYArray = (arr)=>{
880
+ const toYMap = (obj, ensureId = false)=>{
881
+ const yMap = new external_yjs_namespaceObject.Map();
882
+ if (ensureId && !obj.id) yMap.set('id', id_id.uuid());
883
+ for (const [key, value] of Object.entries(obj))if ('conditions' === key && Array.isArray(value)) {
884
+ const yArr = new external_yjs_namespaceObject.Array();
885
+ value.forEach((child)=>{
886
+ if (child instanceof external_yjs_namespaceObject.Map) yArr.push([
887
+ child
888
+ ]);
889
+ else if ('object' == typeof child && null !== child) yArr.push([
890
+ toYMap(child, true)
891
+ ]);
892
+ else yArr.push([
893
+ child
894
+ ]);
895
+ });
896
+ yMap.set(key, yArr);
897
+ } else yMap.set(key, value);
898
+ return yMap;
899
+ };
900
+ const ensureYArray = (arr, ensureId = false)=>{
637
901
  if (!arr) return new external_yjs_namespaceObject.Array();
638
902
  if (arr instanceof external_yjs_namespaceObject.Array) return arr;
639
903
  const yArr = new external_yjs_namespaceObject.Array();
@@ -641,20 +905,17 @@ const createVBI = ()=>({
641
905
  if (item instanceof external_yjs_namespaceObject.Map) yArr.push([
642
906
  item
643
907
  ]);
644
- else if ('object' == typeof item && null !== item) {
645
- const yMap = new external_yjs_namespaceObject.Map();
646
- for (const [key, value] of Object.entries(item))yMap.set(key, value);
647
- yArr.push([
648
- yMap
649
- ]);
650
- } else yArr.push([
908
+ else if ('object' == typeof item && null !== item) yArr.push([
909
+ toYMap(item, ensureId)
910
+ ]);
911
+ else yArr.push([
651
912
  item
652
913
  ]);
653
914
  });
654
915
  return yArr;
655
916
  };
656
- dsl.set('whereFilters', ensureYArray(vbi.whereFilters));
657
- dsl.set('havingFilters', ensureYArray(vbi.havingFilters));
917
+ dsl.set('whereFilters', ensureYArray(vbi.whereFilters, true));
918
+ dsl.set('havingFilters', ensureYArray(vbi.havingFilters, true));
658
919
  dsl.set('measures', ensureYArray(vbi.measures));
659
920
  dsl.set('dimensions', ensureYArray(vbi.dimensions));
660
921
  });
@@ -662,6 +923,55 @@ const createVBI = ()=>({
662
923
  }
663
924
  });
664
925
  const VBI = createVBI();
926
+ const external_zod_namespaceObject = require("zod");
927
+ const zVBIFilter = external_zod_namespaceObject.z.object({
928
+ id: external_zod_namespaceObject.z.string(),
929
+ field: external_zod_namespaceObject.z.string(),
930
+ op: external_zod_namespaceObject.z.string().optional(),
931
+ value: external_zod_namespaceObject.z.any().optional()
932
+ });
933
+ const zVBIWhereGroup = external_zod_namespaceObject.z.lazy(()=>external_zod_namespaceObject.z.object({
934
+ id: external_zod_namespaceObject.z.string(),
935
+ op: external_zod_namespaceObject.z["enum"]([
936
+ 'and',
937
+ 'or'
938
+ ]),
939
+ conditions: external_zod_namespaceObject.z.array(zVBIWhereClause)
940
+ }));
941
+ const zVBIWhereClause = external_zod_namespaceObject.z.lazy(()=>external_zod_namespaceObject.z.union([
942
+ zVBIFilter,
943
+ zVBIWhereGroup
944
+ ]));
945
+ function isVBIFilter(clause) {
946
+ return 'field' in clause;
947
+ }
948
+ function isVBIWhereGroup(clause) {
949
+ return 'conditions' in clause;
950
+ }
951
+ const zVBIHavingFilter = external_zod_namespaceObject.z.object({
952
+ id: external_zod_namespaceObject.z.string(),
953
+ field: external_zod_namespaceObject.z.string(),
954
+ op: external_zod_namespaceObject.z.string().optional(),
955
+ value: external_zod_namespaceObject.z.any().optional()
956
+ });
957
+ const zVBIHavingGroup = external_zod_namespaceObject.z.lazy(()=>external_zod_namespaceObject.z.object({
958
+ id: external_zod_namespaceObject.z.string(),
959
+ op: external_zod_namespaceObject.z["enum"]([
960
+ 'and',
961
+ 'or'
962
+ ]),
963
+ conditions: external_zod_namespaceObject.z.array(zVBIHavingClause)
964
+ }));
965
+ const zVBIHavingClause = external_zod_namespaceObject.z.lazy(()=>external_zod_namespaceObject.z.union([
966
+ zVBIHavingFilter,
967
+ zVBIHavingGroup
968
+ ]));
969
+ function isVBIHavingFilter(clause) {
970
+ return 'field' in clause;
971
+ }
972
+ function isVBIHavingGroup(clause) {
973
+ return 'conditions' in clause;
974
+ }
665
975
  exports.ChartTypeBuilder = __webpack_exports__.ChartTypeBuilder;
666
976
  exports.DimensionsBuilder = __webpack_exports__.DimensionsBuilder;
667
977
  exports.MeasuresBuilder = __webpack_exports__.MeasuresBuilder;
@@ -669,9 +979,12 @@ exports.VBI = __webpack_exports__.VBI;
669
979
  exports.VBIBuilder = __webpack_exports__.VBIBuilder;
670
980
  exports.buildVQuery = __webpack_exports__.buildVQuery;
671
981
  exports.findTreeNodesBy = __webpack_exports__.findTreeNodesBy;
982
+ exports.id = __webpack_exports__.id;
983
+ exports.isVBIFilter = __webpack_exports__.isVBIFilter;
984
+ exports.isVBIHavingFilter = __webpack_exports__.isVBIHavingFilter;
985
+ exports.isVBIHavingGroup = __webpack_exports__.isVBIHavingGroup;
986
+ exports.isVBIWhereGroup = __webpack_exports__.isVBIWhereGroup;
672
987
  exports.preorderTraverse = __webpack_exports__.preorderTraverse;
673
- exports.zVBIHavingArray = __webpack_exports__.zVBIHavingArray;
674
- exports.zVBIHavingFilter = __webpack_exports__.zVBIHavingFilter;
675
988
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
676
989
  "ChartTypeBuilder",
677
990
  "DimensionsBuilder",
@@ -680,9 +993,12 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
680
993
  "VBIBuilder",
681
994
  "buildVQuery",
682
995
  "findTreeNodesBy",
683
- "preorderTraverse",
684
- "zVBIHavingArray",
685
- "zVBIHavingFilter"
996
+ "id",
997
+ "isVBIFilter",
998
+ "isVBIHavingFilter",
999
+ "isVBIHavingGroup",
1000
+ "isVBIWhereGroup",
1001
+ "preorderTraverse"
686
1002
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
687
1003
  Object.defineProperty(exports, '__esModule', {
688
1004
  value: true