react-semaphor 0.1.381 → 0.1.383

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 (86) hide show
  1. package/DATA_APP_SDK.md +238 -0
  2. package/README.md +7 -0
  3. package/dist/analytics-protocol/index.cjs +1 -1
  4. package/dist/analytics-protocol/index.js +45 -41
  5. package/dist/brand-studio/index.cjs +4 -4
  6. package/dist/brand-studio/index.js +28 -28
  7. package/dist/chunks/analyze-result-contract-CtXfp3nv.js +1 -0
  8. package/dist/chunks/analyze-result-contract-DuhlklhI.js +102 -0
  9. package/dist/chunks/{braces-DOxxfERN.js → braces--20GzUQh.js} +1 -1
  10. package/dist/chunks/{braces-BT-ZyB-g.js → braces-C0Vh_Mft.js} +1 -1
  11. package/dist/chunks/{calendar-preferences-dialog-Dsgs8WDv.js → calendar-preferences-dialog-B-VsxhsA.js} +4 -4
  12. package/dist/chunks/calendar-preferences-dialog-DE67Z3oQ.js +1 -0
  13. package/dist/chunks/catalog-field-grounding-Bnx-3tE0.js +1 -0
  14. package/dist/chunks/catalog-field-grounding-CJKAqtiC.js +100 -0
  15. package/dist/chunks/{dashboard-briefing-launcher-Coks66cV.js → dashboard-briefing-launcher-BIj3X7b3.js} +108 -107
  16. package/dist/chunks/dashboard-briefing-launcher-Czx6BcXW.js +80 -0
  17. package/dist/chunks/dashboard-controls-BP-DcPFs.js +52 -0
  18. package/dist/chunks/{dashboard-controls-BfkcnIdy.js → dashboard-controls-BXxucM4f.js} +115 -114
  19. package/dist/chunks/dashboard-json-BNwshkK2.js +1 -0
  20. package/dist/chunks/{dashboard-json-DjXi4cI6.js → dashboard-json-C6oZuipD.js} +9 -9
  21. package/dist/chunks/edit-dashboard-visual-BAprin3J.js +178 -0
  22. package/dist/chunks/{edit-dashboard-visual-DOW1Ap1N.js → edit-dashboard-visual-CmfrI_L3.js} +1278 -1277
  23. package/dist/chunks/{index-CkoRCh3g.js → index-4W_ElSBJ.js} +219 -239
  24. package/dist/chunks/{index-DlprYjr6.js → index-icb12JV1.js} +900 -952
  25. package/dist/chunks/{layout-grid-DccceHv4.js → layout-grid-B7-klXiK.js} +1 -1
  26. package/dist/chunks/{layout-grid-DTbOIOsE.js → layout-grid-DV89AC9_.js} +1 -1
  27. package/dist/chunks/operators-C8TxpM4C.js +48 -0
  28. package/dist/chunks/operators-DrTQsJXv.js +1 -0
  29. package/dist/chunks/{palette-DCzLwqIw.js → palette-5IwhMbSF.js} +1 -1
  30. package/dist/chunks/{palette-SimHJELn.js → palette-Dj-dgPYh.js} +1 -1
  31. package/dist/chunks/{save-zNVYH02T.js → save-16C6YSW2.js} +1 -1
  32. package/dist/chunks/{save-D2O96E5A.js → save-C5fwVdTF.js} +1 -1
  33. package/dist/chunks/search-0LmWwZzW.js +57 -0
  34. package/dist/chunks/search-Dq1Mbb03.js +21 -0
  35. package/dist/chunks/{source-identity-Dj3dryN9.js → source-identity-CN4xiyKJ.js} +5 -5
  36. package/dist/chunks/{switch-DMPsMpHW.js → switch-DUdaHFZQ.js} +2328 -2414
  37. package/dist/chunks/{switch-Jhyl63RF.js → switch-bdJp0Bkw.js} +29 -54
  38. package/dist/chunks/use-create-flow-overlay-state-BIHKf_XK.js +21 -0
  39. package/dist/chunks/{use-create-flow-overlay-state-r5JKyXU8.js → use-create-flow-overlay-state-YvqCp6Zo.js} +75 -75
  40. package/dist/chunks/{validators-CtNmgsvG.js → validators-CHPH6ORs.js} +641 -498
  41. package/dist/chunks/validators-lWo8m0Q7.js +1 -0
  42. package/dist/chunks/x-B_cx7LwM.js +26 -0
  43. package/dist/chunks/x-IdR_js6f.js +139 -0
  44. package/dist/dashboard/index.cjs +1 -1
  45. package/dist/dashboard/index.js +1 -1
  46. package/dist/dashboard-authoring/index.cjs +3 -3
  47. package/dist/dashboard-authoring/index.js +105 -92
  48. package/dist/data-app-builder/index.cjs +23 -23
  49. package/dist/data-app-builder/index.js +17 -15
  50. package/dist/data-app-sdk/index.cjs +68 -1
  51. package/dist/data-app-sdk/index.js +2731 -384
  52. package/dist/data-app-sdk-adapters/index.cjs +1 -0
  53. package/dist/data-app-sdk-adapters/index.js +383 -0
  54. package/dist/data-app-sdk-validation/index.cjs +1 -1
  55. package/dist/data-app-sdk-validation/index.js +1073 -6
  56. package/dist/index.cjs +1 -1
  57. package/dist/index.js +15 -15
  58. package/dist/surfboard/index.cjs +1 -1
  59. package/dist/surfboard/index.js +2 -2
  60. package/dist/types/analytics-protocol.d.ts +58 -31
  61. package/dist/types/dashboard-assistant.d.ts +40 -15
  62. package/dist/types/dashboard-authoring.d.ts +36 -16
  63. package/dist/types/dashboard.d.ts +8 -8
  64. package/dist/types/data-app-builder.d.ts +35 -11
  65. package/dist/types/data-app-sdk-adapters.d.ts +733 -0
  66. package/dist/types/data-app-sdk-validation.d.ts +85 -25
  67. package/dist/types/data-app-sdk.d.ts +217 -147
  68. package/dist/types/main.d.ts +35 -11
  69. package/dist/types/shared.d.ts +8 -8
  70. package/dist/types/surfboard.d.ts +8 -8
  71. package/dist/types/types.d.ts +8 -8
  72. package/package.json +9 -2
  73. package/src/data-app-sdk/README.md +240 -0
  74. package/dist/chunks/calendar-preferences-dialog-iZs8XqyH.js +0 -1
  75. package/dist/chunks/catalog-field-grounding-8L9I0zdg.js +0 -1
  76. package/dist/chunks/catalog-field-grounding-BK4BX8sZ.js +0 -200
  77. package/dist/chunks/dashboard-briefing-launcher-B5vPTl8P.js +0 -80
  78. package/dist/chunks/dashboard-controls-Dyqye6fh.js +0 -52
  79. package/dist/chunks/dashboard-json-CV_LnO9x.js +0 -1
  80. package/dist/chunks/edit-dashboard-visual-yinO0yU-.js +0 -178
  81. package/dist/chunks/index-BxM99sFL.js +0 -1
  82. package/dist/chunks/index-CuHybtft.js +0 -51
  83. package/dist/chunks/use-create-flow-overlay-state-NsqFPwdB.js +0 -21
  84. package/dist/chunks/validation-BM3-ShHV.js +0 -1003
  85. package/dist/chunks/validation-BVpqRFar.js +0 -1
  86. package/dist/chunks/validators-jpoYhpHh.js +0 -1
@@ -4875,15 +4875,9 @@ declare type SemaphorDerivedFieldInput = {
4875
4875
  kind: 'field';
4876
4876
  field: SemaphorFieldRef;
4877
4877
  aggregate?: SemaphorAggregateFunction;
4878
- } | {
4879
- kind: 'metric';
4880
- metric: SemaphorFieldRef;
4881
- } | {
4882
- kind: 'dimension';
4883
- dimension: SemaphorFieldRef;
4884
4878
  };
4885
4879
 
4886
- declare type SemaphorDerivedFieldResultRole = 'measure' | 'group' | 'date' | 'id' | 'filter';
4880
+ declare type SemaphorDerivedFieldResultRole = 'measure' | 'dimension' | 'date' | 'id' | 'unknown';
4887
4881
 
4888
4882
  declare type SemaphorDialect = 'postgres' | 'mysql' | 'mssql' | 'snowflake' | 'clickhouse' | 'bigquery' | 'redshift' | 'duckdb' | 'sqlite' | 'unknown';
4889
4883
 
@@ -4907,9 +4901,10 @@ declare type SemaphorFieldRef = {
4907
4901
  declare type SemaphorInputBinding = {
4908
4902
  inputId: string;
4909
4903
  kind?: 'filter' | 'control';
4910
- controlRole?: 'grain' | 'metric' | 'dimension' | 'aggregation' | 'sqlParam';
4904
+ controlRole?: 'grain' | 'measure' | 'dimension' | 'aggregation' | 'sqlParam';
4911
4905
  operator?: SemaphorInputOperator;
4912
4906
  field?: SemaphorFieldRef;
4907
+ relationshipHint?: SemaphorRelationshipHint;
4913
4908
  };
4914
4909
 
4915
4910
  declare type SemaphorInputOperator = '=' | '!=' | 'in' | 'not_in' | 'contains' | 'not_contains' | 'between' | 'not_between' | '>' | '>=' | '<' | '<=';
@@ -4919,10 +4914,17 @@ declare type SemaphorInputOptionsIntent = {
4919
4914
  version?: SemaphorProtocolVersion;
4920
4915
  id?: string;
4921
4916
  label?: string;
4917
+ inputId: string;
4922
4918
  source: SemaphorSourceRef;
4923
- field: SemaphorFieldRef;
4919
+ labelField: SemaphorFieldRef;
4920
+ valueField: SemaphorFieldRef;
4921
+ searchField?: SemaphorFieldRef;
4922
+ disambiguationFields?: SemaphorFieldRef[];
4923
+ population?: SemaphorOptionPopulation;
4924
+ dependencies?: SemaphorOptionDependencies;
4924
4925
  search?: string;
4925
4926
  limit?: number;
4927
+ inputs?: SemaphorInputBinding[];
4926
4928
  derivedFields?: SemaphorDerivedFieldDefinition[];
4927
4929
  };
4928
4930
 
@@ -4984,6 +4986,7 @@ declare type SemaphorMatrixIntent = {
4984
4986
  values: SemaphorMatrixValueField[];
4985
4987
  filters?: SemaphorAnalyticsFilter[];
4986
4988
  inputs?: SemaphorInputBinding[];
4989
+ relationshipHint?: SemaphorRelationshipHint;
4987
4990
  totals?: SemaphorMatrixTotalOptions;
4988
4991
  sort?: SemaphorMatrixSortRule[];
4989
4992
  expansion?: SemaphorMatrixExpansionOptions;
@@ -5106,8 +5109,8 @@ declare type SemaphorMetricIntent = {
5106
5109
  version?: SemaphorProtocolVersion;
5107
5110
  id?: string;
5108
5111
  source: SemaphorSourceRef;
5109
- metrics: SemaphorFieldRef[];
5110
- primaryMetric?: SemaphorFieldRef;
5112
+ measures: SemaphorFieldRef[];
5113
+ primaryMeasure?: SemaphorFieldRef;
5111
5114
  label?: string;
5112
5115
  dateField?: SemaphorFieldRef;
5113
5116
  timeGrain?: SemaphorTimeGrain;
@@ -5124,10 +5127,26 @@ declare type SemaphorMetricIntent = {
5124
5127
  direction: 'asc' | 'desc';
5125
5128
  };
5126
5129
  inputs?: SemaphorInputBinding[];
5130
+ relationshipHint?: SemaphorRelationshipHint;
5127
5131
  limit?: number;
5128
5132
  derivedFields?: SemaphorDerivedFieldDefinition[];
5129
5133
  };
5130
5134
 
5135
+ declare type SemaphorOptionDependencies = {
5136
+ mode?: 'auto' | 'independent' | 'explicit';
5137
+ includeInputIds?: string[];
5138
+ excludeInputIds?: string[];
5139
+ };
5140
+
5141
+ declare type SemaphorOptionPopulation = {
5142
+ kind: 'option_source';
5143
+ baseSource?: never;
5144
+ } | {
5145
+ kind: 'related_population';
5146
+ baseSource: SemaphorSourceRef;
5147
+ relationshipHint?: SemaphorRelationshipHint;
5148
+ };
5149
+
5131
5150
  declare type SemaphorPaginationMetadata = {
5132
5151
  page: number;
5133
5152
  pageSize: number;
@@ -5170,9 +5189,14 @@ declare type SemaphorRecordsIntent = {
5170
5189
  direction: 'asc' | 'desc';
5171
5190
  };
5172
5191
  inputs?: SemaphorInputBinding[];
5192
+ relationshipHint?: SemaphorRelationshipHint;
5173
5193
  derivedFields?: SemaphorDerivedFieldDefinition[];
5174
5194
  };
5175
5195
 
5196
+ declare type SemaphorRelationshipHint = {
5197
+ relationshipIds?: string[];
5198
+ };
5199
+
5176
5200
  declare type SemaphorRelativeTimeWindow = {
5177
5201
  kind?: 'relative';
5178
5202
  unit: 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';
@@ -1655,15 +1655,9 @@ declare type SemaphorDerivedFieldInput = {
1655
1655
  kind: 'field';
1656
1656
  field: SemaphorFieldRef;
1657
1657
  aggregate?: SemaphorAggregateFunction;
1658
- } | {
1659
- kind: 'metric';
1660
- metric: SemaphorFieldRef;
1661
- } | {
1662
- kind: 'dimension';
1663
- dimension: SemaphorFieldRef;
1664
1658
  };
1665
1659
 
1666
- declare type SemaphorDerivedFieldResultRole = 'measure' | 'group' | 'date' | 'id' | 'filter';
1660
+ declare type SemaphorDerivedFieldResultRole = 'measure' | 'dimension' | 'date' | 'id' | 'unknown';
1667
1661
 
1668
1662
  declare type SemaphorDialect = 'postgres' | 'mysql' | 'mssql' | 'snowflake' | 'clickhouse' | 'bigquery' | 'redshift' | 'duckdb' | 'sqlite' | 'unknown';
1669
1663
 
@@ -1687,9 +1681,10 @@ declare type SemaphorFieldRef = {
1687
1681
  declare type SemaphorInputBinding = {
1688
1682
  inputId: string;
1689
1683
  kind?: 'filter' | 'control';
1690
- controlRole?: 'grain' | 'metric' | 'dimension' | 'aggregation' | 'sqlParam';
1684
+ controlRole?: 'grain' | 'measure' | 'dimension' | 'aggregation' | 'sqlParam';
1691
1685
  operator?: SemaphorInputOperator;
1692
1686
  field?: SemaphorFieldRef;
1687
+ relationshipHint?: SemaphorRelationshipHint;
1693
1688
  };
1694
1689
 
1695
1690
  declare type SemaphorInputOperator = '=' | '!=' | 'in' | 'not_in' | 'contains' | 'not_contains' | 'between' | 'not_between' | '>' | '>=' | '<' | '<=';
@@ -1752,6 +1747,7 @@ declare type SemaphorMatrixIntent = {
1752
1747
  values: SemaphorMatrixValueField[];
1753
1748
  filters?: SemaphorAnalyticsFilter[];
1754
1749
  inputs?: SemaphorInputBinding[];
1750
+ relationshipHint?: SemaphorRelationshipHint;
1755
1751
  totals?: SemaphorMatrixTotalOptions;
1756
1752
  sort?: SemaphorMatrixSortRule[];
1757
1753
  expansion?: SemaphorMatrixExpansionOptions;
@@ -1840,6 +1836,10 @@ declare type SemaphorMatrixValueField = {
1840
1836
 
1841
1837
  declare type SemaphorProtocolVersion = 1;
1842
1838
 
1839
+ declare type SemaphorRelationshipHint = {
1840
+ relationshipIds?: string[];
1841
+ };
1842
+
1843
1843
  declare type SemaphorSemanticSourceRef = Extract<SemaphorSourceRef, {
1844
1844
  kind: 'semantic';
1845
1845
  }>;
@@ -2015,15 +2015,9 @@ declare type SemaphorDerivedFieldInput = {
2015
2015
  kind: 'field';
2016
2016
  field: SemaphorFieldRef;
2017
2017
  aggregate?: SemaphorAggregateFunction;
2018
- } | {
2019
- kind: 'metric';
2020
- metric: SemaphorFieldRef;
2021
- } | {
2022
- kind: 'dimension';
2023
- dimension: SemaphorFieldRef;
2024
2018
  };
2025
2019
 
2026
- declare type SemaphorDerivedFieldResultRole = 'measure' | 'group' | 'date' | 'id' | 'filter';
2020
+ declare type SemaphorDerivedFieldResultRole = 'measure' | 'dimension' | 'date' | 'id' | 'unknown';
2027
2021
 
2028
2022
  declare type SemaphorDialect = 'postgres' | 'mysql' | 'mssql' | 'snowflake' | 'clickhouse' | 'bigquery' | 'redshift' | 'duckdb' | 'sqlite' | 'unknown';
2029
2023
 
@@ -2047,9 +2041,10 @@ declare type SemaphorFieldRef = {
2047
2041
  declare type SemaphorInputBinding = {
2048
2042
  inputId: string;
2049
2043
  kind?: 'filter' | 'control';
2050
- controlRole?: 'grain' | 'metric' | 'dimension' | 'aggregation' | 'sqlParam';
2044
+ controlRole?: 'grain' | 'measure' | 'dimension' | 'aggregation' | 'sqlParam';
2051
2045
  operator?: SemaphorInputOperator;
2052
2046
  field?: SemaphorFieldRef;
2047
+ relationshipHint?: SemaphorRelationshipHint;
2053
2048
  };
2054
2049
 
2055
2050
  declare type SemaphorInputOperator = '=' | '!=' | 'in' | 'not_in' | 'contains' | 'not_contains' | 'between' | 'not_between' | '>' | '>=' | '<' | '<=';
@@ -2112,6 +2107,7 @@ declare type SemaphorMatrixIntent = {
2112
2107
  values: SemaphorMatrixValueField[];
2113
2108
  filters?: SemaphorAnalyticsFilter[];
2114
2109
  inputs?: SemaphorInputBinding[];
2110
+ relationshipHint?: SemaphorRelationshipHint;
2115
2111
  totals?: SemaphorMatrixTotalOptions;
2116
2112
  sort?: SemaphorMatrixSortRule[];
2117
2113
  expansion?: SemaphorMatrixExpansionOptions;
@@ -2200,6 +2196,10 @@ declare type SemaphorMatrixValueField = {
2200
2196
 
2201
2197
  declare type SemaphorProtocolVersion = 1;
2202
2198
 
2199
+ declare type SemaphorRelationshipHint = {
2200
+ relationshipIds?: string[];
2201
+ };
2202
+
2203
2203
  declare type SemaphorSemanticSourceRef = Extract<SemaphorSourceRef, {
2204
2204
  kind: 'semantic';
2205
2205
  }>;
@@ -3010,15 +3010,9 @@ declare type SemaphorDerivedFieldInput = {
3010
3010
  kind: 'field';
3011
3011
  field: SemaphorFieldRef;
3012
3012
  aggregate?: SemaphorAggregateFunction;
3013
- } | {
3014
- kind: 'metric';
3015
- metric: SemaphorFieldRef;
3016
- } | {
3017
- kind: 'dimension';
3018
- dimension: SemaphorFieldRef;
3019
3013
  };
3020
3014
 
3021
- declare type SemaphorDerivedFieldResultRole = 'measure' | 'group' | 'date' | 'id' | 'filter';
3015
+ declare type SemaphorDerivedFieldResultRole = 'measure' | 'dimension' | 'date' | 'id' | 'unknown';
3022
3016
 
3023
3017
  declare type SemaphorDialect = 'postgres' | 'mysql' | 'mssql' | 'snowflake' | 'clickhouse' | 'bigquery' | 'redshift' | 'duckdb' | 'sqlite' | 'unknown';
3024
3018
 
@@ -3042,9 +3036,10 @@ declare type SemaphorFieldRef = {
3042
3036
  declare type SemaphorInputBinding = {
3043
3037
  inputId: string;
3044
3038
  kind?: 'filter' | 'control';
3045
- controlRole?: 'grain' | 'metric' | 'dimension' | 'aggregation' | 'sqlParam';
3039
+ controlRole?: 'grain' | 'measure' | 'dimension' | 'aggregation' | 'sqlParam';
3046
3040
  operator?: SemaphorInputOperator;
3047
3041
  field?: SemaphorFieldRef;
3042
+ relationshipHint?: SemaphorRelationshipHint;
3048
3043
  };
3049
3044
 
3050
3045
  declare type SemaphorInputOperator = '=' | '!=' | 'in' | 'not_in' | 'contains' | 'not_contains' | 'between' | 'not_between' | '>' | '>=' | '<' | '<=';
@@ -3107,6 +3102,7 @@ declare type SemaphorMatrixIntent = {
3107
3102
  values: SemaphorMatrixValueField[];
3108
3103
  filters?: SemaphorAnalyticsFilter[];
3109
3104
  inputs?: SemaphorInputBinding[];
3105
+ relationshipHint?: SemaphorRelationshipHint;
3110
3106
  totals?: SemaphorMatrixTotalOptions;
3111
3107
  sort?: SemaphorMatrixSortRule[];
3112
3108
  expansion?: SemaphorMatrixExpansionOptions;
@@ -3230,6 +3226,10 @@ declare type SemaphorProtocolVersion = 1;
3230
3226
 
3231
3227
  declare type SemaphorQueryPath = 'query_spec' | 'sql' | 'sql_python';
3232
3228
 
3229
+ declare type SemaphorRelationshipHint = {
3230
+ relationshipIds?: string[];
3231
+ };
3232
+
3233
3233
  declare type SemaphorSemanticSourceRef = Extract<SemaphorSourceRef, {
3234
3234
  kind: 'semantic';
3235
3235
  }>;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "email": "support@semaphor.cloud"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "0.1.381",
8
+ "version": "0.1.383",
9
9
  "description": "Fully interactive and customizable dashboards for your apps.",
10
10
  "keywords": [
11
11
  "react",
@@ -16,7 +16,9 @@
16
16
  "type": "module",
17
17
  "files": [
18
18
  "dist",
19
- "CHANGELOG.md"
19
+ "CHANGELOG.md",
20
+ "DATA_APP_SDK.md",
21
+ "src/data-app-sdk/README.md"
20
22
  ],
21
23
  "main": "dist/index.cjs",
22
24
  "module": "dist/index.js",
@@ -72,6 +74,11 @@
72
74
  "import": "./dist/data-app-sdk/index.js",
73
75
  "require": "./dist/data-app-sdk/index.cjs"
74
76
  },
77
+ "./data-app-sdk/adapters": {
78
+ "types": "./dist/types/data-app-sdk-adapters.d.ts",
79
+ "import": "./dist/data-app-sdk-adapters/index.js",
80
+ "require": "./dist/data-app-sdk-adapters/index.cjs"
81
+ },
75
82
  "./data-app-sdk/validation": {
76
83
  "types": "./dist/types/data-app-sdk-validation.d.ts",
77
84
  "import": "./dist/data-app-sdk-validation/index.js",
@@ -0,0 +1,240 @@
1
+ # Data App SDK Quick Reference
2
+
3
+ Use this file as the public contract quick reference for generated Semaphor
4
+ Data Apps. Do not inspect SDK implementation internals to discover these
5
+ patterns.
6
+
7
+ ## Imports
8
+
9
+ ```tsx
10
+ import {
11
+ SemaphorDataAppProvider,
12
+ semaphor,
13
+ useClearInvalidSemaphorInputValue,
14
+ useSemaphorInputs,
15
+ useSemaphorQuery,
16
+ } from "react-semaphor/data-app-sdk";
17
+
18
+ import type {
19
+ SemaphorQueryResult,
20
+ SemaphorRecordsField,
21
+ SemaphorRecordsQueryResult,
22
+ SemaphorSourceRef,
23
+ } from "react-semaphor/data-app-sdk";
24
+ ```
25
+
26
+ ## Source And Fields
27
+
28
+ ```tsx
29
+ const source = {
30
+ kind: "semantic",
31
+ domainId: "sales",
32
+ datasetName: "orders",
33
+ } satisfies SemaphorSourceRef;
34
+
35
+ const revenue = {
36
+ name: "revenue",
37
+ label: "Revenue",
38
+ role: "measure",
39
+ dataType: "number",
40
+ aggregate: "SUM",
41
+ source,
42
+ } satisfies SemaphorRecordsField;
43
+
44
+ const segment = {
45
+ name: "segment",
46
+ label: "Segment",
47
+ role: "dimension",
48
+ dataType: "string",
49
+ source,
50
+ } satisfies SemaphorRecordsField;
51
+ ```
52
+
53
+ Use `SemaphorRecordsField` for `semaphor.records(...)` fields so every selected
54
+ field has a concrete role.
55
+
56
+ ## Metric
57
+
58
+ ```tsx
59
+ const revenueKpi = semaphor.metric({
60
+ id: "revenue-kpi",
61
+ source,
62
+ measures: [revenue],
63
+ primaryMeasure: revenue,
64
+ });
65
+
66
+ const result = useSemaphorQuery(revenueKpi);
67
+ ```
68
+
69
+ ## Records
70
+
71
+ ```tsx
72
+ const revenueBySegment = semaphor.records({
73
+ id: "revenue-by-segment",
74
+ source,
75
+ fields: [segment, revenue],
76
+ orderBy: { field: revenue, direction: "desc" },
77
+ limit: 10,
78
+ });
79
+
80
+ const result = useSemaphorQuery(revenueBySegment);
81
+ ```
82
+
83
+ ## Row Access
84
+
85
+ Read rows with `columns[].key`; display `columns[].label`.
86
+
87
+ ```tsx
88
+ function RecordsTable({ result }: { result: SemaphorRecordsQueryResult }) {
89
+ const records = result.records ?? [];
90
+ const columns = result.columns ?? [];
91
+
92
+ return (
93
+ <table>
94
+ <thead>
95
+ <tr>
96
+ {columns.map((column) => (
97
+ <th key={column.key}>{column.label || column.name}</th>
98
+ ))}
99
+ </tr>
100
+ </thead>
101
+ <tbody>
102
+ {records.map((row, rowIndex) => (
103
+ <tr key={rowIndex}>
104
+ {columns.map((column) => (
105
+ <td key={column.key}>{String(row[column.key] ?? "")}</td>
106
+ ))}
107
+ </tr>
108
+ ))}
109
+ </tbody>
110
+ </table>
111
+ );
112
+ }
113
+ ```
114
+
115
+ When accepting a generic `SemaphorQueryResult`, narrow before reading records:
116
+
117
+ ```tsx
118
+ function queryRecords(result: SemaphorQueryResult) {
119
+ return "records" in result && Array.isArray(result.records)
120
+ ? result.records
121
+ : [];
122
+ }
123
+ ```
124
+
125
+ ## Input Options
126
+
127
+ ```tsx
128
+ const segmentFilter = semaphor.filter({
129
+ id: "segment",
130
+ label: "Segment",
131
+ field: segment,
132
+ operator: "in",
133
+ });
134
+
135
+ const segmentOptions = semaphor.inputOptions({
136
+ id: "segment-options",
137
+ inputId: "segment",
138
+ source,
139
+ labelField: segment,
140
+ valueField: segment,
141
+ dependencies: { mode: "auto" },
142
+ limit: 100,
143
+ });
144
+
145
+ function SegmentFilter() {
146
+ const [segmentHandle] = useSemaphorInputs([segmentFilter]);
147
+ const optionsResult = useSemaphorQuery(segmentOptions, {
148
+ inputs: [segmentHandle],
149
+ });
150
+
151
+ useClearInvalidSemaphorInputValue(segmentHandle, optionsResult);
152
+ }
153
+ ```
154
+
155
+ Pass the full `optionsResult` to `useClearInvalidSemaphorInputValue`; do not
156
+ pass only `optionsResult.options`, because idle/loading results can also expose
157
+ an empty options array.
158
+
159
+ ## Shared Inputs With Source-Specific Bindings
160
+
161
+ Use `semaphor.bindInput(...)` when one visible input maps to different query
162
+ fields.
163
+
164
+ ```tsx
165
+ const dateRange = semaphor.filter({
166
+ id: "date_range",
167
+ label: "Date Range",
168
+ field: orderDate,
169
+ operator: "between",
170
+ });
171
+
172
+ function Dashboard() {
173
+ const [dateRangeHandle] = useSemaphorInputs([dateRange]);
174
+
175
+ const orders = useSemaphorQuery(ordersQuery, {
176
+ inputs: [semaphor.bindInput(dateRangeHandle, { field: orderDate })],
177
+ });
178
+ const invoices = useSemaphorQuery(invoicesQuery, {
179
+ inputs: [semaphor.bindInput(dateRangeHandle, { field: invoiceDate })],
180
+ });
181
+
182
+ const range = Array.isArray(dateRangeHandle.value)
183
+ ? dateRangeHandle.value
184
+ : [];
185
+ const [start, end] = range;
186
+ }
187
+ ```
188
+
189
+ Narrow `handle.value` with `Array.isArray(...)` before indexing date ranges or
190
+ multi-select values.
191
+
192
+ ## Related Dimension Filters
193
+
194
+ Use a related human-readable dimension as the visible filter and preserve the
195
+ relationship hint when binding that input into each fact query.
196
+
197
+ ```tsx
198
+ const materialFamilyFilter = semaphor.filter<string[]>({
199
+ id: "material_family",
200
+ label: "Material Family",
201
+ field: materialFamily,
202
+ operator: "in",
203
+ multi: true,
204
+ });
205
+
206
+ const materialOptions = semaphor.inputOptions({
207
+ id: "material-family-options",
208
+ inputId: "material_family",
209
+ source: materialSource,
210
+ labelField: materialFamily,
211
+ valueField: materialFamily,
212
+ limit: 100,
213
+ });
214
+
215
+ function OpsViews() {
216
+ const materialHandle = useSemaphorInput(materialFamilyFilter);
217
+ useSemaphorQuery(materialOptions);
218
+
219
+ useSemaphorQuery(purchaseQuery, {
220
+ inputs: [
221
+ semaphor.bindInput(materialHandle, {
222
+ field: materialFamily,
223
+ relationshipHint: { relationshipIds: ["purchase_material"] },
224
+ }),
225
+ ],
226
+ });
227
+
228
+ useSemaphorQuery(salesQuery, {
229
+ inputs: [
230
+ semaphor.bindInput(materialHandle, {
231
+ field: materialFamily,
232
+ relationshipHint: { relationshipIds: ["sales_material"] },
233
+ }),
234
+ ],
235
+ });
236
+ }
237
+ ```
238
+
239
+ Do not fetch broad rows and filter or join them in React to simulate
240
+ related-dimension behavior. Let Semaphor execute the relationship-aware filter.
@@ -1 +0,0 @@
1
- "use strict";const e=require("react/jsx-runtime"),l=require("react"),t=require("./index-CkoRCh3g.js"),o=require("./switch-Jhyl63RF.js");require("./index-BxM99sFL.js");require("./catalog-field-grounding-8L9I0zdg.js");function G(n={}){var y,P,z,A;const{authToken:d,tokenProps:a}=t.useSemaphorContext(),x=n.enabled??!0,m=(d==null?void 0:d.accessToken)??null,f=(a==null?void 0:a.apiServiceUrl)??null,[L,C]=l.useState(!1),[j,b]=l.useState(!1),[h,g]=l.useState(!1),[N,c]=l.useState(null),[v,S]=l.useState(null),k=v||{tz:((P=(y=a==null?void 0:a.params)==null?void 0:y.calendarContext)==null?void 0:P.tz)||null,weekStart:((A=(z=a==null?void 0:a.params)==null?void 0:z.calendarContext)==null?void 0:A.weekStart)??null},p=l.useCallback(async()=>{if(!(!x||!m||!f)){C(!0),c(null);try{const i=await fetch(`${f}/v1/user-preferences/calendar`,{method:"GET",headers:{Authorization:`Bearer ${m}`}});if(!i.ok){const u=await i.json().catch(()=>({}));throw new Error(u.error||"Failed to fetch preferences")}const r=await i.json();S({tz:r.tz,weekStart:r.weekStart,source:r.source,isInherited:r.isInherited,userHasPrefs:r.userHasPrefs,inherited:r.inherited})}catch(i){const r=i instanceof Error?i.message:"Unknown error";c(r)}finally{C(!1)}}},[m,f,x]);l.useEffect(()=>{x&&p()},[x,p]);const T=l.useCallback(async i=>{if(!m||!f)return c("Not authenticated"),!1;b(!0),c(null);try{const r=await fetch(`${f}/v1/user-preferences/calendar`,{method:"PATCH",headers:{"Content-Type":"application/json",Authorization:`Bearer ${m}`},body:JSON.stringify(i)});if(!r.ok){const u=await r.json().catch(()=>({}));throw new Error(u.error||"Failed to update preferences")}return await p(),!0}catch(r){const u=r instanceof Error?r.message:"Unknown error";return c(u),!1}finally{b(!1)}},[m,f,p]),w=l.useCallback(async()=>{if(!m||!f)return c("Not authenticated"),!1;g(!0),c(null);try{const i=await fetch(`${f}/v1/user-preferences/calendar`,{method:"DELETE",headers:{Authorization:`Bearer ${m}`}});if(!i.ok){const u=await i.json().catch(()=>({}));throw new Error(u.error||"Failed to clear preferences")}const r=await i.text();if(r)try{const u=JSON.parse(r);return S({tz:u.tz,weekStart:u.weekStart,source:u.source,isInherited:u.isInherited??!0,userHasPrefs:!1,inherited:u.inherited}),!0}catch{}return await p(),!0}catch(i){const r=i instanceof Error?i.message:"Unknown error";return c(r),!1}finally{g(!1)}},[m,f,p]);return{preferences:k,isLoading:L,isSaving:j,isClearing:h,error:N,updatePreferences:T,clearPreferences:w,refetch:p}}const E=[{value:"America/New_York",label:"Eastern Time (US & Canada)"},{value:"America/Chicago",label:"Central Time (US & Canada)"},{value:"America/Denver",label:"Mountain Time (US & Canada)"},{value:"America/Los_Angeles",label:"Pacific Time (US & Canada)"},{value:"America/Phoenix",label:"Arizona"},{value:"America/Anchorage",label:"Alaska"},{value:"Pacific/Honolulu",label:"Hawaii"},{value:"Europe/London",label:"London"},{value:"Europe/Paris",label:"Paris, Berlin, Rome"},{value:"Asia/Tokyo",label:"Tokyo"},{value:"Asia/Shanghai",label:"Beijing, Shanghai"},{value:"Asia/Kolkata",label:"Mumbai, New Delhi"},{value:"Australia/Sydney",label:"Sydney"},{value:"UTC",label:"UTC"}],M=[{value:0,label:"Sunday"},{value:1,label:"Monday"},{value:6,label:"Saturday"}],H="text-[10px] font-medium uppercase tracking-[0.08em] text-muted-foreground";function W(){try{const n=Intl;if(n.supportedValuesOf)return n.supportedValuesOf("timeZone")}catch{}return E.map(n=>n.value)}function _(n){switch(n){case"tenant":return"tenant";case"organization":return"organization";case"system":return"system";default:return"default"}}function O(n){const d=E.find(a=>a.value===n);return d?d.label:n}function q(n){const d=M.find(a=>a.value===n);return d?d.label:String(n)}function V({open:n,onOpenChange:d}){var D,U,F;const{preferences:a,isLoading:x,isSaving:m,isClearing:f,updatePreferences:L,clearPreferences:C}=G({enabled:n}),j=a.tz||((D=a.inherited)==null?void 0:D.tz)||Intl.DateTimeFormat().resolvedOptions().timeZone,b=a.weekStart??((U=a.inherited)==null?void 0:U.weekStart)??1,[h,g]=l.useState(!a.userHasPrefs),[N,c]=l.useState(!1),[v,S]=l.useState(j),[k,p]=l.useState(b),[T,w]=l.useState(!1),y=l.useMemo(()=>W(),[]),P=l.useMemo(()=>y.filter(s=>!E.some(R=>R.value===s)),[y]),z=l.useMemo(()=>O(v),[v]),A=a.inherited?O(a.inherited.tz):"UTC",i=a.inherited?q(a.inherited.weekStart):"Monday",r=_((F=a.inherited)==null?void 0:F.source);l.useEffect(()=>{if(!n){c(!1);return}N||(a.userHasPrefs!==void 0&&g(!a.userHasPrefs),S(j),p(b))},[n,N,a.userHasPrefs,j,b]);const u=async()=>{if(x){t.ue.error("Preferences are still loading. Please try again.");return}h?await C()?(t.ue.success("Now using default settings. Please refresh the page to apply changes.",{duration:5e3}),d(!1)):t.ue.error("Failed to save preferences. Please try again."):await L({tz:v,weekStart:k})?(t.ue.success("Preferences saved. Please refresh the page to apply changes.",{duration:5e3}),d(!1)):t.ue.error("Failed to save preferences. Please try again.")},$=()=>{d(!1)},I=m||f,B=I||x;return e.jsx(t.Dialog,{open:n,onOpenChange:d,children:e.jsxs(t.DialogContent,{className:"rounded-control border-border/60 sm:max-w-[440px] sm:rounded-control",children:[e.jsxs(t.DialogHeader,{children:[e.jsx(t.DialogTitle,{className:"text-[15px]",children:"Calendar preferences"}),e.jsx(t.DialogDescription,{className:"text-[13px] leading-5",children:"Set your timezone and week-start for date calculations and displays."})]}),e.jsxs("div",{className:"space-y-4 py-1",children:[e.jsxs(t.RadioGroup,{value:h?"defaults":"custom",onValueChange:s=>{c(!0),g(s==="defaults")},className:"space-y-0.5",children:[e.jsxs("label",{htmlFor:"mode-defaults",className:o.cn("flex cursor-pointer items-start gap-2 rounded-control px-2 py-1.5 hover:bg-muted/50",h&&"bg-muted/50"),onClick:()=>{c(!0),g(!0)},children:[e.jsx(t.RadioGroupItem,{value:"defaults",id:"mode-defaults",className:"mt-0.5"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("p",{className:"text-[13px] font-medium text-foreground",children:["Use ",r," defaults"]}),e.jsxs("p",{className:"text-[12px] text-muted-foreground",children:[A,", week starts ",i]})]})]}),e.jsxs("label",{htmlFor:"mode-custom",className:o.cn("flex cursor-pointer items-start gap-2 rounded-control px-2 py-1.5 hover:bg-muted/50",!h&&"bg-muted/50"),onClick:()=>{c(!0),g(!1)},children:[e.jsx(t.RadioGroupItem,{value:"custom",id:"mode-custom",className:"mt-0.5"}),e.jsx("p",{className:"flex-1 text-[13px] font-medium text-foreground",children:"Use custom settings"})]})]}),e.jsxs("div",{className:o.cn("space-y-4 border-t border-border/60 pt-4 transition-opacity",h&&"pointer-events-none opacity-50"),children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(o.Label,{className:H,children:"Timezone"}),e.jsxs(o.Popover,{open:T,onOpenChange:w,modal:!0,children:[e.jsx(o.PopoverTrigger,{asChild:!0,children:e.jsxs(o.Button,{variant:"outline",size:"xs",role:"combobox","aria-expanded":T,className:"w-full justify-between text-[12px] font-normal",disabled:h,children:[e.jsx("span",{className:"truncate",children:z}),e.jsx(t.ChevronsUpDown,{className:"ml-2 h-3.5 w-3.5 shrink-0 opacity-50"})]})}),e.jsx(o.PopoverContent,{className:"z-50 w-[--radix-popover-trigger-width] p-0",align:"start",children:e.jsxs(t.Command,{className:"overflow-visible",children:[e.jsx(t.CommandInput,{placeholder:"Search timezones…"}),e.jsxs(t.CommandList,{children:[e.jsx(t.CommandEmpty,{children:"No timezone found."}),e.jsx(t.CommandGroup,{heading:"Common",children:E.map(s=>e.jsxs(t.CommandItem,{value:`${s.value} ${s.label}`,onSelect:()=>{c(!0),S(s.value),w(!1)},children:[e.jsx(o.Check,{className:o.cn("h-3.5 w-3.5",v===s.value?"opacity-100":"opacity-0")}),e.jsx("span",{className:"flex-1",children:s.label}),e.jsx("span",{className:"text-[11px] text-muted-foreground",children:s.value})]},s.value))}),e.jsx(t.CommandSeparator,{}),e.jsx(t.CommandGroup,{heading:"All timezones",children:P.map(s=>e.jsxs(t.CommandItem,{value:s,onSelect:()=>{c(!0),S(s),w(!1)},children:[e.jsx(o.Check,{className:o.cn("h-3.5 w-3.5",v===s?"opacity-100":"opacity-0")}),s]},s))})]})]})})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(o.Label,{className:H,children:"Week starts on"}),e.jsx(t.RadioGroup,{value:String(k),onValueChange:s=>{c(!0),p(Number(s))},className:"flex gap-4",disabled:h,children:M.map(s=>e.jsxs("label",{htmlFor:`week-start-${s.value}`,className:o.cn("flex cursor-pointer items-center gap-2 text-[13px]",h&&"cursor-not-allowed"),children:[e.jsx(t.RadioGroupItem,{value:String(s.value),id:`week-start-${s.value}`,disabled:h}),s.label]},s.value))})]})]})]}),e.jsxs(t.DialogFooter,{children:[e.jsx(o.Button,{variant:"outline",size:"xs",onClick:$,disabled:I,children:"Cancel"}),e.jsx(o.Button,{size:"xs",onClick:u,disabled:B,children:I?e.jsxs(e.Fragment,{children:[e.jsx(o.LoaderCircle,{className:"h-3.5 w-3.5 animate-spin"}),"Saving…"]}):"Save"})]})]})})}exports.CalendarPreferencesDialog=V;
@@ -1 +0,0 @@
1
- "use strict";const o={answerSummary:"string",responseDetail:"responseDetail",mode:"string",comparisonType:"string",executionResult:"unknown",compiledQuery:"unknown",data:"unknown",resultSets:"record",columns:"unknownArray",records:"recordArray",rowCount:"number",rowLimitExceeded:"boolean",output:"string",querySpec:"unknown",metadata:"record",validation:"unknown",coverage:"unknown",diagnosticFeedback:"unknown",missingFields:"stringArray",warnings:"unknownArray",comparison:"unknown",population:"unknown",comparisons:"recordArray",fieldsUsed:"unknown",changes:"recordArray",largestNegativeChanges:"recordArray",largestPositiveChanges:"recordArray",drivers:"recordArray",absoluteDeltaDrivers:"recordArray",largestNegativeDrivers:"recordArray",largestPositiveDrivers:"recordArray",periodRows:"recordArray",sql:"unknown",omitted:"stringArray"},b=new Set(Object.keys(o)),S=new Set(["compact","standard","debug"]);function D(){return Object.keys(o)}function g(e){return b.has(e)}function F(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Semaphor analyze result must be an object.");const n=e,t=Object.keys(n).filter(r=>!g(r));if(t.length)throw new Error(`Semaphor analyze result contains unsupported top-level field(s): ${t.join(", ")}.`);for(const[r,i]of Object.entries(n)){if(i===void 0)continue;const a=o[r];if(!k(i,a))throw new Error(`Semaphor analyze result field "${r}" does not match contract kind "${a}".`)}return n}function k(e,n){switch(n){case"boolean":return typeof e=="boolean";case"number":return typeof e=="number"&&Number.isFinite(e);case"record":return A(e);case"recordArray":return Array.isArray(e)&&e.every(A);case"responseDetail":return typeof e=="string"&&S.has(e);case"string":return typeof e=="string";case"stringArray":return Array.isArray(e)&&e.every(t=>typeof t=="string");case"unknown":return!0;case"unknownArray":return Array.isArray(e)}}function A(e){return!!(e&&typeof e=="object"&&!Array.isArray(e))}function c(e){return typeof e=="string"?e.trim().toLowerCase():""}function p(e){return String(e.column_name||e.name||e.qualifiedFieldName||"")}function w(e){return Array.from(new Set([e.column_name,e.name,e.qualifiedFieldName,e.alias].filter(n=>typeof n=="string"&&n.trim().length>0).map(n=>n.trim())))}function d(e){const n=T(e);return n?n.includes("int")||n.includes("uint")||n.includes("bigint")||n.includes("smallint")||n.includes("tinyint")||n.includes("numeric")||n.includes("decimal")||n.includes("double")||n.includes("float")||n.includes("number")||n.includes("real")||n.includes("money")||n.includes("currency")||n.includes("percent")?"number":n.includes("timestamp")||n.includes("datetime")||n.startsWith("time")?"datetime":n.includes("date")?"date":n.includes("bool")?"boolean":"string":"unknown"}function T(e){let n=c(e),t="";for(;n&&n!==t;)t=n,n=f(n,"nullable"),n=f(n,"lowcardinality");return n}function f(e,n){const t=`${n}(`;return!e.startsWith(t)||!e.endsWith(")")?e:e.slice(t.length,-1).trim()}function h(e){const n=d(e);return n==="date"||n==="datetime"}function u(e){return h(e.dataType||e.data_type)}function y(e){const n=C(e);return n==="id"||n==="row_id"}function l(e){const n=C(e);return y(e)||n.endsWith("_id")||n.endsWith("_key")||n.endsWith("_number")}function C(e){return c(p(e)||e.name||e.alias).replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")}function m(e,n={}){const t=c(e.role);return t==="metric"||t==="measure"?!n.excludeIdentifiers||!l(e):t==="groupby"||t==="dimension"||t==="date"||t==="id"?!1:d(e.dataType||e.data_type)==="number"&&(!n.excludeIdentifiers||!l(e))}function _(e){return!m(e)&&!u(e)}function E(e){const n=new Set,t=new Set,r=new Set;for(const i of e){if(y(i))continue;const a=w(i);if(a.length!==0){if(u(i)){a.forEach(s=>t.add(s));continue}if(m(i,{excludeIdentifiers:!0})){a.forEach(s=>n.add(s));continue}a.forEach(s=>r.add(s))}}return{validMetricCandidates:Array.from(n).sort(),validDateCandidates:Array.from(t).sort(),validDimensionCandidates:Array.from(r).sort()}}exports.SEMAPHOR_ANALYZE_RESULT_FIELD_CONTRACT=o;exports.buildAnalyticsCatalogFieldSummary=E;exports.getAnalyticsCatalogFieldCandidates=w;exports.getAnalyticsCatalogFieldName=p;exports.getSemaphorAnalyzeResultFieldNames=D;exports.isAnalyticsCatalogDateField=u;exports.isAnalyticsCatalogDimensionField=_;exports.isAnalyticsCatalogMetricField=m;exports.isAnalyticsDateLikeDataType=h;exports.isAnalyticsMetricIdentifierField=l;exports.isAnalyticsTechnicalIdentifierField=y;exports.isSemaphorAnalyzeResultFieldName=g;exports.normalizeAnalyticsCatalogDataType=d;exports.normalizeAnalyticsCatalogName=c;exports.parseSemaphorAnalyzeResult=F;