react-semaphor 0.1.369 → 0.1.371

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 (53) hide show
  1. package/dist/analytics-protocol/index.cjs +1 -1
  2. package/dist/analytics-protocol/index.js +40 -38
  3. package/dist/chunks/{calendar-preferences-dialog-6q51A6XC.js → calendar-preferences-dialog-ClBAkMmF.js} +1 -1
  4. package/dist/chunks/{calendar-preferences-dialog-CUGzkNcE.js → calendar-preferences-dialog-Dn6o2r2Y.js} +1 -1
  5. package/dist/chunks/{dashboard-briefing-launcher-BEZnvIla.js → dashboard-briefing-launcher-BO-kXtEd.js} +1 -1
  6. package/dist/chunks/{dashboard-briefing-launcher-ptERmNJr.js → dashboard-briefing-launcher-D3Xfc_26.js} +3 -3
  7. package/dist/chunks/{dashboard-controls-CqKC5oEk.js → dashboard-controls-B3sdy_Zx.js} +3 -3
  8. package/dist/chunks/{dashboard-controls-CGt6_hMf.js → dashboard-controls-DcXMFgGR.js} +1 -1
  9. package/dist/chunks/{dashboard-json-6SgPm_QW.js → dashboard-json-BWfkEy48.js} +1 -1
  10. package/dist/chunks/{dashboard-json-CYSbOdmE.js → dashboard-json-CFURS_OR.js} +1 -1
  11. package/dist/chunks/{edit-dashboard-visual-w6hKbjlw.js → edit-dashboard-visual-BD2AJLiT.js} +1 -1
  12. package/dist/chunks/{edit-dashboard-visual-ByQx_M2i.js → edit-dashboard-visual-DjdhKiP2.js} +3 -3
  13. package/dist/chunks/{index-CPyEi9gS.js → index-C0Qnfr_7.js} +5 -4
  14. package/dist/chunks/{index-BtqYNH_S.js → index-DlLvzmJF.js} +2 -2
  15. package/dist/chunks/{resource-management-panel-Bf8-3eUf.js → resource-management-panel-DytUMSGA.js} +1 -1
  16. package/dist/chunks/{resource-management-panel-mJ84NxzC.js → resource-management-panel-YvIfaphX.js} +2 -2
  17. package/dist/chunks/{use-create-flow-overlay-state-BfoXDDrd.js → use-create-flow-overlay-state-BETXykC9.js} +2 -2
  18. package/dist/chunks/{use-create-flow-overlay-state-c6rCm36x.js → use-create-flow-overlay-state-CwIG1Ekp.js} +1 -1
  19. package/dist/chunks/{use-visual-utils-NN0e3fBP.js → use-visual-utils-Bk135OgA.js} +1 -1
  20. package/dist/chunks/{use-visual-utils-C_c-aiqi.js → use-visual-utils-BzFjIykb.js} +1 -1
  21. package/dist/chunks/{validation-nOPr0mTk.js → validation-CQFpcSSP.js} +446 -246
  22. package/dist/chunks/validation-D4Zz6WPD.js +1 -0
  23. package/dist/chunks/validators-CuKnUZFO.js +2171 -0
  24. package/dist/chunks/validators-DHee9kM2.js +1 -0
  25. package/dist/dashboard/index.cjs +1 -1
  26. package/dist/dashboard/index.js +1 -1
  27. package/dist/dashboard-authoring/index.cjs +1 -1
  28. package/dist/dashboard-authoring/index.js +1 -1
  29. package/dist/data-app-builder/index.cjs +1 -1
  30. package/dist/data-app-builder/index.js +1 -1
  31. package/dist/data-app-sdk/index.cjs +1 -1
  32. package/dist/data-app-sdk/index.js +261 -183
  33. package/dist/data-app-sdk-validation/index.cjs +1 -1
  34. package/dist/data-app-sdk-validation/index.js +4 -3
  35. package/dist/index.cjs +1 -1
  36. package/dist/index.js +5 -5
  37. package/dist/surfboard/index.cjs +1 -1
  38. package/dist/surfboard/index.js +2 -2
  39. package/dist/types/analytics-protocol.d.ts +542 -2
  40. package/dist/types/dashboard-assistant.d.ts +508 -4
  41. package/dist/types/dashboard-authoring.d.ts +217 -3
  42. package/dist/types/dashboard.d.ts +67 -2
  43. package/dist/types/data-app-builder.d.ts +197 -1
  44. package/dist/types/data-app-sdk-validation.d.ts +520 -6
  45. package/dist/types/data-app-sdk.d.ts +543 -8
  46. package/dist/types/main.d.ts +215 -3
  47. package/dist/types/shared.d.ts +66 -2
  48. package/dist/types/surfboard.d.ts +67 -2
  49. package/dist/types/types.d.ts +67 -2
  50. package/package.json +1 -1
  51. package/dist/chunks/validation-Dsf7PydY.js +0 -1
  52. package/dist/chunks/validators-CVuWOHYv.js +0 -1032
  53. package/dist/chunks/validators-oc8qtP4q.js +0 -1
@@ -1083,8 +1083,14 @@ export declare const CALCULATED_FIELD_ENTITY_MARKER: "SEMAPHOR_CALCULATED_FIELD"
1083
1083
 
1084
1084
  /**
1085
1085
  * Formula metadata for calculated fields (UI-only metadata)
1086
- * This is supplementary data to help the UI display and edit calculated fields.
1087
- * The `expression` field remains the source of truth for the backend.
1086
+ * This is supplementary runtime/compiler data to help dashboard UI display,
1087
+ * edit, and execute calculated fields.
1088
+ *
1089
+ * Public source-level calculation metadata belongs in `Field.derivedField`
1090
+ * (`SemaphorDerivedFieldDefinition`). `calculatedFormula` deliberately uses
1091
+ * indexed `{field_N}` tokens and full runtime Field objects so current dashboard
1092
+ * query execution can resolve aliases, joins, filters, and aggregates without
1093
+ * doing catalog lookups.
1088
1094
  *
1089
1095
  * IMPORTANT: This metadata is ALWAYS updated atomically with the expression field.
1090
1096
  * Both are generated together from the same dialog inputs, preventing drift.
@@ -3257,6 +3263,15 @@ export declare interface Field {
3257
3263
  role?: 'groupby' | 'metric' | 'sortby' | 'pivotby' | 'detail';
3258
3264
  expression?: string;
3259
3265
  calculatedFormula?: CalculatedFieldFormula;
3266
+ /**
3267
+ * Public, source-level derived-field metadata for semantic/domain-authored
3268
+ * calculations. This is the AI/MCP/Data App-facing contract: named-token
3269
+ * expression, typed inputs, result role, and compute stage.
3270
+ *
3271
+ * Dashboard-local calculated fields may omit this because they are local
3272
+ * runtime artifacts rather than semantic-domain definitions.
3273
+ */
3274
+ derivedField?: SemaphorDerivedFieldDefinition;
3260
3275
  format?: FormatSpec;
3261
3276
  aggregate?: AggregateFunction;
3262
3277
  fieldScope?: FieldScope;
@@ -4420,7 +4435,7 @@ declare type SemaphorAnalyticsFilterBase = {
4420
4435
 
4421
4436
  declare type SemaphorAnalyticsFilterOperator = SemaphorInputOperator | 'not_contains' | 'is_null' | 'is_not_null';
4422
4437
 
4423
- declare type SemaphorAnalyticsIntent = SemaphorMetricIntent | SemaphorRecordsIntent | SemaphorInputOptionsIntent | SemaphorSqlIntent;
4438
+ declare type SemaphorAnalyticsIntent = SemaphorMetricIntent | SemaphorRecordsIntent | SemaphorInputOptionsIntent | SemaphorSqlIntent | SemaphorMatrixIntent;
4424
4439
 
4425
4440
  declare type SemaphorAnalyticsNullFilter = SemaphorAnalyticsFilterBase & {
4426
4441
  operator: SemaphorAnalyticsNullFilterOperator;
@@ -4441,8 +4456,54 @@ export declare const SemaphorContextProvider: ({ children, dashboardProps, }: {
4441
4456
  dashboardProps: DashboardProps;
4442
4457
  }) => JSX.Element;
4443
4458
 
4459
+ declare type SemaphorDerivedFieldAggregationBehavior = 'additive' | 'non_additive' | 'ratio_of_sums' | 'weighted' | 'pre_aggregated' | 'snapshot';
4460
+
4461
+ declare type SemaphorDerivedFieldAggregationStrategy = 'default' | 'symmetric_aggregate' | 'aggregate_then_join' | 'weighted';
4462
+
4463
+ declare type SemaphorDerivedFieldComputeStage = 'row' | 'aggregate';
4464
+
4465
+ declare type SemaphorDerivedFieldDefinition = {
4466
+ kind: 'derived_field';
4467
+ name: string;
4468
+ label: string;
4469
+ description?: string;
4470
+ resultRole: SemaphorDerivedFieldResultRole;
4471
+ dataType: NonNullable<SemaphorFieldRef['dataType']>;
4472
+ computeStage: SemaphorDerivedFieldComputeStage;
4473
+ expression: string;
4474
+ expressionLanguage?: 'semaphor_sql_template';
4475
+ inputs: Record<string, SemaphorDerivedFieldInput>;
4476
+ defaultAggregate?: SemaphorAggregateFunction;
4477
+ aggregationBehavior?: SemaphorDerivedFieldAggregationBehavior;
4478
+ aggregationStrategy?: SemaphorDerivedFieldAggregationStrategy;
4479
+ format?: unknown;
4480
+ tags?: string[];
4481
+ };
4482
+
4483
+ declare type SemaphorDerivedFieldInput = {
4484
+ kind: 'field';
4485
+ field: SemaphorFieldRef;
4486
+ aggregate?: SemaphorAggregateFunction;
4487
+ } | {
4488
+ kind: 'metric';
4489
+ metric: SemaphorFieldRef;
4490
+ } | {
4491
+ kind: 'dimension';
4492
+ dimension: SemaphorFieldRef;
4493
+ };
4494
+
4495
+ declare type SemaphorDerivedFieldResultRole = 'measure' | 'group' | 'date' | 'id' | 'filter';
4496
+
4444
4497
  declare type SemaphorDialect = 'postgres' | 'mysql' | 'mssql' | 'snowflake' | 'clickhouse' | 'bigquery' | 'redshift' | 'duckdb' | 'sqlite' | 'unknown';
4445
4498
 
4499
+ /**
4500
+ * Explorer-backed table source. This is intentionally distinct from raw SQL:
4501
+ * matrix planning needs stable source metadata, fields, and dialect context.
4502
+ */
4503
+ declare type SemaphorExplorerSourceRef = Extract<SemaphorSourceRef, {
4504
+ kind: 'physical';
4505
+ }>;
4506
+
4446
4507
  declare type SemaphorFieldRef = {
4447
4508
  name: string;
4448
4509
  label?: string;
@@ -4471,6 +4532,150 @@ declare type SemaphorInputOptionsIntent = {
4471
4532
  field: SemaphorFieldRef;
4472
4533
  search?: string;
4473
4534
  limit?: number;
4535
+ derivedFields?: SemaphorDerivedFieldDefinition[];
4536
+ };
4537
+
4538
+ declare type SemaphorMatrixAxisExpansionOptions = {
4539
+ defaultDepth?: number;
4540
+ lazy?: boolean;
4541
+ expandedPaths?: SemaphorMatrixMemberPathSegment[][];
4542
+ };
4543
+
4544
+ declare type SemaphorMatrixAxisLevel = {
4545
+ id?: string;
4546
+ field: SemaphorFieldRef;
4547
+ grain?: SemaphorTimeGrain;
4548
+ label?: string;
4549
+ subtotal?: boolean | SemaphorMatrixSubtotalOptions;
4550
+ sortBy?: SemaphorMatrixAxisSortRule;
4551
+ };
4552
+
4553
+ declare type SemaphorMatrixAxisSortRule = {
4554
+ direction: 'asc' | 'desc';
4555
+ by: {
4556
+ kind: 'label';
4557
+ } | {
4558
+ kind: 'field';
4559
+ field: SemaphorFieldRef;
4560
+ aggregate?: SemaphorAggregateFunction;
4561
+ };
4562
+ nulls?: 'warehouseDefault' | 'first' | 'last';
4563
+ scope?: 'global' | 'withinParent';
4564
+ };
4565
+
4566
+ declare type SemaphorMatrixDisplayLimitOptions = {
4567
+ rows?: SemaphorMatrixDisplayLimitRule;
4568
+ columns?: SemaphorMatrixDisplayLimitRule;
4569
+ };
4570
+
4571
+ declare type SemaphorMatrixDisplayLimitRule = {
4572
+ limit: number;
4573
+ by?: 'label' | 'value';
4574
+ direction?: 'top' | 'bottom';
4575
+ others?: boolean | {
4576
+ label?: string;
4577
+ };
4578
+ };
4579
+
4580
+ declare type SemaphorMatrixExpansionOptions = {
4581
+ rows?: SemaphorMatrixAxisExpansionOptions;
4582
+ columns?: SemaphorMatrixAxisExpansionOptions;
4583
+ };
4584
+
4585
+ declare type SemaphorMatrixIntent = {
4586
+ kind: 'matrix';
4587
+ version?: SemaphorProtocolVersion;
4588
+ id?: string;
4589
+ label?: string;
4590
+ source: SemaphorMatrixSourceRef;
4591
+ rows: SemaphorMatrixAxisLevel[];
4592
+ columns?: SemaphorMatrixAxisLevel[];
4593
+ values: SemaphorMatrixValueField[];
4594
+ filters?: SemaphorAnalyticsFilter[];
4595
+ inputs?: SemaphorInputBinding[];
4596
+ totals?: SemaphorMatrixTotalOptions;
4597
+ sort?: SemaphorMatrixSortRule[];
4598
+ expansion?: SemaphorMatrixExpansionOptions;
4599
+ layout?: SemaphorMatrixLayoutOptions;
4600
+ displayLimits?: SemaphorMatrixDisplayLimitOptions;
4601
+ };
4602
+
4603
+ declare type SemaphorMatrixLayoutOptions = {
4604
+ hierarchy?: 'compact' | 'tabular' | 'outline';
4605
+ valuesPlacement?: 'columns' | 'rows';
4606
+ stickyRowHeaders?: boolean;
4607
+ stickyColumnHeaders?: boolean;
4608
+ };
4609
+
4610
+ declare type SemaphorMatrixMemberPathSegment = {
4611
+ levelId: string;
4612
+ value: unknown;
4613
+ };
4614
+
4615
+ declare type SemaphorMatrixSortRule = {
4616
+ axis: 'row' | 'column';
4617
+ targetId?: string;
4618
+ direction: 'asc' | 'desc';
4619
+ by: {
4620
+ kind: 'label';
4621
+ } | {
4622
+ kind: 'field';
4623
+ field: SemaphorFieldRef;
4624
+ aggregate?: SemaphorAggregateFunction;
4625
+ } | {
4626
+ kind: 'value';
4627
+ valueId: string;
4628
+ rowPath?: SemaphorMatrixMemberPathSegment[];
4629
+ columnPath?: SemaphorMatrixMemberPathSegment[];
4630
+ };
4631
+ nulls?: 'warehouseDefault' | 'first' | 'last';
4632
+ scope?: 'global' | 'withinParent';
4633
+ };
4634
+
4635
+ declare type SemaphorMatrixSourceRef = SemaphorSemanticSourceRef | SemaphorExplorerSourceRef;
4636
+
4637
+ declare type SemaphorMatrixSubtotalOptions = {
4638
+ enabled?: boolean;
4639
+ position?: 'before' | 'after';
4640
+ label?: string;
4641
+ };
4642
+
4643
+ declare type SemaphorMatrixTotalCalculation = {
4644
+ kind: 'defaultAggregate';
4645
+ } | {
4646
+ kind: 'blank';
4647
+ } | {
4648
+ kind: 'labelOnly';
4649
+ label?: string;
4650
+ } | {
4651
+ kind: 'customAggregate';
4652
+ aggregate: SemaphorAggregateFunction;
4653
+ } | {
4654
+ kind: 'percentOfParent';
4655
+ } | {
4656
+ kind: 'percentOfGrandTotal';
4657
+ } | {
4658
+ kind: 'customExpression';
4659
+ expressionId: string;
4660
+ };
4661
+
4662
+ declare type SemaphorMatrixTotalOptions = {
4663
+ rows?: boolean | 'perLevel';
4664
+ columns?: boolean | 'perLevel';
4665
+ grandTotal?: boolean | {
4666
+ rows?: boolean;
4667
+ columns?: boolean;
4668
+ };
4669
+ rowPosition?: 'top' | 'bottom';
4670
+ columnPosition?: 'left' | 'right';
4671
+ };
4672
+
4673
+ declare type SemaphorMatrixValueField = {
4674
+ id?: string;
4675
+ field: SemaphorFieldRef;
4676
+ aggregate?: SemaphorAggregateFunction;
4677
+ label?: string;
4678
+ totalBehavior?: SemaphorMatrixTotalCalculation;
4474
4679
  };
4475
4680
 
4476
4681
  declare type SemaphorMetricAnalysis = {
@@ -4504,6 +4709,7 @@ declare type SemaphorMetricIntent = {
4504
4709
  };
4505
4710
  inputs?: SemaphorInputBinding[];
4506
4711
  limit?: number;
4712
+ derivedFields?: SemaphorDerivedFieldDefinition[];
4507
4713
  };
4508
4714
 
4509
4715
  declare type SemaphorPaginationRequest = {
@@ -4537,6 +4743,7 @@ declare type SemaphorRecordsIntent = {
4537
4743
  direction: 'asc' | 'desc';
4538
4744
  };
4539
4745
  inputs?: SemaphorInputBinding[];
4746
+ derivedFields?: SemaphorDerivedFieldDefinition[];
4540
4747
  };
4541
4748
 
4542
4749
  declare type SemaphorRelativeTimeWindow = {
@@ -4547,6 +4754,10 @@ declare type SemaphorRelativeTimeWindow = {
4547
4754
  completeness?: 'include_partial' | 'complete_periods';
4548
4755
  };
4549
4756
 
4757
+ declare type SemaphorSemanticSourceRef = Extract<SemaphorSourceRef, {
4758
+ kind: 'semantic';
4759
+ }>;
4760
+
4550
4761
  declare type SemaphorSourceRef = {
4551
4762
  kind: 'semantic';
4552
4763
  domainId: string;
@@ -5383,6 +5594,7 @@ export declare type TDataColumn = {
5383
5594
  role?: 'groupby' | 'metric' | 'sortby' | 'pivotby' | 'detail';
5384
5595
  expression?: string;
5385
5596
  calculatedFormula?: CalculatedFieldFormula;
5597
+ derivedField?: SemaphorDerivedFieldDefinition;
5386
5598
  format?: FormatSpec;
5387
5599
  sourceField?: string;
5388
5600
  aggregate?: AggregateFunction;
@@ -73,8 +73,14 @@ declare type CacheConfig = {
73
73
 
74
74
  /**
75
75
  * Formula metadata for calculated fields (UI-only metadata)
76
- * This is supplementary data to help the UI display and edit calculated fields.
77
- * The `expression` field remains the source of truth for the backend.
76
+ * This is supplementary runtime/compiler data to help dashboard UI display,
77
+ * edit, and execute calculated fields.
78
+ *
79
+ * Public source-level calculation metadata belongs in `Field.derivedField`
80
+ * (`SemaphorDerivedFieldDefinition`). `calculatedFormula` deliberately uses
81
+ * indexed `{field_N}` tokens and full runtime Field objects so current dashboard
82
+ * query execution can resolve aliases, joins, filters, and aggregates without
83
+ * doing catalog lookups.
78
84
  *
79
85
  * IMPORTANT: This metadata is ALWAYS updated atomically with the expression field.
80
86
  * Both are generated together from the same dialog inputs, preventing drift.
@@ -1047,6 +1053,15 @@ declare interface Field {
1047
1053
  role?: 'groupby' | 'metric' | 'sortby' | 'pivotby' | 'detail';
1048
1054
  expression?: string;
1049
1055
  calculatedFormula?: CalculatedFieldFormula;
1056
+ /**
1057
+ * Public, source-level derived-field metadata for semantic/domain-authored
1058
+ * calculations. This is the AI/MCP/Data App-facing contract: named-token
1059
+ * expression, typed inputs, result role, and compute stage.
1060
+ *
1061
+ * Dashboard-local calculated fields may omit this because they are local
1062
+ * runtime artifacts rather than semantic-domain definitions.
1063
+ */
1064
+ derivedField?: SemaphorDerivedFieldDefinition;
1050
1065
  format?: FormatSpec;
1051
1066
  aggregate?: AggregateFunction;
1052
1067
  fieldScope?: FieldScope;
@@ -1557,8 +1572,57 @@ declare type SelectedEntities = SelectedEntity[];
1557
1572
 
1558
1573
  declare type SelectedEntity = DatabaseEntityReference | DataModelEntityReference | DatasetEntityReference | FileEntityReference;
1559
1574
 
1575
+ declare type SemaphorAggregateFunction = 'SUM' | 'COUNT' | 'AVG' | 'MIN' | 'MAX' | 'MEDIAN' | 'DISTINCT';
1576
+
1577
+ declare type SemaphorDerivedFieldAggregationBehavior = 'additive' | 'non_additive' | 'ratio_of_sums' | 'weighted' | 'pre_aggregated' | 'snapshot';
1578
+
1579
+ declare type SemaphorDerivedFieldAggregationStrategy = 'default' | 'symmetric_aggregate' | 'aggregate_then_join' | 'weighted';
1580
+
1581
+ declare type SemaphorDerivedFieldComputeStage = 'row' | 'aggregate';
1582
+
1583
+ declare type SemaphorDerivedFieldDefinition = {
1584
+ kind: 'derived_field';
1585
+ name: string;
1586
+ label: string;
1587
+ description?: string;
1588
+ resultRole: SemaphorDerivedFieldResultRole;
1589
+ dataType: NonNullable<SemaphorFieldRef['dataType']>;
1590
+ computeStage: SemaphorDerivedFieldComputeStage;
1591
+ expression: string;
1592
+ expressionLanguage?: 'semaphor_sql_template';
1593
+ inputs: Record<string, SemaphorDerivedFieldInput>;
1594
+ defaultAggregate?: SemaphorAggregateFunction;
1595
+ aggregationBehavior?: SemaphorDerivedFieldAggregationBehavior;
1596
+ aggregationStrategy?: SemaphorDerivedFieldAggregationStrategy;
1597
+ format?: unknown;
1598
+ tags?: string[];
1599
+ };
1600
+
1601
+ declare type SemaphorDerivedFieldInput = {
1602
+ kind: 'field';
1603
+ field: SemaphorFieldRef;
1604
+ aggregate?: SemaphorAggregateFunction;
1605
+ } | {
1606
+ kind: 'metric';
1607
+ metric: SemaphorFieldRef;
1608
+ } | {
1609
+ kind: 'dimension';
1610
+ dimension: SemaphorFieldRef;
1611
+ };
1612
+
1613
+ declare type SemaphorDerivedFieldResultRole = 'measure' | 'group' | 'date' | 'id' | 'filter';
1614
+
1560
1615
  declare type SemaphorDialect = 'postgres' | 'mysql' | 'mssql' | 'snowflake' | 'clickhouse' | 'bigquery' | 'redshift' | 'duckdb' | 'sqlite' | 'unknown';
1561
1616
 
1617
+ declare type SemaphorFieldRef = {
1618
+ name: string;
1619
+ label?: string;
1620
+ role?: 'dimension' | 'measure' | 'date' | 'id' | 'unknown';
1621
+ dataType?: 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'unknown';
1622
+ source?: SemaphorSourceRef;
1623
+ aggregate?: SemaphorAggregateFunction;
1624
+ };
1625
+
1562
1626
  declare type SemaphorSourceRef = {
1563
1627
  kind: 'semantic';
1564
1628
  domainId: string;
@@ -158,8 +158,14 @@ export declare type CacheConfig = {
158
158
 
159
159
  /**
160
160
  * Formula metadata for calculated fields (UI-only metadata)
161
- * This is supplementary data to help the UI display and edit calculated fields.
162
- * The `expression` field remains the source of truth for the backend.
161
+ * This is supplementary runtime/compiler data to help dashboard UI display,
162
+ * edit, and execute calculated fields.
163
+ *
164
+ * Public source-level calculation metadata belongs in `Field.derivedField`
165
+ * (`SemaphorDerivedFieldDefinition`). `calculatedFormula` deliberately uses
166
+ * indexed `{field_N}` tokens and full runtime Field objects so current dashboard
167
+ * query execution can resolve aliases, joins, filters, and aggregates without
168
+ * doing catalog lookups.
163
169
  *
164
170
  * IMPORTANT: This metadata is ALWAYS updated atomically with the expression field.
165
171
  * Both are generated together from the same dialog inputs, preventing drift.
@@ -1298,6 +1304,15 @@ declare interface Field {
1298
1304
  role?: 'groupby' | 'metric' | 'sortby' | 'pivotby' | 'detail';
1299
1305
  expression?: string;
1300
1306
  calculatedFormula?: CalculatedFieldFormula;
1307
+ /**
1308
+ * Public, source-level derived-field metadata for semantic/domain-authored
1309
+ * calculations. This is the AI/MCP/Data App-facing contract: named-token
1310
+ * expression, typed inputs, result role, and compute stage.
1311
+ *
1312
+ * Dashboard-local calculated fields may omit this because they are local
1313
+ * runtime artifacts rather than semantic-domain definitions.
1314
+ */
1315
+ derivedField?: SemaphorDerivedFieldDefinition;
1301
1316
  format?: FormatSpec;
1302
1317
  aggregate?: AggregateFunction;
1303
1318
  fieldScope?: FieldScope;
@@ -1917,8 +1932,57 @@ declare type SemanticExecutionPayload = {
1917
1932
  }>;
1918
1933
  };
1919
1934
 
1935
+ declare type SemaphorAggregateFunction = 'SUM' | 'COUNT' | 'AVG' | 'MIN' | 'MAX' | 'MEDIAN' | 'DISTINCT';
1936
+
1937
+ declare type SemaphorDerivedFieldAggregationBehavior = 'additive' | 'non_additive' | 'ratio_of_sums' | 'weighted' | 'pre_aggregated' | 'snapshot';
1938
+
1939
+ declare type SemaphorDerivedFieldAggregationStrategy = 'default' | 'symmetric_aggregate' | 'aggregate_then_join' | 'weighted';
1940
+
1941
+ declare type SemaphorDerivedFieldComputeStage = 'row' | 'aggregate';
1942
+
1943
+ declare type SemaphorDerivedFieldDefinition = {
1944
+ kind: 'derived_field';
1945
+ name: string;
1946
+ label: string;
1947
+ description?: string;
1948
+ resultRole: SemaphorDerivedFieldResultRole;
1949
+ dataType: NonNullable<SemaphorFieldRef['dataType']>;
1950
+ computeStage: SemaphorDerivedFieldComputeStage;
1951
+ expression: string;
1952
+ expressionLanguage?: 'semaphor_sql_template';
1953
+ inputs: Record<string, SemaphorDerivedFieldInput>;
1954
+ defaultAggregate?: SemaphorAggregateFunction;
1955
+ aggregationBehavior?: SemaphorDerivedFieldAggregationBehavior;
1956
+ aggregationStrategy?: SemaphorDerivedFieldAggregationStrategy;
1957
+ format?: unknown;
1958
+ tags?: string[];
1959
+ };
1960
+
1961
+ declare type SemaphorDerivedFieldInput = {
1962
+ kind: 'field';
1963
+ field: SemaphorFieldRef;
1964
+ aggregate?: SemaphorAggregateFunction;
1965
+ } | {
1966
+ kind: 'metric';
1967
+ metric: SemaphorFieldRef;
1968
+ } | {
1969
+ kind: 'dimension';
1970
+ dimension: SemaphorFieldRef;
1971
+ };
1972
+
1973
+ declare type SemaphorDerivedFieldResultRole = 'measure' | 'group' | 'date' | 'id' | 'filter';
1974
+
1920
1975
  declare type SemaphorDialect = 'postgres' | 'mysql' | 'mssql' | 'snowflake' | 'clickhouse' | 'bigquery' | 'redshift' | 'duckdb' | 'sqlite' | 'unknown';
1921
1976
 
1977
+ declare type SemaphorFieldRef = {
1978
+ name: string;
1979
+ label?: string;
1980
+ role?: 'dimension' | 'measure' | 'date' | 'id' | 'unknown';
1981
+ dataType?: 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'unknown';
1982
+ source?: SemaphorSourceRef;
1983
+ aggregate?: SemaphorAggregateFunction;
1984
+ };
1985
+
1922
1986
  declare type SemaphorSourceRef = {
1923
1987
  kind: 'semantic';
1924
1988
  domainId: string;
@@ -2578,6 +2642,7 @@ export declare type TDataColumn = {
2578
2642
  role?: 'groupby' | 'metric' | 'sortby' | 'pivotby' | 'detail';
2579
2643
  expression?: string;
2580
2644
  calculatedFormula?: CalculatedFieldFormula;
2645
+ derivedField?: SemaphorDerivedFieldDefinition;
2581
2646
  format?: FormatSpec;
2582
2647
  sourceField?: string;
2583
2648
  aggregate?: AggregateFunction;
@@ -571,8 +571,14 @@ export declare const CALCULATED_FIELD_ENTITY_MARKER: "SEMAPHOR_CALCULATED_FIELD"
571
571
 
572
572
  /**
573
573
  * Formula metadata for calculated fields (UI-only metadata)
574
- * This is supplementary data to help the UI display and edit calculated fields.
575
- * The `expression` field remains the source of truth for the backend.
574
+ * This is supplementary runtime/compiler data to help dashboard UI display,
575
+ * edit, and execute calculated fields.
576
+ *
577
+ * Public source-level calculation metadata belongs in `Field.derivedField`
578
+ * (`SemaphorDerivedFieldDefinition`). `calculatedFormula` deliberately uses
579
+ * indexed `{field_N}` tokens and full runtime Field objects so current dashboard
580
+ * query execution can resolve aliases, joins, filters, and aggregates without
581
+ * doing catalog lookups.
576
582
  *
577
583
  * IMPORTANT: This metadata is ALWAYS updated atomically with the expression field.
578
584
  * Both are generated together from the same dialog inputs, preventing drift.
@@ -1846,6 +1852,15 @@ export declare interface Field {
1846
1852
  role?: 'groupby' | 'metric' | 'sortby' | 'pivotby' | 'detail';
1847
1853
  expression?: string;
1848
1854
  calculatedFormula?: CalculatedFieldFormula;
1855
+ /**
1856
+ * Public, source-level derived-field metadata for semantic/domain-authored
1857
+ * calculations. This is the AI/MCP/Data App-facing contract: named-token
1858
+ * expression, typed inputs, result role, and compute stage.
1859
+ *
1860
+ * Dashboard-local calculated fields may omit this because they are local
1861
+ * runtime artifacts rather than semantic-domain definitions.
1862
+ */
1863
+ derivedField?: SemaphorDerivedFieldDefinition;
1849
1864
  format?: FormatSpec;
1850
1865
  aggregate?: AggregateFunction;
1851
1866
  fieldScope?: FieldScope;
@@ -2677,8 +2692,57 @@ declare type SemanticExecutionPayload = {
2677
2692
  }>;
2678
2693
  };
2679
2694
 
2695
+ declare type SemaphorAggregateFunction = 'SUM' | 'COUNT' | 'AVG' | 'MIN' | 'MAX' | 'MEDIAN' | 'DISTINCT';
2696
+
2697
+ declare type SemaphorDerivedFieldAggregationBehavior = 'additive' | 'non_additive' | 'ratio_of_sums' | 'weighted' | 'pre_aggregated' | 'snapshot';
2698
+
2699
+ declare type SemaphorDerivedFieldAggregationStrategy = 'default' | 'symmetric_aggregate' | 'aggregate_then_join' | 'weighted';
2700
+
2701
+ declare type SemaphorDerivedFieldComputeStage = 'row' | 'aggregate';
2702
+
2703
+ declare type SemaphorDerivedFieldDefinition = {
2704
+ kind: 'derived_field';
2705
+ name: string;
2706
+ label: string;
2707
+ description?: string;
2708
+ resultRole: SemaphorDerivedFieldResultRole;
2709
+ dataType: NonNullable<SemaphorFieldRef['dataType']>;
2710
+ computeStage: SemaphorDerivedFieldComputeStage;
2711
+ expression: string;
2712
+ expressionLanguage?: 'semaphor_sql_template';
2713
+ inputs: Record<string, SemaphorDerivedFieldInput>;
2714
+ defaultAggregate?: SemaphorAggregateFunction;
2715
+ aggregationBehavior?: SemaphorDerivedFieldAggregationBehavior;
2716
+ aggregationStrategy?: SemaphorDerivedFieldAggregationStrategy;
2717
+ format?: unknown;
2718
+ tags?: string[];
2719
+ };
2720
+
2721
+ declare type SemaphorDerivedFieldInput = {
2722
+ kind: 'field';
2723
+ field: SemaphorFieldRef;
2724
+ aggregate?: SemaphorAggregateFunction;
2725
+ } | {
2726
+ kind: 'metric';
2727
+ metric: SemaphorFieldRef;
2728
+ } | {
2729
+ kind: 'dimension';
2730
+ dimension: SemaphorFieldRef;
2731
+ };
2732
+
2733
+ declare type SemaphorDerivedFieldResultRole = 'measure' | 'group' | 'date' | 'id' | 'filter';
2734
+
2680
2735
  declare type SemaphorDialect = 'postgres' | 'mysql' | 'mssql' | 'snowflake' | 'clickhouse' | 'bigquery' | 'redshift' | 'duckdb' | 'sqlite' | 'unknown';
2681
2736
 
2737
+ declare type SemaphorFieldRef = {
2738
+ name: string;
2739
+ label?: string;
2740
+ role?: 'dimension' | 'measure' | 'date' | 'id' | 'unknown';
2741
+ dataType?: 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'unknown';
2742
+ source?: SemaphorSourceRef;
2743
+ aggregate?: SemaphorAggregateFunction;
2744
+ };
2745
+
2682
2746
  declare type SemaphorSourceRef = {
2683
2747
  kind: 'semantic';
2684
2748
  domainId: string;
@@ -3362,6 +3426,7 @@ export declare type TDataColumn = {
3362
3426
  role?: 'groupby' | 'metric' | 'sortby' | 'pivotby' | 'detail';
3363
3427
  expression?: string;
3364
3428
  calculatedFormula?: CalculatedFieldFormula;
3429
+ derivedField?: SemaphorDerivedFieldDefinition;
3365
3430
  format?: FormatSpec;
3366
3431
  sourceField?: string;
3367
3432
  aggregate?: AggregateFunction;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "email": "support@semaphor.cloud"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "0.1.369",
8
+ "version": "0.1.371",
9
9
  "description": "Fully interactive and customizable dashboards for your apps.",
10
10
  "keywords": [
11
11
  "react",
@@ -1 +0,0 @@
1
- "use strict";const w=require("./validators-oc8qtP4q.js"),u=require("./source-identity-C-xaeE_I.js");function v(e){var t;const r=j(e);return{version:1,kind:"metric",id:e.id,label:e.label,source:S(e),metrics:r,primaryMetric:Q(e,r),dateField:e.dateField?a(e.dateField,"date"):void 0,timeGrain:e.timeGrain,dimensions:(t=e.dimensions)==null?void 0:t.map(o=>a(o,"dimension")),comparison:Z(e.comparison),orderBy:e.orderBy?{field:a(e.orderBy.field),direction:e.orderBy.direction}:void 0,inputs:p(e.inputs),limit:e.limit}}function M(e){var t;return{...v(e),...e.timeWindow?{timeWindow:e.timeWindow}:{},...(t=e.filters)!=null&&t.length?{filters:e.filters}:{},...e.analysis?{analysis:e.analysis}:{}}}function D(e){return{...e.chartTitle?{chartTitle:e.chartTitle}:{},...e.chartType?{chartType:e.chartType}:{},...e.driverMode?{driverMode:e.driverMode}:{},...e.includePopulation!==void 0?{includePopulation:e.includePopulation}:{},...e.calendarContext?{calendarContext:e.calendarContext}:{}}}function Q(e,r){if(!e.primaryMetric)return r[0]||{name:"",role:"measure"};const t=a(e.primaryMetric,"measure"),o=V(t,r),i=o.length===1?o[0]:void 0;return i?_(t,i):t}function j(e){const r=[];for(const t of e.metrics.map(o=>a(o,"measure"))){if(!t.name)continue;const o=r.findIndex(i=>K(i,t));if(o===-1){r.push(t);continue}r[o]=_(r[o],t)}return r}function K(e,r){return u.semaphorFieldRefsMatch(e,r)&&f(e)===f(r)}function E(e,r){return f(r)===f(e)}function N(e,r){return r.name!==e.name||e.source&&!u.semaphorFieldRefsMatch(r,e)?!1:E(e,r)}function V(e,r){const t=r.filter(o=>N(e,o));return e.aggregate!==void 0,t}function f(e){return(e.aggregate||"SUM").toUpperCase()}function _(e,r){if(e.aggregate&&r.aggregate&&e.aggregate!==r.aggregate)throw new Error(`Metric "${e.name}" was requested with conflicting aggregate semantics: ${e.aggregate} and ${r.aggregate}.`);return{...u.preferSemaphorFieldRefMetadata(e,r),aggregate:e.aggregate||r.aggregate}}function C(e){var t;if("sort"in e)throw new Error("semaphor.records supports orderBy for a single deterministic sort. Multiple sort clauses are not supported by the analytics protocol yet.");if(!Y(e))throw new Error("semaphor.records needs at least one field.");const r=W(e.fields);return{version:1,kind:"records",id:e.id,label:e.label,source:S(e),fields:r,dateField:e.dateField?a(e.dateField,"date"):void 0,timeGrain:e.timeGrain,...e.timeWindow?{timeWindow:e.timeWindow}:{},...(t=e.filters)!=null&&t.length?{filters:e.filters}:{},orderBy:e.orderBy?{field:a(e.orderBy.field),direction:e.orderBy.direction}:void 0,inputs:p(e.inputs),limit:e.limit,...e.pagination?{pagination:e.pagination}:{}}}function W(e){return e.map(r=>{const t=a(r);if(!t.role)throw new Error(`semaphor.records field "${t.name}" needs an explicit role.`);return t})}function R(e){return{version:1,kind:"inputOptions",id:e.id,label:e.label,source:S(e),field:a(e.field,"dimension"),search:e.search,limit:e.limit}}function $(e){var r;return{version:1,kind:"sql",id:e.id,label:e.label,source:e.source,sql:e.sql,...e.defaultParameters?{defaultParameters:e.defaultParameters}:{},...e.pythonCode?{pythonCode:e.pythonCode}:{},...(r=e.fields)!=null&&r.length?{fields:e.fields.map(t=>a(t))}:{},inputs:p(e.inputs),limit:e.limit,...e.pagination?{pagination:e.pagination}:{},rationale:e.rationale}}function T(e){if("toAnalyticsInput"in e){const n=e.toAnalyticsInput();return{inputId:n.inputId,kind:n.kind,...n.controlRole?{controlRole:n.controlRole}:{},...n.operator?{operator:n.operator}:{},...n.field?{field:n.field}:{}}}if("id"in e){const n=I(e);return{inputId:n.inputId,kind:n.kind,...n.controlRole?{controlRole:n.controlRole}:{},...n.operator?{operator:n.operator}:{},...n.field?{field:n.field}:{}}}const r="kind"in e?e.kind:void 0,t="operator"in e?F(e.operator,e.inputId):void 0,o="controlRole"in e?e.controlRole:"role"in e?e.role:void 0,i=U(o)?o:void 0;return{inputId:e.inputId,...r?{kind:r}:{},...i?{controlRole:i}:{},...t?{operator:t}:{},...e.field?{field:e.field}:{}}}function U(e){return e==="grain"||e==="metric"||e==="dimension"||e==="aggregation"||e==="sqlParam"}function G(e){const r=p(e);return r.length>0?r:void 0}function P(e){return(e||[]).map(X)}function L(e){return P(e).filter(r=>r.isActive)}function I(e){if(e.kind==="filter"){const r=F(e.operator,e.id);return{inputId:e.id,kind:e.kind,label:e.label,field:a(e.field,"dimension"),operator:r||"in"}}return{inputId:e.id,kind:e.kind,label:e.label,controlRole:e.role}}function J(e=[]){return e.map(r=>typeof r=="object"?r:{label:String(r),value:r})}function h(e){return e==null?!1:Array.isArray(e)?e.length>0:typeof e=="string"?e.trim().length>0:!0}function X(e){if("toAnalyticsInput"in e)return e.toAnalyticsInput();if("kind"in e&&"isActive"in e)return e;if("id"in e){const r=I(e),t=Object.prototype.hasOwnProperty.call(e,"value")?e.value:e.defaultValue;return{inputId:r.inputId,kind:r.kind,label:r.label,...r.field?{field:r.field}:{},...r.operator?{operator:r.operator}:{},...r.controlRole?{controlRole:r.controlRole}:{},value:t,isActive:h(t)}}return{...e,kind:"filter",isActive:h(e.value),value:e.value}}function S(e){return e.source}function Y(e){var r;return!!((r=e.fields)!=null&&r.length)}function a(e,r){return{...e,role:e.role||r}}function p(e){return(e||[]).map(T)}function Z(e){if(e)return e}function F(e,r){if(e===void 0)return;const t=w.normalizeSemaphorInputOperator(e);if(!t)throw new Error(`useSemaphorInput "${r}" uses unsupported filter operator "${e}".`);return t}function H(e,r={}){const t=r.pathPrefix||"analysisOptions";if(e===void 0)return{ok:!0};if(!e||typeof e!="object"||Array.isArray(e))return s(t,"Data App analysis options must be an object.");const o=e,i={};if(o.chartTitle!==void 0){if(typeof o.chartTitle!="string")return s(`${t}.chartTitle`,'Data App analysis option "chartTitle" must be a string.');i.chartTitle=o.chartTitle}if(o.chartType!==void 0){if(typeof o.chartType!="string")return s(`${t}.chartType`,'Data App analysis option "chartType" must be a string.');i.chartType=o.chartType}if(o.driverMode!==void 0){if(!te(o.driverMode))return s(`${t}.driverMode`,'Data App analysis option "driverMode" must be absolute_delta, largest_negative, largest_positive, positive_and_negative, or all.');i.driverMode=o.driverMode}if(o.includePopulation!==void 0){if(typeof o.includePopulation!="boolean")return s(`${t}.includePopulation`,'Data App analysis option "includePopulation" must be a boolean.');i.includePopulation=o.includePopulation}if(o.calendarContext!==void 0){const n=oe(o.calendarContext,{pathPrefix:`${t}.calendarContext`,validateTimezone:r.validateTimezone});if(!n.ok)return n;i.calendarContext=n.calendarContext}return{ok:!0,analysisOptions:i}}function ee(e){const r=e.queries.map((i,n)=>re(i,n,{fieldCatalogs:e.fieldCatalogs||[],requireFieldCatalog:!!e.requireFieldCatalog,validateTimezone:e.validateTimezone})),t=r.flatMap(i=>i.diagnostics),o=r.map(i=>i.executionResult);return{ok:t.every(i=>i.severity!=="error"),diagnostics:t,queries:r,intents:r.flatMap(i=>i.intent?[i.intent]:[]),executionResults:o}}function re(e,r,t){const o=`queries.${r}`;try{const i=ne(e),n=he(e,i),d=w.validateSemaphorAnalyticsIntent(i),l=[...ce({querySpec:e,queryId:n,intent:i,pathPrefix:o}),...d.errors.map(y=>q(y,{queryHook:e.queryHook,queryId:n,pathPrefix:o,severity:"error",intent:i})),...d.warnings.map(y=>q(y,{queryHook:e.queryHook,queryId:n,pathPrefix:o,severity:"warning",intent:i})),...se({querySpec:e,queryId:n,intent:i,pathPrefix:o,fieldCatalogs:t.fieldCatalogs,requireFieldCatalog:t.requireFieldCatalog}),...ue({querySpec:e,queryId:n,intent:i,pathPrefix:o,validateTimezone:t.validateTimezone})],c=ye(d,l);return{queryHook:e.queryHook,queryId:n,intent:i,diagnostics:l,executionResult:b({intent:i,validation:c,diagnostics:l})}}catch(i){const n={severity:"error",code:"invalid_query_spec",message:i instanceof Error?i.message:String(i),path:o,queryHook:e.queryHook,queryId:O(e.spec)},d=B([n]);return{queryHook:e.queryHook,queryId:n.queryId,diagnostics:[n],executionResult:b({validation:d,diagnostics:[n]})}}}function s(e,r){return{ok:!1,issues:[{code:"invalid_analysis_option",message:r,path:e}]}}function x(e){return!!(e&&typeof e=="object"&&!Array.isArray(e))}function te(e){return e==="absolute_delta"||e==="largest_negative"||e==="largest_positive"||e==="positive_and_negative"||e==="all"}function ie(e){return e.trim().length>0&&!Number.isNaN(Date.parse(e))}function oe(e,r){var c;if(!e||typeof e!="object"||Array.isArray(e))return s(r.pathPrefix,'Data App analysis option "calendarContext" must be an object.');const t=e,o=t.tz,i=t.weekStart,n=t.anchor,d=n&&typeof n=="object"&&!Array.isArray(n)?n.iso:void 0,l=typeof o=="string"?((c=r.validateTimezone)==null?void 0:c.call(r,o))??o:null;return l?typeof i!="number"||!Number.isInteger(i)||i<0||i>6?s(`${r.pathPrefix}.weekStart`,'Data App analysis option "calendarContext.weekStart" must be an integer from 0 to 6.'):n!=="now"&&!(typeof d=="string"&&ie(d))?s(`${r.pathPrefix}.anchor`,'Data App analysis option "calendarContext.anchor" must be "now" or an object with a valid iso string.'):{ok:!0,calendarContext:{tz:l,weekStart:i,anchor:n}}:s(`${r.pathPrefix}.tz`,'Data App analysis option "calendarContext.tz" must be a valid timezone string.')}function ne(e){return ae(e.spec)}function ae(e){if(!x(e))throw new Error("useSemaphorQuery spec must be an object.");if(e.queryKind==="metric")return v(e);if(e.queryKind==="analysis")return M(e);if(e.queryKind==="records")return C(e);if(e.queryKind==="sql")return $(e);if(e.queryKind==="inputOptions")return R(e);throw new Error("useSemaphorQuery spec.queryKind must be metric, analysis, records, inputOptions, or sql.")}function se(e){if(e.intent.kind==="sql")return[];if(e.fieldCatalogs.length===0&&!e.requireFieldCatalog)return[];const r=me(e.fieldCatalogs,e.intent.source);return r?[...de({...e,catalog:r}),...le({...e,catalog:r})]:[{severity:"error",code:"invalid_source_ref",message:`Source ref for ${e.querySpec.queryHook} does not match a visible Semaphor source.`,path:`${e.pathPrefix}.spec.source`,queryHook:e.querySpec.queryHook,queryId:e.queryId,intentId:e.intent.id,source:e.intent.source}]}function de(e){return fe(e.intent).flatMap(({field:r,path:t})=>z(e.catalog,r,e.intent.source)?[]:[{severity:"error",code:"missing_field",message:`Field "${r.name}" is not visible on the selected Semaphor source.`,path:`${e.pathPrefix}.${t}`,queryHook:e.querySpec.queryHook,queryId:e.queryId,intentId:e.intent.id,source:m(r,e.intent.source),field:r}])}function le(e){return("inputs"in e.intent?e.intent.inputs||[]:[]).flatMap((t,o)=>{if(!t.field)return[];const i=m(t.field,e.intent.source);return u.semaphorSourcesReferToSameDataset(i,e.intent.source)?z(e.catalog,t.field,e.intent.source)?[]:[{severity:"error",code:"missing_field",message:`Input "${t.inputId}" references field "${t.field.name}", which is not visible on the selected Semaphor source.`,path:`${e.pathPrefix}.spec.inputs.${o}.field`,queryHook:e.querySpec.queryHook,queryId:e.queryId,intentId:e.intent.id,source:i,field:t.field}]:[{severity:"error",code:"unsupported_input_filter_composition",message:`Input "${t.inputId}" filters a different Semaphor source than the query. Cross-source Data App inputs are not supported yet.`,path:`${e.pathPrefix}.spec.inputs.${o}.field`,queryHook:e.querySpec.queryHook,queryId:e.queryId,intentId:e.intent.id,source:i,field:t.field}]})}function ue(e){if(e.querySpec.spec.queryKind!=="analysis")return[];const r=H(e.querySpec.spec,{pathPrefix:`${e.pathPrefix}.spec`,validateTimezone:e.validateTimezone});return r.ok?[]:r.issues.map(t=>({severity:"error",code:t.code,message:t.message,path:t.path,queryHook:e.querySpec.queryHook,queryId:e.queryId,intentId:e.intent.id,source:e.intent.source}))}function ce(e){return e.querySpec.spec.queryKind!=="sql"?[]:x(e.querySpec.spec)?Object.prototype.hasOwnProperty.call(e.querySpec.spec,"parameters")?[{severity:"error",code:"deprecated_sql_parameters",message:"semaphor.sql uses defaultParameters for static SQL param(...) fallback values. The legacy parameters field is not supported.",path:`${e.pathPrefix}.spec.parameters`,queryHook:e.querySpec.queryHook,queryId:e.queryId,intentId:e.intent.id}]:[]:[]}function fe(e){return e.kind==="metric"?[...e.metrics.map((r,t)=>({field:r,path:`spec.metrics.${t}`})),...e.primaryMetric?[{field:e.primaryMetric,path:"spec.primaryMetric"}]:[],...e.dateField?[{field:e.dateField,path:"spec.dateField"}]:[],...(e.dimensions||[]).map((r,t)=>({field:r,path:`spec.dimensions.${t}`})),...e.orderBy?[{field:e.orderBy.field,path:"spec.orderBy.field"}]:[],...(e.filters||[]).map((r,t)=>({field:r.field,path:`spec.filters.${t}.field`}))]:e.kind==="records"?[...e.fields.map((r,t)=>({field:r,path:`spec.fields.${t}`})),...e.dateField?[{field:e.dateField,path:"spec.dateField"}]:[],...e.orderBy?[{field:e.orderBy.field,path:"spec.orderBy.field"}]:[],...(e.filters||[]).map((r,t)=>({field:r.field,path:`spec.filters.${t}.field`}))]:e.kind==="inputOptions"?[{field:e.field,path:"spec.field"}]:[]}function me(e,r){return e.find(t=>g(t,r))}function z(e,r,t){const o=m(r,t);if(g(e,o))return e.fields.find(i=>pe(i,r)&&g(e,m(i,e.source)))}function g(e,r){return[e.source,...e.sourceAliases||[]].some(t=>u.semaphorSourcesReferToSameDataset(t,r))}function m(e,r){return e.source||r}function pe(e,r){return!!(e.name&&r.name&&e.name===r.name)}function q(e,r){return{severity:r.severity,code:e.code||"invalid_analytics_intent",message:e.message,path:e.path?`${r.pathPrefix}.spec.${e.path}`:r.pathPrefix,queryHook:r.queryHook,queryId:r.queryId,intentId:r.intent.id,source:r.intent.source}}function ye(e,r){const t=B(r);return{ok:t.ok&&e.ok,errors:A([...e.errors,...t.errors]),warnings:A([...e.warnings,...t.warnings]),repairHints:[...e.repairHints,...t.repairHints]}}function B(e){const r=e.filter(o=>o.severity==="error").map(k),t=e.filter(o=>o.severity==="warning").map(k);return{ok:r.length===0,errors:r,warnings:t,repairHints:r.map(o=>{var i,n;return{code:o.code,message:o.message,fieldRole:o.fieldRole,invalidField:(i=o.repairHint)==null?void 0:i.invalidField,recommendedNextStep:((n=o.repairHint)==null?void 0:n.recommendedNextStep)||"Update the Data App SDK query spec to use visible Semaphor source and field refs."}})}}function k(e){var r;return{code:e.code,message:e.message,path:e.path,fieldRole:e.code==="invalid_source_ref"?"source":void 0,repairHint:{code:e.code,message:e.message,invalidField:(r=e.field)==null?void 0:r.name,fieldRole:e.code==="invalid_source_ref"?"source":void 0,recommendedNextStep:e.code==="unsupported_input_filter_composition"?"Use an input field from the same Semaphor source as the query, or split the query into separate source-scoped queries.":"Update the query spec to use a visible Semaphor source and field ref."}}}function A(e){const r=new Set;return e.filter(t=>{const o=`${t.code}:${t.path||""}:${t.message}`;return r.has(o)?!1:(r.add(o),!0)})}function b(e){var t,o;const r=e.diagnostics.filter(i=>i.severity==="error");return{intentId:(t=e.intent)==null?void 0:t.id,status:r.length?"failed":"answered",resultShape:(o=e.intent)==null?void 0:o.kind,intent:e.intent,validation:e.validation,coverage:{answeredObligations:r.length?[]:["query_spec_validation"],missingObligations:r.length?["query_spec_validation"]:[],warnings:e.validation.warnings},missingFields:r.filter(i=>i.code==="missing_field").flatMap(i=>{var n;return(n=i.field)!=null&&n.name?[i.field.name]:[]}),warnings:e.diagnostics.filter(i=>i.severity==="warning").map(i=>i.message),metadata:{validationKind:"data_app_sdk_query_spec"}}}function he(e,r){return r.id||O(e.spec)}function O(e){if(!e||typeof e!="object"||!("id"in e))return;const r=e.id;return typeof r=="string"&&r.trim()?r:void 0}exports.hasSemaphorInputValue=h;exports.normalizeSemaphorAnalysisQueryOptions=H;exports.normalizeSemaphorInputOptions=J;exports.toSemaphorActiveInputSnapshots=L;exports.toSemaphorAnalysisIntent=M;exports.toSemaphorAnalysisQueryOptions=D;exports.toSemaphorInputBinding=T;exports.toSemaphorInputBindings=G;exports.toSemaphorInputOptionsIntent=R;exports.toSemaphorInputSnapshots=P;exports.toSemaphorInputSpec=I;exports.toSemaphorMetricIntent=v;exports.toSemaphorRecordsIntent=C;exports.toSemaphorSqlIntent=$;exports.validateSemaphorDataAppQuerySpecs=ee;