@sisense/sdk-data 2.12.0 → 2.13.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.
@@ -721,6 +721,146 @@ export declare const topRanking: (attribute: Attribute, measure: Measure, count:
721
721
  * @returns A filter instance
722
722
  */
723
723
  export declare const bottomRanking: (attribute: Attribute, measure: Measure, count: number, config?: BaseFilterConfig) => Filter;
724
+ /**
725
+ * Creates a filter that returns the top N values of the last dimension,
726
+ * independently for each unique combination of all preceding dimensions.
727
+ *
728
+ * This filter applies ranking within groups rather than globally. It shows the top N values
729
+ * of the rightmost dimension for every unique combination of the other dimensions to its left.
730
+ * The order of dimensions in your query determines the grouping behavior.
731
+ *
732
+ * **Key Differences from {@link topRanking}:**
733
+ * - `topRanking`: Filters a specific dimension globally (you specify which dimension)
734
+ * - `measureTopRanking`: Always filters the last/rightmost dimension, grouped by all others
735
+ *
736
+ * **How it works:**
737
+ * - With 1 dimension: Returns the top N values of that dimension
738
+ * - With 2+ dimensions: Returns the top N values of the LAST dimension for each combination of the others
739
+ *
740
+ * @example
741
+ * **Example 1: Single dimension (equivalent to topRanking) - Query with one dimension [Category]**
742
+ * ```ts
743
+ * // Returns top 5 Categories by total revenue
744
+ * filterFactory.measureTopRanking(
745
+ * measureFactory.sum(DM.Commerce.Revenue),
746
+ * 5
747
+ * )
748
+ * ```
749
+ * Result: 5 categories (e.g., Cell Phones, Computers, TVs, etc.)
750
+ *
751
+ * This produces the same result as:
752
+ * ```ts
753
+ * filterFactory.topRanking(
754
+ * DM.Commerce.Category,
755
+ * measureFactory.sum(DM.Commerce.Revenue),
756
+ * 5
757
+ * )
758
+ * ```
759
+ *
760
+ * **Note:** With only one dimension, there are no groups to rank within,
761
+ * so the behavior is identical to `topRanking`.
762
+ *
763
+ * @example
764
+ * **Example 2: Two dimensions - Query with dimensions [Gender, Category]**
765
+ * ```ts
766
+ * // Returns top 2 Categories for each Gender
767
+ * filterFactory.measureTopRanking(
768
+ * measureFactory.sum(DM.Commerce.Revenue),
769
+ * 2
770
+ * )
771
+ * ```
772
+ * Result: 3 genders × 2 categories each = 6 rows
773
+ * - Male: Top 2 categories by revenue
774
+ * - Female: Top 2 categories by revenue
775
+ * - Unspecified: Top 2 categories by revenue
776
+ *
777
+ * @example
778
+ * **Example 3: Three dimensions - Query with dimensions [Gender, Age Range, Category]**
779
+ * ```ts
780
+ * // Returns top 2 Categories for each (Gender, Age Range) combination
781
+ * filterFactory.measureTopRanking(
782
+ * measureFactory.sum(DM.Commerce.Revenue),
783
+ * 2
784
+ * )
785
+ * ```
786
+ * Result: 3 genders × 7 age ranges × 2 categories per combination = ~42 rows
787
+ *
788
+ * @param measure - Base measure to rank by
789
+ * @param count - Number of items to return per group (applies to the last dimension)
790
+ * @param config - Optional configuration for the filter
791
+ * @returns A filter instance
792
+ */
793
+ export declare const measureTopRanking: (measure: BaseMeasure, count: number, config?: BaseFilterConfig) => Filter;
794
+ /**
795
+ * Creates a filter that returns the bottom N values of the last dimension,
796
+ * independently for each unique combination of all preceding dimensions.
797
+ *
798
+ * This filter applies ranking within groups rather than globally. It shows the bottom N values
799
+ * of the rightmost dimension for every unique combination of the other dimensions to its left.
800
+ * The order of dimensions in your query determines the grouping behavior.
801
+ *
802
+ * **Key Differences from {@link bottomRanking}:**
803
+ * - `bottomRanking`: Filters a specific dimension globally (you specify which dimension)
804
+ * - `measureBottomRanking`: Always filters the last/rightmost dimension, grouped by all others
805
+ *
806
+ * **How it works:**
807
+ * - With 1 dimension: Returns the bottom N values of that dimension
808
+ * - With 2+ dimensions: Returns the bottom N values of the LAST dimension for each combination of the others
809
+ *
810
+ * @example
811
+ * **Example 1: Single dimension (equivalent to bottomRanking) - Query with one dimension [Category]**
812
+ * ```ts
813
+ * // Returns bottom 5 Categories by revenue
814
+ * filterFactory.measureBottomRanking(
815
+ * measureFactory.sum(DM.Commerce.Revenue),
816
+ * 5
817
+ * )
818
+ * ```
819
+ * Result: 5 categories with lowest revenue (e.g., Accessories, Cables, etc.)
820
+ *
821
+ * This produces the same result as:
822
+ * ```ts
823
+ * filterFactory.bottomRanking(
824
+ * DM.Commerce.Category,
825
+ * measureFactory.sum(DM.Commerce.Revenue),
826
+ * 5
827
+ * )
828
+ * ```
829
+ *
830
+ * **Note:** With only one dimension, there are no groups to rank within,
831
+ * so the behavior is identical to `bottomRanking`.
832
+ *
833
+ * @example
834
+ * **Example 2: Two dimensions - Query with dimensions [Gender, Category]**
835
+ * ```ts
836
+ * // Returns bottom 2 Categories for each Gender
837
+ * filterFactory.measureBottomRanking(
838
+ * measureFactory.sum(DM.Commerce.Revenue),
839
+ * 2
840
+ * )
841
+ * ```
842
+ * Result: 3 genders × 2 categories each = 6 rows
843
+ * - Male: Bottom 2 categories by revenue
844
+ * - Female: Bottom 2 categories by revenue
845
+ * - Unspecified: Bottom 2 categories by revenue
846
+ *
847
+ * @example
848
+ * **Example 3: Three dimensions - Query with dimensions [Gender, Age Range, Category]**
849
+ * ```ts
850
+ * // Returns bottom 2 Categories for each (Gender, Age Range) combination
851
+ * filterFactory.measureBottomRanking(
852
+ * measureFactory.sum(DM.Commerce.Revenue),
853
+ * 2
854
+ * )
855
+ * ```
856
+ * Result: 3 genders × 7 age ranges × 2 categories per combination = ~42 rows
857
+ *
858
+ * @param measure - Base measure to rank by
859
+ * @param count - Number of items to return per group (applies to the last dimension)
860
+ * @param config - Optional configuration for the filter
861
+ * @returns A filter instance
862
+ */
863
+ export declare const measureBottomRanking: (measure: BaseMeasure, count: number, config?: BaseFilterConfig) => Filter;
724
864
  /**
725
865
  * Creates a filter that contains a list of dependent/cascading filters,
726
866
  * where each filter depends on the results or state of the previous ones in the array.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /* eslint-disable max-lines */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.customFilter = exports.logic = exports.cascading = exports.bottomRanking = exports.topRanking = exports.measureBetweenNotEqual = exports.measureBetween = exports.measureLessThan = exports.measureLessThanOrEqual = exports.measureGreaterThanOrEqual = exports.measureGreaterThan = exports.measureEquals = exports.measureBase = exports.today = exports.thisQuarter = exports.thisMonth = exports.thisYear = exports.dateRelativeTo = exports.dateRelativeFrom = exports.dateRelative = exports.dateRange = exports.dateTo = exports.dateFrom = exports.members = exports.numeric = exports.betweenNotEqual = exports.between = exports.lessThanOrEqual = exports.lessThan = exports.greaterThanOrEqual = exports.greaterThan = exports.equals = exports.doesntEqual = exports.like = exports.startsWith = exports.endsWith = exports.contains = exports.doesntStartWith = exports.doesntEndWith = exports.doesntContain = exports.exclude = exports.intersection = exports.union = void 0;
4
+ exports.customFilter = exports.logic = exports.cascading = exports.measureBottomRanking = exports.measureTopRanking = exports.bottomRanking = exports.topRanking = exports.measureBetweenNotEqual = exports.measureBetween = exports.measureLessThan = exports.measureLessThanOrEqual = exports.measureGreaterThanOrEqual = exports.measureGreaterThan = exports.measureEquals = exports.measureBase = exports.today = exports.thisQuarter = exports.thisMonth = exports.thisYear = exports.dateRelativeTo = exports.dateRelativeFrom = exports.dateRelative = exports.dateRange = exports.dateTo = exports.dateFrom = exports.members = exports.numeric = exports.betweenNotEqual = exports.between = exports.lessThanOrEqual = exports.lessThan = exports.greaterThanOrEqual = exports.greaterThan = exports.equals = exports.doesntEqual = exports.like = exports.startsWith = exports.endsWith = exports.contains = exports.doesntStartWith = exports.doesntEndWith = exports.doesntContain = exports.exclude = exports.intersection = exports.union = void 0;
5
5
  /* eslint-disable max-params */
6
6
  /* eslint-disable @typescript-eslint/no-shadow */
7
7
  const compose_code_utils_js_1 = require("../compose-code-utils.js");
@@ -750,19 +750,146 @@ exports.topRanking = (0, compose_code_utils_js_1.withComposeCodeForFilter)((attr
750
750
  * @returns A filter instance
751
751
  */
752
752
  exports.bottomRanking = (0, compose_code_utils_js_1.withComposeCodeForFilter)((attribute, measure, count, config) => new filters_js_1.RankingFilter(attribute, measure, filters_js_1.RankingOperators.Bottom, count, config), 'bottomRanking');
753
- const relate = (node) => {
754
- if (Array.isArray(node)) {
755
- const [first, ...rest] = node;
756
- return rest.length === 0
757
- ? relate(first)
758
- : {
759
- operator: 'AND',
760
- left: relate(first),
761
- right: relate(rest),
762
- };
763
- }
764
- return node;
765
- };
753
+ /**
754
+ * Creates a filter that returns the top N values of the last dimension,
755
+ * independently for each unique combination of all preceding dimensions.
756
+ *
757
+ * This filter applies ranking within groups rather than globally. It shows the top N values
758
+ * of the rightmost dimension for every unique combination of the other dimensions to its left.
759
+ * The order of dimensions in your query determines the grouping behavior.
760
+ *
761
+ * **Key Differences from {@link topRanking}:**
762
+ * - `topRanking`: Filters a specific dimension globally (you specify which dimension)
763
+ * - `measureTopRanking`: Always filters the last/rightmost dimension, grouped by all others
764
+ *
765
+ * **How it works:**
766
+ * - With 1 dimension: Returns the top N values of that dimension
767
+ * - With 2+ dimensions: Returns the top N values of the LAST dimension for each combination of the others
768
+ *
769
+ * @example
770
+ * **Example 1: Single dimension (equivalent to topRanking) - Query with one dimension [Category]**
771
+ * ```ts
772
+ * // Returns top 5 Categories by total revenue
773
+ * filterFactory.measureTopRanking(
774
+ * measureFactory.sum(DM.Commerce.Revenue),
775
+ * 5
776
+ * )
777
+ * ```
778
+ * Result: 5 categories (e.g., Cell Phones, Computers, TVs, etc.)
779
+ *
780
+ * This produces the same result as:
781
+ * ```ts
782
+ * filterFactory.topRanking(
783
+ * DM.Commerce.Category,
784
+ * measureFactory.sum(DM.Commerce.Revenue),
785
+ * 5
786
+ * )
787
+ * ```
788
+ *
789
+ * **Note:** With only one dimension, there are no groups to rank within,
790
+ * so the behavior is identical to `topRanking`.
791
+ *
792
+ * @example
793
+ * **Example 2: Two dimensions - Query with dimensions [Gender, Category]**
794
+ * ```ts
795
+ * // Returns top 2 Categories for each Gender
796
+ * filterFactory.measureTopRanking(
797
+ * measureFactory.sum(DM.Commerce.Revenue),
798
+ * 2
799
+ * )
800
+ * ```
801
+ * Result: 3 genders × 2 categories each = 6 rows
802
+ * - Male: Top 2 categories by revenue
803
+ * - Female: Top 2 categories by revenue
804
+ * - Unspecified: Top 2 categories by revenue
805
+ *
806
+ * @example
807
+ * **Example 3: Three dimensions - Query with dimensions [Gender, Age Range, Category]**
808
+ * ```ts
809
+ * // Returns top 2 Categories for each (Gender, Age Range) combination
810
+ * filterFactory.measureTopRanking(
811
+ * measureFactory.sum(DM.Commerce.Revenue),
812
+ * 2
813
+ * )
814
+ * ```
815
+ * Result: 3 genders × 7 age ranges × 2 categories per combination = ~42 rows
816
+ *
817
+ * @param measure - Base measure to rank by
818
+ * @param count - Number of items to return per group (applies to the last dimension)
819
+ * @param config - Optional configuration for the filter
820
+ * @returns A filter instance
821
+ */
822
+ exports.measureTopRanking = (0, compose_code_utils_js_1.withComposeCodeForFilter)((measure, count, config) => new filters_js_1.MeasureRankingFilter(measure, filters_js_1.RankingOperators.Top, count, config), 'measureTopRanking');
823
+ /**
824
+ * Creates a filter that returns the bottom N values of the last dimension,
825
+ * independently for each unique combination of all preceding dimensions.
826
+ *
827
+ * This filter applies ranking within groups rather than globally. It shows the bottom N values
828
+ * of the rightmost dimension for every unique combination of the other dimensions to its left.
829
+ * The order of dimensions in your query determines the grouping behavior.
830
+ *
831
+ * **Key Differences from {@link bottomRanking}:**
832
+ * - `bottomRanking`: Filters a specific dimension globally (you specify which dimension)
833
+ * - `measureBottomRanking`: Always filters the last/rightmost dimension, grouped by all others
834
+ *
835
+ * **How it works:**
836
+ * - With 1 dimension: Returns the bottom N values of that dimension
837
+ * - With 2+ dimensions: Returns the bottom N values of the LAST dimension for each combination of the others
838
+ *
839
+ * @example
840
+ * **Example 1: Single dimension (equivalent to bottomRanking) - Query with one dimension [Category]**
841
+ * ```ts
842
+ * // Returns bottom 5 Categories by revenue
843
+ * filterFactory.measureBottomRanking(
844
+ * measureFactory.sum(DM.Commerce.Revenue),
845
+ * 5
846
+ * )
847
+ * ```
848
+ * Result: 5 categories with lowest revenue (e.g., Accessories, Cables, etc.)
849
+ *
850
+ * This produces the same result as:
851
+ * ```ts
852
+ * filterFactory.bottomRanking(
853
+ * DM.Commerce.Category,
854
+ * measureFactory.sum(DM.Commerce.Revenue),
855
+ * 5
856
+ * )
857
+ * ```
858
+ *
859
+ * **Note:** With only one dimension, there are no groups to rank within,
860
+ * so the behavior is identical to `bottomRanking`.
861
+ *
862
+ * @example
863
+ * **Example 2: Two dimensions - Query with dimensions [Gender, Category]**
864
+ * ```ts
865
+ * // Returns bottom 2 Categories for each Gender
866
+ * filterFactory.measureBottomRanking(
867
+ * measureFactory.sum(DM.Commerce.Revenue),
868
+ * 2
869
+ * )
870
+ * ```
871
+ * Result: 3 genders × 2 categories each = 6 rows
872
+ * - Male: Bottom 2 categories by revenue
873
+ * - Female: Bottom 2 categories by revenue
874
+ * - Unspecified: Bottom 2 categories by revenue
875
+ *
876
+ * @example
877
+ * **Example 3: Three dimensions - Query with dimensions [Gender, Age Range, Category]**
878
+ * ```ts
879
+ * // Returns bottom 2 Categories for each (Gender, Age Range) combination
880
+ * filterFactory.measureBottomRanking(
881
+ * measureFactory.sum(DM.Commerce.Revenue),
882
+ * 2
883
+ * )
884
+ * ```
885
+ * Result: 3 genders × 7 age ranges × 2 categories per combination = ~42 rows
886
+ *
887
+ * @param measure - Base measure to rank by
888
+ * @param count - Number of items to return per group (applies to the last dimension)
889
+ * @param config - Optional configuration for the filter
890
+ * @returns A filter instance
891
+ */
892
+ exports.measureBottomRanking = (0, compose_code_utils_js_1.withComposeCodeForFilter)((measure, count, config) => new filters_js_1.MeasureRankingFilter(measure, filters_js_1.RankingOperators.Bottom, count, config), 'measureBottomRanking');
766
893
  // CASCADING FILTERS
767
894
  /**
768
895
  * Creates a filter that contains a list of dependent/cascading filters,
@@ -819,6 +946,26 @@ exports.cascading = (0, compose_code_utils_js_1.withComposeCodeForFilter)((filte
819
946
  // eslint-disable-next-line @typescript-eslint/no-namespace
820
947
  var logic;
821
948
  (function (logic) {
949
+ /**
950
+ * Relates a filter or filter relations node
951
+ *
952
+ * @param node - Filter or filter relations node
953
+ * @returns Related filter or filter relations node
954
+ * @internal
955
+ */
956
+ const relate = (node) => {
957
+ if (Array.isArray(node)) {
958
+ const [first, ...rest] = node;
959
+ return rest.length === 0
960
+ ? relate(first)
961
+ : {
962
+ operator: 'AND',
963
+ left: relate(first),
964
+ right: relate(rest),
965
+ };
966
+ }
967
+ return node;
968
+ };
822
969
  /**
823
970
  * Creates an 'AND' filter relations
824
971
  *
@@ -1,5 +1,5 @@
1
1
  import { DimensionalElement } from '../base.js';
2
- import { Attribute, BaseFilterConfig, CompleteBaseFilterConfig, CompleteMembersFilterConfig, Filter, LevelAttribute, Measure, MembersFilterConfig } from '../interfaces.js';
2
+ import { Attribute, BaseFilterConfig, BaseMeasure, CompleteBaseFilterConfig, CompleteMembersFilterConfig, Filter, LevelAttribute, Measure, MembersFilterConfig } from '../interfaces.js';
3
3
  import { AnyObject, JSONObject } from '../types.js';
4
4
  /**
5
5
  * Different text operators that can be used with text filters
@@ -70,6 +70,7 @@ export declare const FilterTypes: {
70
70
  readonly exclude: "exclude";
71
71
  readonly measure: "measure";
72
72
  readonly ranking: "ranking";
73
+ readonly measureRanking: "measure-ranking";
73
74
  readonly text: "text";
74
75
  readonly numeric: "numeric";
75
76
  readonly dateRange: "dateRange";
@@ -298,6 +299,32 @@ export declare class RankingFilter extends AbstractFilter {
298
299
  */
299
300
  filterJaql(): any;
300
301
  }
302
+ /**
303
+ * @internal
304
+ */
305
+ export declare class MeasureRankingFilter extends AbstractFilter {
306
+ /**
307
+ * @internal
308
+ */
309
+ readonly __serializable: string;
310
+ count: number;
311
+ operator: string;
312
+ measure: BaseMeasure;
313
+ constructor(measure: BaseMeasure, operator: string, count: number, config?: BaseFilterConfig, composeCode?: string);
314
+ /**
315
+ * gets the element's ID
316
+ */
317
+ get id(): string;
318
+ /**
319
+ * Gets a serializable representation of the element
320
+ */
321
+ serialize(): JSONObject;
322
+ /**
323
+ * Gets JAQL representing this Filter instance
324
+ */
325
+ filterJaql(): any;
326
+ jaql(nested?: boolean | undefined): any;
327
+ }
301
328
  /**
302
329
  * @internal
303
330
  */
@@ -427,6 +454,13 @@ export declare function isNumericFilter(filter: Filter & AnyObject): filter is N
427
454
  * @internal
428
455
  */
429
456
  export declare function isRankingFilter(filter: Filter & AnyObject): filter is RankingFilter;
457
+ /**
458
+ * Checks if a filter is a MeasureRankingFilter.
459
+ *
460
+ * @param filter - The filter to check.
461
+ * @internal
462
+ */
463
+ export declare function isMeasureRankingFilter(filter: Filter & AnyObject): filter is MeasureRankingFilter;
430
464
  /**
431
465
  * Checks if a filter is a MeasureFilter.
432
466
  *
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createFilter = exports.isDateRangeFilter = exports.isTextFilter = exports.isRelativeDateFilter = exports.isCascadingFilter = exports.isLogicalAttributeFilter = exports.isExcludeFilter = exports.isMeasureFilter = exports.isRankingFilter = exports.isNumericFilter = exports.isMembersFilter = exports.isCustomFilter = exports.CustomFilter = exports.RelativeDateFilter = exports.DateRangeFilter = exports.TextFilter = exports.NumericFilter = exports.RankingFilter = exports.MeasureFilter = exports.DoubleOperatorFilter = exports.ExcludeFilter = exports.CascadingFilter = exports.MembersFilter = exports.LogicalAttributeFilter = exports.FilterTypes = exports.RankingOperators = exports.LogicalOperators = exports.DateOperators = exports.NumericOperators = exports.TextOperators = void 0;
6
+ exports.createFilter = exports.isDateRangeFilter = exports.isTextFilter = exports.isRelativeDateFilter = exports.isCascadingFilter = exports.isLogicalAttributeFilter = exports.isExcludeFilter = exports.isMeasureFilter = exports.isMeasureRankingFilter = exports.isRankingFilter = exports.isNumericFilter = exports.isMembersFilter = exports.isCustomFilter = exports.CustomFilter = exports.RelativeDateFilter = exports.DateRangeFilter = exports.TextFilter = exports.NumericFilter = exports.MeasureRankingFilter = exports.RankingFilter = exports.MeasureFilter = exports.DoubleOperatorFilter = exports.ExcludeFilter = exports.CascadingFilter = exports.MembersFilter = exports.LogicalAttributeFilter = exports.FilterTypes = exports.RankingOperators = exports.LogicalOperators = exports.DateOperators = exports.NumericOperators = exports.TextOperators = void 0;
7
7
  /* eslint-disable max-lines */
8
8
  const hash_it_1 = __importDefault(require("hash-it"));
9
9
  const merge_js_1 = __importDefault(require("lodash-es/merge.js"));
@@ -83,6 +83,7 @@ exports.FilterTypes = {
83
83
  exclude: 'exclude',
84
84
  measure: 'measure',
85
85
  ranking: 'ranking',
86
+ measureRanking: 'measure-ranking',
86
87
  text: 'text',
87
88
  numeric: 'numeric',
88
89
  dateRange: 'dateRange',
@@ -530,6 +531,60 @@ class RankingFilter extends AbstractFilter {
530
531
  }
531
532
  }
532
533
  exports.RankingFilter = RankingFilter;
534
+ /**
535
+ * @internal
536
+ */
537
+ class MeasureRankingFilter extends AbstractFilter {
538
+ constructor(measure, operator, count, config, composeCode) {
539
+ super(measure.attribute, exports.FilterTypes.measureRanking, config, composeCode);
540
+ /**
541
+ * @internal
542
+ */
543
+ this.__serializable = 'MeasureRankingFilter';
544
+ this.count = count;
545
+ this.operator = operator;
546
+ this.measure = measure;
547
+ }
548
+ /**
549
+ * gets the element's ID
550
+ */
551
+ get id() {
552
+ return `${this.operator}_${this.count}_measure_${this.measure.id}`;
553
+ }
554
+ /**
555
+ * Gets a serializable representation of the element
556
+ */
557
+ serialize() {
558
+ const result = super.serialize();
559
+ result.measure = this.measure.serialize();
560
+ result.count = this.count;
561
+ result.operator = this.operator;
562
+ return result;
563
+ }
564
+ /**
565
+ * Gets JAQL representing this Filter instance
566
+ */
567
+ filterJaql() {
568
+ const result = {};
569
+ result[this.operator] = this.count;
570
+ return result;
571
+ }
572
+ jaql(nested) {
573
+ if (this.config.disabled) {
574
+ return AbstractFilter.disabledJaql(nested);
575
+ }
576
+ const result = super.jaql(nested);
577
+ if ((0, measures_js_1.isDimensionalBaseMeasure)(this.measure)) {
578
+ Object.entries(this.measure.jaql().jaql).forEach(([key, value]) => {
579
+ result.jaql[key] = value;
580
+ });
581
+ }
582
+ // Add type: 'measure' for measure-based filters
583
+ result.jaql.type = 'measure';
584
+ return result;
585
+ }
586
+ }
587
+ exports.MeasureRankingFilter = MeasureRankingFilter;
533
588
  /**
534
589
  * @internal
535
590
  */
@@ -756,6 +811,16 @@ function isRankingFilter(filter) {
756
811
  return filter && filter.__serializable === 'RankingFilter';
757
812
  }
758
813
  exports.isRankingFilter = isRankingFilter;
814
+ /**
815
+ * Checks if a filter is a MeasureRankingFilter.
816
+ *
817
+ * @param filter - The filter to check.
818
+ * @internal
819
+ */
820
+ function isMeasureRankingFilter(filter) {
821
+ return filter && filter.__serializable === 'MeasureRankingFilter';
822
+ }
823
+ exports.isMeasureRankingFilter = isMeasureRankingFilter;
759
824
  /**
760
825
  * Checks if a filter is a MeasureFilter.
761
826
  *
@@ -834,31 +899,24 @@ function createFilter(json) {
834
899
  switch (json.filterType) {
835
900
  case exports.FilterTypes.logicalAttribute:
836
901
  return new LogicalAttributeFilter(json.filters.map((f) => createFilter(f)), json.operator);
837
- break;
838
902
  case exports.FilterTypes.members:
839
903
  return new MembersFilter((0, factory_js_1.create)(json.attribute), json.members);
840
- break;
841
904
  case exports.FilterTypes.exclude:
842
905
  return new ExcludeFilter(createFilter(json.filter), json.input && createFilter(json.input));
843
- break;
844
906
  case exports.FilterTypes.measure:
845
907
  return new MeasureFilter((0, factory_js_1.create)(json.attribute), (0, factory_js_1.create)(json.measure), json.operatorA, json.valueA, json.operatorB, json.valueB);
846
- break;
847
908
  case exports.FilterTypes.ranking:
848
909
  return new RankingFilter((0, factory_js_1.create)(json.attribute), (0, factory_js_1.create)(json.measure), json.operator, json.count);
849
- break;
910
+ case exports.FilterTypes.measureRanking:
911
+ return new MeasureRankingFilter((0, factory_js_1.create)(json.measure), json.operator, json.count);
850
912
  case exports.FilterTypes.numeric:
851
913
  return new NumericFilter((0, factory_js_1.create)(json.attribute), json.operatorA, json.valueA, json.operatorB, json.valueB);
852
- break;
853
914
  case exports.FilterTypes.text:
854
915
  return new TextFilter((0, factory_js_1.create)(json.attribute), json.operatorA, json.valueA);
855
- break;
856
916
  case exports.FilterTypes.relativeDate:
857
917
  return new RelativeDateFilter((0, factory_js_1.create)(json.attribute), json.offset, json.count, json.operator, json.anchor);
858
- break;
859
918
  case exports.FilterTypes.dateRange:
860
919
  return new DateRangeFilter((0, factory_js_1.create)(json.attribute), json.valueA, json.valueB);
861
- break;
862
920
  }
863
921
  throw new translatable_error_js_1.TranslatableError('errors.filter.unsupportedType', {
864
922
  filterType: json.filterType,
@@ -209,6 +209,10 @@ const createMeasureFilterFromConditionFilterJaql = (measure, conditionFilterJaql
209
209
  return filterFactory.measureBetween(measure, conditionFilterJaql.from, conditionFilterJaql.to, { guid });
210
210
  case types_js_1.ConditionFilterType.IS_NOT_BETWEEN:
211
211
  return filterFactory.exclude(filterFactory.measureBetween(measure, (_a = conditionFilterJaql.exclude) === null || _a === void 0 ? void 0 : _a.from, (_b = conditionFilterJaql.exclude) === null || _b === void 0 ? void 0 : _b.to, { guid }), undefined, { guid });
212
+ case types_js_1.ConditionFilterType.TOP:
213
+ return filterFactory.measureTopRanking(measure, conditionFilterJaql[types_js_1.ConditionFilterType.TOP], { guid });
214
+ case types_js_1.ConditionFilterType.BOTTOM:
215
+ return filterFactory.measureBottomRanking(measure, conditionFilterJaql[types_js_1.ConditionFilterType.BOTTOM], { guid });
212
216
  }
213
217
  throw new translatable_error_js_1.TranslatableError('errors.filter.unsupportedConditionFilter', {
214
218
  filter: JSON.stringify(conditionFilterJaql),