react-semaphor 0.1.459 → 0.1.461

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 (114) hide show
  1. package/dist/analytics-protocol/index.cjs +1 -1
  2. package/dist/analytics-protocol/index.js +32 -32
  3. package/dist/brand-studio/index.cjs +1 -1
  4. package/dist/brand-studio/index.js +4 -4
  5. package/dist/briefings/index.cjs +1 -1
  6. package/dist/briefings/index.js +4 -4
  7. package/dist/chunks/{analyze-result-contract-BbRJ-C06.js → analyze-result-contract-DROq4vgY.js} +1 -1
  8. package/dist/chunks/{analyze-result-contract-LPDNldic.cjs → analyze-result-contract-DSGoFuXQ.cjs} +1 -1
  9. package/dist/chunks/canonical-result-keys-CEQefvdO.js +33 -0
  10. package/dist/chunks/canonical-result-keys-Cb96edol.cjs +1 -0
  11. package/dist/chunks/{common-types-H51FLKB7.js → common-types-BHVKgxRR.js} +1 -1
  12. package/dist/chunks/{common-types-C57kJ59w.cjs → common-types-BcV9PD9D.cjs} +1 -1
  13. package/dist/chunks/{dashboard-briefing-launcher-ClCj98sq.js → dashboard-briefing-launcher-3owMxX5K.js} +60 -61
  14. package/dist/chunks/{dashboard-briefing-launcher-DHtEouuH.cjs → dashboard-briefing-launcher-xuGrw8H3.cjs} +2 -2
  15. package/dist/chunks/{dashboard-controls-B8gsKlxc.js → dashboard-controls-B4GvjGr1.js} +44 -45
  16. package/dist/chunks/{dashboard-controls-VRShl9J0.cjs → dashboard-controls-Bpm_xOXQ.cjs} +1 -1
  17. package/dist/chunks/dashboard-filter-value-compatibility-KXIyvbhc.js +677 -0
  18. package/dist/chunks/dashboard-filter-value-compatibility-UapptYnn.cjs +1 -0
  19. package/dist/chunks/dashboard-input-contract-BkRFQ7Tq.cjs +1 -0
  20. package/dist/chunks/{dashboard-date-comparison-definition-DC3ekV2S.js → dashboard-input-contract-D5dxTWJ5.js} +41 -25
  21. package/dist/chunks/{dashboard-json-i_Auue_K.js → dashboard-json-DzyxoBp-.js} +13 -14
  22. package/dist/chunks/dashboard-json-yLM01xK4.cjs +1 -0
  23. package/dist/chunks/{edit-dashboard-visual-DWWyT55u.cjs → edit-dashboard-visual-1T278Nr_.cjs} +28 -28
  24. package/dist/chunks/{edit-dashboard-visual-B3JF0fe4.js → edit-dashboard-visual-nwSasO_j.js} +880 -894
  25. package/dist/chunks/{editor-action-buttons-BTlCsP63.cjs → editor-action-buttons-CX1Pken3.cjs} +2 -2
  26. package/dist/chunks/{editor-action-buttons-C9x3nGnb.js → editor-action-buttons-Dqw0asfA.js} +28 -28
  27. package/dist/chunks/index-B1qplNxl.cjs +1392 -0
  28. package/dist/chunks/{index-BS2-ZZGf.js → index-DazD5k0F.js} +45362 -42931
  29. package/dist/chunks/{index-BIFLI8ul.js → index-De_7nrwb.js} +10 -10
  30. package/dist/chunks/index-DjjKJPDy.cjs +4 -0
  31. package/dist/chunks/{matrix-result-contract-CofATICL.js → matrix-result-contract-BTpPuHOc.js} +88 -104
  32. package/dist/chunks/matrix-result-contract-ZRNfeIbI.cjs +1 -0
  33. package/dist/chunks/{pivot-header-presentation-B9nXXKlW.cjs → pivot-header-presentation-BijPbP33.cjs} +1 -1
  34. package/dist/chunks/{pivot-header-presentation-D-0jvUwn.js → pivot-header-presentation-DW0gKG8g.js} +2 -2
  35. package/dist/chunks/{pivot-result-identity-Bb4EixVN.cjs → pivot-result-identity-DxHtiKVj.cjs} +1 -1
  36. package/dist/chunks/{pivot-result-identity-DU1v-5Xk.js → pivot-result-identity-Z9tN2tEV.js} +1 -1
  37. package/dist/chunks/{pivot-result-lifecycle-DTLRuDEW.cjs → pivot-result-lifecycle-BXzIlQVu.cjs} +1 -1
  38. package/dist/chunks/{pivot-result-lifecycle-CHWEGU2o.js → pivot-result-lifecycle-g2U-vzQb.js} +7 -7
  39. package/dist/chunks/{raw-temporal-contract-BtjH_G-d.cjs → raw-temporal-contract-DfAvqNMo.cjs} +1 -1
  40. package/dist/chunks/{raw-temporal-contract-CxncLze5.js → raw-temporal-contract-UtAqoOZO.js} +1 -1
  41. package/dist/chunks/{report-preferences-dialog-BK0yAJnQ.cjs → report-preferences-dialog-DKPyjiCt.cjs} +1 -1
  42. package/dist/chunks/{report-preferences-dialog-BDpkcUtz.js → report-preferences-dialog-Dv3vCCFt.js} +6 -6
  43. package/dist/chunks/{report-runtime-context-DqxS4wbi.cjs → report-runtime-context-C0NfLPfc.cjs} +1 -1
  44. package/dist/chunks/{report-runtime-context-SM6YO61_.js → report-runtime-context-CNncA3VD.js} +11 -11
  45. package/dist/chunks/{saved-temporal-bucket-format-CFfWXRl9.cjs → saved-temporal-bucket-format-3QKveR3v.cjs} +1 -1
  46. package/dist/chunks/{saved-temporal-bucket-format-SGAV0ivR.js → saved-temporal-bucket-format-Dd2eixTH.js} +11 -11
  47. package/dist/chunks/switch-DBZsEV0U.cjs +138 -0
  48. package/dist/chunks/{switch-DQR-Va05.js → switch-kPUJEC1A.js} +6615 -5219
  49. package/dist/chunks/{temporal-bucket-5UYEotyQ.js → temporal-bucket-C85rmFmC.js} +4 -4
  50. package/dist/chunks/temporal-bucket-authoring-1fZuPAVb.js +653 -0
  51. package/dist/chunks/temporal-bucket-authoring-BK1UhYpD.cjs +1 -0
  52. package/dist/chunks/{temporal-bucket-contract-D5d-xEl3.js → temporal-bucket-contract-DXXNZssK.js} +1 -1
  53. package/dist/chunks/{temporal-bucket-contract-D2-93DGr.cjs → temporal-bucket-contract-xFkvboaw.cjs} +1 -1
  54. package/dist/chunks/{temporal-bucket-DHY1y9lq.cjs → temporal-bucket-pMfghsLX.cjs} +1 -1
  55. package/dist/chunks/{token-types-GbxRUozo.js → token-types-BLxc7UwR.js} +1 -1
  56. package/dist/chunks/{token-types-D7CaaI80.cjs → token-types-BYYO109W.cjs} +1 -1
  57. package/dist/chunks/{update-policy-hednMF-0.js → update-policy-CB8XJIoY.js} +1 -1
  58. package/dist/chunks/{update-policy-BmiOd0PB.cjs → update-policy-DMjjGjQY.cjs} +1 -1
  59. package/dist/chunks/{validators-DEmd8Sin.js → validators-DVd8s3qY.js} +416 -350
  60. package/dist/chunks/validators-dJlwubP4.cjs +1 -0
  61. package/dist/dashboard/index.cjs +1 -1
  62. package/dist/dashboard/index.js +2 -2
  63. package/dist/dashboard-authoring/index.cjs +3 -3
  64. package/dist/dashboard-authoring/index.js +328 -311
  65. package/dist/data-app-builder/index.cjs +1 -1
  66. package/dist/data-app-builder/index.js +2 -2
  67. package/dist/data-app-codegen/index.cjs +1 -1
  68. package/dist/data-app-codegen/index.js +2 -2
  69. package/dist/data-app-codegen-node/index.cjs +1 -1
  70. package/dist/data-app-codegen-node/index.js +3 -3
  71. package/dist/data-app-sdk/index.cjs +1 -1
  72. package/dist/data-app-sdk/index.js +55 -55
  73. package/dist/data-app-sdk-adapters/index.cjs +1 -1
  74. package/dist/data-app-sdk-adapters/index.js +61 -56
  75. package/dist/data-app-sdk-validation/index.cjs +1 -1
  76. package/dist/data-app-sdk-validation/index.js +9 -9
  77. package/dist/format-utils/index.cjs +1 -1
  78. package/dist/format-utils/index.js +15 -15
  79. package/dist/index.cjs +1 -1
  80. package/dist/index.js +154 -155
  81. package/dist/report-runtime-context/index.cjs +1 -1
  82. package/dist/report-runtime-context/index.js +2 -2
  83. package/dist/style.css +1 -1
  84. package/dist/surfboard/index.cjs +1 -1
  85. package/dist/surfboard/index.js +3 -3
  86. package/dist/types/analytics-protocol.d.ts +16 -8
  87. package/dist/types/briefings.d.ts +95 -13
  88. package/dist/types/dashboard-assistant.d.ts +11 -6
  89. package/dist/types/dashboard-authoring.d.ts +257 -19
  90. package/dist/types/dashboard.d.ts +109 -14
  91. package/dist/types/data-app-builder.d.ts +11 -6
  92. package/dist/types/data-app-codegen-node.d.ts +16 -8
  93. package/dist/types/data-app-codegen.d.ts +16 -8
  94. package/dist/types/data-app-sdk-adapters.d.ts +17 -11
  95. package/dist/types/data-app-sdk-validation.d.ts +17 -11
  96. package/dist/types/data-app-sdk.d.ts +17 -11
  97. package/dist/types/index.cjs +1 -1
  98. package/dist/types/index.js +4 -4
  99. package/dist/types/main.d.ts +225 -20
  100. package/dist/types/shared.d.ts +95 -13
  101. package/dist/types/surfboard.d.ts +109 -14
  102. package/dist/types/types.d.ts +109 -14
  103. package/package.json +1 -1
  104. package/dist/chunks/canonical-result-keys-BA0HCP4e.cjs +0 -1
  105. package/dist/chunks/canonical-result-keys-D6avdjpA.js +0 -467
  106. package/dist/chunks/dashboard-date-comparison-definition-Ces4alFm.cjs +0 -1
  107. package/dist/chunks/dashboard-json-BhvPMpZA.cjs +0 -1
  108. package/dist/chunks/index-DHF-2AqS.cjs +0 -1392
  109. package/dist/chunks/index-k8tEp0ys.cjs +0 -4
  110. package/dist/chunks/matrix-result-contract-zamd9euI.cjs +0 -1
  111. package/dist/chunks/switch-f3TuZNLr.cjs +0 -138
  112. package/dist/chunks/temporal-bucket-authoring-K1kE6R_z.js +0 -222
  113. package/dist/chunks/temporal-bucket-authoring-o3Emn05L.cjs +0 -1
  114. package/dist/chunks/validators-BDYprKI9.cjs +0 -1
@@ -559,6 +559,51 @@ declare type DashboardAIContext = AIContext & {
559
559
 
560
560
  declare type DashboardAIContextMode = 'auto' | 'fixed';
561
561
 
562
+ declare type DashboardFilterApplication = {
563
+ kind: 'cardMappings';
564
+ /**
565
+ * Sparse grounded bindings and explicit exclusions. A missing config card
566
+ * may reuse a proven Option Value target on an executable source; it is not
567
+ * an implicit exclusion, and source identity alone is not field evidence.
568
+ */
569
+ cards: DashboardFilterCardApplication[];
570
+ };
571
+
572
+ declare type DashboardFilterBoundCardApplication = {
573
+ kind: 'bound';
574
+ cardId: string;
575
+ bindingId: string;
576
+ target: DashboardFilterTarget;
577
+ };
578
+
579
+ declare type DashboardFilterCardApplication = DashboardFilterBoundCardApplication | DashboardFilterExcludedCardApplication;
580
+
581
+ declare type DashboardFilterExcludedCardApplication = {
582
+ kind: 'excluded';
583
+ cardId: string;
584
+ };
585
+
586
+ /** Persisted label/value option definition for a mapped dashboard filter. */
587
+ declare type DashboardFilterOptionSource = SemaphorInputOptionSource;
588
+
589
+ declare type DashboardFilterTarget = {
590
+ kind: 'field';
591
+ field: DashboardFilterTargetField;
592
+ };
593
+
594
+ /** Persisted, source-qualified field that a mapped filter targets. */
595
+ declare type DashboardFilterTargetField = {
596
+ name: string;
597
+ source: DashboardFilterTargetSource;
598
+ dataType: 'string' | 'number' | 'boolean' | 'date' | 'datetime';
599
+ /** Catalog-grounded physical column used when it differs from the semantic name. */
600
+ sourceField?: string;
601
+ };
602
+
603
+ declare type DashboardFilterTargetSource = Extract<SemaphorSourceRef, {
604
+ kind: 'semantic' | 'physical';
605
+ }>;
606
+
562
607
  declare type DashboardInput = FilterDashboardInput | ControlDashboardInput;
563
608
 
564
609
  declare type DashboardInputBase = {
@@ -619,14 +664,14 @@ declare type DashboardInputScope = {
619
664
  sectionIds: string[];
620
665
  };
621
666
 
622
- declare type DashboardInputSlot = ({
667
+ declare type DashboardInputSlot = {
623
668
  status: 'set';
624
669
  value: DashboardInputValue;
625
670
  comparisonSelection?: GlobalDateComparisonSelection;
626
- }) | ({
671
+ } | {
627
672
  status: 'cleared';
628
673
  comparisonSelection?: GlobalDateComparisonSelection;
629
- }) | {
674
+ } | {
630
675
  status?: never;
631
676
  value?: never;
632
677
  comparisonSelection: GlobalDateComparisonSelection;
@@ -723,11 +768,11 @@ declare type DateOptions = {
723
768
  options: Intl.DateTimeFormatOptions;
724
769
  };
725
770
 
726
- declare type DateSelectionMode = 'range' | 'months';
771
+ declare type DateSelectionMode = 'range' | 'months' | 'day';
727
772
 
728
773
  declare type DateUnit = 'day' | 'week' | 'month' | 'quarter' | 'year';
729
774
 
730
- declare type DefaultDateFilter = RelativeDateFilter | FixedMonthDefaultDateFilter;
775
+ declare type DefaultDateFilter = RelativeDateFilter | FixedMonthDefaultDateFilter | FixedDayDefaultDateFilter;
731
776
 
732
777
  /**
733
778
  * Field configuration for detail table columns.
@@ -1098,6 +1143,14 @@ declare type EmailSettings = {
1098
1143
  senderTitle: string;
1099
1144
  };
1100
1145
 
1146
+ declare type EmbeddedFilterDashboardInput = DashboardInputBase & {
1147
+ kind: 'filter';
1148
+ filter: TFilter;
1149
+ filterReference?: never;
1150
+ optionSource?: DashboardFilterOptionSource;
1151
+ application?: DashboardFilterApplication;
1152
+ };
1153
+
1101
1154
  declare type EntityType = 'table' | 'view' | 'materialized view' | 'model' | 'file' | 'dataset' | 'url' | 'upload';
1102
1155
 
1103
1156
  declare interface Field {
@@ -1201,10 +1254,7 @@ declare interface FilterCondition {
1201
1254
  temporalBucket?: TemporalBucketMetadata;
1202
1255
  }
1203
1256
 
1204
- declare type FilterDashboardInput = DashboardInputBase & {
1205
- kind: 'filter';
1206
- filter: TFilter;
1207
- };
1257
+ declare type FilterDashboardInput = EmbeddedFilterDashboardInput | ReferencedFilterDashboardInput;
1208
1258
 
1209
1259
  /**
1210
1260
  * Display mode for individual filters
@@ -1312,6 +1362,17 @@ declare type FilterSemanticContext = {
1312
1362
 
1313
1363
  declare type FilterValue = string | number | boolean | Date | null | [number, number] | [string, string] | string[] | number[];
1314
1364
 
1365
+ /**
1366
+ * Absolute fixed calendar-day default used by Day Picker defaults.
1367
+ * - `date` is a timezone-agnostic calendar day (`YYYY-MM-DD`); it resolves to
1368
+ * that day's start/end in the dashboard timezone at load time.
1369
+ */
1370
+ declare type FixedDayDefaultDateFilter = {
1371
+ mode: 'fixed';
1372
+ unit: 'day';
1373
+ date: string;
1374
+ };
1375
+
1315
1376
  /**
1316
1377
  * Absolute fixed month/year default used by Month Picker defaults.
1317
1378
  * - `month` is 0-indexed (0=January, 11=December) to align with MonthPicker.
@@ -1700,6 +1761,17 @@ declare type RangeValue = {
1700
1761
  gt?: string | number;
1701
1762
  };
1702
1763
 
1764
+ declare type ReferencedFilterDashboardInput = DashboardInputBase & {
1765
+ kind: 'filter';
1766
+ filter?: never;
1767
+ filterReference: {
1768
+ kind: 'dashboardFilter';
1769
+ filterId: string;
1770
+ };
1771
+ optionSource?: DashboardFilterOptionSource;
1772
+ application?: DashboardFilterApplication;
1773
+ };
1774
+
1703
1775
  declare type RelativeDateFilter = {
1704
1776
  mode: 'last';
1705
1777
  n: number;
@@ -1834,6 +1906,16 @@ declare type SemaphorInputBinding = {
1834
1906
 
1835
1907
  declare type SemaphorInputOperator = '=' | '!=' | 'in' | 'not_in' | 'contains' | 'not_contains' | 'between' | 'not_between' | '>' | '>=' | '<' | '<=';
1836
1908
 
1909
+ declare type SemaphorInputOptionSource = {
1910
+ source: Extract<SemaphorSourceRef, {
1911
+ kind: 'semantic' | 'physical';
1912
+ }>;
1913
+ labelField: SemaphorFieldRef;
1914
+ valueField: SemaphorFieldRef;
1915
+ searchField?: SemaphorFieldRef;
1916
+ disambiguationFields?: SemaphorFieldRef[];
1917
+ };
1918
+
1837
1919
  declare type SemaphorMatrixAxisExpansionOptions = {
1838
1920
  defaultDepth?: number;
1839
1921
  lazy?: boolean;
@@ -2766,7 +2848,7 @@ declare type TFilter = {
2766
2848
  type?: 'single' | 'multiple';
2767
2849
  uiType?: 'radio' | 'dropdown' | 'tabs';
2768
2850
  dateSelectionMode?: DateSelectionMode;
2769
- defaultValues?: (string | number)[];
2851
+ defaultValues?: (string | number | boolean)[];
2770
2852
  defaultDateFilter?: DefaultDateFilter;
2771
2853
  sheetId?: string;
2772
2854
  location?: FilterLocation;
@@ -2927,11 +3009,11 @@ declare type TInlineFilter = {
2927
3009
  type?: 'single' | 'multiple';
2928
3010
  /** UI component for single-select filters */
2929
3011
  uiType?: 'radio' | 'dropdown' | 'tabs';
2930
- /** Date picker type: 'range' for full calendar, 'months' for month picker */
3012
+ /** Date picker type: 'range' for full calendar, 'months' for month picker, 'day' for single-day picker */
2931
3013
  dateSelectionMode?: DateSelectionMode;
2932
3014
  /** Default values applied when the dashboard first loads */
2933
- defaultValues?: (string | number)[];
2934
- /** Default date filter applied on dashboard load (relative or fixed month/year) */
3015
+ defaultValues?: (string | number | boolean)[];
3016
+ /** Default date filter applied on dashboard load (relative, fixed month/year, or fixed day) */
2935
3017
  defaultDateFilter?: DefaultDateFilter;
2936
3018
  /** Search mode for numeric filters: 'text' treats as text, 'numeric' enables operators (>, <, =) */
2937
3019
  searchMode?: 'text' | 'numeric' | 'auto';
@@ -702,6 +702,51 @@ export declare type DashboardEventHandlers = {
702
702
  onExportData?: (payload: ExportDataPayload) => void;
703
703
  };
704
704
 
705
+ export declare type DashboardFilterApplication = {
706
+ kind: 'cardMappings';
707
+ /**
708
+ * Sparse grounded bindings and explicit exclusions. A missing config card
709
+ * may reuse a proven Option Value target on an executable source; it is not
710
+ * an implicit exclusion, and source identity alone is not field evidence.
711
+ */
712
+ cards: DashboardFilterCardApplication[];
713
+ };
714
+
715
+ export declare type DashboardFilterBoundCardApplication = {
716
+ kind: 'bound';
717
+ cardId: string;
718
+ bindingId: string;
719
+ target: DashboardFilterTarget;
720
+ };
721
+
722
+ export declare type DashboardFilterCardApplication = DashboardFilterBoundCardApplication | DashboardFilterExcludedCardApplication;
723
+
724
+ export declare type DashboardFilterExcludedCardApplication = {
725
+ kind: 'excluded';
726
+ cardId: string;
727
+ };
728
+
729
+ /** Persisted label/value option definition for a mapped dashboard filter. */
730
+ export declare type DashboardFilterOptionSource = SemaphorInputOptionSource;
731
+
732
+ export declare type DashboardFilterTarget = {
733
+ kind: 'field';
734
+ field: DashboardFilterTargetField;
735
+ };
736
+
737
+ /** Persisted, source-qualified field that a mapped filter targets. */
738
+ export declare type DashboardFilterTargetField = {
739
+ name: string;
740
+ source: DashboardFilterTargetSource;
741
+ dataType: 'string' | 'number' | 'boolean' | 'date' | 'datetime';
742
+ /** Catalog-grounded physical column used when it differs from the semantic name. */
743
+ sourceField?: string;
744
+ };
745
+
746
+ export declare type DashboardFilterTargetSource = Extract<SemaphorSourceRef, {
747
+ kind: 'semantic' | 'physical';
748
+ }>;
749
+
705
750
  export declare type DashboardInput = FilterDashboardInput | ControlDashboardInput;
706
751
 
707
752
  export declare type DashboardInputBase = {
@@ -771,14 +816,14 @@ export declare type DashboardInputScope = {
771
816
  sectionIds: string[];
772
817
  };
773
818
 
774
- export declare type DashboardInputSlot = ({
819
+ export declare type DashboardInputSlot = {
775
820
  status: 'set';
776
821
  value: DashboardInputValue;
777
822
  comparisonSelection?: GlobalDateComparisonSelection;
778
- }) | ({
823
+ } | {
779
824
  status: 'cleared';
780
825
  comparisonSelection?: GlobalDateComparisonSelection;
781
- }) | {
826
+ } | {
782
827
  status?: never;
783
828
  value?: never;
784
829
  comparisonSelection: GlobalDateComparisonSelection;
@@ -993,11 +1038,11 @@ export declare type DateOptions = {
993
1038
  options: Intl.DateTimeFormatOptions;
994
1039
  };
995
1040
 
996
- declare type DateSelectionMode = 'range' | 'months';
1041
+ declare type DateSelectionMode = 'range' | 'months' | 'day';
997
1042
 
998
1043
  declare type DateUnit = 'day' | 'week' | 'month' | 'quarter' | 'year';
999
1044
 
1000
- declare type DefaultDateFilter = RelativeDateFilter | FixedMonthDefaultDateFilter;
1045
+ declare type DefaultDateFilter = RelativeDateFilter | FixedMonthDefaultDateFilter | FixedDayDefaultDateFilter;
1001
1046
 
1002
1047
  /**
1003
1048
  * Field configuration for detail table columns.
@@ -1457,6 +1502,14 @@ export declare type EmailSettings = {
1457
1502
  senderTitle: string;
1458
1503
  };
1459
1504
 
1505
+ export declare type EmbeddedFilterDashboardInput = DashboardInputBase & {
1506
+ kind: 'filter';
1507
+ filter: TFilter;
1508
+ filterReference?: never;
1509
+ optionSource?: DashboardFilterOptionSource;
1510
+ application?: DashboardFilterApplication;
1511
+ };
1512
+
1460
1513
  export declare const EMPTY_SELECTION: SelectionState;
1461
1514
 
1462
1515
  declare type EntityType = 'table' | 'view' | 'materialized view' | 'model' | 'file' | 'dataset' | 'url' | 'upload';
@@ -1573,10 +1626,7 @@ declare interface FilterCondition {
1573
1626
  temporalBucket?: TemporalBucketMetadata;
1574
1627
  }
1575
1628
 
1576
- export declare type FilterDashboardInput = DashboardInputBase & {
1577
- kind: 'filter';
1578
- filter: TFilter;
1579
- };
1629
+ export declare type FilterDashboardInput = EmbeddedFilterDashboardInput | ReferencedFilterDashboardInput;
1580
1630
 
1581
1631
  /**
1582
1632
  * Display mode for individual filters
@@ -1684,6 +1734,17 @@ declare type FilterSemanticContext = {
1684
1734
 
1685
1735
  declare type FilterValue = string | number | boolean | Date | null | [number, number] | [string, string] | string[] | number[];
1686
1736
 
1737
+ /**
1738
+ * Absolute fixed calendar-day default used by Day Picker defaults.
1739
+ * - `date` is a timezone-agnostic calendar day (`YYYY-MM-DD`); it resolves to
1740
+ * that day's start/end in the dashboard timezone at load time.
1741
+ */
1742
+ declare type FixedDayDefaultDateFilter = {
1743
+ mode: 'fixed';
1744
+ unit: 'day';
1745
+ date: string;
1746
+ };
1747
+
1687
1748
  /**
1688
1749
  * Absolute fixed month/year default used by Month Picker defaults.
1689
1750
  * - `month` is 0-indexed (0=January, 11=December) to align with MonthPicker.
@@ -2080,6 +2141,17 @@ declare type MonthAlignedFiscalCalendar = {
2080
2141
 
2081
2142
  declare type NoneOptions = {};
2082
2143
 
2144
+ export declare type NormalizedDashboardInput = NormalizedFilterDashboardInput | ControlDashboardInput;
2145
+
2146
+ /** Runtime form after dashboard-filter references are resolved once. */
2147
+ export declare type NormalizedFilterDashboardInput = DashboardInputBase & {
2148
+ kind: 'filter';
2149
+ filter: TFilter;
2150
+ optionSource?: DashboardFilterOptionSource;
2151
+ application?: DashboardFilterApplication;
2152
+ definitionOrigin: 'embedded' | 'dashboardFilter';
2153
+ };
2154
+
2083
2155
  export declare type NumberAxisFormat = {
2084
2156
  decimalPlaces?: number;
2085
2157
  minimumFractionDigits?: number;
@@ -2237,6 +2309,17 @@ declare type RawTemporalPresentationTarget = {
2237
2309
  columnKey: string;
2238
2310
  };
2239
2311
 
2312
+ export declare type ReferencedFilterDashboardInput = DashboardInputBase & {
2313
+ kind: 'filter';
2314
+ filter?: never;
2315
+ filterReference: {
2316
+ kind: 'dashboardFilter';
2317
+ filterId: string;
2318
+ };
2319
+ optionSource?: DashboardFilterOptionSource;
2320
+ application?: DashboardFilterApplication;
2321
+ };
2322
+
2240
2323
  declare type RelativeDateFilter = {
2241
2324
  mode: 'last';
2242
2325
  n: number;
@@ -2316,6 +2399,8 @@ export declare type ResolvedDashboardInput = {
2316
2399
  exports: Partial<Record<DashboardInputExportKey, string | number | boolean | null>>;
2317
2400
  filter?: TFilter;
2318
2401
  filterValue?: TFilterValue;
2402
+ /** Present when a set filter slot cannot be used with its current definition. */
2403
+ invalidFilterSelection?: boolean;
2319
2404
  control?: ControlDefinition;
2320
2405
  controlValue?: unknown;
2321
2406
  missingRequiredValue?: boolean;
@@ -2323,7 +2408,7 @@ export declare type ResolvedDashboardInput = {
2323
2408
  };
2324
2409
 
2325
2410
  export declare type ResolvedDashboardInputContext = {
2326
- inputs: DashboardInput[];
2411
+ inputs: NormalizedDashboardInput[];
2327
2412
  resolvedInputs: ResolvedDashboardInput[];
2328
2413
  activeFilters: TFilterValue[];
2329
2414
  controlDefinitions: ControlDefinition[];
@@ -2571,6 +2656,16 @@ declare type SemaphorInputBinding = {
2571
2656
 
2572
2657
  declare type SemaphorInputOperator = '=' | '!=' | 'in' | 'not_in' | 'contains' | 'not_contains' | 'between' | 'not_between' | '>' | '>=' | '<' | '<=';
2573
2658
 
2659
+ declare type SemaphorInputOptionSource = {
2660
+ source: Extract<SemaphorSourceRef, {
2661
+ kind: 'semantic' | 'physical';
2662
+ }>;
2663
+ labelField: SemaphorFieldRef;
2664
+ valueField: SemaphorFieldRef;
2665
+ searchField?: SemaphorFieldRef;
2666
+ disambiguationFields?: SemaphorFieldRef[];
2667
+ };
2668
+
2574
2669
  declare type SemaphorMatrixAxisExpansionOptions = {
2575
2670
  defaultDepth?: number;
2576
2671
  lazy?: boolean;
@@ -3606,7 +3701,7 @@ declare type TFilter = {
3606
3701
  type?: 'single' | 'multiple';
3607
3702
  uiType?: 'radio' | 'dropdown' | 'tabs';
3608
3703
  dateSelectionMode?: DateSelectionMode;
3609
- defaultValues?: (string | number)[];
3704
+ defaultValues?: (string | number | boolean)[];
3610
3705
  defaultDateFilter?: DefaultDateFilter;
3611
3706
  sheetId?: string;
3612
3707
  location?: FilterLocation;
@@ -3775,11 +3870,11 @@ export declare type TInlineFilter = {
3775
3870
  type?: 'single' | 'multiple';
3776
3871
  /** UI component for single-select filters */
3777
3872
  uiType?: 'radio' | 'dropdown' | 'tabs';
3778
- /** Date picker type: 'range' for full calendar, 'months' for month picker */
3873
+ /** Date picker type: 'range' for full calendar, 'months' for month picker, 'day' for single-day picker */
3779
3874
  dateSelectionMode?: DateSelectionMode;
3780
3875
  /** Default values applied when the dashboard first loads */
3781
- defaultValues?: (string | number)[];
3782
- /** Default date filter applied on dashboard load (relative or fixed month/year) */
3876
+ defaultValues?: (string | number | boolean)[];
3877
+ /** Default date filter applied on dashboard load (relative, fixed month/year, or fixed day) */
3783
3878
  defaultDateFilter?: DefaultDateFilter;
3784
3879
  /** Search mode for numeric filters: 'text' treats as text, 'numeric' enables operators (>, <, =) */
3785
3880
  searchMode?: 'text' | 'numeric' | 'auto';
@@ -1212,6 +1212,51 @@ export declare type DashboardEventHandlers = {
1212
1212
  onExportData?: (payload: ExportDataPayload) => void;
1213
1213
  };
1214
1214
 
1215
+ export declare type DashboardFilterApplication = {
1216
+ kind: 'cardMappings';
1217
+ /**
1218
+ * Sparse grounded bindings and explicit exclusions. A missing config card
1219
+ * may reuse a proven Option Value target on an executable source; it is not
1220
+ * an implicit exclusion, and source identity alone is not field evidence.
1221
+ */
1222
+ cards: DashboardFilterCardApplication[];
1223
+ };
1224
+
1225
+ export declare type DashboardFilterBoundCardApplication = {
1226
+ kind: 'bound';
1227
+ cardId: string;
1228
+ bindingId: string;
1229
+ target: DashboardFilterTarget;
1230
+ };
1231
+
1232
+ export declare type DashboardFilterCardApplication = DashboardFilterBoundCardApplication | DashboardFilterExcludedCardApplication;
1233
+
1234
+ export declare type DashboardFilterExcludedCardApplication = {
1235
+ kind: 'excluded';
1236
+ cardId: string;
1237
+ };
1238
+
1239
+ /** Persisted label/value option definition for a mapped dashboard filter. */
1240
+ export declare type DashboardFilterOptionSource = SemaphorInputOptionSource;
1241
+
1242
+ export declare type DashboardFilterTarget = {
1243
+ kind: 'field';
1244
+ field: DashboardFilterTargetField;
1245
+ };
1246
+
1247
+ /** Persisted, source-qualified field that a mapped filter targets. */
1248
+ export declare type DashboardFilterTargetField = {
1249
+ name: string;
1250
+ source: DashboardFilterTargetSource;
1251
+ dataType: 'string' | 'number' | 'boolean' | 'date' | 'datetime';
1252
+ /** Catalog-grounded physical column used when it differs from the semantic name. */
1253
+ sourceField?: string;
1254
+ };
1255
+
1256
+ export declare type DashboardFilterTargetSource = Extract<SemaphorSourceRef, {
1257
+ kind: 'semantic' | 'physical';
1258
+ }>;
1259
+
1215
1260
  export declare type DashboardInput = FilterDashboardInput | ControlDashboardInput;
1216
1261
 
1217
1262
  export declare type DashboardInputBase = {
@@ -1281,14 +1326,14 @@ export declare type DashboardInputScope = {
1281
1326
  sectionIds: string[];
1282
1327
  };
1283
1328
 
1284
- export declare type DashboardInputSlot = ({
1329
+ export declare type DashboardInputSlot = {
1285
1330
  status: 'set';
1286
1331
  value: DashboardInputValue;
1287
1332
  comparisonSelection?: GlobalDateComparisonSelection;
1288
- }) | ({
1333
+ } | {
1289
1334
  status: 'cleared';
1290
1335
  comparisonSelection?: GlobalDateComparisonSelection;
1291
- }) | {
1336
+ } | {
1292
1337
  status?: never;
1293
1338
  value?: never;
1294
1339
  comparisonSelection: GlobalDateComparisonSelection;
@@ -1518,7 +1563,7 @@ export declare type DateOptions = {
1518
1563
  options: Intl.DateTimeFormatOptions;
1519
1564
  };
1520
1565
 
1521
- export declare type DateSelectionMode = 'range' | 'months';
1566
+ export declare type DateSelectionMode = 'range' | 'months' | 'day';
1522
1567
 
1523
1568
  export declare type DateUnit = 'day' | 'week' | 'month' | 'quarter' | 'year';
1524
1569
 
@@ -1526,7 +1571,7 @@ export declare const DEFAULT_CALENDAR_CONTEXT: CalendarContext;
1526
1571
 
1527
1572
  export declare const DEFAULT_SEMANTIC_DOMAIN_ACCESS: SemanticDomainAccess;
1528
1573
 
1529
- declare type DefaultDateFilter = RelativeDateFilter | FixedMonthDefaultDateFilter;
1574
+ declare type DefaultDateFilter = RelativeDateFilter | FixedMonthDefaultDateFilter | FixedDayDefaultDateFilter;
1530
1575
 
1531
1576
  export declare type DeleteBriefingResponse = {
1532
1577
  success: boolean;
@@ -2029,6 +2074,14 @@ export declare type EmailSettings = {
2029
2074
  senderTitle: string;
2030
2075
  };
2031
2076
 
2077
+ export declare type EmbeddedFilterDashboardInput = DashboardInputBase & {
2078
+ kind: 'filter';
2079
+ filter: TFilter;
2080
+ filterReference?: never;
2081
+ optionSource?: DashboardFilterOptionSource;
2082
+ application?: DashboardFilterApplication;
2083
+ };
2084
+
2032
2085
  export declare const EMPTY_SELECTION: SelectionState;
2033
2086
 
2034
2087
  export declare type EntityColumnGroup = {
@@ -2155,10 +2208,7 @@ export declare interface FilterCondition {
2155
2208
  temporalBucket?: TemporalBucketMetadata;
2156
2209
  }
2157
2210
 
2158
- export declare type FilterDashboardInput = DashboardInputBase & {
2159
- kind: 'filter';
2160
- filter: TFilter;
2161
- };
2211
+ export declare type FilterDashboardInput = EmbeddedFilterDashboardInput | ReferencedFilterDashboardInput;
2162
2212
 
2163
2213
  /**
2164
2214
  * Display mode for individual filters
@@ -2266,6 +2316,17 @@ export declare type FilterSemanticContext = {
2266
2316
 
2267
2317
  export declare type FilterValue = string | number | boolean | Date | null | [number, number] | [string, string] | string[] | number[];
2268
2318
 
2319
+ /**
2320
+ * Absolute fixed calendar-day default used by Day Picker defaults.
2321
+ * - `date` is a timezone-agnostic calendar day (`YYYY-MM-DD`); it resolves to
2322
+ * that day's start/end in the dashboard timezone at load time.
2323
+ */
2324
+ declare type FixedDayDefaultDateFilter = {
2325
+ mode: 'fixed';
2326
+ unit: 'day';
2327
+ date: string;
2328
+ };
2329
+
2269
2330
  /**
2270
2331
  * Absolute fixed month/year default used by Month Picker defaults.
2271
2332
  * - `month` is 0-indexed (0=January, 11=December) to align with MonthPicker.
@@ -2960,6 +3021,17 @@ declare type MonthAlignedFiscalCalendar = {
2960
3021
 
2961
3022
  declare type NoneOptions = {};
2962
3023
 
3024
+ export declare type NormalizedDashboardInput = NormalizedFilterDashboardInput | ControlDashboardInput;
3025
+
3026
+ /** Runtime form after dashboard-filter references are resolved once. */
3027
+ export declare type NormalizedFilterDashboardInput = DashboardInputBase & {
3028
+ kind: 'filter';
3029
+ filter: TFilter;
3030
+ optionSource?: DashboardFilterOptionSource;
3031
+ application?: DashboardFilterApplication;
3032
+ definitionOrigin: 'embedded' | 'dashboardFilter';
3033
+ };
3034
+
2963
3035
  export declare type NumberAxisFormat = {
2964
3036
  decimalPlaces?: number;
2965
3037
  minimumFractionDigits?: number;
@@ -3256,6 +3328,17 @@ declare type RawTemporalValueMetadata = {
3256
3328
  valueKind: RawTemporalValueKind;
3257
3329
  };
3258
3330
 
3331
+ export declare type ReferencedFilterDashboardInput = DashboardInputBase & {
3332
+ kind: 'filter';
3333
+ filter?: never;
3334
+ filterReference: {
3335
+ kind: 'dashboardFilter';
3336
+ filterId: string;
3337
+ };
3338
+ optionSource?: DashboardFilterOptionSource;
3339
+ application?: DashboardFilterApplication;
3340
+ };
3341
+
3259
3342
  export declare type RelativeDateFilter = {
3260
3343
  mode: 'last';
3261
3344
  n: number;
@@ -3330,6 +3413,8 @@ export declare type ResolvedDashboardInput = {
3330
3413
  exports: Partial<Record<DashboardInputExportKey, string | number | boolean | null>>;
3331
3414
  filter?: TFilter;
3332
3415
  filterValue?: TFilterValue;
3416
+ /** Present when a set filter slot cannot be used with its current definition. */
3417
+ invalidFilterSelection?: boolean;
3333
3418
  control?: ControlDefinition;
3334
3419
  controlValue?: unknown;
3335
3420
  missingRequiredValue?: boolean;
@@ -3337,7 +3422,7 @@ export declare type ResolvedDashboardInput = {
3337
3422
  };
3338
3423
 
3339
3424
  export declare type ResolvedDashboardInputContext = {
3340
- inputs: DashboardInput[];
3425
+ inputs: NormalizedDashboardInput[];
3341
3426
  resolvedInputs: ResolvedDashboardInput[];
3342
3427
  activeFilters: TFilterValue[];
3343
3428
  controlDefinitions: ControlDefinition[];
@@ -3653,6 +3738,16 @@ declare type SemaphorInputBinding = {
3653
3738
 
3654
3739
  declare type SemaphorInputOperator = '=' | '!=' | 'in' | 'not_in' | 'contains' | 'not_contains' | 'between' | 'not_between' | '>' | '>=' | '<' | '<=';
3655
3740
 
3741
+ declare type SemaphorInputOptionSource = {
3742
+ source: Extract<SemaphorSourceRef, {
3743
+ kind: 'semantic' | 'physical';
3744
+ }>;
3745
+ labelField: SemaphorFieldRef;
3746
+ valueField: SemaphorFieldRef;
3747
+ searchField?: SemaphorFieldRef;
3748
+ disambiguationFields?: SemaphorFieldRef[];
3749
+ };
3750
+
3656
3751
  declare type SemaphorMatrixAxisExpansionOptions = {
3657
3752
  defaultDepth?: number;
3658
3753
  lazy?: boolean;
@@ -4789,7 +4884,7 @@ export declare type TFilter = {
4789
4884
  type?: 'single' | 'multiple';
4790
4885
  uiType?: 'radio' | 'dropdown' | 'tabs';
4791
4886
  dateSelectionMode?: DateSelectionMode;
4792
- defaultValues?: (string | number)[];
4887
+ defaultValues?: (string | number | boolean)[];
4793
4888
  defaultDateFilter?: DefaultDateFilter;
4794
4889
  sheetId?: string;
4795
4890
  location?: FilterLocation;
@@ -4958,11 +5053,11 @@ export declare type TInlineFilter = {
4958
5053
  type?: 'single' | 'multiple';
4959
5054
  /** UI component for single-select filters */
4960
5055
  uiType?: 'radio' | 'dropdown' | 'tabs';
4961
- /** Date picker type: 'range' for full calendar, 'months' for month picker */
5056
+ /** Date picker type: 'range' for full calendar, 'months' for month picker, 'day' for single-day picker */
4962
5057
  dateSelectionMode?: DateSelectionMode;
4963
5058
  /** Default values applied when the dashboard first loads */
4964
- defaultValues?: (string | number)[];
4965
- /** Default date filter applied on dashboard load (relative or fixed month/year) */
5059
+ defaultValues?: (string | number | boolean)[];
5060
+ /** Default date filter applied on dashboard load (relative, fixed month/year, or fixed day) */
4966
5061
  defaultDateFilter?: DefaultDateFilter;
4967
5062
  /** Search mode for numeric filters: 'text' treats as text, 'numeric' enables operators (>, <, =) */
4968
5063
  searchMode?: 'text' | 'numeric' | 'auto';
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "email": "support@semaphor.cloud"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "0.1.459",
8
+ "version": "0.1.461",
9
9
  "description": "Fully interactive and customizable dashboards for your apps.",
10
10
  "keywords": [
11
11
  "react",
@@ -1 +0,0 @@
1
- "use strict";require("./validators-BDYprKI9.cjs");require("./analyze-result-contract-LPDNldic.cjs");const E=require("./temporal-bucket-DHY1y9lq.cjs");require("../value-format-preferences/index.cjs");const _=new Set(["previous_period","same_period_last_year","start_vs_end","target"]),R=new Set([..._,"none",""]);function l(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function L(e){const o=l(e.preferences)?e.preferences:void 0,r=o&&l(o.kpiVisualOptions)?o.kpiVisualOptions:void 0,i=o&&l(o.tableVisualOptions)?o.tableVisualOptions:void 0;return{preferences:o,kpiOptions:r,kpiComparison:r&&l(r.metricComparison)?r.metricComparison:void 0,kpiComparisonPresent:!!r&&"metricComparison"in r,tableOptions:i,tableComparison:i&&l(i.metricComparison)?i.metricComparison:void 0,tableComparisonPresent:!!i&&"metricComparison"in i}}function O(e){const o=[],r=(i,a)=>{if(Array.isArray(i)){i.forEach((n,c)=>r(n,`${a}[${c}]`));return}if(!l(i))return;const m=i.config;if(l(m)){const n=L(i),c=!!(n.kpiComparisonPresent||n.tableComparisonPresent),g=m.metricColumns,p=Array.isArray(g)?g.flatMap((s,t)=>l(s)?[{index:t,metric:s}]:[]):[];if((p.some(({metric:s})=>"comparisonType"in s)||c)&&o.push({path:a,card:i,metrics:p,malformedMetricIndexes:Array.isArray(g)?g.flatMap((s,t)=>l(s)?[]:[t]):[],malformedMetricColumns:"metricColumns"in m&&!Array.isArray(g),hasLegacyPresentation:c}),"metricColumns"in m||c)return}Object.entries(i).forEach(([n,c])=>r(c,a?`${a}.${n}`:n))};return r(e,"$"),o}const I={difference:"difference",change:"percent_change",change_difference:"both",ratio:"ratio"};function w(e,o){if(!e)return;const r=Object.fromEntries(o.flatMap(i=>typeof e[i]=="string"?[[i,e[i]]]:[]));return Object.keys(r).length?r:void 0}function M(e,o,r){if(e!==void 0){if(!l(e)){r.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:o,message:"Legacy comparison formatOptions must be an object."});return}Object.entries(e).forEach(([i,a])=>{if(i==="decimalPlaces"){(typeof a!="number"||!Number.isInteger(a)||a<0||a>6)&&r.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${o}.decimalPlaces`,message:"Legacy comparison decimalPlaces must be an integer from 0 through 6."});return}i==="type"&&(a===void 0||a==="auto")||a!==void 0&&r.push({severity:"error",code:"unsupported_comparison_format",path:`${o}.${i}`,message:`Legacy comparison format option "${i}" has no canonical presentation mapping.`})})}}function v(e,o){const r=o==="kpi"?e.calculationType:e.calculatedAs,i=o==="table"&&r===void 0?"both":I[String(r)],a=l(e.formatOptions)?e.formatOptions:void 0,m=l(e.conditionalLabels)?e.conditionalLabels:void 0,n=l(o==="kpi"?e.colorConfig:e.colors)?o==="kpi"?e.colorConfig:e.colors:void 0,c={};if(i&&(c.displayMode=i),typeof(a==null?void 0:a.decimalPlaces)=="number"&&(c.precision=a.decimalPlaces),o==="kpi"){const s=e.showArrow!==!1,t=e.showColor!==!1;c.indicatorStyle=s?t?"arrow_badge":"arrow":t?"badge":"none",c.showColor=t,(e.position==="left"||e.position==="right"||e.position==="top")&&(c.position=e.position),typeof e.conditionalLabel=="boolean"&&(c.conditionalLabel=e.conditionalLabel),typeof e.labelName=="string"&&(c.labelName=e.labelName)}else(e.indicatorStyle==="arrow_badge"||e.indicatorStyle==="arrow"||e.indicatorStyle==="badge"||e.indicatorStyle==="none")&&(c.indicatorStyle=e.indicatorStyle);const g=m?{...w(m,["increase","decrease"]),...typeof m.noChange=="string"?{neutral:m.noChange}:typeof m.neutral=="string"?{neutral:m.neutral}:{}}:void 0;g&&Object.keys(g).length&&(c.conditionalLabels=g);const p=n?{...w(n,["increase","decrease"]),...typeof n.noChange=="string"?{neutral:n.noChange}:typeof n.neutral=="string"?{neutral:n.neutral}:{}}:void 0;return p&&Object.keys(p).length&&(c.colors=p),c}function $(e){return{...E.COMPARISON_PRESENTATION_DEFAULTS,...e}}function T(e){return e.some(({metric:o})=>o.comparisonType==="previous_period"||o.comparisonType==="same_period_last_year"||o.comparisonType==="target"?!0:l(o.comparison)&&o.comparison.mode==="explicit")}function C(e){const o=e.card.config;return e.metrics.length===2&&(o.groupByColumns===void 0||Array.isArray(o.groupByColumns)&&o.groupByColumns.length===0)}function P(e,o,r,i){const a=o==="kpi"?["enabled","calculationType","formatOptions","showArrow","showColor","conditionalLabel","labelName","position","conditionalLabels","colorConfig","lowerIsBetter"]:["calculatedAs","indicatorStyle","formatOptions","colors","lowerIsBetter"];Object.keys(e).forEach(s=>{a.includes(s)||i.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${r}.${s}`,message:`Unknown legacy comparison presentation field "${s}" cannot be dropped automatically.`})});const m=o==="kpi"?"calculationType":"calculatedAs";e[m]!==void 0&&!I[String(e[m])]&&i.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${r}.${m}`,message:`Legacy comparison ${m} is unsupported.`}),o==="kpi"&&e.position!==void 0&&!["left","right","top"].includes(String(e.position))&&i.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${r}.position`,message:"Legacy comparison position is unsupported."}),o==="kpi"&&e.labelName!==void 0&&typeof e.labelName!="string"&&i.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${r}.labelName`,message:"Legacy comparison labelName must be a string."}),(o==="kpi"?[["conditionalLabels",["increase","decrease","noChange"]],["colorConfig",["increase","decrease","noChange"]]]:[["colors",["increase","decrease","neutral"]]]).forEach(([s,t])=>{if(e[s]!==void 0){if(!l(e[s])){i.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${r}.${s}`,message:`Legacy comparison ${s} must be an object.`});return}Object.entries(e[s]).forEach(([f,u])=>{t.includes(f)?typeof u!="string"&&i.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${r}.${s}.${f}`,message:`Legacy comparison ${s}.${f} must be a string.`}):i.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${r}.${s}.${f}`,message:`Unknown legacy comparison ${s} field "${f}" cannot be dropped automatically.`})})}}),(o==="kpi"?["enabled","showArrow","showColor","conditionalLabel","lowerIsBetter"]:["lowerIsBetter"]).forEach(s=>{e[s]!==void 0&&typeof e[s]!="boolean"&&i.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${r}.${s}`,message:`Legacy comparison ${s} must be a boolean.`})}),o==="table"&&e.indicatorStyle!==void 0&&!["arrow_badge","arrow","badge","none"].includes(String(e.indicatorStyle))&&i.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${r}.indicatorStyle`,message:"Legacy comparison indicatorStyle is unsupported."}),M(e.formatOptions,`${r}.formatOptions`,i);const g=v(e,o);E.validateComparisonPresentationSpec(g,r).errors.forEach(s=>{i.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:s.path||r,message:s.message})})}function S(e){const o=L(e.card),r=o.kpiComparison?v(o.kpiComparison,"kpi"):void 0,i=o.tableComparison?v(o.tableComparison,"table"):void 0;return{namespaces:o,kpi:r,table:i,presentation:r||i}}function B(e){const o=l(e.preferences)?e.preferences:{},r=l(o.kpiVisualOptions)?o.kpiVisualOptions:{},i=l(r.metricComparison)?r.metricComparison:{},a=l(o.tableVisualOptions)?o.tableVisualOptions:{},m=l(a.metricComparison)?a.metricComparison:{};return r.lowerIsBetter===!0||i.lowerIsBetter===!0||m.lowerIsBetter===!0?"lower_is_better":"higher_is_better"}function D(e){switch(e.comparisonType){case"previous_period":return{mode:"explicit",spec:{kind:"previous_period"}};case"same_period_last_year":return{mode:"explicit",spec:{kind:"previous_year"}};case"target":return{mode:"explicit",spec:{kind:"target",targetValue:e.targetValue}};default:return}}function j(e){const o=l(e.preferences)?e.preferences:void 0;if(!o)return;const r=l(o.kpiVisualOptions)?o.kpiVisualOptions:void 0;r&&delete r.lowerIsBetter;const i=l(o.tableVisualOptions)?o.tableVisualOptions:void 0,a=i&&l(i.metricComparison)?i.metricComparison:void 0;a&&delete a.lowerIsBetter}function x(e){const o=O(e);if(!o.length)return{document:e,changed:!1,changes:[],diagnostics:[]};const r=[];if(o.forEach(n=>{var c,g,p,s;if(n.malformedMetricColumns&&r.push({severity:"error",code:"malformed_metric_columns",path:`${n.path}.config.metricColumns`,message:"Metric columns must be an array before comparison migration."}),n.malformedMetricIndexes.forEach(t=>{r.push({severity:"error",code:"malformed_metric_columns",path:`${n.path}.config.metricColumns[${t}]`,message:"Metric columns must contain objects before comparison migration."})}),n.metrics.forEach(({metric:t,index:f})=>{if(!("comparisonType"in t))return;const u=`${n.path}.config.metricColumns[${f}]`,d=String(t.comparisonType||"");"comparison"in t&&r.push({severity:"error",code:"conflicting_comparison_contracts",path:u,message:"Metric contains both legacy and canonical comparison configuration; resolve the conflict before migration."});const h=l(t.parameters)?t.parameters:void 0,b=h&&l(h.windowTransform)?h.windowTransform:void 0;_.has(d)&&(b==null?void 0:b.function)==="previous_period_delta"&&r.push({severity:"error",code:"conflicting_comparison_window_transform",path:u,message:"A metric cannot combine baseline comparison with previous_period_delta; resolve the authoring intent before migration."}),R.has(d)||r.push({severity:"error",code:"unsupported_comparison_type",path:`${u}.comparisonType`,message:`Unsupported legacy metric comparison type "${d}".`}),t.comparisonType==="target"&&(typeof t.targetValue!="number"||!Number.isFinite(t.targetValue))&&r.push({severity:"error",code:"invalid_target_value",path:`${u}.targetValue`,message:"Legacy target comparison requires a finite metric targetValue."}),t.comparisonType==="start_vs_end"&&r.push({severity:"error",code:"unsupported_start_vs_end",path:`${u}.comparisonType`,message:"start_vs_end is retired and cannot be migrated automatically."}),t.targetValue!==void 0&&t.comparisonType!=="target"&&r.push({severity:"warning",code:"stray_target_value",path:`${u}.targetValue`,message:"Dead non-target targetValue will be removed without changing the baseline."})}),n.hasLegacyPresentation){const{namespaces:t,kpi:f,table:u}=S(n),d=[(c=t.kpiOptions)==null?void 0:c.lowerIsBetter,(g=t.kpiComparison)==null?void 0:g.lowerIsBetter,(p=t.tableComparison)==null?void 0:p.lowerIsBetter].filter(h=>typeof h=="boolean");new Set(d).size>1&&r.push({severity:"error",code:"conflicting_legacy_polarity",path:`${n.path}.preferences`,message:"Legacy comparison polarity values disagree; resolve the conflict before migration."}),((s=t.kpiOptions)==null?void 0:s.lowerIsBetter)!==void 0&&typeof t.kpiOptions.lowerIsBetter!="boolean"&&r.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${n.path}.preferences.kpiVisualOptions.lowerIsBetter`,message:"Legacy comparison lowerIsBetter must be a boolean."}),t.kpiComparisonPresent&&!t.kpiComparison&&r.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${n.path}.preferences.kpiVisualOptions.metricComparison`,message:"Legacy KPI comparison presentation must be an object."}),t.tableComparisonPresent&&!t.tableComparison&&r.push({severity:"error",code:"invalid_legacy_comparison_presentation",path:`${n.path}.preferences.tableVisualOptions.metricComparison`,message:"Legacy table comparison presentation must be an object."}),"comparisonPresentation"in(t.preferences||{})&&r.push({severity:"error",code:"conflicting_comparison_presentation_contracts",path:`${n.path}.preferences.comparisonPresentation`,message:"Card contains both legacy and canonical comparison presentation; resolve the conflict before migration."}),t.kpiComparison&&typeof t.kpiComparison.enabled=="boolean"&&"metricPairComparisonEnabled"in(t.preferences||{})&&C(n)&&r.push({severity:"error",code:"conflicting_comparison_presentation_contracts",path:`${n.path}.preferences.metricPairComparisonEnabled`,message:"Card contains both legacy and canonical metric-pair enablement; resolve the conflict before migration."}),t.kpiComparison&&P(t.kpiComparison,"kpi",`${n.path}.preferences.kpiVisualOptions.metricComparison`,r),t.tableComparison&&P(t.tableComparison,"table",`${n.path}.preferences.tableVisualOptions.metricComparison`,r),f&&u&&JSON.stringify($(f))!==JSON.stringify($(u))&&r.push({severity:"error",code:"conflicting_legacy_presentation_namespaces",path:`${n.path}.preferences`,message:"KPI and table comparison presentation values disagree; resolve the conflict before migration."})}}),r.some(n=>n.severity==="error"))return{document:e,changed:!1,changes:[],diagnostics:r};const i=JSON.parse(JSON.stringify(e)),a=O(i),m=[];return a.forEach(n=>{var g;const c=B(n.card);if(n.metrics.forEach(({metric:p,index:s})=>{if(!("comparisonType"in p))return;const t=String(p.comparisonType||""),f=`${n.path}.config.metricColumns[${s}]`,u=D(p),d=["comparisonType"];delete p.comparisonType,"targetValue"in p&&(delete p.targetValue,d.push("targetValue")),"comparisonDisplay"in p&&(delete p.comparisonDisplay,d.push("comparisonDisplay")),u?p.comparison=u:delete p.comparison,_.has(t)&&(p.comparisonPolarity=c),m.push({kind:"metric",path:f,metricId:typeof p.id=="string"?p.id:void 0,legacyType:t,comparison:u,comparisonPolarity:_.has(t)?c:void 0,removedFields:d})}),j(n.card),n.hasLegacyPresentation){const{namespaces:p,presentation:s}=S(n),t=(g=p.kpiComparison)==null?void 0:g.enabled,f={...s};typeof t=="boolean"&&T(n.metrics)&&(f.showComparison=t);const u=typeof t=="boolean"&&C(n)?t:void 0,d=typeof t=="boolean"&&!T(n.metrics)&&!C(n)?["kpiVisualOptions.metricComparison.enabled"]:void 0,h=p.preferences,b=[];n.metrics.forEach(({metric:y})=>{"comparisonPolarity"in y||(y.comparisonPolarity=c,typeof y.id=="string"&&b.push(y.id))}),Object.keys(f).length&&(h.comparisonPresentation=f),u!==void 0&&(h.metricPairComparisonEnabled=u),p.kpiOptions&&delete p.kpiOptions.metricComparison,p.tableOptions&&delete p.tableOptions.metricComparison,m.push({kind:"presentation",path:`${n.path}.preferences`,comparisonPresentation:Object.keys(f).length?f:void 0,metricPairComparisonEnabled:u,comparisonPolarityMetricIds:b,intentionallyDiscardedFields:d,removedFields:[...p.kpiComparison?["kpiVisualOptions.metricComparison"]:[],...p.tableComparison?["tableVisualOptions.metricComparison"]:[]]})}}),{document:i,changed:!0,changes:m,diagnostics:r}}const k=["bar","horizontalBar","line","area","stackedArea","combo","stackedBar","stackedLine"],K=new Set(k);function V(e){return typeof e=="string"&&K.has(e)}function Y(e){return e==="detailTable"||e==="table"||e==="aggregateTable"||e==="pivotTable"||e==="custom"||V(e)}function A(e){return!!(e!=null&&e.trim())}function F(e){return A(e.sql)||A(e.normalizedPython)?"freeform":e.hasExecutableConfig?"config":"none"}const U="SEMAPHOR_CALCULATED_FIELD";function N(e,o,r){if(r&&(o==="groupby"||o==="pivotby"))return r;if(o==="metric"&&e.name==="*"&&!e.expression)return e.alias||"count";if(e.alias)return e.alias;const i=e.entityName&&e.entityName!==U?e.entityName:void 0;if(e.role==="metric"){let a=e.aggregate||"metric";if(e.expression){const m=e.expression.match(/^(COUNT|SUM|AVG|MIN|MAX|MEDIAN|DISTINCT)\s*\(/i);a=m?m[1].toLowerCase():"expr"}else a=a.toLowerCase();return i&&i!==e.name?`${i}_${e.name}_${a}`:`${e.name}_${a}`}return i&&i!==e.name?`${i}_${e.name}`:e.name}function H(e){return N(e,"detail")}function q(e){const o=e.label;return o&&e.labelCount===1&&(o===e.rawKey||!e.rawKeys.has(o))?o:e.rawKey}exports.SEMAPHOR_CARTESIAN_CHART_TYPES=k;exports.isSemaphorCartesianChartType=V;exports.resolveCanonicalDetailResultRawKey=H;exports.resolveCanonicalResultOutputKey=q;exports.resolveCanonicalResultRawKey=N;exports.resolveTemporalResultOwner=F;exports.supportsCanonicalDashboardTemporalResult=Y;exports.transformComparisonDocument=x;