@grafana/plugin-ui 0.15.0 → 0.16.0-dsconfig.a155abe

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 (240) hide show
  1. package/README.md +33 -0
  2. package/dist/cjs/index.cjs +16764 -9897
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs/index.d.cts +719 -2
  5. package/dist/esm/_virtual/index.js +3 -5
  6. package/dist/esm/_virtual/index.js.map +1 -1
  7. package/dist/esm/async-query-data/DatasourceWithAsyncBackend.js +1 -1
  8. package/dist/esm/async-query-data/RunQueryButtons.js +5 -5
  9. package/dist/esm/async-query-data/RunQueryButtons.js.map +1 -1
  10. package/dist/esm/components/ConfigEditor/AdvancedSettings/AdvancedHttpSettings.js +1 -1
  11. package/dist/esm/components/ConfigEditor/Auth/Auth.js +1 -1
  12. package/dist/esm/components/ConfigEditor/Auth/auth-method/AuthMethodSettings.js +4 -4
  13. package/dist/esm/components/ConfigEditor/Auth/auth-method/AuthMethodSettings.js.map +1 -1
  14. package/dist/esm/components/ConfigEditor/Auth/auth-method/BasicAuth.js +1 -1
  15. package/dist/esm/components/ConfigEditor/Auth/custom-headers/CustomHeader.js +1 -1
  16. package/dist/esm/components/ConfigEditor/Auth/custom-headers/CustomHeaders.js +3 -3
  17. package/dist/esm/components/ConfigEditor/Auth/custom-headers/CustomHeaders.js.map +1 -1
  18. package/dist/esm/components/ConfigEditor/Auth/tls/SelfSignedCertificate.js +1 -1
  19. package/dist/esm/components/ConfigEditor/Auth/tls/SkipTLSVerification.js +1 -1
  20. package/dist/esm/components/ConfigEditor/Auth/tls/TLSClientAuth.js +1 -1
  21. package/dist/esm/components/ConfigEditor/Auth/tls/TLSSettings.js +1 -1
  22. package/dist/esm/components/ConfigEditor/Auth/tls/TLSSettingsSection.js +1 -1
  23. package/dist/esm/components/ConfigEditor/Auth/types.js +1 -1
  24. package/dist/esm/components/ConfigEditor/Auth/utils.js +1 -1
  25. package/dist/esm/components/ConfigEditor/ConfigSection/ConfigDescriptionLink.js +1 -1
  26. package/dist/esm/components/ConfigEditor/ConfigSection/ConfigSection.js +1 -1
  27. package/dist/esm/components/ConfigEditor/ConfigSection/ConfigSubSection.js +1 -1
  28. package/dist/esm/components/ConfigEditor/ConfigSection/GenericConfigSection.js +2 -2
  29. package/dist/esm/components/ConfigEditor/ConfigSection/GenericConfigSection.js.map +1 -1
  30. package/dist/esm/components/ConfigEditor/Connection/ConnectionSettings.js +1 -1
  31. package/dist/esm/components/ConfigEditor/DataSourceDescription.js +1 -1
  32. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js +217 -0
  33. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js.map +1 -0
  34. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.js +27 -0
  35. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.js.map +1 -0
  36. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/FieldInput.js +135 -0
  37. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/FieldInput.js.map +1 -0
  38. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js +80 -0
  39. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js.map +1 -0
  40. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js +54 -0
  41. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js.map +1 -0
  42. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js +155 -0
  43. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js.map +1 -0
  44. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/cel.js +75 -0
  45. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/cel.js.map +1 -0
  46. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/config.js +262 -0
  47. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/config.js.map +1 -0
  48. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/datasource.js +354 -0
  49. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/datasource.js.map +1 -0
  50. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js +138 -0
  51. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js.map +1 -0
  52. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/formInterpreter.js +93 -0
  53. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/formInterpreter.js.map +1 -0
  54. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useDatasourceConfigForm.js +253 -0
  55. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useDatasourceConfigForm.js.map +1 -0
  56. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useHealthChecks.js +106 -0
  57. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useHealthChecks.js.map +1 -0
  58. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/AuthorizationHeaderField.js +52 -0
  59. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/AuthorizationHeaderField.js.map +1 -0
  60. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ComplexFieldNote.js +26 -0
  61. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ComplexFieldNote.js.map +1 -0
  62. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/FileUploadField.js +106 -0
  63. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/FileUploadField.js.map +1 -0
  64. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/IndexedPairEditor.js +124 -0
  65. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/IndexedPairEditor.js.map +1 -0
  66. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ObjectArrayEditor.js +190 -0
  67. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ObjectArrayEditor.js.map +1 -0
  68. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PdcFieldNote.js +31 -0
  69. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PdcFieldNote.js.map +1 -0
  70. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PrimitiveInputs.js +103 -0
  71. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PrimitiveInputs.js.map +1 -0
  72. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/SecureFieldInput.js +59 -0
  73. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/SecureFieldInput.js.map +1 -0
  74. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/StringArrayInput.js +80 -0
  75. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/StringArrayInput.js.map +1 -0
  76. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/layoutParts.js +82 -0
  77. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/layoutParts.js.map +1 -0
  78. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/resolvePluginName.js +30 -0
  79. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/resolvePluginName.js.map +1 -0
  80. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/styles.js +340 -0
  81. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/styles.js.map +1 -0
  82. package/dist/esm/components/ConfigEditor/SecureSocksProxyToggle.js +1 -1
  83. package/dist/esm/components/CustomHeadersSettings/CustomHeadersSettings.js +2 -2
  84. package/dist/esm/components/CustomHeadersSettings/CustomHeadersSettings.js.map +1 -1
  85. package/dist/esm/components/DataLinks/DataLink.js +3 -3
  86. package/dist/esm/components/DataLinks/DataLink.js.map +1 -1
  87. package/dist/esm/components/DataLinks/DataLinks.js +1 -1
  88. package/dist/esm/components/DataSourcePicker/DataSourcePicker.js +2 -2
  89. package/dist/esm/components/DataSourcePicker/DataSourcePicker.js.map +1 -1
  90. package/dist/esm/components/DatePicker/DatePicker.js +3 -3
  91. package/dist/esm/components/DatePicker/DatePicker.js.map +1 -1
  92. package/dist/esm/components/DatePickerWithInput/DatePickerWithInput.js +2 -2
  93. package/dist/esm/components/DatePickerWithInput/DatePickerWithInput.js.map +1 -1
  94. package/dist/esm/components/DebounceInput/DebounceInput.js +4 -4
  95. package/dist/esm/components/DebounceInput/DebounceInput.js.map +1 -1
  96. package/dist/esm/components/Plugins/PluginSignatureBadge.js +1 -1
  97. package/dist/esm/components/QueryEditor/AccessoryButton.js +1 -1
  98. package/dist/esm/components/QueryEditor/CatalogSelector.js +5 -5
  99. package/dist/esm/components/QueryEditor/CatalogSelector.js.map +1 -1
  100. package/dist/esm/components/QueryEditor/ConfirmModal.js +3 -3
  101. package/dist/esm/components/QueryEditor/ConfirmModal.js.map +1 -1
  102. package/dist/esm/components/QueryEditor/DatasetSelector.js +2 -2
  103. package/dist/esm/components/QueryEditor/DatasetSelector.js.map +1 -1
  104. package/dist/esm/components/QueryEditor/EditorField.js +1 -1
  105. package/dist/esm/components/QueryEditor/EditorFieldGroup.js +1 -1
  106. package/dist/esm/components/QueryEditor/EditorHeader.js +1 -1
  107. package/dist/esm/components/QueryEditor/EditorList.js +2 -2
  108. package/dist/esm/components/QueryEditor/EditorList.js.map +1 -1
  109. package/dist/esm/components/QueryEditor/EditorRow.js +1 -1
  110. package/dist/esm/components/QueryEditor/EditorRows.js +1 -1
  111. package/dist/esm/components/QueryEditor/EditorStack.js +1 -1
  112. package/dist/esm/components/QueryEditor/EditorSwitch.js +1 -1
  113. package/dist/esm/components/QueryEditor/FlexItem.js +1 -1
  114. package/dist/esm/components/QueryEditor/InlineSelect.js +2 -2
  115. package/dist/esm/components/QueryEditor/InlineSelect.js.map +1 -1
  116. package/dist/esm/components/QueryEditor/InputGroup.js +4 -4
  117. package/dist/esm/components/QueryEditor/InputGroup.js.map +1 -1
  118. package/dist/esm/components/QueryEditor/QueryEditor.js +6 -6
  119. package/dist/esm/components/QueryEditor/QueryEditor.js.map +1 -1
  120. package/dist/esm/components/QueryEditor/QueryHeader.js +4 -4
  121. package/dist/esm/components/QueryEditor/QueryHeader.js.map +1 -1
  122. package/dist/esm/components/QueryEditor/RunQueryButton.js +1 -1
  123. package/dist/esm/components/QueryEditor/Space.js +1 -1
  124. package/dist/esm/components/QueryEditor/TableSelector.js +1 -1
  125. package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js +4 -4
  126. package/dist/esm/components/QueryEditor/query-editor-raw/QueryEditorRaw.js.map +1 -1
  127. package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js +3 -3
  128. package/dist/esm/components/QueryEditor/query-editor-raw/QueryToolbox.js.map +1 -1
  129. package/dist/esm/components/QueryEditor/query-editor-raw/QueryValidator.js +5 -5
  130. package/dist/esm/components/QueryEditor/query-editor-raw/QueryValidator.js.map +1 -1
  131. package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js +3 -3
  132. package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js.map +1 -1
  133. package/dist/esm/components/QueryEditor/types.js +1 -1
  134. package/dist/esm/components/QueryEditor/utils/useSqlChange.js +2 -2
  135. package/dist/esm/components/QueryEditor/utils/useSqlChange.js.map +1 -1
  136. package/dist/esm/components/QueryEditor/visual-query-builder/AwesomeQueryBuilder.js +1 -1
  137. package/dist/esm/components/QueryEditor/visual-query-builder/EditorField.js +1 -1
  138. package/dist/esm/components/QueryEditor/visual-query-builder/EditorRow.js +1 -1
  139. package/dist/esm/components/QueryEditor/visual-query-builder/EditorRows.js +1 -1
  140. package/dist/esm/components/QueryEditor/visual-query-builder/GroupByRow.js +2 -2
  141. package/dist/esm/components/QueryEditor/visual-query-builder/GroupByRow.js.map +1 -1
  142. package/dist/esm/components/QueryEditor/visual-query-builder/OrderByRow.js +5 -5
  143. package/dist/esm/components/QueryEditor/visual-query-builder/OrderByRow.js.map +1 -1
  144. package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js +1 -1
  145. package/dist/esm/components/QueryEditor/visual-query-builder/SQLGroupByRow.js +1 -1
  146. package/dist/esm/components/QueryEditor/visual-query-builder/SQLOrderByRow.js +1 -1
  147. package/dist/esm/components/QueryEditor/visual-query-builder/SQLSelectRow.js +1 -1
  148. package/dist/esm/components/QueryEditor/visual-query-builder/SQLWhereRow.js +1 -1
  149. package/dist/esm/components/QueryEditor/visual-query-builder/SelectRow.js +5 -5
  150. package/dist/esm/components/QueryEditor/visual-query-builder/SelectRow.js.map +1 -1
  151. package/dist/esm/components/QueryEditor/visual-query-builder/VisualEditor.js +1 -1
  152. package/dist/esm/components/QueryEditor/visual-query-builder/WhereRow.js +6 -6
  153. package/dist/esm/components/QueryEditor/visual-query-builder/WhereRow.js.map +1 -1
  154. package/dist/esm/components/QueryEditorRow/QueryEditorRow.js +1 -1
  155. package/dist/esm/components/SQLEditor/components/SQLEditor.js +6 -6
  156. package/dist/esm/components/SQLEditor/components/SQLEditor.js.map +1 -1
  157. package/dist/esm/components/SQLEditor/hooks/useLatestCallback.js +4 -4
  158. package/dist/esm/components/SQLEditor/hooks/useLatestCallback.js.map +1 -1
  159. package/dist/esm/components/Segment/Segment.js +4 -4
  160. package/dist/esm/components/Segment/Segment.js.map +1 -1
  161. package/dist/esm/components/VisualQueryBuilder/components/LabelFilterItem.js +5 -5
  162. package/dist/esm/components/VisualQueryBuilder/components/LabelFilterItem.js.map +1 -1
  163. package/dist/esm/components/VisualQueryBuilder/components/LabelFilters.js +3 -3
  164. package/dist/esm/components/VisualQueryBuilder/components/LabelFilters.js.map +1 -1
  165. package/dist/esm/components/VisualQueryBuilder/components/OperationEditor.js +1 -1
  166. package/dist/esm/components/VisualQueryBuilder/components/OperationEditorBody.js +4 -4
  167. package/dist/esm/components/VisualQueryBuilder/components/OperationEditorBody.js.map +1 -1
  168. package/dist/esm/components/VisualQueryBuilder/components/OperationExplainedBox.js +1 -1
  169. package/dist/esm/components/VisualQueryBuilder/components/OperationHeader.js +3 -3
  170. package/dist/esm/components/VisualQueryBuilder/components/OperationHeader.js.map +1 -1
  171. package/dist/esm/components/VisualQueryBuilder/components/OperationInfoButton.js +3 -3
  172. package/dist/esm/components/VisualQueryBuilder/components/OperationInfoButton.js.map +1 -1
  173. package/dist/esm/components/VisualQueryBuilder/components/OperationList.js +2 -2
  174. package/dist/esm/components/VisualQueryBuilder/components/OperationList.js.map +1 -1
  175. package/dist/esm/components/VisualQueryBuilder/components/OperationListExplained.js +1 -1
  176. package/dist/esm/components/VisualQueryBuilder/components/OperationParamEditor.js +1 -1
  177. package/dist/esm/components/VisualQueryBuilder/components/OperationsEditorRow.js +1 -1
  178. package/dist/esm/components/VisualQueryBuilder/components/QueryBuilderHints.js +2 -2
  179. package/dist/esm/components/VisualQueryBuilder/components/QueryBuilderHints.js.map +1 -1
  180. package/dist/esm/components/VisualQueryBuilder/components/QueryEditorModeToggle.js +1 -1
  181. package/dist/esm/components/VisualQueryBuilder/components/QueryHeaderSwitch.js +2 -2
  182. package/dist/esm/components/VisualQueryBuilder/components/QueryHeaderSwitch.js.map +1 -1
  183. package/dist/esm/components/VisualQueryBuilder/components/QueryOptionGroup.js +1 -1
  184. package/dist/esm/components/VisualQueryBuilder/components/RawQuery.js +1 -1
  185. package/dist/esm/components/VisualQueryBuilder/types.js +1 -1
  186. package/dist/esm/hooks/useDebounce.js +3 -3
  187. package/dist/esm/hooks/useDebounce.js.map +1 -1
  188. package/dist/esm/index.d.ts +719 -2
  189. package/dist/esm/index.js +11 -0
  190. package/dist/esm/index.js.map +1 -1
  191. package/dist/esm/node_modules/js-yaml/dist/js-yaml.js +3043 -0
  192. package/dist/esm/node_modules/js-yaml/dist/js-yaml.js.map +1 -0
  193. package/dist/esm/node_modules/react-hook-form/dist/index.esm.js +2766 -0
  194. package/dist/esm/node_modules/react-hook-form/dist/index.esm.js.map +1 -0
  195. package/dist/esm/node_modules/semver/classes/range.js +24 -4
  196. package/dist/esm/node_modules/semver/classes/range.js.map +1 -1
  197. package/dist/esm/node_modules/semver/classes/semver.js +19 -2
  198. package/dist/esm/node_modules/semver/classes/semver.js.map +1 -1
  199. package/dist/esm/node_modules/semver/functions/diff.js +1 -1
  200. package/dist/esm/node_modules/semver/functions/diff.js.map +1 -1
  201. package/dist/esm/node_modules/semver/functions/truncate.js +62 -0
  202. package/dist/esm/node_modules/semver/functions/truncate.js.map +1 -0
  203. package/dist/esm/node_modules/semver/index.js +3 -0
  204. package/dist/esm/node_modules/semver/index.js.map +1 -1
  205. package/dist/esm/node_modules/semver/internal/re.js +3 -3
  206. package/dist/esm/node_modules/semver/internal/re.js.map +1 -1
  207. package/dist/esm/node_modules/semver/ranges/subset.js +3 -3
  208. package/dist/esm/node_modules/semver/ranges/subset.js.map +1 -1
  209. package/dist/esm/node_modules/tslib/tslib.es6.js.map +1 -1
  210. package/dist/esm/schema/utils/constants.js +4 -0
  211. package/dist/esm/schema/utils/constants.js.map +1 -0
  212. package/dist/esm/schema/utils/dsconfig.js +97 -0
  213. package/dist/esm/schema/utils/dsconfig.js.map +1 -0
  214. package/dist/esm/schema/utils/llm.js +54 -0
  215. package/dist/esm/schema/utils/llm.js.map +1 -0
  216. package/dist/esm/schema/utils/packs.js +113 -0
  217. package/dist/esm/schema/utils/packs.js.map +1 -0
  218. package/dist/esm/schema/utils/provisioning.js +434 -0
  219. package/dist/esm/schema/utils/provisioning.js.map +1 -0
  220. package/dist/esm/schema/utils/registry.js +30 -0
  221. package/dist/esm/schema/utils/registry.js.map +1 -0
  222. package/dist/esm/schema/utils/useDatasourceSchema.js +39 -0
  223. package/dist/esm/schema/utils/useDatasourceSchema.js.map +1 -0
  224. package/package.json +15 -10
  225. package/dist/esm/_virtual/_commonjsHelpers.js +0 -6
  226. package/dist/esm/_virtual/_commonjsHelpers.js.map +0 -1
  227. package/dist/esm/_virtual/index2.js +0 -6
  228. package/dist/esm/_virtual/index2.js.map +0 -1
  229. package/dist/esm/_virtual/index3.js +0 -4
  230. package/dist/esm/_virtual/index3.js.map +0 -1
  231. package/dist/esm/_virtual/react.development.js +0 -4
  232. package/dist/esm/_virtual/react.development.js.map +0 -1
  233. package/dist/esm/_virtual/react.production.min.js +0 -4
  234. package/dist/esm/_virtual/react.production.min.js.map +0 -1
  235. package/dist/esm/node_modules/react/cjs/react.development.js +0 -2752
  236. package/dist/esm/node_modules/react/cjs/react.development.js.map +0 -1
  237. package/dist/esm/node_modules/react/cjs/react.production.min.js +0 -39
  238. package/dist/esm/node_modules/react/cjs/react.production.min.js.map +0 -1
  239. package/dist/esm/node_modules/react/index.js +0 -20
  240. package/dist/esm/node_modules/react/index.js.map +0 -1
@@ -0,0 +1,27 @@
1
+ import React, { Component } from 'react';
2
+ import { Alert } from '@grafana/ui';
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
7
+ class DatasourceErrorBoundary extends Component {
8
+ constructor() {
9
+ super(...arguments);
10
+ __publicField(this, "state", { error: null });
11
+ }
12
+ static getDerivedStateFromError(error) {
13
+ return { error };
14
+ }
15
+ componentDidCatch(error, info) {
16
+ console.error("[DatasourceConfigWizard] Caught error:", error, info.componentStack);
17
+ }
18
+ render() {
19
+ if (this.state.error) {
20
+ return /* @__PURE__ */ React.createElement(Alert, { severity: "warning", title: "Configuration wizard unavailable" }, "Could not load the configuration wizard", this.props.dsName ? ` for ${this.props.dsName}` : "", ". Use the Settings link to configure this datasource manually.");
21
+ }
22
+ return this.props.children;
23
+ }
24
+ }
25
+
26
+ export { DatasourceErrorBoundary };
27
+ //# sourceMappingURL=DatasourceErrorBoundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatasourceErrorBoundary.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.tsx"],"sourcesContent":["import React, { Component, type ReactNode, type ErrorInfo } from 'react';\nimport { Alert } from '@grafana/ui';\n\n/** Lightweight error boundary scoped to datasource config widgets — won't crash the host UI. */\nexport class DatasourceErrorBoundary extends Component<\n { children: ReactNode; dsName?: string },\n { error: Error | null }\n> {\n state: { error: Error | null } = { error: null };\n\n static getDerivedStateFromError(error: Error) {\n return { error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n console.error('[DatasourceConfigWizard] Caught error:', error, info.componentStack);\n }\n\n render() {\n if (this.state.error) {\n return (\n <Alert severity=\"warning\" title=\"Configuration wizard unavailable\">\n Could not load the configuration wizard\n {this.props.dsName ? ` for ${this.props.dsName}` : ''}. Use the Settings link to configure this datasource\n manually.\n </Alert>\n );\n }\n return this.props.children;\n }\n}\n"],"names":[],"mappings":";;;;;;AAIO,MAAM,gCAAgC,SAG3C,CAAA;AAAA,EAHK,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AAIL,IAAiC,aAAA,CAAA,IAAA,EAAA,OAAA,EAAA,EAAE,OAAO,IAAK,EAAA,CAAA;AAAA;AAAA,EAE/C,OAAO,yBAAyB,KAAc,EAAA;AAC5C,IAAA,OAAO,EAAE,KAAM,EAAA;AAAA;AACjB,EAEA,iBAAA,CAAkB,OAAc,IAAiB,EAAA;AAC/C,IAAA,OAAA,CAAQ,KAAM,CAAA,wCAAA,EAA0C,KAAO,EAAA,IAAA,CAAK,cAAc,CAAA;AAAA;AACpF,EAEA,MAAS,GAAA;AACP,IAAI,IAAA,IAAA,CAAK,MAAM,KAAO,EAAA;AACpB,MAAA,2CACG,KAAM,EAAA,EAAA,QAAA,EAAS,SAAU,EAAA,KAAA,EAAM,sCAAmC,yCAEhE,EAAA,IAAA,CAAK,KAAM,CAAA,MAAA,GAAS,QAAQ,IAAK,CAAA,KAAA,CAAM,MAAM,CAAA,CAAA,GAAK,IAAG,gEAExD,CAAA;AAAA;AAGJ,IAAA,OAAO,KAAK,KAAM,CAAA,QAAA;AAAA;AAEtB;;;;"}
@@ -0,0 +1,135 @@
1
+ import React from 'react';
2
+ import { SecureFieldInput } from './inputs/SecureFieldInput.js';
3
+ import { StringArrayInput } from './inputs/StringArrayInput.js';
4
+ import { IndexedPairEditor } from './inputs/IndexedPairEditor.js';
5
+ import { FileUploadField } from './inputs/FileUploadField.js';
6
+ import { ObjectArrayEditor } from './inputs/ObjectArrayEditor.js';
7
+ import { ComplexFieldNote } from './inputs/ComplexFieldNote.js';
8
+ import { RadioInput, SelectInput, BooleanInput, NumberInput, TextAreaInput, TextInput } from './inputs/PrimitiveInputs.js';
9
+
10
+ function resolveFieldInputKind(field, hasSetValue) {
11
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12
+ if (((_a = field.ui) == null ? undefined : _a.component) === "fileUpload" && field.ui.fileMapping && hasSetValue) {
13
+ return "fileUpload";
14
+ }
15
+ if (field.target === "secureJsonData") {
16
+ return "secure";
17
+ }
18
+ if (((_b = field.ui) == null ? undefined : _b.component) === "radio") {
19
+ return "radio";
20
+ }
21
+ if (((_c = field.ui) == null ? undefined : _c.component) === "select") {
22
+ return "select";
23
+ }
24
+ if (field.valueType === "boolean") {
25
+ return "boolean";
26
+ }
27
+ if (field.valueType === "number") {
28
+ return "number";
29
+ }
30
+ if (((_d = field.ui) == null ? undefined : _d.component) === "textarea") {
31
+ return "textarea";
32
+ }
33
+ if (((_e = field.storage) == null ? undefined : _e.type) === "indexedPair") {
34
+ return "indexedPair";
35
+ }
36
+ if (field.valueType === "array" && ((_f = field.item) == null ? undefined : _f.valueType) === "string") {
37
+ return "stringArray";
38
+ }
39
+ if (field.valueType === "array" && ((_g = field.item) == null ? undefined : _g.valueType) === "object" && ((_h = field.item.fields) == null ? undefined : _h.length)) {
40
+ return "objectArray";
41
+ }
42
+ if (field.valueType === "object" || field.valueType === "map" || field.valueType === "array" && (((_i = field.item) == null ? undefined : _i.valueType) === "object" || ((_j = field.item) == null ? undefined : _j.valueType) === "map")) {
43
+ return "complex";
44
+ }
45
+ return "text";
46
+ }
47
+ function SecureInput({ field, formField, disabled }) {
48
+ var _a, _b, _c;
49
+ const label = (_a = field.label) != null ? _a : field.key;
50
+ return /* @__PURE__ */ React.createElement(
51
+ SecureFieldInput,
52
+ {
53
+ formField,
54
+ placeholder: (_c = (_b = field.ui) == null ? undefined : _b.placeholder) != null ? _c : label,
55
+ disabled,
56
+ label
57
+ }
58
+ );
59
+ }
60
+ function FileUploadInput({ field, formField, disabled, setValue }) {
61
+ if (!setValue) {
62
+ return null;
63
+ }
64
+ return /* @__PURE__ */ React.createElement(FileUploadField, { field, formField, disabled, setValue });
65
+ }
66
+ function IndexedPairInput({ field, formField, disabled }) {
67
+ var _a, _b, _c, _d, _e;
68
+ const items = Array.isArray(formField.value) ? formField.value : [];
69
+ const maxItems = (_c = (_b = (_a = field.validations) == null ? undefined : _a.find((v) => v.type === "itemCount")) == null ? undefined : _b.max) != null ? _c : 10;
70
+ const itemLabel = (_e = (_d = field.label) == null ? undefined : _d.toLowerCase().replace(/s$/, "")) != null ? _e : "header";
71
+ return /* @__PURE__ */ React.createElement(
72
+ IndexedPairEditor,
73
+ {
74
+ value: items,
75
+ onChange: formField.onChange,
76
+ maxItems,
77
+ disabled,
78
+ itemLabel
79
+ }
80
+ );
81
+ }
82
+ function StringArrayField({ field, formField, disabled }) {
83
+ var _a, _b;
84
+ const label = (_a = field.label) != null ? _a : field.key;
85
+ return /* @__PURE__ */ React.createElement(
86
+ StringArrayInput,
87
+ {
88
+ value: Array.isArray(formField.value) ? formField.value : [],
89
+ onChange: formField.onChange,
90
+ placeholder: (_b = field.ui) == null ? undefined : _b.placeholder,
91
+ disabled,
92
+ itemLabel: label.toLowerCase().replace(/s$/, "")
93
+ }
94
+ );
95
+ }
96
+ function ObjectArrayInput({ field, formField, disabled, errorMessage }) {
97
+ return /* @__PURE__ */ React.createElement(
98
+ ObjectArrayEditor,
99
+ {
100
+ field,
101
+ value: formField.value,
102
+ onChange: formField.onChange,
103
+ disabled,
104
+ errorMessage
105
+ }
106
+ );
107
+ }
108
+ function ComplexInput({ field, formField }) {
109
+ var _a;
110
+ const label = (_a = field.label) != null ? _a : field.key;
111
+ const count = Array.isArray(formField.value) ? formField.value.length : 0;
112
+ return /* @__PURE__ */ React.createElement(ComplexFieldNote, { count, label });
113
+ }
114
+ const FIELD_INPUTS = {
115
+ fileUpload: FileUploadInput,
116
+ secure: SecureInput,
117
+ radio: RadioInput,
118
+ select: SelectInput,
119
+ boolean: BooleanInput,
120
+ number: NumberInput,
121
+ textarea: TextAreaInput,
122
+ indexedPair: IndexedPairInput,
123
+ stringArray: StringArrayField,
124
+ objectArray: ObjectArrayInput,
125
+ complex: ComplexInput,
126
+ text: TextInput
127
+ };
128
+ function FieldInput(props) {
129
+ const kind = resolveFieldInputKind(props.field, props.setValue !== undefined);
130
+ const Component = FIELD_INPUTS[kind];
131
+ return /* @__PURE__ */ React.createElement(Component, { ...props });
132
+ }
133
+
134
+ export { FieldInput, resolveFieldInputKind };
135
+ //# sourceMappingURL=FieldInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldInput.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/FieldInput.tsx"],"sourcesContent":["import React from 'react';\nimport type { ConfigField } from '../../../schema/schema';\nimport type { IndexedPairItem } from './datasource';\nimport type { FieldInputProps } from './inputs/types';\nimport { SecureFieldInput } from './inputs/SecureFieldInput';\nimport { StringArrayInput } from './inputs/StringArrayInput';\nimport { IndexedPairEditor } from './inputs/IndexedPairEditor';\nimport { FileUploadField } from './inputs/FileUploadField';\nimport { ObjectArrayEditor } from './inputs/ObjectArrayEditor';\nimport { ComplexFieldNote } from './inputs/ComplexFieldNote';\nimport { TextInput, NumberInput, BooleanInput, TextAreaInput, SelectInput, RadioInput } from './inputs/PrimitiveInputs';\n\nexport type { FieldInputProps };\n\n/** Discriminant identifying which input component renders a field. */\nexport type FieldInputKind =\n | 'fileUpload'\n | 'secure'\n | 'radio'\n | 'select'\n | 'boolean'\n | 'number'\n | 'textarea'\n | 'indexedPair'\n | 'stringArray'\n | 'objectArray'\n | 'complex'\n | 'text';\n\n/**\n * Resolve a field to its input kind.\n *\n * Order matters: earlier rules win. Cross-cutting storage concerns (secure\n * storage, indexed-pair storage) intentionally take precedence over\n * `valueType`, and an explicit `ui.component` (radio/select/textarea) takes\n * precedence over the type-derived default. `fileUpload` requires `setValue`\n * because it distributes parsed values across sibling fields.\n */\nexport function resolveFieldInputKind(field: ConfigField, hasSetValue: boolean): FieldInputKind {\n if (field.ui?.component === 'fileUpload' && field.ui.fileMapping && hasSetValue) {\n return 'fileUpload';\n }\n if (field.target === 'secureJsonData') {\n return 'secure';\n }\n if (field.ui?.component === 'radio') {\n return 'radio';\n }\n if (field.ui?.component === 'select') {\n return 'select';\n }\n if (field.valueType === 'boolean') {\n return 'boolean';\n }\n if (field.valueType === 'number') {\n return 'number';\n }\n if (field.ui?.component === 'textarea') {\n return 'textarea';\n }\n if (field.storage?.type === 'indexedPair') {\n return 'indexedPair';\n }\n if (field.valueType === 'array' && field.item?.valueType === 'string') {\n return 'stringArray';\n }\n if (field.valueType === 'array' && field.item?.valueType === 'object' && field.item.fields?.length) {\n return 'objectArray';\n }\n if (\n field.valueType === 'object' ||\n field.valueType === 'map' ||\n (field.valueType === 'array' && (field.item?.valueType === 'object' || field.item?.valueType === 'map'))\n ) {\n return 'complex';\n }\n return 'text';\n}\n\n// ── Adapters: map the normalized FieldInputProps onto each leaf component's own API ──\n\n/** Password/token stored in secureJsonData. */\nfunction SecureInput({ field, formField, disabled }: FieldInputProps) {\n const label = field.label ?? field.key;\n return (\n <SecureFieldInput\n formField={formField}\n placeholder={field.ui?.placeholder ?? label}\n disabled={disabled}\n label={label}\n />\n );\n}\n\n/** JSON file upload that distributes parsed keys across sibling fields. */\nfunction FileUploadInput({ field, formField, disabled, setValue }: FieldInputProps) {\n // Only reachable when setValue exists (see resolveFieldInputKind), but guard anyway.\n if (!setValue) {\n return null;\n }\n return <FileUploadField field={field} formField={formField} disabled={disabled} setValue={setValue} />;\n}\n\n/** Editable key/value list backed by indexed storage (e.g. HTTP headers). */\nfunction IndexedPairInput({ field, formField, disabled }: FieldInputProps) {\n const items = Array.isArray(formField.value) ? (formField.value as IndexedPairItem[]) : [];\n const maxItems =\n field.validations?.find((v): v is { type: 'itemCount'; max?: number } => v.type === 'itemCount')?.max ?? 10;\n const itemLabel = field.label?.toLowerCase().replace(/s$/, '') ?? 'header';\n return (\n <IndexedPairEditor\n value={items}\n onChange={formField.onChange}\n maxItems={maxItems}\n disabled={disabled}\n itemLabel={itemLabel}\n />\n );\n}\n\n/** Row-based editor for an array of strings. */\nfunction StringArrayField({ field, formField, disabled }: FieldInputProps) {\n const label = field.label ?? field.key;\n return (\n <StringArrayInput\n value={Array.isArray(formField.value) ? (formField.value as string[]) : []}\n onChange={formField.onChange}\n placeholder={field.ui?.placeholder}\n disabled={disabled}\n itemLabel={label.toLowerCase().replace(/s$/, '')}\n />\n );\n}\n\n/** Inline editor for an array of objects with defined item fields. */\nfunction ObjectArrayInput({ field, formField, disabled, errorMessage }: FieldInputProps) {\n return (\n <ObjectArrayEditor\n field={field}\n value={formField.value}\n onChange={formField.onChange}\n disabled={disabled}\n errorMessage={errorMessage}\n />\n );\n}\n\n/** Read-only note for complex shapes not editable in the wizard. */\nfunction ComplexInput({ field, formField }: FieldInputProps) {\n const label = field.label ?? field.key;\n const count = Array.isArray(formField.value) ? formField.value.length : 0;\n return <ComplexFieldNote count={count} label={label} />;\n}\n\n/** Registry mapping each resolved kind to its renderer. */\nconst FIELD_INPUTS: Record<FieldInputKind, React.ComponentType<FieldInputProps>> = {\n fileUpload: FileUploadInput,\n secure: SecureInput,\n radio: RadioInput,\n select: SelectInput,\n boolean: BooleanInput,\n number: NumberInput,\n textarea: TextAreaInput,\n indexedPair: IndexedPairInput,\n stringArray: StringArrayField,\n objectArray: ObjectArrayInput,\n complex: ComplexInput,\n text: TextInput,\n};\n\n/**\n * Render the appropriate input for a schema field.\n *\n * Replaces the former `renderFieldInput` switch with a resolver + component\n * registry: each input is an independently testable component, and adding a\n * new input means extending the registry rather than editing a growing\n * conditional.\n */\nexport function FieldInput(props: FieldInputProps) {\n const kind = resolveFieldInputKind(props.field, props.setValue !== undefined);\n const Component = FIELD_INPUTS[kind];\n return <Component {...props} />;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import { Controller } from '../../../node_modules/react-hook-form/dist/index.esm.js';
3
+ import { useStyles2, Tooltip, Icon } from '@grafana/ui';
4
+ import { resolveActiveOverride, formKey } from './config.js';
5
+ import { isFieldRequired, buildValidationRules, parseItemErrors } from './fieldUtils.js';
6
+ import { PdcFieldNote } from './inputs/PdcFieldNote.js';
7
+ import { FieldInput } from './FieldInput.js';
8
+ import { getFieldStyles } from './styles.js';
9
+
10
+ function SchemaField({
11
+ field,
12
+ control,
13
+ errors,
14
+ disabled,
15
+ dsUid,
16
+ watchedValues,
17
+ fieldById,
18
+ celContext,
19
+ setValue
20
+ }) {
21
+ const styles = useStyles2(getFieldStyles);
22
+ const activeOverride = resolveActiveOverride(field, watchedValues, fieldById);
23
+ const fk = formKey(field);
24
+ if (field.key === "pdcInjected" && field.target === "jsonData") {
25
+ return /* @__PURE__ */ React.createElement(
26
+ Controller,
27
+ {
28
+ name: fk,
29
+ control,
30
+ render: ({ field: formField }) => /* @__PURE__ */ React.createElement(
31
+ PdcFieldNote,
32
+ {
33
+ enabled: !!formField.value,
34
+ description: field.description,
35
+ configUrl: `/connections/datasources/edit/${dsUid}`
36
+ }
37
+ )
38
+ }
39
+ );
40
+ }
41
+ const required = isFieldRequired(field, watchedValues, fieldById, celContext);
42
+ const validationRules = buildValidationRules(field, required);
43
+ return /* @__PURE__ */ React.createElement(
44
+ Controller,
45
+ {
46
+ name: fk,
47
+ control,
48
+ rules: validationRules,
49
+ render: ({ field: formField }) => {
50
+ var _a, _b, _c, _d, _e;
51
+ const errorMessage = (_a = errors[fk]) == null ? undefined : _a.message;
52
+ const label = (_b = field.label) != null ? _b : field.key;
53
+ const description = (_c = activeOverride == null ? undefined : activeOverride.description) != null ? _c : field.description;
54
+ const effectiveField = activeOverride ? {
55
+ ...field,
56
+ description,
57
+ ui: {
58
+ ...field.ui,
59
+ placeholder: (_e = activeOverride.placeholder) != null ? _e : (_d = field.ui) == null ? undefined : _d.placeholder
60
+ }
61
+ } : field;
62
+ const isReadOnly = !!(activeOverride == null ? undefined : activeOverride.readOnly);
63
+ const isBool = field.valueType === "boolean";
64
+ return /* @__PURE__ */ React.createElement("div", { className: isBool ? styles.fieldRowCenter : styles.fieldRow }, /* @__PURE__ */ React.createElement("div", { className: isBool ? styles.fieldLabelRowCompact : styles.fieldLabelRow }, /* @__PURE__ */ React.createElement("span", { className: styles.fieldLabel }, label, required && /* @__PURE__ */ React.createElement("span", { className: styles.fieldRequired }, "*")), description && /* @__PURE__ */ React.createElement(Tooltip, { content: description }, /* @__PURE__ */ React.createElement(Icon, { name: "info-circle", size: "xs", className: styles.fieldInfoIcon }))), /* @__PURE__ */ React.createElement("div", { className: styles.fieldInputCol }, /* @__PURE__ */ React.createElement(
65
+ FieldInput,
66
+ {
67
+ field: effectiveField,
68
+ formField,
69
+ disabled: disabled || isReadOnly,
70
+ errorMessage,
71
+ setValue
72
+ }
73
+ ), errorMessage && !parseItemErrors(errorMessage) && /* @__PURE__ */ React.createElement("span", { className: styles.fieldError }, errorMessage)));
74
+ }
75
+ }
76
+ );
77
+ }
78
+
79
+ export { SchemaField };
80
+ //# sourceMappingURL=SchemaField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaField.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/SchemaField.tsx"],"sourcesContent":["import React from 'react';\nimport { type useForm, Controller } from 'react-hook-form';\nimport { useStyles2, Icon, Tooltip } from '@grafana/ui';\nimport type { ConfigField } from '../../../schema/schema';\nimport { resolveActiveOverride, formKey } from './config';\nimport type { FormValues } from './datasource';\nimport { isFieldRequired, buildValidationRules, parseItemErrors } from './fieldUtils';\nimport { PdcFieldNote } from './inputs/PdcFieldNote';\nimport { FieldInput } from './FieldInput';\nimport { getFieldStyles } from './styles';\n\nexport type SchemaFieldProps = {\n field: ConfigField;\n control: ReturnType<typeof useForm<FormValues>>['control'];\n errors: ReturnType<typeof useForm<FormValues>>['formState']['errors'];\n disabled?: boolean;\n dsUid: string;\n watchedValues: Record<string, unknown>;\n fieldById: Map<string, ConfigField>;\n celContext?: Record<string, unknown>;\n setValue?: (name: string, value: unknown) => void;\n};\n\nexport function SchemaField({\n field,\n control,\n errors,\n disabled,\n dsUid,\n watchedValues,\n fieldById,\n celContext,\n setValue,\n}: SchemaFieldProps) {\n const styles = useStyles2(getFieldStyles);\n\n const activeOverride = resolveActiveOverride(field, watchedValues, fieldById);\n const fk = formKey(field);\n\n if (field.key === 'pdcInjected' && field.target === 'jsonData') {\n return (\n <Controller\n name={fk}\n control={control}\n render={({ field: formField }) => (\n <PdcFieldNote\n enabled={!!formField.value}\n description={field.description}\n configUrl={`/connections/datasources/edit/${dsUid}`}\n />\n )}\n />\n );\n }\n\n const required = isFieldRequired(field, watchedValues, fieldById, celContext);\n const validationRules = buildValidationRules(field, required);\n\n return (\n <Controller\n name={fk}\n control={control}\n rules={validationRules}\n render={({ field: formField }) => {\n const errorMessage = errors[fk]?.message as string | undefined;\n const label = field.label ?? field.key;\n const description = activeOverride?.description ?? field.description;\n const effectiveField = activeOverride\n ? {\n ...field,\n description,\n ui: {\n ...field.ui,\n placeholder: activeOverride.placeholder ?? field.ui?.placeholder,\n } as ConfigField['ui'],\n }\n : field;\n const isReadOnly = !!activeOverride?.readOnly;\n const isBool = field.valueType === 'boolean';\n\n return (\n <div className={isBool ? styles.fieldRowCenter : styles.fieldRow}>\n <div className={isBool ? styles.fieldLabelRowCompact : styles.fieldLabelRow}>\n <span className={styles.fieldLabel}>\n {label}\n {required && <span className={styles.fieldRequired}>*</span>}\n </span>\n {description && (\n <Tooltip content={description}>\n <Icon name=\"info-circle\" size=\"xs\" className={styles.fieldInfoIcon} />\n </Tooltip>\n )}\n </div>\n <div className={styles.fieldInputCol}>\n <FieldInput\n field={effectiveField}\n formField={formField}\n disabled={disabled || isReadOnly}\n errorMessage={errorMessage}\n setValue={setValue}\n />\n {/* Show global error only if it's NOT a per-item error (those render inline) */}\n {errorMessage && !parseItemErrors(errorMessage) && (\n <span className={styles.fieldError}>{errorMessage}</span>\n )}\n </div>\n </div>\n );\n }}\n />\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ import { cx } from '@emotion/css';
3
+ import { useStyles2 } from '@grafana/ui';
4
+ import { getTabStyles } from './styles.js';
5
+
6
+ function SidebarNav({ groups, activeIndex, sectionStates, onSelect }) {
7
+ const styles = useStyles2(getTabStyles);
8
+ const visibleGroups = groups.filter((g) => g.group.id !== "_required");
9
+ return /* @__PURE__ */ React.createElement("nav", { className: styles.sidebar }, /* @__PURE__ */ React.createElement("div", { className: styles.sidebarTitle }, "Connect data source"), /* @__PURE__ */ React.createElement("ul", { className: styles.navList }, visibleGroups.map((g, vi) => {
10
+ var _a, _b;
11
+ const origIndex = groups.indexOf(g);
12
+ const state = (_a = sectionStates[origIndex]) != null ? _a : "draft";
13
+ const isActive = origIndex === activeIndex;
14
+ const isOptional = g.group.optional === true;
15
+ const isLast = vi === visibleGroups.length - 1;
16
+ const nextIsOptional = !isLast && ((_b = visibleGroups[vi + 1]) == null ? undefined : _b.group.optional) === true;
17
+ return /* @__PURE__ */ React.createElement("li", { key: g.group.id }, /* @__PURE__ */ React.createElement(
18
+ "div",
19
+ {
20
+ className: cx(styles.navItem, isActive && styles.navItemActive),
21
+ onClick: () => onSelect(origIndex),
22
+ role: "button",
23
+ tabIndex: 0,
24
+ onKeyDown: (e) => {
25
+ if (e.key === "Enter" || e.key === " ") {
26
+ e.preventDefault();
27
+ onSelect(origIndex);
28
+ }
29
+ }
30
+ },
31
+ /* @__PURE__ */ React.createElement("div", { className: styles.navDotWrap }, /* @__PURE__ */ React.createElement(
32
+ "span",
33
+ {
34
+ className: cx(
35
+ styles.navDot,
36
+ isOptional && styles.navDotOptional,
37
+ isActive && styles.navDotActive,
38
+ state === "validated" && !isActive && styles.navDotValidated,
39
+ state === "error" && !isActive && styles.navDotError
40
+ )
41
+ }
42
+ ), !isLast && /* @__PURE__ */ React.createElement(
43
+ "div",
44
+ {
45
+ className: cx(styles.navConnector, (isOptional || nextIsOptional) && styles.navConnectorDashed)
46
+ }
47
+ )),
48
+ /* @__PURE__ */ React.createElement("span", { className: cx(styles.navLabel, isActive && styles.navLabelActive) }, g.group.title)
49
+ ));
50
+ })));
51
+ }
52
+
53
+ export { SidebarNav };
54
+ //# sourceMappingURL=SidebarNav.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SidebarNav.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.tsx"],"sourcesContent":["import React from 'react';\nimport { cx } from '@emotion/css';\nimport { useStyles2 } from '@grafana/ui';\nimport type { ResolvedGroup } from './hooks/useDatasourceConfigForm';\nimport { getTabStyles } from './styles';\n\nexport type SectionState = 'active' | 'draft' | 'validated' | 'error';\n\ntype SidebarNavProps = {\n groups: ResolvedGroup[];\n activeIndex: number;\n sectionStates: SectionState[];\n onSelect: (index: number) => void;\n};\n\nexport function SidebarNav({ groups, activeIndex, sectionStates, onSelect }: SidebarNavProps) {\n const styles = useStyles2(getTabStyles);\n\n // Filter out _required synthetic group\n const visibleGroups = groups.filter((g) => g.group.id !== '_required');\n\n return (\n <nav className={styles.sidebar}>\n <div className={styles.sidebarTitle}>Connect data source</div>\n <ul className={styles.navList}>\n {visibleGroups.map((g, vi) => {\n // Map back to original index for state/selection\n const origIndex = groups.indexOf(g);\n const state = sectionStates[origIndex] ?? 'draft';\n const isActive = origIndex === activeIndex;\n const isOptional = g.group.optional === true;\n const isLast = vi === visibleGroups.length - 1;\n // Next item determines connector style\n const nextIsOptional = !isLast && visibleGroups[vi + 1]?.group.optional === true;\n\n return (\n <li key={g.group.id}>\n <div\n className={cx(styles.navItem, isActive && styles.navItemActive)}\n onClick={() => onSelect(origIndex)}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onSelect(origIndex);\n }\n }}\n >\n <div className={styles.navDotWrap}>\n <span\n className={cx(\n styles.navDot,\n isOptional && styles.navDotOptional,\n isActive && styles.navDotActive,\n state === 'validated' && !isActive && styles.navDotValidated,\n state === 'error' && !isActive && styles.navDotError\n )}\n />\n {!isLast && (\n <div\n className={cx(styles.navConnector, (isOptional || nextIsOptional) && styles.navConnectorDashed)}\n />\n )}\n </div>\n <span className={cx(styles.navLabel, isActive && styles.navLabelActive)}>{g.group.title}</span>\n </div>\n </li>\n );\n })}\n </ul>\n </nav>\n );\n}\n"],"names":[],"mappings":";;;;;AAeO,SAAS,WAAW,EAAE,MAAA,EAAQ,WAAa,EAAA,aAAA,EAAe,UAA6B,EAAA;AAC5F,EAAM,MAAA,MAAA,GAAS,WAAW,YAAY,CAAA;AAGtC,EAAM,MAAA,aAAA,GAAgB,OAAO,MAAO,CAAA,CAAC,MAAM,CAAE,CAAA,KAAA,CAAM,OAAO,WAAW,CAAA;AAErE,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,SAAI,SAAW,EAAA,MAAA,CAAO,2BACpB,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,WAAW,MAAO,CAAA,YAAA,EAAA,EAAc,qBAAmB,CACxD,kBAAA,KAAA,CAAA,aAAA,CAAC,QAAG,SAAW,EAAA,MAAA,CAAO,WACnB,aAAc,CAAA,GAAA,CAAI,CAAC,CAAA,EAAG,EAAO,KAAA;AAzBtC,IAAA,IAAA,EAAA,EAAA,EAAA;AA2BU,IAAM,MAAA,SAAA,GAAY,MAAO,CAAA,OAAA,CAAQ,CAAC,CAAA;AAClC,IAAA,MAAM,KAAQ,GAAA,CAAA,EAAA,GAAA,aAAA,CAAc,SAAS,CAAA,KAAvB,IAA4B,GAAA,EAAA,GAAA,OAAA;AAC1C,IAAA,MAAM,WAAW,SAAc,KAAA,WAAA;AAC/B,IAAM,MAAA,UAAA,GAAa,CAAE,CAAA,KAAA,CAAM,QAAa,KAAA,IAAA;AACxC,IAAM,MAAA,MAAA,GAAS,EAAO,KAAA,aAAA,CAAc,MAAS,GAAA,CAAA;AAE7C,IAAM,MAAA,cAAA,GAAiB,CAAC,MAAU,IAAA,CAAA,CAAA,EAAA,GAAA,aAAA,CAAc,KAAK,CAAC,CAAA,KAApB,IAAuB,GAAA,SAAA,GAAA,EAAA,CAAA,KAAA,CAAM,QAAa,MAAA,IAAA;AAE5E,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAG,GAAK,EAAA,CAAA,CAAE,MAAM,EACf,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,WAAW,EAAG,CAAA,MAAA,CAAO,OAAS,EAAA,QAAA,IAAY,OAAO,aAAa,CAAA;AAAA,QAC9D,OAAA,EAAS,MAAM,QAAA,CAAS,SAAS,CAAA;AAAA,QACjC,IAAK,EAAA,QAAA;AAAA,QACL,QAAU,EAAA,CAAA;AAAA,QACV,SAAA,EAAW,CAAC,CAAM,KAAA;AAChB,UAAA,IAAI,CAAE,CAAA,GAAA,KAAQ,OAAW,IAAA,CAAA,CAAE,QAAQ,GAAK,EAAA;AACtC,YAAA,CAAA,CAAE,cAAe,EAAA;AACjB,YAAA,QAAA,CAAS,SAAS,CAAA;AAAA;AACpB;AACF,OAAA;AAAA,sBAEC,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,MAAA,CAAO,UACrB,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAW,EAAA,EAAA;AAAA,YACT,MAAO,CAAA,MAAA;AAAA,YACP,cAAc,MAAO,CAAA,cAAA;AAAA,YACrB,YAAY,MAAO,CAAA,YAAA;AAAA,YACnB,KAAU,KAAA,WAAA,IAAe,CAAC,QAAA,IAAY,MAAO,CAAA,eAAA;AAAA,YAC7C,KAAU,KAAA,OAAA,IAAW,CAAC,QAAA,IAAY,MAAO,CAAA;AAAA;AAC3C;AAAA,OACF,EACC,CAAC,MACA,oBAAA,KAAA,CAAA,aAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,WAAW,EAAG,CAAA,MAAA,CAAO,eAAe,UAAc,IAAA,cAAA,KAAmB,OAAO,kBAAkB;AAAA;AAAA,OAGpG,CAAA;AAAA,sBACC,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAK,SAAW,EAAA,EAAA,CAAG,MAAO,CAAA,QAAA,EAAU,QAAY,IAAA,MAAA,CAAO,cAAc,CAAA,EAAA,EAAI,CAAE,CAAA,KAAA,CAAM,KAAM;AAAA,KAE5F,CAAA;AAAA,GAEH,CACH,CACF,CAAA;AAEJ;;;;"}
@@ -0,0 +1,155 @@
1
+ import React, { useRef, useMemo, useState, useCallback } from 'react';
2
+ import { useStyles2, Spinner, Icon, Collapse } from '@grafana/ui';
3
+ import { isAuthGroupId } from './config.js';
4
+ import { FetchErrorState, GroupFields, FormFooter } from './layoutParts.js';
5
+ import { SidebarNav } from './SidebarNav.js';
6
+ import { getTabStyles } from './styles.js';
7
+
8
+ function TabLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderActions }) {
9
+ const styles = useStyles2(getTabStyles);
10
+ const sectionRefs = useRef(/* @__PURE__ */ new Map());
11
+ const {
12
+ resolvedGroups,
13
+ httpHeadersField,
14
+ handleSubmit,
15
+ initializing,
16
+ fetchError,
17
+ submitting,
18
+ readOnly,
19
+ isFieldVisible,
20
+ isGroupValid,
21
+ groupHasData,
22
+ onSubmit
23
+ } = form;
24
+ const displayGroups = useMemo(() => resolvedGroups.filter((g) => g.group.id !== "_required"), [resolvedGroups]);
25
+ const [expandedSections, setExpandedSections] = useState(() => {
26
+ const expanded = /* @__PURE__ */ new Set();
27
+ for (let i = 0; i < displayGroups.length; i++) {
28
+ if (!displayGroups[i].group.optional) {
29
+ expanded.add(i);
30
+ }
31
+ }
32
+ return expanded;
33
+ });
34
+ const hasExpandedForData = useRef(false);
35
+ useMemo(() => {
36
+ if (initializing || hasExpandedForData.current) {
37
+ return;
38
+ }
39
+ hasExpandedForData.current = true;
40
+ setExpandedSections((prev) => {
41
+ const next = new Set(prev);
42
+ for (let i = 0; i < displayGroups.length; i++) {
43
+ if (groupHasData(displayGroups[i])) {
44
+ next.add(i);
45
+ }
46
+ }
47
+ return next;
48
+ });
49
+ }, [initializing, displayGroups, groupHasData]);
50
+ const [activeSection, setActiveSection] = useState(0);
51
+ const toggleSection = useCallback((index) => {
52
+ setExpandedSections((prev) => {
53
+ const next = new Set(prev);
54
+ if (next.has(index)) {
55
+ next.delete(index);
56
+ } else {
57
+ next.add(index);
58
+ }
59
+ return next;
60
+ });
61
+ }, []);
62
+ const scrollToSection = useCallback(
63
+ (index) => {
64
+ setActiveSection(index);
65
+ if (!expandedSections.has(index)) {
66
+ setExpandedSections((prev) => new Set(prev).add(index));
67
+ }
68
+ const el = sectionRefs.current.get(index);
69
+ if (el) {
70
+ el.scrollIntoView({ behavior: "smooth", block: "start" });
71
+ }
72
+ },
73
+ [expandedSections]
74
+ );
75
+ const sectionStates = useMemo(() => {
76
+ return displayGroups.map((g, i) => {
77
+ if (i === activeSection) {
78
+ return "active";
79
+ }
80
+ if (!isGroupValid(g)) {
81
+ return "error";
82
+ }
83
+ if (groupHasData(g)) {
84
+ return "validated";
85
+ }
86
+ return "draft";
87
+ });
88
+ }, [displayGroups, activeSection, isGroupValid, groupHasData]);
89
+ if (initializing) {
90
+ return /* @__PURE__ */ React.createElement("div", { className: styles.loadingContainer }, /* @__PURE__ */ React.createElement(Spinner, { size: "sm", inline: true }), " Loading configuration\u2026");
91
+ }
92
+ if (fetchError) {
93
+ return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(FetchErrorState, { error: fetchError, dsUid, buttonClassName: styles.formButtons }));
94
+ }
95
+ return /* @__PURE__ */ React.createElement("div", { className: styles.root }, submitting && /* @__PURE__ */ React.createElement("div", { className: styles.overlay }, /* @__PURE__ */ React.createElement(Spinner, { size: "sm" }), /* @__PURE__ */ React.createElement("span", null, "Saving & testing\u2026")), /* @__PURE__ */ React.createElement(
96
+ SidebarNav,
97
+ {
98
+ groups: displayGroups,
99
+ activeIndex: activeSection,
100
+ sectionStates,
101
+ onSelect: scrollToSection
102
+ }
103
+ ), /* @__PURE__ */ React.createElement("div", { className: styles.main }, readOnly && /* @__PURE__ */ React.createElement("div", { className: styles.readOnlyBanner }, /* @__PURE__ */ React.createElement(Icon, { name: "lock", size: "xs" }), /* @__PURE__ */ React.createElement("span", null, "Read-only \u2014 managed externally")), /* @__PURE__ */ React.createElement("div", { className: styles.requiredNotice }, "Fields marked with * are required"), /* @__PURE__ */ React.createElement("form", { onSubmit: handleSubmit(onSubmit), className: styles.form }, displayGroups.map((g, i) => {
104
+ const visibleFields = g.fields.filter(isFieldVisible);
105
+ if (visibleFields.length === 0 && !httpHeadersField) {
106
+ return null;
107
+ }
108
+ const showHeaders = Boolean(
109
+ httpHeadersField && (isAuthGroupId(g.group.id) || g.group.id === "url-and-auth" || g.group.id === "_required" || g.group.fieldRefs.includes("httpHeaders"))
110
+ );
111
+ const sectionLabel = /* @__PURE__ */ React.createElement("span", { className: styles.sectionLabel }, /* @__PURE__ */ React.createElement("span", { className: styles.sectionLabelText }, g.group.title), g.group.optional && /* @__PURE__ */ React.createElement("span", { className: styles.sectionBadge }, "Optional"));
112
+ return /* @__PURE__ */ React.createElement(
113
+ "div",
114
+ {
115
+ key: g.group.id,
116
+ ref: (el) => {
117
+ if (el) {
118
+ sectionRefs.current.set(i, el);
119
+ }
120
+ },
121
+ className: styles.section
122
+ },
123
+ /* @__PURE__ */ React.createElement(
124
+ Collapse,
125
+ {
126
+ label: sectionLabel,
127
+ isOpen: expandedSections.has(i),
128
+ collapsible: true,
129
+ onToggle: () => {
130
+ toggleSection(i);
131
+ setActiveSection(i);
132
+ },
133
+ className: styles.collapseHeader
134
+ },
135
+ /* @__PURE__ */ React.createElement("div", { className: styles.sectionBody }, g.group.description && /* @__PURE__ */ React.createElement("div", { className: styles.sectionDescription }, g.group.description), /* @__PURE__ */ React.createElement(GroupFields, { group: g, form, dsUid, showAuthHeaders: showHeaders }))
136
+ )
137
+ );
138
+ }), /* @__PURE__ */ React.createElement(
139
+ FormFooter,
140
+ {
141
+ form,
142
+ schema,
143
+ dsUid,
144
+ dsName,
145
+ onRetest,
146
+ healthError,
147
+ renderActions,
148
+ saveDisabled: submitting,
149
+ className: styles.formButtons
150
+ }
151
+ ))));
152
+ }
153
+
154
+ export { TabLayout };
155
+ //# sourceMappingURL=TabLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabLayout.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/TabLayout.tsx"],"sourcesContent":["import React, { type ReactNode, useCallback, useMemo, useRef, useState } from 'react';\nimport { useStyles2, Icon, Spinner, Collapse } from '@grafana/ui';\nimport type { DatasourceConfigSchema } from '../../../schema/schema';\nimport { isAuthGroupId } from './config';\nimport type { useDatasourceConfigForm } from './hooks/useDatasourceConfigForm';\nimport { GroupFields, FormFooter, FetchErrorState } from './layoutParts';\nimport { SidebarNav, type SectionState } from './SidebarNav';\nimport { getTabStyles } from './styles';\n\ntype TabLayoutProps = {\n form: ReturnType<typeof useDatasourceConfigForm>;\n schema: DatasourceConfigSchema;\n dsUid: string;\n dsName: string;\n onRetest?: () => void;\n healthError?: string;\n renderActions?: (props: { dsUid: string; dsName: string; dsType: string; healthError?: string }) => ReactNode;\n};\n\nexport function TabLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderActions }: TabLayoutProps) {\n const styles = useStyles2(getTabStyles);\n const sectionRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n const {\n resolvedGroups,\n httpHeadersField,\n handleSubmit,\n initializing,\n fetchError,\n submitting,\n readOnly,\n isFieldVisible,\n isGroupValid,\n groupHasData,\n onSubmit,\n } = form;\n\n // Filter out _required synthetic group — in tab mode we show all groups from schema directly\n const displayGroups = useMemo(() => resolvedGroups.filter((g) => g.group.id !== '_required'), [resolvedGroups]);\n\n // Expand/collapse state: required or groups with data start expanded, optional start collapsed\n const [expandedSections, setExpandedSections] = useState<Set<number>>(() => {\n const expanded = new Set<number>();\n for (let i = 0; i < displayGroups.length; i++) {\n if (!displayGroups[i].group.optional) {\n expanded.add(i);\n }\n }\n return expanded;\n });\n\n // Re-evaluate on data load: expand sections that have saved data\n const hasExpandedForData = useRef(false);\n useMemo(() => {\n if (initializing || hasExpandedForData.current) {\n return;\n }\n hasExpandedForData.current = true;\n setExpandedSections((prev) => {\n const next = new Set(prev);\n for (let i = 0; i < displayGroups.length; i++) {\n if (groupHasData(displayGroups[i])) {\n next.add(i);\n }\n }\n return next;\n });\n }, [initializing, displayGroups, groupHasData]);\n\n const [activeSection, setActiveSection] = useState(0);\n\n const toggleSection = useCallback((index: number) => {\n setExpandedSections((prev) => {\n const next = new Set(prev);\n if (next.has(index)) {\n next.delete(index);\n } else {\n next.add(index);\n }\n return next;\n });\n }, []);\n\n const scrollToSection = useCallback(\n (index: number) => {\n setActiveSection(index);\n if (!expandedSections.has(index)) {\n setExpandedSections((prev) => new Set(prev).add(index));\n }\n const el = sectionRefs.current.get(index);\n if (el) {\n el.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n },\n [expandedSections]\n );\n\n // Compute sidebar states\n const sectionStates: SectionState[] = useMemo(() => {\n return displayGroups.map((g, i) => {\n if (i === activeSection) {\n return 'active';\n }\n if (!isGroupValid(g)) {\n return 'error';\n }\n if (groupHasData(g)) {\n return 'validated';\n }\n return 'draft';\n });\n }, [displayGroups, activeSection, isGroupValid, groupHasData]);\n\n if (initializing) {\n return (\n <div className={styles.loadingContainer}>\n <Spinner size=\"sm\" inline /> Loading configuration…\n </div>\n );\n }\n\n if (fetchError) {\n return (\n <div>\n <FetchErrorState error={fetchError} dsUid={dsUid} buttonClassName={styles.formButtons} />\n </div>\n );\n }\n\n return (\n <div className={styles.root}>\n {submitting && (\n <div className={styles.overlay}>\n <Spinner size=\"sm\" />\n <span>Saving & testing…</span>\n </div>\n )}\n\n <SidebarNav\n groups={displayGroups}\n activeIndex={activeSection}\n sectionStates={sectionStates}\n onSelect={scrollToSection}\n />\n\n <div className={styles.main}>\n {readOnly && (\n <div className={styles.readOnlyBanner}>\n <Icon name=\"lock\" size=\"xs\" />\n <span>Read-only — managed externally</span>\n </div>\n )}\n\n <div className={styles.requiredNotice}>Fields marked with * are required</div>\n\n <form onSubmit={handleSubmit(onSubmit)} className={styles.form}>\n {displayGroups.map((g, i) => {\n const visibleFields = g.fields.filter(isFieldVisible);\n if (visibleFields.length === 0 && !httpHeadersField) {\n return null;\n }\n\n const showHeaders = Boolean(\n httpHeadersField &&\n (isAuthGroupId(g.group.id) ||\n g.group.id === 'url-and-auth' ||\n g.group.id === '_required' ||\n g.group.fieldRefs.includes('httpHeaders'))\n );\n\n const sectionLabel = (\n <span className={styles.sectionLabel}>\n <span className={styles.sectionLabelText}>{g.group.title}</span>\n {g.group.optional && <span className={styles.sectionBadge}>Optional</span>}\n </span>\n );\n\n return (\n <div\n key={g.group.id}\n ref={(el) => {\n if (el) {\n sectionRefs.current.set(i, el);\n }\n }}\n className={styles.section}\n >\n <Collapse\n label={sectionLabel}\n isOpen={expandedSections.has(i)}\n collapsible\n onToggle={() => {\n toggleSection(i);\n setActiveSection(i);\n }}\n className={styles.collapseHeader}\n >\n <div className={styles.sectionBody}>\n {g.group.description && <div className={styles.sectionDescription}>{g.group.description}</div>}\n <GroupFields group={g} form={form} dsUid={dsUid} showAuthHeaders={showHeaders} />\n </div>\n </Collapse>\n </div>\n );\n })}\n\n <FormFooter\n form={form}\n schema={schema}\n dsUid={dsUid}\n dsName={dsName}\n onRetest={onRetest}\n healthError={healthError}\n renderActions={renderActions}\n saveDisabled={submitting}\n className={styles.formButtons}\n />\n </form>\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ import { evaluate, parse } from '@marcbachmann/cel-js';
2
+
3
+ const exprCache = /* @__PURE__ */ new Map();
4
+ function getCompiled(expr) {
5
+ if (exprCache.has(expr)) {
6
+ return exprCache.get(expr);
7
+ }
8
+ try {
9
+ const compiled = parse(expr);
10
+ exprCache.set(expr, compiled);
11
+ return compiled;
12
+ } catch (e) {
13
+ exprCache.set(expr, null);
14
+ return null;
15
+ }
16
+ }
17
+ function buildCelContext(values) {
18
+ const ctx = {};
19
+ for (const [key, value] of Object.entries(values)) {
20
+ setNestedValue(ctx, key, value);
21
+ }
22
+ return ctx;
23
+ }
24
+ function setNestedValue(obj, path, value) {
25
+ const parts = path.split(".");
26
+ let current = obj;
27
+ for (let i = 0; i < parts.length - 1; i++) {
28
+ const part = parts[i];
29
+ if (!(part in current) || typeof current[part] !== "object" || current[part] === null) {
30
+ current[part] = {};
31
+ }
32
+ current = current[part];
33
+ }
34
+ current[parts[parts.length - 1]] = value;
35
+ }
36
+ function evaluateCelExpression(expr, context, defaultValue = false) {
37
+ if (!expr || !expr.trim()) {
38
+ return defaultValue;
39
+ }
40
+ const compiled = getCompiled(expr);
41
+ if (!compiled) {
42
+ return defaultValue;
43
+ }
44
+ try {
45
+ const result = compiled(context);
46
+ return !!result;
47
+ } catch (e) {
48
+ return defaultValue;
49
+ }
50
+ }
51
+ function evaluateCelDirect(expr, context) {
52
+ return evaluate(expr, context);
53
+ }
54
+ function isValidCelExpression(expr) {
55
+ try {
56
+ parse(expr);
57
+ return true;
58
+ } catch (e) {
59
+ return false;
60
+ }
61
+ }
62
+ function extractFieldRefs(expr) {
63
+ const matches = expr.matchAll(/([\w.]+)\s*(?:==|!=)/g);
64
+ const refs = /* @__PURE__ */ new Set();
65
+ for (const m of matches) {
66
+ refs.add(m[1]);
67
+ }
68
+ return [...refs];
69
+ }
70
+ function clearExpressionCache() {
71
+ exprCache.clear();
72
+ }
73
+
74
+ export { buildCelContext, clearExpressionCache, evaluateCelDirect, evaluateCelExpression, extractFieldRefs, isValidCelExpression };
75
+ //# sourceMappingURL=cel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cel.js","sources":["../../../../../src/components/ConfigEditor/DatasourceConfigWizard/cel.ts"],"sourcesContent":["/**\n * CEL (Common Expression Language) expression evaluator for schema conditions.\n *\n * Used by `dependsOn`, `requiredWhen`, `disabledWhen`, and `overrides[].when`.\n * Wraps @marcbachmann/cel-js with field-ID-aware context building.\n *\n * Go equivalent: github.com/google/cel-go\n */\n\nimport { evaluate as celEvaluate, parse as celParse } from '@marcbachmann/cel-js';\n\n// ============================================================\n// Expression cache — parse once, evaluate many times\n// ============================================================\n\ntype CompiledExpr = (ctx: Record<string, unknown>) => unknown;\nconst exprCache = new Map<string, CompiledExpr | null>();\n\nfunction getCompiled(expr: string): CompiledExpr | null {\n if (exprCache.has(expr)) {\n return exprCache.get(expr)!;\n }\n try {\n const compiled = celParse(expr);\n exprCache.set(expr, compiled);\n return compiled;\n } catch {\n exprCache.set(expr, null);\n return null;\n }\n}\n\n// ============================================================\n// Context builder — flat field values → nested object for CEL\n// ============================================================\n\n/**\n * Build a nested context object from flat form values keyed by field IDs.\n *\n * CEL interprets dots as property access, so `jsonData.auth_method == 'oauth2'`\n * requires `{ jsonData: { auth_method: 'oauth2' } }`.\n *\n * This function takes flat key-value pairs (from react-hook-form `watch()`)\n * and builds the nested structure CEL expects.\n *\n * @param values - Flat map of form keys to values (e.g. `{ \"auth_method\": \"oauth2\", \"oauth2.oauth2_type\": \"jwt\" }`)\n * @param fieldIdToFormKey - Optional map from field ID to form key for translation\n */\nexport function buildCelContext(values: Record<string, unknown>): Record<string, unknown> {\n const ctx: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(values)) {\n setNestedValue(ctx, key, value);\n }\n\n return ctx;\n}\n\nfunction setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void {\n const parts = path.split('.');\n let current = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (!(part in current) || typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {};\n }\n current = current[part] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = value;\n}\n\n// ============================================================\n// Public API\n// ============================================================\n\n/**\n * Evaluate a CEL expression against a context of field values.\n * Returns the boolean result, or `defaultValue` if the expression is invalid.\n *\n * @example\n * ```ts\n * evaluateCelExpression(\"jsonData.auth_method == 'oauth2'\", { jsonData: { auth_method: 'oauth2' } })\n * // => true\n *\n * evaluateCelExpression(\"auth_method == 'oauth2' && oauth2_type == 'jwt'\", { auth_method: 'oauth2', oauth2_type: 'jwt' })\n * // => true\n * ```\n */\nexport function evaluateCelExpression(expr: string, context: Record<string, unknown>, defaultValue = false): boolean {\n if (!expr || !expr.trim()) {\n return defaultValue;\n }\n\n const compiled = getCompiled(expr);\n if (!compiled) {\n return defaultValue;\n }\n\n try {\n const result = compiled(context);\n return !!result;\n } catch {\n return defaultValue;\n }\n}\n\n/**\n * Evaluate a CEL expression directly using `evaluate` (no caching).\n * Useful for one-off evaluations or testing.\n */\nexport function evaluateCelDirect(expr: string, context: Record<string, unknown>): unknown {\n return celEvaluate(expr, context);\n}\n\n/**\n * Validate that a CEL expression can be parsed without errors.\n * Returns true if valid, false otherwise.\n */\nexport function isValidCelExpression(expr: string): boolean {\n try {\n celParse(expr);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Extract all field ID references from a simple expression.\n * Used by `resolveRequiredFieldsGroup` to find dependency relationships.\n *\n * For simple expressions like `fieldA == 'x'`, returns `['fieldA']`.\n * For compound expressions like `fieldA == 'x' && fieldB == 'y'`, returns `['fieldA', 'fieldB']`.\n *\n * This uses regex extraction (not AST walking) for simplicity and speed.\n */\nexport function extractFieldRefs(expr: string): string[] {\n // Match identifiers (possibly dotted) that precede == or !=\n const matches = expr.matchAll(/([\\w.]+)\\s*(?:==|!=)/g);\n const refs = new Set<string>();\n for (const m of matches) {\n refs.add(m[1]);\n }\n return [...refs];\n}\n\n/**\n * Clear the expression cache. Useful for testing.\n */\nexport function clearExpressionCache(): void {\n exprCache.clear();\n}\n"],"names":["celParse","celEvaluate"],"mappings":";;AAgBA,MAAM,SAAA,uBAAgB,GAAiC,EAAA;AAEvD,SAAS,YAAY,IAAmC,EAAA;AACtD,EAAI,IAAA,SAAA,CAAU,GAAI,CAAA,IAAI,CAAG,EAAA;AACvB,IAAO,OAAA,SAAA,CAAU,IAAI,IAAI,CAAA;AAAA;AAE3B,EAAI,IAAA;AACF,IAAM,MAAA,QAAA,GAAWA,MAAS,IAAI,CAAA;AAC9B,IAAU,SAAA,CAAA,GAAA,CAAI,MAAM,QAAQ,CAAA;AAC5B,IAAO,OAAA,QAAA;AAAA,GACD,CAAA,OAAA,CAAA,EAAA;AACN,IAAU,SAAA,CAAA,GAAA,CAAI,MAAM,IAAI,CAAA;AACxB,IAAO,OAAA,IAAA;AAAA;AAEX;AAkBO,SAAS,gBAAgB,MAA0D,EAAA;AACxF,EAAA,MAAM,MAA+B,EAAC;AAEtC,EAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,MAAM,CAAG,EAAA;AACjD,IAAe,cAAA,CAAA,GAAA,EAAK,KAAK,KAAK,CAAA;AAAA;AAGhC,EAAO,OAAA,GAAA;AACT;AAEA,SAAS,cAAA,CAAe,GAA8B,EAAA,IAAA,EAAc,KAAsB,EAAA;AACxF,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,KAAA,CAAM,GAAG,CAAA;AAC5B,EAAA,IAAI,OAAU,GAAA,GAAA;AACd,EAAA,KAAA,IAAS,IAAI,CAAG,EAAA,CAAA,GAAI,KAAM,CAAA,MAAA,GAAS,GAAG,CAAK,EAAA,EAAA;AACzC,IAAM,MAAA,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAI,IAAA,EAAE,IAAQ,IAAA,OAAA,CAAA,IAAY,OAAO,OAAA,CAAQ,IAAI,CAAA,KAAM,QAAY,IAAA,OAAA,CAAQ,IAAI,CAAA,KAAM,IAAM,EAAA;AACrF,MAAQ,OAAA,CAAA,IAAI,IAAI,EAAC;AAAA;AAEnB,IAAA,OAAA,GAAU,QAAQ,IAAI,CAAA;AAAA;AAExB,EAAA,OAAA,CAAQ,KAAM,CAAA,KAAA,CAAM,MAAS,GAAA,CAAC,CAAC,CAAI,GAAA,KAAA;AACrC;AAmBO,SAAS,qBAAsB,CAAA,IAAA,EAAc,OAAkC,EAAA,YAAA,GAAe,KAAgB,EAAA;AACnH,EAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,IAAA,CAAK,MAAQ,EAAA;AACzB,IAAO,OAAA,YAAA;AAAA;AAGT,EAAM,MAAA,QAAA,GAAW,YAAY,IAAI,CAAA;AACjC,EAAA,IAAI,CAAC,QAAU,EAAA;AACb,IAAO,OAAA,YAAA;AAAA;AAGT,EAAI,IAAA;AACF,IAAM,MAAA,MAAA,GAAS,SAAS,OAAO,CAAA;AAC/B,IAAA,OAAO,CAAC,CAAC,MAAA;AAAA,GACH,CAAA,OAAA,CAAA,EAAA;AACN,IAAO,OAAA,YAAA;AAAA;AAEX;AAMgB,SAAA,iBAAA,CAAkB,MAAc,OAA2C,EAAA;AACzF,EAAO,OAAAC,QAAA,CAAY,MAAM,OAAO,CAAA;AAClC;AAMO,SAAS,qBAAqB,IAAuB,EAAA;AAC1D,EAAI,IAAA;AACF,IAAAD,KAAA,CAAS,IAAI,CAAA;AACb,IAAO,OAAA,IAAA;AAAA,GACD,CAAA,OAAA,CAAA,EAAA;AACN,IAAO,OAAA,KAAA;AAAA;AAEX;AAWO,SAAS,iBAAiB,IAAwB,EAAA;AAEvD,EAAM,MAAA,OAAA,GAAU,IAAK,CAAA,QAAA,CAAS,uBAAuB,CAAA;AACrD,EAAM,MAAA,IAAA,uBAAW,GAAY,EAAA;AAC7B,EAAA,KAAA,MAAW,KAAK,OAAS,EAAA;AACvB,IAAK,IAAA,CAAA,GAAA,CAAI,CAAE,CAAA,CAAC,CAAC,CAAA;AAAA;AAEf,EAAO,OAAA,CAAC,GAAG,IAAI,CAAA;AACjB;AAKO,SAAS,oBAA6B,GAAA;AAC3C,EAAA,SAAA,CAAU,KAAM,EAAA;AAClB;;;;"}