@grafana/plugin-ui 0.14.1-dsconfig.0d5c985 → 0.14.1-dsconfig.7535e54

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 (230) hide show
  1. package/dist/cjs/index.cjs +1215 -1152
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.d.cts +286 -157
  4. package/dist/cjs/schemas.cjs +25 -0
  5. package/dist/cjs/schemas.cjs.map +1 -0
  6. package/dist/cjs/schemas.d.cts +448 -0
  7. package/dist/cjs/test-utils.d.cts +23 -23
  8. package/dist/cjs/useDatasourceSchema-DLkP-L1p.js +15795 -0
  9. package/dist/cjs/useDatasourceSchema-DLkP-L1p.js.map +1 -0
  10. package/dist/esm/components/ConfigEditor/ConfigSection/ConfigDescriptionLink.js +2 -2
  11. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js +16 -11
  12. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceConfigWizard.js.map +1 -1
  13. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.js +27 -0
  14. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/DatasourceErrorBoundary.js.map +1 -0
  15. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js +18 -7
  16. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SchemaField.js.map +1 -1
  17. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js +1 -1
  18. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SidebarNav.js.map +1 -1
  19. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js +11 -6
  20. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/TabLayout.js.map +1 -1
  21. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/cel.js +75 -0
  22. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/cel.js.map +1 -0
  23. package/dist/esm/{datasource/schema → components/ConfigEditor/DatasourceConfigWizard}/config.js +37 -14
  24. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/config.js.map +1 -0
  25. package/dist/esm/{datasource/schema → components/ConfigEditor/DatasourceConfigWizard}/datasource.js +129 -3
  26. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/datasource.js.map +1 -0
  27. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js +62 -12
  28. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/fieldUtils.js.map +1 -1
  29. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{useDatasourceConfigForm.js → hooks/useDatasourceConfigForm.js} +71 -29
  30. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useDatasourceConfigForm.js.map +1 -0
  31. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useHealthChecks.js +106 -0
  32. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/hooks/useHealthChecks.js.map +1 -0
  33. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{AuthorizationHeaderField.js → inputs/AuthorizationHeaderField.js} +6 -8
  34. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/AuthorizationHeaderField.js.map +1 -0
  35. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{ComplexFieldNote.js → inputs/ComplexFieldNote.js} +6 -4
  36. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ComplexFieldNote.js.map +1 -0
  37. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/FileUploadField.js +106 -0
  38. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/FileUploadField.js.map +1 -0
  39. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{IndexedPairEditor.js → inputs/IndexedPairEditor.js} +52 -52
  40. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/IndexedPairEditor.js.map +1 -0
  41. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ObjectArrayEditor.js +190 -0
  42. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/ObjectArrayEditor.js.map +1 -0
  43. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{PdcFieldNote.js → inputs/PdcFieldNote.js} +5 -8
  44. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/PdcFieldNote.js.map +1 -0
  45. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{SecureFieldInput.js → inputs/SecureFieldInput.js} +8 -10
  46. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/SecureFieldInput.js.map +1 -0
  47. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/StringArrayInput.js +80 -0
  48. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/inputs/StringArrayInput.js.map +1 -0
  49. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/renderFieldInput.js +76 -41
  50. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/renderFieldInput.js.map +1 -1
  51. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/resolvePluginName.js +30 -0
  52. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/resolvePluginName.js.map +1 -0
  53. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/{tabStyles.js → styles.js} +125 -6
  54. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/styles.js.map +1 -0
  55. package/dist/esm/components/DataLinks/DataLink.js +2 -2
  56. package/dist/esm/components/DataLinks/DataLinks.js +2 -2
  57. package/dist/esm/components/DataSourcePicker/DataSourcePicker.js +7 -7
  58. package/dist/esm/components/DatePicker/styles.js +2 -2
  59. package/dist/esm/components/DatePickerWithInput/styles.js +2 -2
  60. package/dist/esm/components/QueryEditor/EditorField.js +2 -2
  61. package/dist/esm/components/QueryEditor/EditorHeader.js +2 -2
  62. package/dist/esm/components/QueryEditor/EditorRow.js +2 -2
  63. package/dist/esm/components/QueryEditor/EditorSwitch.js +2 -2
  64. package/dist/esm/components/QueryEditor/InputGroup.js +2 -2
  65. package/dist/esm/components/QueryEditor/Space.js +2 -2
  66. package/dist/esm/components/QueryEditor/query-editor-raw/RawEditor.js +2 -2
  67. package/dist/esm/components/QueryEditor/visual-query-builder/EditorField.js +2 -2
  68. package/dist/esm/components/QueryEditor/visual-query-builder/EditorRow.js +2 -2
  69. package/dist/esm/components/QueryEditor/visual-query-builder/Preview.js +2 -2
  70. package/dist/esm/components/QueryEditor/visual-query-builder/SelectRow.js +2 -2
  71. package/dist/esm/datasource/SqlDatasource.js +10 -10
  72. package/dist/esm/index.d.ts +286 -157
  73. package/dist/esm/index.js +10 -4
  74. package/dist/esm/index.js.map +1 -1
  75. package/dist/esm/schema/registry/alertmanager.schema.json.js +77 -0
  76. package/dist/esm/schema/registry/alertmanager.schema.json.js.map +1 -0
  77. package/dist/esm/schema/registry/cloudwatch.schema.json.js +384 -0
  78. package/dist/esm/schema/registry/cloudwatch.schema.json.js.map +1 -0
  79. package/dist/esm/schema/registry/elasticsearch.schema.json.js +287 -0
  80. package/dist/esm/schema/registry/elasticsearch.schema.json.js.map +1 -0
  81. package/dist/esm/schema/registry/grafana-amazonprometheus-datasource.schema.json.js +166 -0
  82. package/dist/esm/schema/registry/grafana-amazonprometheus-datasource.schema.json.js.map +1 -0
  83. package/dist/esm/schema/registry/grafana-appdynamics-datasource.schema.json.js +145 -0
  84. package/dist/esm/schema/registry/grafana-appdynamics-datasource.schema.json.js.map +1 -0
  85. package/dist/esm/schema/registry/grafana-astradb-datasource.schema.json.js +123 -0
  86. package/dist/esm/schema/registry/grafana-astradb-datasource.schema.json.js.map +1 -0
  87. package/dist/esm/schema/registry/grafana-athena-datasource.schema.json.js +158 -0
  88. package/dist/esm/schema/registry/grafana-athena-datasource.schema.json.js.map +1 -0
  89. package/dist/esm/schema/registry/grafana-azure-data-explorer-datasource.schema.json.js +204 -0
  90. package/dist/esm/schema/registry/grafana-azure-data-explorer-datasource.schema.json.js.map +1 -0
  91. package/dist/esm/schema/registry/grafana-azure-monitor-datasource.schema.json.js +294 -0
  92. package/dist/esm/schema/registry/grafana-azure-monitor-datasource.schema.json.js.map +1 -0
  93. package/dist/esm/schema/registry/grafana-azuredevops-datasource.schema.json.js +101 -0
  94. package/dist/esm/schema/registry/grafana-azuredevops-datasource.schema.json.js.map +1 -0
  95. package/dist/esm/schema/registry/grafana-azureprometheus-datasource.schema.json.js +125 -0
  96. package/dist/esm/schema/registry/grafana-azureprometheus-datasource.schema.json.js.map +1 -0
  97. package/dist/esm/schema/registry/grafana-bigquery-datasource.schema.json.js +508 -0
  98. package/dist/esm/schema/registry/grafana-bigquery-datasource.schema.json.js.map +1 -0
  99. package/dist/esm/schema/registry/grafana-clickhouse-datasource.schema.json.js +1400 -0
  100. package/dist/esm/schema/registry/grafana-clickhouse-datasource.schema.json.js.map +1 -0
  101. package/dist/esm/schema/registry/grafana-cockroachdb-datasource.schema.json.js +302 -0
  102. package/dist/esm/schema/registry/grafana-cockroachdb-datasource.schema.json.js.map +1 -0
  103. package/dist/esm/schema/registry/grafana-databricks-datasource.schema.json.js +291 -0
  104. package/dist/esm/schema/registry/grafana-databricks-datasource.schema.json.js.map +1 -0
  105. package/dist/esm/schema/registry/grafana-datadog-datasource.schema.json.js +155 -0
  106. package/dist/esm/schema/registry/grafana-datadog-datasource.schema.json.js.map +1 -0
  107. package/dist/esm/schema/registry/grafana-dynatrace-datasource.schema.json.js +179 -0
  108. package/dist/esm/schema/registry/grafana-dynatrace-datasource.schema.json.js.map +1 -0
  109. package/dist/esm/schema/registry/grafana-falconlogscale-datasource.schema.json.js +134 -0
  110. package/dist/esm/schema/registry/grafana-falconlogscale-datasource.schema.json.js.map +1 -0
  111. package/dist/esm/schema/registry/grafana-github-datasource.schema.json.js +156 -0
  112. package/dist/esm/schema/registry/grafana-github-datasource.schema.json.js.map +1 -0
  113. package/dist/esm/schema/registry/grafana-gitlab-datasource.schema.json.js +84 -0
  114. package/dist/esm/schema/registry/grafana-gitlab-datasource.schema.json.js.map +1 -0
  115. package/dist/esm/schema/registry/grafana-googlesheets-datasource.schema.json.js +231 -0
  116. package/dist/esm/schema/registry/grafana-googlesheets-datasource.schema.json.js.map +1 -0
  117. package/dist/esm/schema/registry/grafana-honeycomb-datasource.schema.json.js +87 -0
  118. package/dist/esm/schema/registry/grafana-honeycomb-datasource.schema.json.js.map +1 -0
  119. package/dist/esm/schema/registry/grafana-iot-sitewise-datasource.schema.json.js +159 -0
  120. package/dist/esm/schema/registry/grafana-iot-sitewise-datasource.schema.json.js.map +1 -0
  121. package/dist/esm/schema/registry/grafana-jira-datasource.schema.json.js +188 -0
  122. package/dist/esm/schema/registry/grafana-jira-datasource.schema.json.js.map +1 -0
  123. package/dist/esm/schema/registry/grafana-looker-datasource.schema.json.js +82 -0
  124. package/dist/esm/schema/registry/grafana-looker-datasource.schema.json.js.map +1 -0
  125. package/dist/esm/schema/registry/grafana-mongodb-datasource.schema.json.js +278 -0
  126. package/dist/esm/schema/registry/grafana-mongodb-datasource.schema.json.js.map +1 -0
  127. package/dist/esm/schema/registry/grafana-mqtt-datasource.schema.json.js +168 -0
  128. package/dist/esm/schema/registry/grafana-mqtt-datasource.schema.json.js.map +1 -0
  129. package/dist/esm/schema/registry/grafana-newrelic-datasource.schema.json.js +129 -0
  130. package/dist/esm/schema/registry/grafana-newrelic-datasource.schema.json.js.map +1 -0
  131. package/dist/esm/schema/registry/grafana-odbc-datasource.schema.json.js +56 -0
  132. package/dist/esm/schema/registry/grafana-odbc-datasource.schema.json.js.map +1 -0
  133. package/dist/esm/schema/registry/grafana-opensearch-datasource.schema.json.js +212 -0
  134. package/dist/esm/schema/registry/grafana-opensearch-datasource.schema.json.js.map +1 -0
  135. package/dist/esm/schema/registry/grafana-oracle-datasource.schema.json.js +186 -0
  136. package/dist/esm/schema/registry/grafana-oracle-datasource.schema.json.js.map +1 -0
  137. package/dist/esm/schema/registry/grafana-pagerduty-datasource.schema.json.js +85 -0
  138. package/dist/esm/schema/registry/grafana-pagerduty-datasource.schema.json.js.map +1 -0
  139. package/dist/esm/schema/registry/grafana-postgresql-datasource.schema.json.js +411 -0
  140. package/dist/esm/schema/registry/grafana-postgresql-datasource.schema.json.js.map +1 -0
  141. package/dist/esm/schema/registry/grafana-pyroscope-datasource.schema.json.js +41 -0
  142. package/dist/esm/schema/registry/grafana-pyroscope-datasource.schema.json.js.map +1 -0
  143. package/dist/esm/schema/registry/grafana-redshift-datasource.schema.json.js +201 -0
  144. package/dist/esm/schema/registry/grafana-redshift-datasource.schema.json.js.map +1 -0
  145. package/dist/esm/schema/registry/grafana-salesforce-datasource.schema.json.js +201 -0
  146. package/dist/esm/schema/registry/grafana-salesforce-datasource.schema.json.js.map +1 -0
  147. package/dist/esm/schema/registry/grafana-saphana-datasource.schema.json.js +208 -0
  148. package/dist/esm/schema/registry/grafana-saphana-datasource.schema.json.js.map +1 -0
  149. package/dist/esm/schema/registry/grafana-sentry-datasource.schema.json.js +94 -0
  150. package/dist/esm/schema/registry/grafana-sentry-datasource.schema.json.js.map +1 -0
  151. package/dist/esm/schema/registry/grafana-servicenow-datasource.schema.json.js +179 -0
  152. package/dist/esm/schema/registry/grafana-servicenow-datasource.schema.json.js.map +1 -0
  153. package/dist/esm/schema/registry/grafana-snowflake-datasource.schema.json.js +304 -0
  154. package/dist/esm/schema/registry/grafana-snowflake-datasource.schema.json.js.map +1 -0
  155. package/dist/esm/schema/registry/grafana-splunk-datasource.schema.json.js +319 -0
  156. package/dist/esm/schema/registry/grafana-splunk-datasource.schema.json.js.map +1 -0
  157. package/dist/esm/schema/registry/grafana-splunkobservability-datasource.schema.json.js +90 -0
  158. package/dist/esm/schema/registry/grafana-splunkobservability-datasource.schema.json.js.map +1 -0
  159. package/dist/esm/schema/registry/grafana-strava-datasource.schema.json.js +74 -0
  160. package/dist/esm/schema/registry/grafana-strava-datasource.schema.json.js.map +1 -0
  161. package/dist/esm/schema/registry/grafana-sumologic-datasource.schema.json.js +102 -0
  162. package/dist/esm/schema/registry/grafana-sumologic-datasource.schema.json.js.map +1 -0
  163. package/dist/esm/schema/registry/grafana-surrealdb-datasource.schema.json.js +92 -0
  164. package/dist/esm/schema/registry/grafana-surrealdb-datasource.schema.json.js.map +1 -0
  165. package/dist/esm/schema/registry/grafana-timestream-datasource.schema.json.js +145 -0
  166. package/dist/esm/schema/registry/grafana-timestream-datasource.schema.json.js.map +1 -0
  167. package/dist/esm/schema/registry/grafana-wavefront-datasource.schema.json.js +80 -0
  168. package/dist/esm/schema/registry/grafana-wavefront-datasource.schema.json.js.map +1 -0
  169. package/dist/esm/schema/registry/grafana-x-ray-datasource.schema.json.js +112 -0
  170. package/dist/esm/schema/registry/grafana-x-ray-datasource.schema.json.js.map +1 -0
  171. package/dist/esm/schema/registry/grafana-yugabyte-datasource.schema.json.js +114 -0
  172. package/dist/esm/schema/registry/grafana-yugabyte-datasource.schema.json.js.map +1 -0
  173. package/dist/esm/schema/registry/graphite.schema.json.js +104 -0
  174. package/dist/esm/schema/registry/graphite.schema.json.js.map +1 -0
  175. package/dist/esm/schema/registry/index.js +137 -0
  176. package/dist/esm/schema/registry/index.js.map +1 -0
  177. package/dist/esm/schema/registry/influxdb.schema.json.js +717 -0
  178. package/dist/esm/schema/registry/influxdb.schema.json.js.map +1 -0
  179. package/dist/esm/schema/registry/jaeger.schema.json.js +59 -0
  180. package/dist/esm/schema/registry/jaeger.schema.json.js.map +1 -0
  181. package/dist/esm/schema/registry/loki.schema.json.js +545 -0
  182. package/dist/esm/schema/registry/loki.schema.json.js.map +1 -0
  183. package/dist/esm/schema/registry/marcusolsson-csv-datasource.schema.json.js +45 -0
  184. package/dist/esm/schema/registry/marcusolsson-csv-datasource.schema.json.js.map +1 -0
  185. package/dist/esm/schema/registry/marcusolsson-json-datasource.schema.json.js +36 -0
  186. package/dist/esm/schema/registry/marcusolsson-json-datasource.schema.json.js.map +1 -0
  187. package/dist/esm/schema/registry/mssql.schema.json.js +292 -0
  188. package/dist/esm/schema/registry/mssql.schema.json.js.map +1 -0
  189. package/dist/esm/schema/registry/mysql.schema.json.js +304 -0
  190. package/dist/esm/schema/registry/mysql.schema.json.js.map +1 -0
  191. package/dist/esm/schema/registry/opentsdb.schema.json.js +113 -0
  192. package/dist/esm/schema/registry/opentsdb.schema.json.js.map +1 -0
  193. package/dist/esm/schema/registry/prometheus.schema.json.js +783 -0
  194. package/dist/esm/schema/registry/prometheus.schema.json.js.map +1 -0
  195. package/dist/esm/schema/registry/stackdriver.schema.json.js +224 -0
  196. package/dist/esm/schema/registry/stackdriver.schema.json.js.map +1 -0
  197. package/dist/esm/schema/registry/tempo.schema.json.js +664 -0
  198. package/dist/esm/schema/registry/tempo.schema.json.js.map +1 -0
  199. package/dist/esm/schema/registry/yesoreyeram-infinity-datasource.schema.json.js +1073 -0
  200. package/dist/esm/schema/registry/yesoreyeram-infinity-datasource.schema.json.js.map +1 -0
  201. package/dist/esm/schema/registry/zipkin.schema.json.js +40 -0
  202. package/dist/esm/schema/registry/zipkin.schema.json.js.map +1 -0
  203. package/dist/esm/schema/utils/dsconfig.js +97 -0
  204. package/dist/esm/schema/utils/dsconfig.js.map +1 -0
  205. package/dist/esm/{datasource/schema/llmHints.js → schema/utils/llm.js} +1 -1
  206. package/dist/esm/schema/utils/llm.js.map +1 -0
  207. package/dist/esm/{datasource/schema/provisioningYaml.js → schema/utils/provisioning.js} +79 -3
  208. package/dist/esm/schema/utils/provisioning.js.map +1 -0
  209. package/dist/esm/schema/utils/useDatasourceSchema.js +16 -0
  210. package/dist/esm/schema/utils/useDatasourceSchema.js.map +1 -0
  211. package/dist/esm/schemas.d.ts +448 -0
  212. package/dist/esm/schemas.js +6 -0
  213. package/dist/esm/schemas.js.map +1 -0
  214. package/dist/esm/test-utils.d.ts +23 -23
  215. package/package.json +23 -6
  216. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/AuthorizationHeaderField.js.map +0 -1
  217. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/ComplexFieldNote.js.map +0 -1
  218. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/IndexedPairEditor.js.map +0 -1
  219. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/PdcFieldNote.js.map +0 -1
  220. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/SecureFieldInput.js.map +0 -1
  221. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/StringArrayInput.js +0 -84
  222. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/StringArrayInput.js.map +0 -1
  223. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/tabStyles.js.map +0 -1
  224. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/useDatasourceConfigForm.js.map +0 -1
  225. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/wizardStyles.js +0 -124
  226. package/dist/esm/components/ConfigEditor/DatasourceConfigWizard/wizardStyles.js.map +0 -1
  227. package/dist/esm/datasource/schema/config.js.map +0 -1
  228. package/dist/esm/datasource/schema/datasource.js.map +0 -1
  229. package/dist/esm/datasource/schema/llmHints.js.map +0 -1
  230. package/dist/esm/datasource/schema/provisioningYaml.js.map +0 -1
@@ -17,11 +17,13 @@ var AutoSizer = require('react-virtualized-auto-sizer');
17
17
  var sqlFormatter = require('sql-formatter');
18
18
  var rxjs = require('rxjs');
19
19
  var operators$1 = require('rxjs/operators');
20
+ var useDatasourceSchema = require('./useDatasourceSchema-DLkP-L1p.js');
20
21
  var reactHookForm = require('react-hook-form');
22
+ require('@marcbachmann/cel-js');
21
23
  var dnd = require('@hello-pangea/dnd');
22
24
  var reactPopperTooltip = require('react-popper-tooltip');
23
25
  var Prism = require('prismjs');
24
- var yaml = require('js-yaml');
26
+ require('js-yaml');
25
27
 
26
28
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
27
29
 
@@ -29,7 +31,6 @@ var React__default = /*#__PURE__*/_interopDefaultCompat(React);
29
31
  var Calendar__default = /*#__PURE__*/_interopDefaultCompat(Calendar);
30
32
  var AutoSizer__default = /*#__PURE__*/_interopDefaultCompat(AutoSizer);
31
33
  var Prism__default = /*#__PURE__*/_interopDefaultCompat(Prism);
32
- var yaml__default = /*#__PURE__*/_interopDefaultCompat(yaml);
33
34
 
34
35
  const QueryEditorRow = (props) => {
35
36
  var _a, _b;
@@ -78,7 +79,7 @@ function Segment(props) {
78
79
  );
79
80
  }
80
81
 
81
- const getStyles$v = (theme) => {
82
+ const getStyles$x = (theme) => {
82
83
  const containerBorder = theme.isDark ? theme.v1.palette.dark9 : theme.v1.palette.gray5;
83
84
  return {
84
85
  container: css.css`
@@ -228,7 +229,7 @@ const getBodyStyles = (theme) => {
228
229
 
229
230
  const DatePicker = React.memo((props) => {
230
231
  const theme = ui.useTheme2();
231
- const styles = getStyles$v(theme);
232
+ const styles = getStyles$x(theme);
232
233
  const { isOpen, onClose } = props;
233
234
  if (!isOpen) {
234
235
  return null;
@@ -258,7 +259,7 @@ const Body = React.memo(({ value, onChange }) => {
258
259
  });
259
260
  Body.displayName = "Body";
260
261
 
261
- function getStyles$u() {
262
+ function getStyles$w() {
262
263
  return {
263
264
  input: css.css({
264
265
  /* hides the native Calendar picker icon given when using type=date */
@@ -274,7 +275,7 @@ const formatDate = (date) => date.toISOString().split("T")[0];
274
275
  const DatePickerWithInput = (props) => {
275
276
  const { value, onChange, className, ...rest } = props;
276
277
  const [open, setOpen] = React.useState(false);
277
- const styles = getStyles$u();
278
+ const styles = getStyles$w();
278
279
  return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement(
279
280
  ui.Input,
280
281
  {
@@ -341,15 +342,15 @@ function getSignatureDisplayModel(signature) {
341
342
  }
342
343
  PluginSignatureBadge.displayName = "PluginSignatureBadge";
343
344
 
344
- var __defProp$3 = Object.defineProperty;
345
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
346
- var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
345
+ var __defProp$4 = Object.defineProperty;
346
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
347
+ var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
347
348
  class DataSourcePicker extends React.PureComponent {
348
349
  constructor(props) {
349
350
  super(props);
350
- __publicField$3(this, "dataSourceSrv", runtime.getDataSourceSrv());
351
- __publicField$3(this, "state", {});
352
- __publicField$3(this, "onChange", (item) => {
351
+ __publicField$4(this, "dataSourceSrv", runtime.getDataSourceSrv());
352
+ __publicField$4(this, "state", {});
353
+ __publicField$4(this, "onChange", (item) => {
353
354
  const dsSettings = this.dataSourceSrv.getInstanceSettings(item.value);
354
355
  if (dsSettings) {
355
356
  this.props.onChange(dsSettings);
@@ -429,14 +430,14 @@ class DataSourcePicker extends React.PureComponent {
429
430
  ));
430
431
  }
431
432
  }
432
- __publicField$3(DataSourcePicker, "defaultProps", {
433
+ __publicField$4(DataSourcePicker, "defaultProps", {
433
434
  autoFocus: false,
434
435
  openMenuOnFocus: false,
435
436
  placeholder: "Select datasource"
436
437
  });
437
438
 
438
439
  const { FormField, Switch } = ui.LegacyForms;
439
- const getStyles$t = ui.stylesFactory(() => ({
440
+ const getStyles$v = ui.stylesFactory(() => ({
440
441
  firstRow: css.css`
441
442
  display: flex;
442
443
  `,
@@ -453,7 +454,7 @@ const getStyles$t = ui.stylesFactory(() => ({
453
454
  }));
454
455
  const DataLink = (props) => {
455
456
  const { value, onChange, onDelete, suggestions, className } = props;
456
- const styles = getStyles$t();
457
+ const styles = getStyles$v();
457
458
  const [showInternalLink, setShowInternalLink] = useInternalLink(value.datasourceUid);
458
459
  const handleChange = (field) => (event) => {
459
460
  onChange({
@@ -570,7 +571,7 @@ function useInternalLink(datasourceUid) {
570
571
  return [showInternalLink, setShowInternalLink];
571
572
  }
572
573
 
573
- const getStyles$s = (theme) => ({
574
+ const getStyles$u = (theme) => ({
574
575
  infoText: css.css`
575
576
  padding-bottom: ${theme.v1.spacing.md};
576
577
  color: ${theme.v1.colors.textWeak};
@@ -582,7 +583,7 @@ const getStyles$s = (theme) => ({
582
583
  const DataLinks = (props) => {
583
584
  const { value, onChange } = props;
584
585
  const theme = ui.useTheme2();
585
- const styles = getStyles$s(theme);
586
+ const styles = getStyles$u(theme);
586
587
  return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement("h3", { className: "page-heading" }, "Data links"), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.infoText }, "Add links to existing fields. Links will be shown in log row details next to the field value."), /* @__PURE__ */ React__default.default.createElement("div", { className: "gf-form-group" }, value && value.map((field, index) => {
587
588
  return /* @__PURE__ */ React__default.default.createElement(
588
589
  DataLink,
@@ -5478,7 +5479,7 @@ const getButtonStyles = (theme) => ({
5478
5479
  });
5479
5480
 
5480
5481
  const InputGroup = ({ children }) => {
5481
- const styles = ui.useStyles2(getStyles$r);
5482
+ const styles = ui.useStyles2(getStyles$t);
5482
5483
  const modifiedChildren = React.Children.map(children, (child) => {
5483
5484
  if (React.isValidElement(child) && child.props.invalid) {
5484
5485
  return React.cloneElement(child, { className: css.cx(child.props.className, styles.invalidChild) });
@@ -5496,7 +5497,7 @@ const borderPriority = [
5496
5497
  "focused"
5497
5498
  // highest priority
5498
5499
  ];
5499
- const getStyles$r = () => ({
5500
+ const getStyles$t = () => ({
5500
5501
  root: css.css({
5501
5502
  display: "flex",
5502
5503
  // Style the direct children of the component
@@ -5579,10 +5580,10 @@ const EditorFieldGroup = ({ children }) => {
5579
5580
  };
5580
5581
 
5581
5582
  const EditorHeader = ({ children }) => {
5582
- const styles = ui.useStyles2(getStyles$q);
5583
+ const styles = ui.useStyles2(getStyles$s);
5583
5584
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, children);
5584
5585
  };
5585
- const getStyles$q = (theme) => ({
5586
+ const getStyles$s = (theme) => ({
5586
5587
  root: css.css({
5587
5588
  display: "flex",
5588
5589
  flexWrap: "wrap",
@@ -5595,12 +5596,12 @@ const getStyles$q = (theme) => ({
5595
5596
  const EditorField$1 = (props) => {
5596
5597
  var _a;
5597
5598
  const { label, optional, tooltip, tooltipInteractive, children, width, ...fieldProps } = props;
5598
- const styles = ui.useStyles2(getStyles$p, width);
5599
+ const styles = ui.useStyles2(getStyles$r, width);
5599
5600
  const childInputId = (fieldProps == null ? void 0 : fieldProps.htmlFor) || ((_a = ui.ReactUtils) == null ? void 0 : _a.getChildId(children));
5600
5601
  const labelEl = /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement("label", { className: styles.label, htmlFor: childInputId }, label, optional && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.optional }, " - optional"), tooltip && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { placement: "top", content: tooltip, theme: "info", interactive: tooltipInteractive }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { tabIndex: 0, name: "info-circle", size: "sm", className: styles.icon }))), /* @__PURE__ */ React__default.default.createElement(ui.Space, { v: 0.5 }));
5601
5602
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(ui.Field, { className: styles.field, label: labelEl, ...fieldProps }, children));
5602
5603
  };
5603
- const getStyles$p = (theme, width) => {
5604
+ const getStyles$r = (theme, width) => {
5604
5605
  return {
5605
5606
  root: css.css({
5606
5607
  minWidth: theme.spacing(width != null ? width : 0)
@@ -5628,10 +5629,10 @@ const getStyles$p = (theme, width) => {
5628
5629
  };
5629
5630
 
5630
5631
  const EditorRow$1 = ({ children }) => {
5631
- const styles = ui.useStyles2(getStyles$o);
5632
+ const styles = ui.useStyles2(getStyles$q);
5632
5633
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(EditorStack, { gap: 2 }, children));
5633
5634
  };
5634
- const getStyles$o = (theme) => {
5635
+ const getStyles$q = (theme) => {
5635
5636
  return {
5636
5637
  root: css.css({
5637
5638
  padding: theme.spacing(1),
@@ -5646,10 +5647,10 @@ const EditorRows$1 = ({ children }) => {
5646
5647
  };
5647
5648
 
5648
5649
  const EditorSwitch = (props) => {
5649
- const styles = getStyles$n();
5650
+ const styles = getStyles$p();
5650
5651
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.switch }, /* @__PURE__ */ React__default.default.createElement(ui.Switch, { ...props }));
5651
5652
  };
5652
- const getStyles$n = () => {
5653
+ const getStyles$p = () => {
5653
5654
  return {
5654
5655
  switch: css.css({
5655
5656
  display: "flex",
@@ -5707,10 +5708,10 @@ const getSelectStyles = (theme) => ({
5707
5708
  });
5708
5709
 
5709
5710
  const Space = ({ v = 0, h = 0, layout = "block" }) => {
5710
- const styles = ui.useStyles2(getStyles$m, v, h, layout);
5711
+ const styles = ui.useStyles2(getStyles$o, v, h, layout);
5711
5712
  return /* @__PURE__ */ React__default.default.createElement("span", { className: css.cx(styles.wrapper) });
5712
5713
  };
5713
- const getStyles$m = (theme, v, h, layout) => ({
5714
+ const getStyles$o = (theme, v, h, layout) => ({
5714
5715
  wrapper: css.css([
5715
5716
  {
5716
5717
  paddingRight: theme.spacing(h != null ? h : 0),
@@ -6322,7 +6323,7 @@ function RawEditor({
6322
6323
  language = "sql"
6323
6324
  }) {
6324
6325
  const theme = ui.useTheme2();
6325
- const styles = ui.useStyles2(getStyles$l);
6326
+ const styles = ui.useStyles2(getStyles$n);
6326
6327
  const [isExpanded, setIsExpanded] = React.useState(false);
6327
6328
  const [toolboxRef, toolboxMeasure] = reactUse.useMeasure();
6328
6329
  const [editorRef, editorMeasure] = reactUse.useMeasure();
@@ -6392,7 +6393,7 @@ function RawEditor({
6392
6393
  renderEditor(true)
6393
6394
  ));
6394
6395
  }
6395
- function getStyles$l(theme) {
6396
+ function getStyles$n(theme) {
6396
6397
  return {
6397
6398
  modal: css.css`
6398
6399
  width: 95vw;
@@ -6407,7 +6408,7 @@ function getStyles$l(theme) {
6407
6408
 
6408
6409
  function Preview({ rawSql, language = "sql" }) {
6409
6410
  const [_, copyToClipboard] = reactUse.useCopyToClipboard();
6410
- const styles = ui.useStyles2(getStyles$k);
6411
+ const styles = ui.useStyles2(getStyles$m);
6411
6412
  const labelElement = /* @__PURE__ */ React__default.default.createElement("div", { className: styles.labelWrapper }, /* @__PURE__ */ React__default.default.createElement("label", { className: styles.label }, "Preview"), /* @__PURE__ */ React__default.default.createElement(ui.IconButton, { tooltip: "Copy to clipboard", onClick: () => copyToClipboard(rawSql), name: "copy" }));
6412
6413
  return /* @__PURE__ */ React__default.default.createElement(ui.Field, { label: labelElement, className: styles.grow }, /* @__PURE__ */ React__default.default.createElement(
6413
6414
  ui.CodeEditor,
@@ -6421,7 +6422,7 @@ function Preview({ rawSql, language = "sql" }) {
6421
6422
  }
6422
6423
  ));
6423
6424
  }
6424
- function getStyles$k(theme) {
6425
+ function getStyles$m(theme) {
6425
6426
  return {
6426
6427
  grow: css.css({ flexGrow: 1 }),
6427
6428
  label: css.css({ fontSize: 12, fontWeight: theme.typography.fontWeightMedium }),
@@ -6540,7 +6541,7 @@ function SQLOrderByRow({ fields, query, onQueryChange, db }) {
6540
6541
  const asteriskValue = { label: "*", value: "*" };
6541
6542
  function SelectRow({ sql, columns, onSqlChange, functions }) {
6542
6543
  var _a;
6543
- const styles = ui.useStyles2(getStyles$j);
6544
+ const styles = ui.useStyles2(getStyles$l);
6544
6545
  const columnsWithAsterisk = [asteriskValue, ...columns || []];
6545
6546
  const onColumnChange = React.useCallback(
6546
6547
  (item, index) => (column) => {
@@ -6636,7 +6637,7 @@ function SelectRow({ sql, columns, onSqlChange, functions }) {
6636
6637
  }
6637
6638
  ));
6638
6639
  }
6639
- const getStyles$j = () => {
6640
+ const getStyles$l = () => {
6640
6641
  return { addButton: css.css({ alignSelf: "flex-start" }) };
6641
6642
  };
6642
6643
  function getColumnValue({ parameters }) {
@@ -6982,10 +6983,10 @@ function mapFieldsToTypes(columns) {
6982
6983
  }
6983
6984
 
6984
6985
  const EditorRow = ({ children }) => {
6985
- const styles = ui.useStyles2(getStyles$i);
6986
+ const styles = ui.useStyles2(getStyles$k);
6986
6987
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(EditorStack, { gap: 2 }, children));
6987
6988
  };
6988
- const getStyles$i = (theme) => {
6989
+ const getStyles$k = (theme) => {
6989
6990
  return {
6990
6991
  root: css.css({
6991
6992
  padding: theme.spacing(1),
@@ -6999,12 +7000,12 @@ const EditorField = (props) => {
6999
7000
  var _a;
7000
7001
  const { label, optional, tooltip, children, width, ...fieldProps } = props;
7001
7002
  const theme = ui.useTheme2();
7002
- const styles = getStyles$h(theme, width);
7003
+ const styles = getStyles$j(theme, width);
7003
7004
  const childInputId = (fieldProps == null ? void 0 : fieldProps.htmlFor) || ((_a = ui.ReactUtils) == null ? void 0 : _a.getChildId(children));
7004
7005
  const labelEl = /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, /* @__PURE__ */ React__default.default.createElement("label", { className: styles.label, htmlFor: childInputId }, label, optional && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.optional }, " - optional"), tooltip && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { placement: "top", content: tooltip, theme: "info" }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "sm", className: styles.icon }))), /* @__PURE__ */ React__default.default.createElement(Space, { v: 0.5 }));
7005
7006
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.root }, /* @__PURE__ */ React__default.default.createElement(ui.Field, { className: styles.field, label: labelEl, ...fieldProps }, children));
7006
7007
  };
7007
- const getStyles$h = ui.stylesFactory((theme, width) => {
7008
+ const getStyles$j = ui.stylesFactory((theme, width) => {
7008
7009
  return {
7009
7010
  root: css.css({
7010
7011
  minWidth: theme.spacing(width != null ? width : 0)
@@ -7067,20 +7068,20 @@ const MACRO_NAMES = [
7067
7068
  "$__unixEpochGroupAlias"
7068
7069
  ];
7069
7070
 
7070
- var __defProp$2 = Object.defineProperty;
7071
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7072
- var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
7071
+ var __defProp$3 = Object.defineProperty;
7072
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7073
+ var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
7073
7074
  class SqlDatasource extends runtime.DataSourceWithBackend {
7074
7075
  constructor(instanceSettings, templateSrv = runtime.getTemplateSrv()) {
7075
7076
  super(instanceSettings);
7076
7077
  this.templateSrv = templateSrv;
7077
- __publicField$2(this, "id");
7078
- __publicField$2(this, "name");
7079
- __publicField$2(this, "interval");
7080
- __publicField$2(this, "db");
7081
- __publicField$2(this, "dataset");
7082
- __publicField$2(this, "annotations", {});
7083
- __publicField$2(this, "interpolateVariable", (value, variable) => {
7078
+ __publicField$3(this, "id");
7079
+ __publicField$3(this, "name");
7080
+ __publicField$3(this, "interval");
7081
+ __publicField$3(this, "db");
7082
+ __publicField$3(this, "dataset");
7083
+ __publicField$3(this, "annotations", {});
7084
+ __publicField$3(this, "interpolateVariable", (value, variable) => {
7084
7085
  if (typeof value === "string") {
7085
7086
  if (variable.multi || variable.includeAll) {
7086
7087
  const result = this.getQueryModel().quoteLiteral(value);
@@ -7454,7 +7455,7 @@ const ConfigSubSection = ({ children, ...props }) => {
7454
7455
  function ConfigDescriptionLink(props) {
7455
7456
  const { description, suffix, feature } = props;
7456
7457
  const text = `Learn more about ${feature}`;
7457
- const styles = ui.useStyles2(getStyles$g);
7458
+ const styles = ui.useStyles2(getStyles$i);
7458
7459
  return /* @__PURE__ */ React__default.default.createElement("span", { className: styles.container }, description, /* @__PURE__ */ React__default.default.createElement(
7459
7460
  "a",
7460
7461
  {
@@ -7466,7 +7467,7 @@ function ConfigDescriptionLink(props) {
7466
7467
  text
7467
7468
  ));
7468
7469
  }
7469
- const getStyles$g = (theme) => {
7470
+ const getStyles$i = (theme) => {
7470
7471
  return {
7471
7472
  container: css.css({
7472
7473
  color: theme.colors.text.secondary,
@@ -8435,240 +8436,53 @@ const AdvancedHttpSettings = ({
8435
8436
  ));
8436
8437
  };
8437
8438
 
8438
- function resolveGroups(schema) {
8439
- const fieldMap = /* @__PURE__ */ new Map();
8440
- for (const f of schema.fields) {
8441
- fieldMap.set(f.id, f);
8442
- }
8443
- if (schema.groups && schema.groups.length > 0) {
8444
- return schema.groups.slice().sort((a, b) => {
8445
- var _a, _b;
8446
- return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
8447
- }).map((g) => ({
8448
- group: g,
8449
- fields: g.fieldRefs.map((ref) => fieldMap.get(ref)).filter((f) => f != null)
8450
- }));
8451
- }
8452
- const allFields = schema.fields.filter((f) => f.kind !== "virtual" && !f.isItemField);
8453
- return [
8454
- {
8455
- group: { id: "default", title: "Configuration", fieldRefs: allFields.map((f) => f.id) },
8456
- fields: allFields
8457
- }
8458
- ];
8439
+ const SECURE_FIELD_CONFIGURED = "__CONFIGURED__";
8440
+ function resolveSecureKeyTemplate(template, item, index) {
8441
+ return template.replace(/\{index1\}/g, String(index + 1)).replace(/\{index\}/g, String(index)).replace(/\{item\.(\w+)\}/g, (_, key) => {
8442
+ var _a;
8443
+ return String((_a = item[key]) != null ? _a : "");
8444
+ });
8459
8445
  }
8460
- function resolveRequiredFieldsGroup(schema) {
8461
- var _a;
8462
- const fieldMap = /* @__PURE__ */ new Map();
8463
- for (const f of schema.fields) {
8464
- fieldMap.set(f.id, f);
8465
- }
8466
- const requiredIds = /* @__PURE__ */ new Set();
8467
- for (const f of schema.fields) {
8468
- if (f.required) {
8469
- requiredIds.add(f.id);
8470
- }
8471
- }
8472
- const authGroup = (_a = schema.groups) == null ? void 0 : _a.find((g) => g.id === "auth");
8473
- if (authGroup) {
8474
- for (const ref of authGroup.fieldRefs) {
8475
- if (fieldMap.has(ref)) {
8476
- requiredIds.add(ref);
8477
- }
8478
- }
8479
- }
8480
- if (requiredIds.size === 0) {
8481
- return null;
8482
- }
8483
- const includeIds = /* @__PURE__ */ new Set();
8484
- for (const id of requiredIds) {
8485
- includeIds.add(id);
8486
- const f = fieldMap.get(id);
8487
- if (f == null ? void 0 : f.dependsOn) {
8488
- const parsed = parseDependsOn(f.dependsOn);
8489
- if (parsed && fieldMap.has(parsed.field)) {
8490
- includeIds.add(parsed.field);
8491
- }
8492
- }
8446
+ function evaluateItemCondition(condition, item) {
8447
+ const trimmed = condition.trim();
8448
+ if (trimmed === "true") {
8449
+ return true;
8493
8450
  }
8494
- for (const f of schema.fields) {
8495
- if (f.dependsOn && !includeIds.has(f.id)) {
8496
- const parsed = parseDependsOn(f.dependsOn);
8497
- if (parsed && requiredIds.has(parsed.field)) {
8498
- includeIds.add(f.id);
8499
- }
8500
- }
8451
+ const match = trimmed.match(/^item\.(\w+)\s*==\s*(.+)$/);
8452
+ if (!match) {
8453
+ return false;
8501
8454
  }
8502
- const virtualFields = schema.fields.filter((f) => includeIds.has(f.id));
8503
- if (virtualFields.length === 0) {
8504
- return null;
8455
+ const [, key, rawValue] = match;
8456
+ const actualValue = item[key];
8457
+ const expected = rawValue.trim();
8458
+ if (expected === "true") {
8459
+ return actualValue === true;
8505
8460
  }
8506
- return {
8507
- group: {
8508
- id: "_required",
8509
- title: "Required",
8510
- fieldRefs: virtualFields.map((f) => f.id)
8511
- },
8512
- fields: virtualFields
8513
- };
8514
- }
8515
- function formKey(field) {
8516
- return field.section ? `${field.section}.${field.key}` : field.key;
8517
- }
8518
- function parseDependsOn(expr) {
8519
- var _a, _b;
8520
- const m = expr.match(/^(.+?)\s*==\s*(?:'([^']*)'|"([^"]*)"|(.+))$/);
8521
- if (!m) {
8522
- return null;
8461
+ if (expected === "false") {
8462
+ return actualValue === false;
8523
8463
  }
8524
- return { field: m[1].trim(), value: ((_b = (_a = m[2]) != null ? _a : m[3]) != null ? _b : m[4]).trim() };
8464
+ const unquoted = expected.replace(/^['"]|['"]$/g, "");
8465
+ return String(actualValue) === unquoted;
8525
8466
  }
8526
- function resolveActiveOverride(field, watchedValues, fieldById) {
8527
- var _a;
8528
- if (!field.overrides || field.overrides.length === 0) {
8529
- return void 0;
8530
- }
8531
- for (const ov of field.overrides) {
8532
- const parsed = parseDependsOn(ov.when);
8533
- if (!parsed) {
8467
+ function findActiveSecureOverride(itemFields, item, index) {
8468
+ for (const field of itemFields) {
8469
+ if (!field.overrides) {
8534
8470
  continue;
8535
8471
  }
8536
- const depField = fieldById.get(parsed.field);
8537
- const depKey = depField ? formKey(depField) : parsed.field;
8538
- if (String((_a = watchedValues[depKey]) != null ? _a : "") === parsed.value) {
8539
- return ov;
8540
- }
8541
- }
8542
- return void 0;
8543
- }
8544
- function resolveFieldValue(ref, values, fields) {
8545
- if (ref in values) {
8546
- return values[ref];
8547
- }
8548
- const field = fields.find((f) => f.id === ref);
8549
- if (field) {
8550
- const fk = formKey(field);
8551
- if (fk in values) {
8552
- return values[fk];
8553
- }
8554
- }
8555
- return void 0;
8556
- }
8557
- function evaluateComputedRead(expr, values, fields) {
8558
- function evalExpr(s) {
8559
- var _a;
8560
- s = s.trim();
8561
- if (s.startsWith("(") && findMatchingParen(s, 0) === s.length - 1) {
8562
- s = s.slice(1, -1).trim();
8563
- }
8564
- const qIdx = findTopLevel(s, "?");
8565
- if (qIdx !== -1) {
8566
- const condition = s.slice(0, qIdx).trim();
8567
- const rest = s.slice(qIdx + 1);
8568
- const cIdx = findTopLevel(rest, ":");
8569
- if (cIdx !== -1) {
8570
- const trueExpr = rest.slice(0, cIdx).trim();
8571
- const falseExpr = rest.slice(cIdx + 1).trim();
8572
- return evalCondition(condition) ? evalExpr(trueExpr) : evalExpr(falseExpr);
8573
- }
8574
- }
8575
- const strMatch = (_a = s.match(/^'([^']*)'$/)) != null ? _a : s.match(/^"([^"]*)"$/);
8576
- if (strMatch) {
8577
- return strMatch[1];
8578
- }
8579
- if (s === "true") {
8580
- return true;
8581
- }
8582
- if (s === "false") {
8583
- return false;
8584
- }
8585
- if (/^-?\d+(\.\d+)?$/.test(s)) {
8586
- return Number(s);
8587
- }
8588
- return resolveFieldValue(s, values, fields);
8589
- }
8590
- function evalCondition(cond) {
8591
- const eqMatch = cond.match(/^(.+?)\s*(==|!=)\s*(.+)$/);
8592
- if (eqMatch) {
8593
- const left = evalExpr(eqMatch[1]);
8594
- const right = evalExpr(eqMatch[3]);
8595
- const eq = String(left) === String(right);
8596
- return eqMatch[2] === "==" ? eq : !eq;
8597
- }
8598
- return !!evalExpr(cond);
8599
- }
8600
- function findMatchingParen(s, start) {
8601
- let depth = 0;
8602
- for (let i = start; i < s.length; i++) {
8603
- if (s[i] === "(") {
8604
- depth++;
8605
- } else if (s[i] === ")") {
8606
- depth--;
8607
- if (depth === 0) {
8608
- return i;
8609
- }
8610
- }
8611
- }
8612
- return -1;
8613
- }
8614
- function findTopLevel(s, char) {
8615
- let depth = 0;
8616
- let inStr = null;
8617
- for (let i = 0; i < s.length; i++) {
8618
- const c = s[i];
8619
- if (inStr) {
8620
- if (c === inStr) {
8621
- inStr = null;
8622
- }
8623
- continue;
8624
- }
8625
- if (c === "'" || c === '"') {
8626
- inStr = c;
8627
- continue;
8628
- }
8629
- if (c === "(") {
8630
- depth++;
8472
+ for (const override of field.overrides) {
8473
+ if (!override.secureKey) {
8631
8474
  continue;
8632
8475
  }
8633
- if (c === ")") {
8634
- depth--;
8635
- continue;
8636
- }
8637
- if (depth === 0 && c === char) {
8638
- return i;
8639
- }
8640
- }
8641
- return -1;
8642
- }
8643
- try {
8644
- return evalExpr(expr);
8645
- } catch (e) {
8646
- return void 0;
8647
- }
8648
- }
8649
- function computeVirtualFieldValues(schema, existingValues) {
8650
- var _a;
8651
- const virtualValues = {};
8652
- for (const field of schema.fields) {
8653
- if (field.kind !== "virtual") {
8654
- continue;
8655
- }
8656
- const fk = formKey(field);
8657
- if (((_a = field.storage) == null ? void 0 : _a.type) === "computed" && field.storage.read) {
8658
- const val = evaluateComputedRead(field.storage.read, existingValues, schema.fields);
8659
- if (val !== void 0) {
8660
- virtualValues[fk] = val;
8661
- } else if (field.defaultValue !== void 0) {
8662
- virtualValues[fk] = field.defaultValue;
8476
+ if (evaluateItemCondition(override.when, item)) {
8477
+ return {
8478
+ fieldKey: field.key,
8479
+ resolvedKey: resolveSecureKeyTemplate(override.secureKey, item, index)
8480
+ };
8663
8481
  }
8664
- } else if (field.defaultValue !== void 0) {
8665
- virtualValues[fk] = field.defaultValue;
8666
8482
  }
8667
8483
  }
8668
- return virtualValues;
8484
+ return null;
8669
8485
  }
8670
-
8671
- const SECURE_FIELD_CONFIGURED = "__CONFIGURED__";
8672
8486
  function patternToRegex(pattern) {
8673
8487
  const escaped = pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8674
8488
  return new RegExp("^" + escaped.replace("\\{index\\}", "(\\d+)") + "$");
@@ -8775,7 +8589,7 @@ function resolveRawPath(ref, ds) {
8775
8589
  return void 0;
8776
8590
  }
8777
8591
  async function fetchExistingValues(dsUid, fields) {
8778
- var _a, _b, _c, _d, _e;
8592
+ var _a, _b, _c, _d, _e, _f;
8779
8593
  try {
8780
8594
  const ds = await runtime.getBackendSrv().get(`/api/datasources/uid/${dsUid}`, void 0, void 0, {
8781
8595
  showErrorAlert: false
@@ -8786,7 +8600,7 @@ async function fetchExistingValues(dsUid, fields) {
8786
8600
  values[field.key] = expandIndexedPair(field, ds);
8787
8601
  continue;
8788
8602
  }
8789
- const fk = formKey(field);
8603
+ const fk = useDatasourceSchema.formKey(field);
8790
8604
  switch (field.target) {
8791
8605
  case "root":
8792
8606
  if (ds[field.key] !== void 0) {
@@ -8816,6 +8630,32 @@ async function fetchExistingValues(dsUid, fields) {
8816
8630
  }
8817
8631
  }
8818
8632
  }
8633
+ for (const field of fields) {
8634
+ if (field.valueType !== "array" || !((_f = field.item) == null ? void 0 : _f.fields)) {
8635
+ continue;
8636
+ }
8637
+ const itemFields = field.item.fields;
8638
+ const hasSecureOverride = itemFields.some((f) => {
8639
+ var _a2;
8640
+ return (_a2 = f.overrides) == null ? void 0 : _a2.some((o) => o.secureKey);
8641
+ });
8642
+ if (!hasSecureOverride) {
8643
+ continue;
8644
+ }
8645
+ const fk = useDatasourceSchema.formKey(field);
8646
+ const arr = values[fk];
8647
+ if (!Array.isArray(arr)) {
8648
+ continue;
8649
+ }
8650
+ values[fk] = arr.map((item, idx) => {
8651
+ var _a2;
8652
+ const match = findActiveSecureOverride(itemFields, item, idx);
8653
+ if (match && ((_a2 = ds.secureJsonFields) == null ? void 0 : _a2[match.resolvedKey])) {
8654
+ return { ...item, [match.fieldKey]: SECURE_FIELD_CONFIGURED };
8655
+ }
8656
+ return item;
8657
+ });
8658
+ }
8819
8659
  return { values, readOnly: !!ds.readOnly };
8820
8660
  } catch (err) {
8821
8661
  const message = err instanceof Error ? err.message : "Failed to load datasource configuration";
@@ -8823,7 +8663,7 @@ async function fetchExistingValues(dsUid, fields) {
8823
8663
  }
8824
8664
  }
8825
8665
  function buildDatasourceConfigPayload(data, fields, existing, isFieldVisible) {
8826
- var _a, _b, _c, _d;
8666
+ var _a, _b, _c, _d, _e, _f, _g, _h;
8827
8667
  const rootFields = {};
8828
8668
  const jsonData = { ...(_a = existing.jsonData) != null ? _a : {} };
8829
8669
  const secureJsonData = {};
@@ -8838,7 +8678,7 @@ function buildDatasourceConfigPayload(data, fields, existing, isFieldVisible) {
8838
8678
  if (!isManagedByEffect && !isFieldVisible(field)) {
8839
8679
  continue;
8840
8680
  }
8841
- const fk = formKey(field);
8681
+ const fk = useDatasourceSchema.formKey(field);
8842
8682
  const value = data[fk];
8843
8683
  if (field.target === "secureJsonData") {
8844
8684
  if (value === SECURE_FIELD_CONFIGURED) {
@@ -8872,6 +8712,60 @@ function buildDatasourceConfigPayload(data, fields, existing, isFieldVisible) {
8872
8712
  break;
8873
8713
  }
8874
8714
  }
8715
+ for (const field of fields) {
8716
+ if (field.valueType !== "array" || !((_e = field.item) == null ? void 0 : _e.fields) || field.target !== "jsonData") {
8717
+ continue;
8718
+ }
8719
+ const itemFields = field.item.fields;
8720
+ const hasSecureOverride = itemFields.some((f) => {
8721
+ var _a2;
8722
+ return (_a2 = f.overrides) == null ? void 0 : _a2.some((o) => o.secureKey);
8723
+ });
8724
+ if (!hasSecureOverride) {
8725
+ continue;
8726
+ }
8727
+ const arr = field.section ? (_f = jsonData[field.section]) == null ? void 0 : _f[field.key] : jsonData[field.key];
8728
+ if (!Array.isArray(arr)) {
8729
+ continue;
8730
+ }
8731
+ const secureKeyOverrides = [];
8732
+ for (const f of itemFields) {
8733
+ for (const o of (_g = f.overrides) != null ? _g : []) {
8734
+ if (o.secureKey) {
8735
+ secureKeyOverrides.push({ fieldKey: f.key, override: o });
8736
+ }
8737
+ }
8738
+ }
8739
+ const activeSecureKeys = /* @__PURE__ */ new Set();
8740
+ for (let i = 0; i < arr.length; i++) {
8741
+ const item = arr[i];
8742
+ const match = findActiveSecureOverride(itemFields, item, i);
8743
+ if (!match) {
8744
+ continue;
8745
+ }
8746
+ const resolvedKey = match.resolvedKey;
8747
+ activeSecureKeys.add(resolvedKey);
8748
+ const itemValue = item[match.fieldKey];
8749
+ if (itemValue === SECURE_FIELD_CONFIGURED) {
8750
+ secureJsonFields[resolvedKey] = true;
8751
+ } else if (itemValue && itemValue !== "") {
8752
+ secureJsonData[resolvedKey] = String(itemValue);
8753
+ secureJsonFields[resolvedKey] = false;
8754
+ item[match.fieldKey] = "";
8755
+ }
8756
+ }
8757
+ const existingSecureFields = (_h = existing.secureJsonFields) != null ? _h : {};
8758
+ for (const existingKey of Object.keys(existingSecureFields)) {
8759
+ const couldBeFromThisField = secureKeyOverrides.some((sko) => {
8760
+ const staticPrefix = sko.override.secureKey.split("{")[0];
8761
+ return staticPrefix && existingKey.startsWith(staticPrefix);
8762
+ });
8763
+ if (couldBeFromThisField && !activeSecureKeys.has(existingKey)) {
8764
+ secureJsonFields[existingKey] = false;
8765
+ secureJsonData[existingKey] = "";
8766
+ }
8767
+ }
8768
+ }
8875
8769
  return { rootFields, jsonData, secureJsonData, secureJsonFields };
8876
8770
  }
8877
8771
  async function submitDatasourceConfig(dsUid, data, fields, isFieldVisible) {
@@ -8909,23 +8803,25 @@ function evaluateEffectCondition(when, fieldValue) {
8909
8803
  const eq = String(fieldValue) === String(target);
8910
8804
  return op === "==" ? eq : !eq;
8911
8805
  }
8912
- function isFieldRequired(field, watchedValues, fieldById) {
8913
- var _a;
8806
+ function isFieldRequired(field, watchedValues, fieldById, celContext) {
8914
8807
  if (field.required) {
8915
8808
  return true;
8916
8809
  }
8917
8810
  if (field.requiredWhen) {
8918
- const parsed = parseDependsOn(field.requiredWhen);
8811
+ if (celContext) {
8812
+ return useDatasourceSchema.evaluateCelExpression(field.requiredWhen, celContext);
8813
+ }
8814
+ const parsed = useDatasourceSchema.parseDependsOn(field.requiredWhen);
8919
8815
  if (parsed) {
8920
8816
  const depField = fieldById.get(parsed.field);
8921
- const depKey = depField ? formKey(depField) : parsed.field;
8922
- return String((_a = watchedValues[depKey]) != null ? _a : "") === parsed.value;
8817
+ const depKey = depField ? useDatasourceSchema.formKey(depField) : parsed.field;
8818
+ return useDatasourceSchema.evaluateDependsOn(parsed, useDatasourceSchema.getWatchedValue(watchedValues, depKey));
8923
8819
  }
8924
8820
  }
8925
8821
  return false;
8926
8822
  }
8927
8823
  function buildValidationRules(field, required) {
8928
- var _a, _b, _c, _d, _e, _f;
8824
+ var _a, _b, _c, _d, _e, _f, _g, _h;
8929
8825
  const rules = {};
8930
8826
  const label = (_a = field.label) != null ? _a : field.key;
8931
8827
  if (required) {
@@ -8943,29 +8839,65 @@ function buildValidationRules(field, required) {
8943
8839
  rules.required = `${label} is required`;
8944
8840
  }
8945
8841
  }
8842
+ if (field.valueType === "array" && ((_b = field.item) == null ? void 0 : _b.valueType) === "object" && ((_c = field.item.fields) == null ? void 0 : _c.length)) {
8843
+ const requiredItemFields = field.item.fields.filter((f) => f.required);
8844
+ if (requiredItemFields.length > 0) {
8845
+ const existingValidate = rules.validate;
8846
+ rules.validate = (value) => {
8847
+ var _a2;
8848
+ if (existingValidate) {
8849
+ const r = existingValidate(value);
8850
+ if (r !== true) {
8851
+ return r;
8852
+ }
8853
+ }
8854
+ if (!Array.isArray(value)) {
8855
+ return true;
8856
+ }
8857
+ const itemErrors = {};
8858
+ for (let i = 0; i < value.length; i++) {
8859
+ const item = value[i];
8860
+ const missing = [];
8861
+ for (const rf of requiredItemFields) {
8862
+ const v = item[rf.key];
8863
+ if (v === void 0 || v === null || v === "") {
8864
+ missing.push((_a2 = rf.label) != null ? _a2 : rf.key);
8865
+ }
8866
+ }
8867
+ if (missing.length > 0) {
8868
+ itemErrors[i] = `${missing.join(", ")} required`;
8869
+ }
8870
+ }
8871
+ if (Object.keys(itemErrors).length === 0) {
8872
+ return true;
8873
+ }
8874
+ return `__ITEM_ERRORS__${JSON.stringify(itemErrors)}`;
8875
+ };
8876
+ }
8877
+ }
8946
8878
  if (field.validations) {
8947
8879
  for (const v of field.validations) {
8948
8880
  switch (v.type) {
8949
8881
  case "pattern":
8950
8882
  rules.pattern = {
8951
8883
  value: new RegExp(v.pattern),
8952
- message: (_b = v.message) != null ? _b : `Invalid ${label}`
8884
+ message: (_d = v.message) != null ? _d : `Invalid ${label}`
8953
8885
  };
8954
8886
  break;
8955
8887
  case "range":
8956
8888
  if (v.min !== void 0) {
8957
- rules.min = { value: v.min, message: (_c = v.message) != null ? _c : `Minimum value is ${v.min}` };
8889
+ rules.min = { value: v.min, message: (_e = v.message) != null ? _e : `Minimum value is ${v.min}` };
8958
8890
  }
8959
8891
  if (v.max !== void 0) {
8960
- rules.max = { value: v.max, message: (_d = v.message) != null ? _d : `Maximum value is ${v.max}` };
8892
+ rules.max = { value: v.max, message: (_f = v.message) != null ? _f : `Maximum value is ${v.max}` };
8961
8893
  }
8962
8894
  break;
8963
8895
  case "length":
8964
8896
  if (v.min !== void 0) {
8965
- rules.minLength = { value: v.min, message: (_e = v.message) != null ? _e : `Minimum length is ${v.min}` };
8897
+ rules.minLength = { value: v.min, message: (_g = v.message) != null ? _g : `Minimum length is ${v.min}` };
8966
8898
  }
8967
8899
  if (v.max !== void 0) {
8968
- rules.maxLength = { value: v.max, message: (_f = v.message) != null ? _f : `Maximum length is ${v.max}` };
8900
+ rules.maxLength = { value: v.max, message: (_h = v.message) != null ? _h : `Maximum length is ${v.max}` };
8969
8901
  }
8970
8902
  break;
8971
8903
  }
@@ -8973,16 +8905,24 @@ function buildValidationRules(field, required) {
8973
8905
  }
8974
8906
  return rules;
8975
8907
  }
8908
+ const ITEM_ERRORS_PREFIX = "__ITEM_ERRORS__";
8909
+ function parseItemErrors(errorMessage) {
8910
+ if (!errorMessage || !errorMessage.startsWith(ITEM_ERRORS_PREFIX)) {
8911
+ return null;
8912
+ }
8913
+ try {
8914
+ return JSON.parse(errorMessage.slice(ITEM_ERRORS_PREFIX.length));
8915
+ } catch (e) {
8916
+ return null;
8917
+ }
8918
+ }
8976
8919
 
8977
- function PdcFieldNote({
8978
- enabled,
8979
- description,
8980
- configUrl
8981
- }) {
8982
- const styles = ui.useStyles2(getStyles$f);
8920
+ const PdcFieldNote = (props) => {
8921
+ const { enabled, description, configUrl } = props;
8922
+ const styles = ui.useStyles2(getStyles$h);
8983
8923
  return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.wrapper }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.note }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "shield", size: "xs" }), /* @__PURE__ */ React__default.default.createElement("span", null, "Private data source connect: ", /* @__PURE__ */ React__default.default.createElement("strong", null, enabled ? "Enabled" : "Disabled")), description && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: description }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs" }))), /* @__PURE__ */ React__default.default.createElement(ui.LinkButton, { variant: "secondary", size: "sm", icon: "external-link-alt", href: configUrl }, "Configure in settings"));
8984
- }
8985
- const getStyles$f = (theme) => ({
8924
+ };
8925
+ const getStyles$h = (theme) => ({
8986
8926
  wrapper: css.css({
8987
8927
  display: "flex",
8988
8928
  alignItems: "center",
@@ -9002,18 +8942,14 @@ const getStyles$f = (theme) => ({
9002
8942
  })
9003
8943
  });
9004
8944
 
9005
- function SecureFieldInput({
9006
- formField,
9007
- placeholder,
9008
- disabled,
9009
- label
9010
- }) {
8945
+ function SecureFieldInput(props) {
9011
8946
  var _a;
8947
+ const { formField, placeholder, disabled } = props;
9012
8948
  const isConfigured = formField.value === SECURE_FIELD_CONFIGURED;
9013
8949
  const [revealed, setRevealed] = React.useState(false);
9014
8950
  const styles = ui.useStyles2(getSecureFieldStyles);
9015
8951
  if (isConfigured) {
9016
- return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.configuredRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.configuredBadge }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "lock", size: "xs" }), label, " configured"), !disabled && /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", fill: "text", size: "sm", onClick: () => formField.onChange(""), type: "button" }, "Reset"));
8952
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.configuredRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.configuredBadge }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "lock", size: "xs" }), "Configured"), !disabled && /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", fill: "text", size: "sm", onClick: () => formField.onChange(""), type: "button" }, "Reset"));
9017
8953
  }
9018
8954
  return /* @__PURE__ */ React__default.default.createElement(
9019
8955
  ui.Input,
@@ -9042,7 +8978,8 @@ const getSecureFieldStyles = (theme) => ({
9042
8978
  configuredRow: css.css({
9043
8979
  display: "flex",
9044
8980
  alignItems: "center",
9045
- gap: theme.spacing(1)
8981
+ gap: theme.spacing(1),
8982
+ whiteSpace: "nowrap"
9046
8983
  }),
9047
8984
  configuredBadge: css.css({
9048
8985
  display: "inline-flex",
@@ -9052,108 +8989,180 @@ const getSecureFieldStyles = (theme) => ({
9052
8989
  borderRadius: theme.shape.radius.pill,
9053
8990
  backgroundColor: theme.colors.success.transparent,
9054
8991
  color: theme.colors.success.text,
9055
- fontSize: theme.typography.bodySmall.fontSize
8992
+ fontSize: theme.typography.bodySmall.fontSize,
8993
+ whiteSpace: "nowrap"
9056
8994
  })
9057
8995
  });
9058
8996
 
9059
- function StringArrayInput({
9060
- value,
9061
- onChange,
9062
- placeholder,
9063
- disabled
9064
- }) {
9065
- const [draft, setDraft] = React.useState("");
8997
+ const ComplexFieldNote = (props) => {
8998
+ const { count, label } = props;
8999
+ const styles = ui.useStyles2(getStyles$g);
9000
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.note }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs" }), /* @__PURE__ */ React__default.default.createElement("span", null, count > 0 ? `${count} ${label.toLowerCase()} configured.` : `No ${label.toLowerCase()} configured.`, " Configure in Grafana UI."));
9001
+ };
9002
+ const getStyles$g = (theme) => ({
9003
+ note: css.css({
9004
+ display: "inline-flex",
9005
+ alignItems: "center",
9006
+ gap: theme.spacing(0.5),
9007
+ padding: `${theme.spacing(0.5)} ${theme.spacing(0.75)}`,
9008
+ fontSize: theme.typography.bodySmall.fontSize,
9009
+ color: theme.colors.text.secondary,
9010
+ backgroundColor: theme.colors.background.secondary,
9011
+ borderRadius: theme.shape.radius.default,
9012
+ border: `1px solid ${theme.colors.border.weak}`
9013
+ })
9014
+ });
9015
+
9016
+ function FileUploadField(props) {
9017
+ var _a, _b, _c, _d, _e, _f, _g;
9018
+ const { field, formField, disabled, setValue } = props;
9019
+ const [mode, setModeLocal] = React.useState("upload");
9020
+ const [error, setError] = React.useState(null);
9021
+ const theme = ui.useTheme2();
9022
+ const mapping = (_a = field.ui) == null ? void 0 : _a.fileMapping;
9023
+ const accept = (_c = (_b = field.ui) == null ? void 0 : _b.accept) != null ? _c : [".json"];
9024
+ const setMode = React.useCallback(
9025
+ (next) => {
9026
+ setModeLocal(next);
9027
+ formField.onChange(next);
9028
+ },
9029
+ [formField]
9030
+ );
9031
+ const processJson = React.useCallback(
9032
+ (text) => {
9033
+ const fileMapping = mapping != null ? mapping : {};
9034
+ try {
9035
+ const parsed = JSON.parse(text);
9036
+ if (typeof parsed !== "object" || parsed === null) {
9037
+ setError("Invalid JSON object");
9038
+ return;
9039
+ }
9040
+ const requiredKeys = Object.keys(fileMapping);
9041
+ const missingKeys = requiredKeys.filter((k) => parsed[k] === void 0);
9042
+ if (missingKeys.length > 0) {
9043
+ setError(`Missing keys: ${missingKeys.join(", ")}`);
9044
+ return;
9045
+ }
9046
+ for (const [jsonKey, targetFieldId] of Object.entries(fileMapping)) {
9047
+ if (parsed[jsonKey] !== void 0) {
9048
+ const parts = targetFieldId.split(".");
9049
+ const fk = parts.length === 2 ? parts[1] : targetFieldId;
9050
+ setValue(fk, parsed[jsonKey]);
9051
+ }
9052
+ }
9053
+ setError(null);
9054
+ setModeLocal("manual");
9055
+ formField.onChange("manual");
9056
+ } catch (e) {
9057
+ setError("Invalid JSON");
9058
+ }
9059
+ },
9060
+ [mapping, setValue, formField]
9061
+ );
9062
+ const styles = getStyles$f(theme);
9063
+ if (mode === "manual") {
9064
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttonRow }, /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("paste"), disabled }, "Paste JWT Token"), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.separator }, "or"), /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("upload"), disabled }, "Upload JWT Token"));
9065
+ }
9066
+ if (mode === "paste") {
9067
+ return /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(
9068
+ ui.TextArea,
9069
+ {
9070
+ placeholder: (_e = (_d = field.ui) == null ? void 0 : _d.placeholder) != null ? _e : "Paste Google JWT token here",
9071
+ rows: (_g = (_f = field.ui) == null ? void 0 : _f.rows) != null ? _g : 10,
9072
+ onBlur: (e) => {
9073
+ const val = e.currentTarget.value;
9074
+ if (val.trim()) {
9075
+ processJson(val);
9076
+ }
9077
+ },
9078
+ disabled
9079
+ }
9080
+ ), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttonRow }, /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("upload"), disabled }, "Upload JWT Token"), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.separator }, "or"), /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("manual"), disabled }, "Fill In JWT Token manually")), error && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.error }, error));
9081
+ }
9082
+ return /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(
9083
+ ui.FileDropzone,
9084
+ {
9085
+ options: { multiple: false, accept: accept.join(",") },
9086
+ readAs: "readAsText",
9087
+ onLoad: (result) => {
9088
+ if (typeof result === "string") {
9089
+ processJson(result);
9090
+ }
9091
+ }
9092
+ }
9093
+ ), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttonRow }, /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("paste"), disabled }, "Paste JWT Token"), /* @__PURE__ */ React__default.default.createElement("span", { className: styles.separator }, "or"), /* @__PURE__ */ React__default.default.createElement(ui.Button, { type: "button", fill: "outline", size: "sm", onClick: () => setMode("manual"), disabled }, "Fill In JWT Token manually")), error && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.error }, error));
9094
+ }
9095
+ function getStyles$f(theme) {
9096
+ return {
9097
+ buttonRow: css.css({
9098
+ marginTop: theme.spacing(1),
9099
+ display: "flex",
9100
+ alignItems: "center",
9101
+ gap: theme.spacing(0.5)
9102
+ }),
9103
+ separator: css.css({
9104
+ padding: `0 ${theme.spacing(0.5)}`,
9105
+ color: theme.colors.text.secondary
9106
+ }),
9107
+ error: css.css({
9108
+ color: theme.colors.error.text,
9109
+ fontSize: theme.typography.bodySmall.fontSize,
9110
+ marginTop: theme.spacing(0.5),
9111
+ display: "block"
9112
+ })
9113
+ };
9114
+ }
9115
+
9116
+ const IndexedPairEditor = (props) => {
9117
+ const { value, onChange, maxItems = 10, disabled, hideControls, itemLabel = "header" } = props;
9066
9118
  const styles = ui.useStyles2(getStyles$e);
9067
- const addTag = () => {
9068
- const trimmed = draft.trim();
9069
- if (trimmed && !value.includes(trimmed)) {
9070
- onChange([...value, trimmed]);
9119
+ const items = Array.isArray(value) ? value : [];
9120
+ const addItem = () => {
9121
+ if (items.length >= maxItems) {
9122
+ return;
9071
9123
  }
9072
- setDraft("");
9124
+ onChange([...items, { index: 0, name: "", value: "" }]);
9125
+ };
9126
+ const removeItem = (index) => {
9127
+ onChange(items.filter((_, i) => i !== index));
9073
9128
  };
9074
- const removeTag = (tag) => {
9075
- onChange(value.filter((v) => v !== tag));
9129
+ const updateItem = (index, key, val) => {
9130
+ const updated = items.map((item, i) => i === index ? { ...item, [key]: val } : item);
9131
+ onChange(updated);
9076
9132
  };
9077
- return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.container }, value.length > 0 && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.tags }, value.map((tag) => /* @__PURE__ */ React__default.default.createElement("span", { key: tag, className: styles.tag }, tag, !disabled && /* @__PURE__ */ React__default.default.createElement(
9078
- "button",
9133
+ return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 0.5 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(
9134
+ IndexedPairRow,
9079
9135
  {
9080
- type: "button",
9081
- className: styles.tagRemove,
9082
- onClick: () => removeTag(tag),
9083
- "aria-label": `Remove ${tag}`
9084
- },
9085
- /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "times", size: "xs" })
9086
- )))), /* @__PURE__ */ React__default.default.createElement(
9136
+ key: item.index || `new-${i}`,
9137
+ item,
9138
+ index: i,
9139
+ disabled,
9140
+ onUpdate: updateItem,
9141
+ onRemove: removeItem,
9142
+ hideControls,
9143
+ itemLabel
9144
+ }
9145
+ )), !hideControls && items.length < maxItems && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", size: "sm", icon: "plus", disabled, onClick: addItem, type: "button" }, "Add ", itemLabel)), !hideControls && items.length >= maxItems && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.limitNote }, "Maximum ", maxItems, " ", itemLabel, "s reached"));
9146
+ };
9147
+ const IndexedPairRow = (props) => {
9148
+ const { item, index, disabled, onUpdate, onRemove, hideControls, itemLabel = "header" } = props;
9149
+ const styles = ui.useStyles2(getStyles$e);
9150
+ const secureStyles = ui.useStyles2(getSecureFieldStyles);
9151
+ const isConfigured = item.value === SECURE_FIELD_CONFIGURED;
9152
+ const [editing, setEditing] = React.useState(false);
9153
+ const [revealed, setRevealed] = React.useState(false);
9154
+ return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "row", gap: 1 }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.inputCell }, /* @__PURE__ */ React__default.default.createElement(
9087
9155
  ui.Input,
9088
9156
  {
9089
- value: draft,
9090
- onChange: (e) => setDraft(e.currentTarget.value),
9157
+ value: item.name,
9158
+ placeholder: "key",
9159
+ disabled: disabled || hideControls,
9160
+ onChange: (e) => onUpdate(index, "name", e.currentTarget.value),
9091
9161
  onKeyDown: (e) => {
9092
9162
  if (e.key === "Enter") {
9093
9163
  e.preventDefault();
9094
- addTag();
9095
9164
  }
9096
- },
9097
- onBlur: addTag,
9098
- placeholder,
9099
- disabled
9100
- }
9101
- ));
9102
- }
9103
- const getStyles$e = (theme) => ({
9104
- container: css.css({
9105
- display: "flex",
9106
- flexDirection: "column",
9107
- gap: theme.spacing(0.5)
9108
- }),
9109
- tags: css.css({
9110
- display: "flex",
9111
- flexWrap: "wrap",
9112
- gap: theme.spacing(0.5)
9113
- }),
9114
- tag: css.css({
9115
- display: "inline-flex",
9116
- alignItems: "center",
9117
- gap: theme.spacing(0.25),
9118
- padding: `${theme.spacing(0.25)} ${theme.spacing(0.75)}`,
9119
- borderRadius: theme.shape.radius.pill,
9120
- backgroundColor: theme.colors.background.secondary,
9121
- border: `1px solid ${theme.colors.border.weak}`,
9122
- fontSize: theme.typography.bodySmall.fontSize,
9123
- color: theme.colors.text.primary
9124
- }),
9125
- tagRemove: css.css({
9126
- display: "inline-flex",
9127
- alignItems: "center",
9128
- padding: 0,
9129
- border: "none",
9130
- backgroundColor: "transparent",
9131
- cursor: "pointer",
9132
- color: theme.colors.text.secondary,
9133
- "&:hover": { color: theme.colors.text.primary }
9134
- })
9135
- });
9136
-
9137
- function IndexedPairRow({
9138
- item,
9139
- index,
9140
- disabled,
9141
- onUpdate,
9142
- onRemove,
9143
- hideControls
9144
- }) {
9145
- const styles = ui.useStyles2(getStyles$d);
9146
- const secureStyles = ui.useStyles2(getSecureFieldStyles);
9147
- const isConfigured = item.value === SECURE_FIELD_CONFIGURED;
9148
- const [editing, setEditing] = React.useState(false);
9149
- const [revealed, setRevealed] = React.useState(false);
9150
- return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "row", gap: 1 }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.inputCell }, /* @__PURE__ */ React__default.default.createElement(
9151
- ui.Input,
9152
- {
9153
- value: item.name,
9154
- placeholder: "Header name",
9155
- disabled: disabled || hideControls,
9156
- onChange: (e) => onUpdate(index, "name", e.currentTarget.value)
9165
+ }
9157
9166
  }
9158
9167
  )), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.inputCell }, isConfigured && !editing ? /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "row", gap: 1, alignItems: "center" }, /* @__PURE__ */ React__default.default.createElement("span", { className: secureStyles.configuredBadge }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "lock", size: "xs" }), "Configured"), !disabled && /* @__PURE__ */ React__default.default.createElement(
9159
9168
  ui.Button,
@@ -9172,10 +9181,15 @@ function IndexedPairRow({
9172
9181
  ui.Input,
9173
9182
  {
9174
9183
  value: item.value === SECURE_FIELD_CONFIGURED ? "" : item.value,
9175
- placeholder: "Header value",
9184
+ placeholder: `${itemLabel} value`,
9176
9185
  disabled,
9177
9186
  type: revealed ? "text" : "password",
9178
9187
  onChange: (e) => onUpdate(index, "value", e.currentTarget.value),
9188
+ onKeyDown: (e) => {
9189
+ if (e.key === "Enter") {
9190
+ e.preventDefault();
9191
+ }
9192
+ },
9179
9193
  suffix: /* @__PURE__ */ React__default.default.createElement(
9180
9194
  ui.Button,
9181
9195
  {
@@ -9189,34 +9203,56 @@ function IndexedPairRow({
9189
9203
  }
9190
9204
  )
9191
9205
  }
9192
- )), !hideControls && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: "Remove header" }, /* @__PURE__ */ React__default.default.createElement(
9206
+ )), !hideControls && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: `Remove ${itemLabel}` }, /* @__PURE__ */ React__default.default.createElement(
9193
9207
  ui.Button,
9194
9208
  {
9195
9209
  variant: "secondary",
9196
9210
  fill: "text",
9197
9211
  size: "sm",
9198
9212
  icon: "trash-alt",
9199
- "aria-label": "Remove header",
9213
+ "aria-label": `Remove ${itemLabel}`,
9200
9214
  disabled,
9201
9215
  onClick: () => onRemove(index),
9202
9216
  type: "button"
9203
9217
  }
9204
9218
  )));
9205
- }
9206
- function IndexedPairEditor({
9207
- value,
9208
- onChange,
9209
- maxItems = 10,
9210
- disabled,
9211
- hideControls
9212
- }) {
9219
+ };
9220
+ const getStyles$e = (theme) => ({
9221
+ inputCell: css.css({
9222
+ flex: "1 1 0",
9223
+ minWidth: 0,
9224
+ overflow: "hidden"
9225
+ }),
9226
+ limitNote: css.css({
9227
+ fontSize: theme.typography.bodySmall.fontSize,
9228
+ color: theme.colors.text.secondary
9229
+ })
9230
+ });
9231
+
9232
+ function ObjectArrayEditor(props) {
9233
+ var _a, _b, _c, _d, _e, _f;
9234
+ const { field, value, onChange, disabled, errorMessage } = props;
9213
9235
  const styles = ui.useStyles2(getStyles$d);
9236
+ const itemFields = (_b = (_a = field.item) == null ? void 0 : _a.fields) != null ? _b : [];
9237
+ const layoutRows = computeLayoutRows(itemFields);
9214
9238
  const items = Array.isArray(value) ? value : [];
9239
+ const maxItems = (_e = (_d = (_c = field.validations) == null ? void 0 : _c.find((v) => v.type === "itemCount")) == null ? void 0 : _d.max) != null ? _e : 20;
9240
+ const label = (_f = field.label) != null ? _f : field.key;
9241
+ const itemErrors = parseItemErrors(errorMessage);
9215
9242
  const addItem = () => {
9243
+ var _a2, _b2;
9216
9244
  if (items.length >= maxItems) {
9217
9245
  return;
9218
9246
  }
9219
- onChange([...items, { index: 0, name: "", value: "" }]);
9247
+ const empty = {};
9248
+ for (const f of itemFields) {
9249
+ if (f.valueType === "boolean") {
9250
+ empty[f.key] = (_a2 = f.defaultValue) != null ? _a2 : false;
9251
+ } else {
9252
+ empty[f.key] = (_b2 = f.defaultValue) != null ? _b2 : "";
9253
+ }
9254
+ }
9255
+ onChange([...items, empty]);
9220
9256
  };
9221
9257
  const removeItem = (index) => {
9222
9258
  onChange(items.filter((_, i) => i !== index));
@@ -9225,78 +9261,241 @@ function IndexedPairEditor({
9225
9261
  const updated = items.map((item, i) => i === index ? { ...item, [key]: val } : item);
9226
9262
  onChange(updated);
9227
9263
  };
9228
- return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 0.5 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(
9229
- IndexedPairRow,
9264
+ return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 1 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(
9265
+ ObjectArrayItemRow,
9230
9266
  {
9231
- key: item.index || `new-${i}`,
9267
+ key: i,
9232
9268
  item,
9233
9269
  index: i,
9234
- disabled,
9270
+ itemFields,
9271
+ layoutRows,
9272
+ disabled: !!disabled,
9235
9273
  onUpdate: updateItem,
9236
9274
  onRemove: removeItem,
9237
- hideControls
9275
+ showLabels: true,
9276
+ error: itemErrors == null ? void 0 : itemErrors[i]
9277
+ }
9278
+ )), items.length < maxItems && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", size: "sm", icon: "plus", disabled, onClick: addItem, type: "button" }, "Add ", label.toLowerCase())), items.length >= maxItems && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.limitNote }, "Maximum ", maxItems, " items reached"));
9279
+ }
9280
+ function computeLayoutRows(fields) {
9281
+ var _a;
9282
+ const hasExplicitRow = fields.some((f) => {
9283
+ var _a2;
9284
+ return ((_a2 = f.ui) == null ? void 0 : _a2.row) !== void 0;
9285
+ });
9286
+ if (!hasExplicitRow) {
9287
+ if (fields.length <= 3) {
9288
+ return [fields];
9289
+ }
9290
+ return fields.map((f) => [f]);
9291
+ }
9292
+ const rowMap = /* @__PURE__ */ new Map();
9293
+ const noRow = [];
9294
+ for (const f of fields) {
9295
+ if (((_a = f.ui) == null ? void 0 : _a.row) !== void 0) {
9296
+ const existing = rowMap.get(f.ui.row);
9297
+ if (existing) {
9298
+ existing.push(f);
9299
+ } else {
9300
+ rowMap.set(f.ui.row, [f]);
9301
+ }
9302
+ } else {
9303
+ noRow.push(f);
9304
+ }
9305
+ }
9306
+ const sortedKeys = [...rowMap.keys()].sort((a, b) => a - b);
9307
+ const rows = sortedKeys.map((k) => rowMap.get(k));
9308
+ for (const f of noRow) {
9309
+ rows.push([f]);
9310
+ }
9311
+ return rows;
9312
+ }
9313
+ function makeItemFormField(item, index, fieldKey, onUpdate) {
9314
+ return {
9315
+ name: `item-${index}-${fieldKey}`,
9316
+ value: item[fieldKey],
9317
+ onChange: (eventOrValue) => {
9318
+ if (eventOrValue != null && typeof eventOrValue === "object" && "target" in eventOrValue) {
9319
+ onUpdate(index, fieldKey, eventOrValue.target.value);
9320
+ } else {
9321
+ onUpdate(index, fieldKey, eventOrValue);
9322
+ }
9323
+ },
9324
+ onBlur: () => {
9325
+ }
9326
+ };
9327
+ }
9328
+ function effectiveItemField(field, isSecure) {
9329
+ if (!isSecure) {
9330
+ return field;
9331
+ }
9332
+ return { ...field, semanticType: "password" };
9333
+ }
9334
+ function ObjectArrayItemRow({
9335
+ item,
9336
+ index,
9337
+ itemFields,
9338
+ layoutRows,
9339
+ disabled,
9340
+ onUpdate,
9341
+ onRemove,
9342
+ showLabels,
9343
+ error
9344
+ }) {
9345
+ const styles = ui.useStyles2(getStyles$d);
9346
+ const secureOverride = findActiveSecureOverride(itemFields, item, index);
9347
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.itemRow }, layoutRows.map((row, rowIdx) => /* @__PURE__ */ React__default.default.createElement(ui.Stack, { key: rowIdx, direction: "row", gap: 1, alignItems: "flex-end", wrap: "wrap" }, row.map((field) => {
9348
+ var _a;
9349
+ const isSecureTarget = (secureOverride == null ? void 0 : secureOverride.fieldKey) === field.key;
9350
+ const eff = effectiveItemField(field, !!isSecureTarget);
9351
+ const formField = makeItemFormField(item, index, field.key, onUpdate);
9352
+ if (isSecureTarget && item[field.key] === SECURE_FIELD_CONFIGURED) {
9353
+ formField.value = SECURE_FIELD_CONFIGURED;
9354
+ }
9355
+ return /* @__PURE__ */ React__default.default.createElement("div", { key: field.key, className: field.valueType === "boolean" ? styles.boolCell : styles.inputCell }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.cellLabel }, (_a = field.label) != null ? _a : field.key, field.required && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.required }, " *")), renderFieldInput(eff, formField, disabled));
9356
+ }), rowIdx === 0 && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.removeCellWithLabel }, /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: "Remove" }, /* @__PURE__ */ React__default.default.createElement(
9357
+ ui.Button,
9358
+ {
9359
+ variant: "secondary",
9360
+ fill: "text",
9361
+ size: "sm",
9362
+ icon: "trash-alt",
9363
+ "aria-label": "Remove item",
9364
+ disabled,
9365
+ onClick: () => onRemove(index),
9366
+ type: "button"
9238
9367
  }
9239
- )), !hideControls && items.length < maxItems && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", size: "sm", icon: "plus", disabled, onClick: addItem, type: "button" }, "Add header")), !hideControls && items.length >= maxItems && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.limitNote }, "Maximum ", maxItems, " headers reached"));
9368
+ ))))), error && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.itemError }, error));
9240
9369
  }
9241
9370
  const getStyles$d = (theme) => ({
9371
+ itemRow: css.css({
9372
+ display: "flex",
9373
+ flexDirection: "column",
9374
+ gap: theme.spacing(0.5),
9375
+ padding: theme.spacing(1),
9376
+ borderRadius: theme.shape.radius.default,
9377
+ border: `1px solid ${theme.colors.border.weak}`
9378
+ }),
9242
9379
  inputCell: css.css({
9243
- flex: "1 1 0",
9244
- minWidth: 0,
9380
+ flex: "1 1 120px",
9381
+ minWidth: 120,
9245
9382
  overflow: "hidden"
9246
9383
  }),
9384
+ boolCell: css.css({
9385
+ flex: "0 0 auto",
9386
+ minWidth: 0
9387
+ }),
9388
+ cellLabel: css.css({
9389
+ fontSize: theme.typography.bodySmall.fontSize,
9390
+ color: theme.colors.text.secondary,
9391
+ marginBottom: theme.spacing(0.25)
9392
+ }),
9393
+ required: css.css({
9394
+ color: theme.colors.error.text
9395
+ }),
9396
+ removeCellWithLabel: css.css({
9397
+ flex: "0 0 auto",
9398
+ display: "flex",
9399
+ alignItems: "flex-end",
9400
+ paddingBottom: theme.spacing(0.25)
9401
+ }),
9402
+ itemError: css.css({
9403
+ fontSize: theme.typography.bodySmall.fontSize,
9404
+ color: theme.colors.error.text
9405
+ }),
9247
9406
  limitNote: css.css({
9248
9407
  fontSize: theme.typography.bodySmall.fontSize,
9249
9408
  color: theme.colors.text.secondary
9250
9409
  })
9251
9410
  });
9252
9411
 
9253
- function ComplexFieldNote({ count, label }) {
9412
+ const StringArrayInput = (props) => {
9413
+ const { value, onChange, placeholder, disabled, itemLabel = "item" } = props;
9254
9414
  const styles = ui.useStyles2(getStyles$c);
9255
- return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.note }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs" }), /* @__PURE__ */ React__default.default.createElement("span", null, count > 0 ? `${count} ${label.toLowerCase()} configured.` : `No ${label.toLowerCase()} configured.`, " Configure in Grafana UI."));
9256
- }
9415
+ const items = Array.isArray(value) ? value : [];
9416
+ const lastInputRef = React.useRef(null);
9417
+ const shouldFocusLastRef = React.useRef(false);
9418
+ React.useEffect(() => {
9419
+ if (shouldFocusLastRef.current && lastInputRef.current) {
9420
+ lastInputRef.current.focus();
9421
+ shouldFocusLastRef.current = false;
9422
+ }
9423
+ }, [items.length]);
9424
+ const addItem = () => {
9425
+ shouldFocusLastRef.current = true;
9426
+ onChange([...items, ""]);
9427
+ };
9428
+ const removeItem = (index) => {
9429
+ onChange(items.filter((_, i) => i !== index));
9430
+ };
9431
+ const updateItem = (index, val) => {
9432
+ onChange(items.map((item, i) => i === index ? val : item));
9433
+ };
9434
+ const isItemValid = (index, val) => {
9435
+ const trimmed = val.trim();
9436
+ if (trimmed === "") {
9437
+ return false;
9438
+ }
9439
+ return !items.some((item, i) => i !== index && item.trim() === trimmed);
9440
+ };
9441
+ const handleEnter = (index, currentValue) => {
9442
+ if (!isItemValid(index, currentValue)) {
9443
+ return;
9444
+ }
9445
+ if (index === items.length - 1) {
9446
+ shouldFocusLastRef.current = true;
9447
+ onChange([...items, ""]);
9448
+ }
9449
+ };
9450
+ return /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "column", gap: 0.5 }, items.map((item, i) => /* @__PURE__ */ React__default.default.createElement(ui.Stack, { direction: "row", gap: 1, key: i }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.inputCell }, /* @__PURE__ */ React__default.default.createElement(
9451
+ ui.Input,
9452
+ {
9453
+ ref: i === items.length - 1 ? lastInputRef : void 0,
9454
+ value: item,
9455
+ placeholder: placeholder != null ? placeholder : itemLabel,
9456
+ disabled,
9457
+ onChange: (e) => updateItem(i, e.currentTarget.value),
9458
+ onKeyDown: (e) => {
9459
+ if (e.key === "Enter") {
9460
+ e.preventDefault();
9461
+ handleEnter(i, e.currentTarget.value);
9462
+ }
9463
+ }
9464
+ }
9465
+ )), !disabled && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: `Remove ${itemLabel}` }, /* @__PURE__ */ React__default.default.createElement(
9466
+ ui.Button,
9467
+ {
9468
+ variant: "secondary",
9469
+ fill: "text",
9470
+ size: "sm",
9471
+ icon: "trash-alt",
9472
+ "aria-label": `Remove ${itemLabel}`,
9473
+ onClick: () => removeItem(i),
9474
+ type: "button"
9475
+ }
9476
+ )))), !disabled && /* @__PURE__ */ React__default.default.createElement("div", null, /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "secondary", size: "sm", icon: "plus", onClick: addItem, type: "button" }, "Add")));
9477
+ };
9257
9478
  const getStyles$c = (theme) => ({
9258
- note: css.css({
9259
- display: "inline-flex",
9260
- alignItems: "center",
9261
- gap: theme.spacing(0.5),
9262
- padding: `${theme.spacing(0.5)} ${theme.spacing(0.75)}`,
9263
- fontSize: theme.typography.bodySmall.fontSize,
9264
- color: theme.colors.text.secondary,
9265
- backgroundColor: theme.colors.background.secondary,
9266
- borderRadius: theme.shape.radius.default,
9267
- border: `1px solid ${theme.colors.border.weak}`
9479
+ inputCell: css.css({
9480
+ flex: "1 1 0",
9481
+ minWidth: 0,
9482
+ overflow: "hidden"
9268
9483
  })
9269
9484
  });
9270
9485
 
9271
- function renderFieldInput(field, formField, disabled) {
9272
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
9486
+ function renderFieldInput(field, formField, disabled, errorMessage, setValue) {
9487
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
9273
9488
  const value = formField.value;
9274
9489
  const placeholder = (_a = field.ui) == null ? void 0 : _a.placeholder;
9275
9490
  const label = (_b = field.label) != null ? _b : field.key;
9491
+ if (((_c = field.ui) == null ? void 0 : _c.component) === "fileUpload" && field.ui.fileMapping && setValue) {
9492
+ return /* @__PURE__ */ React__default.default.createElement(FileUploadField, { field, formField, disabled, setValue });
9493
+ }
9276
9494
  if (field.target === "secureJsonData" || field.semanticType === "password" || field.semanticType === "token") {
9277
9495
  return /* @__PURE__ */ React__default.default.createElement(SecureFieldInput, { formField, placeholder: placeholder != null ? placeholder : label, disabled, label });
9278
9496
  }
9279
- if (field.valueType === "boolean") {
9280
- return /* @__PURE__ */ React__default.default.createElement(ui.Switch, { value: !!value, onChange: (e) => formField.onChange(e.currentTarget.checked), disabled });
9281
- }
9282
- if (field.valueType === "number") {
9283
- return /* @__PURE__ */ React__default.default.createElement(
9284
- ui.Input,
9285
- {
9286
- ...formField,
9287
- value: value !== void 0 && value !== null ? Number(value) : "",
9288
- type: "number",
9289
- placeholder,
9290
- disabled,
9291
- onChange: (e) => {
9292
- const n = e.currentTarget.valueAsNumber;
9293
- formField.onChange(Number.isNaN(n) ? void 0 : n);
9294
- }
9295
- }
9296
- );
9297
- }
9298
- if (((_c = field.ui) == null ? void 0 : _c.component) === "radio") {
9299
- const options = ((_e = (_d = field.ui) == null ? void 0 : _d.options) != null ? _e : []).map((opt) => ({
9497
+ if (((_d = field.ui) == null ? void 0 : _d.component) === "radio") {
9498
+ const options = ((_f = (_e = field.ui) == null ? void 0 : _e.options) != null ? _f : []).map((opt) => ({
9300
9499
  label: opt.label,
9301
9500
  value: String(opt.value),
9302
9501
  description: opt.description
@@ -9306,13 +9505,20 @@ function renderFieldInput(field, formField, disabled) {
9306
9505
  {
9307
9506
  options,
9308
9507
  value: String(value != null ? value : ""),
9309
- onChange: (v) => formField.onChange(v),
9508
+ onChange: (v) => {
9509
+ if (field.valueType === "number") {
9510
+ const n = Number(v);
9511
+ formField.onChange(Number.isNaN(n) ? v : n);
9512
+ } else {
9513
+ formField.onChange(v);
9514
+ }
9515
+ },
9310
9516
  disabled
9311
9517
  }
9312
9518
  ));
9313
9519
  }
9314
- if (((_f = field.ui) == null ? void 0 : _f.component) === "select") {
9315
- const options = ((_h = (_g = field.ui) == null ? void 0 : _g.options) != null ? _h : []).map((opt) => ({
9520
+ if (((_g = field.ui) == null ? void 0 : _g.component) === "select") {
9521
+ const options = ((_i = (_h = field.ui) == null ? void 0 : _h.options) != null ? _i : []).map((opt) => ({
9316
9522
  label: opt.label,
9317
9523
  value: String(opt.value),
9318
9524
  description: opt.description
@@ -9327,10 +9533,29 @@ function renderFieldInput(field, formField, disabled) {
9327
9533
  }
9328
9534
  );
9329
9535
  }
9536
+ if (field.valueType === "boolean") {
9537
+ return /* @__PURE__ */ React__default.default.createElement(ui.Switch, { value: !!value, onChange: (e) => formField.onChange(e.currentTarget.checked), disabled });
9538
+ }
9539
+ if (field.valueType === "number") {
9540
+ return /* @__PURE__ */ React__default.default.createElement(
9541
+ ui.Input,
9542
+ {
9543
+ ...formField,
9544
+ value: value !== void 0 && value !== null ? Number(value) : "",
9545
+ type: "number",
9546
+ placeholder,
9547
+ disabled,
9548
+ onChange: (e) => {
9549
+ const n = e.currentTarget.valueAsNumber;
9550
+ formField.onChange(Number.isNaN(n) ? void 0 : n);
9551
+ }
9552
+ }
9553
+ );
9554
+ }
9330
9555
  if (field.semanticType === "url") {
9331
9556
  return /* @__PURE__ */ React__default.default.createElement(ui.Input, { ...formField, value: String(value != null ? value : ""), type: "url", placeholder, disabled });
9332
9557
  }
9333
- if (((_i = field.ui) == null ? void 0 : _i.component) === "textarea") {
9558
+ if (((_j = field.ui) == null ? void 0 : _j.component) === "textarea") {
9334
9559
  return /* @__PURE__ */ React__default.default.createElement(
9335
9560
  ui.TextArea,
9336
9561
  {
@@ -9338,245 +9563,54 @@ function renderFieldInput(field, formField, disabled) {
9338
9563
  value: String(value != null ? value : ""),
9339
9564
  placeholder,
9340
9565
  disabled,
9341
- rows: (_k = (_j = field.ui) == null ? void 0 : _j.rows) != null ? _k : 3
9566
+ rows: (_l = (_k = field.ui) == null ? void 0 : _k.rows) != null ? _l : 3
9342
9567
  }
9343
9568
  );
9344
9569
  }
9345
- if (field.valueType === "array" && ((_l = field.item) == null ? void 0 : _l.valueType) === "string") {
9570
+ if (((_m = field.storage) == null ? void 0 : _m.type) === "indexedPair") {
9571
+ const items = Array.isArray(value) ? value : [];
9572
+ const maxItems = (_p = (_o = (_n = field.validations) == null ? void 0 : _n.find((v) => v.type === "itemCount")) == null ? void 0 : _o.max) != null ? _p : 10;
9573
+ const itemLabel = (_r = (_q = field.label) == null ? void 0 : _q.toLowerCase().replace(/s$/, "")) != null ? _r : "header";
9346
9574
  return /* @__PURE__ */ React__default.default.createElement(
9347
- StringArrayInput,
9575
+ IndexedPairEditor,
9348
9576
  {
9349
- value: Array.isArray(value) ? value : [],
9577
+ value: items,
9350
9578
  onChange: formField.onChange,
9351
- placeholder: placeholder != null ? placeholder : `Add ${label.toLowerCase()}\u2026`,
9352
- disabled
9579
+ maxItems,
9580
+ disabled,
9581
+ itemLabel
9353
9582
  }
9354
9583
  );
9355
9584
  }
9356
- if (((_m = field.storage) == null ? void 0 : _m.type) === "indexedPair") {
9357
- const items = Array.isArray(value) ? value : [];
9358
- const maxItems = (_p = (_o = (_n = field.validations) == null ? void 0 : _n.find((v) => v.type === "itemCount")) == null ? void 0 : _o.max) != null ? _p : 10;
9359
- return /* @__PURE__ */ React__default.default.createElement(IndexedPairEditor, { value: items, onChange: formField.onChange, maxItems, disabled });
9360
- }
9361
- if (field.valueType === "object" || field.valueType === "map" || field.valueType === "array" && (((_q = field.item) == null ? void 0 : _q.valueType) === "object" || ((_r = field.item) == null ? void 0 : _r.valueType) === "map")) {
9362
- const count = Array.isArray(value) ? value.length : 0;
9363
- return /* @__PURE__ */ React__default.default.createElement(ComplexFieldNote, { count, label });
9364
- }
9365
- return /* @__PURE__ */ React__default.default.createElement(ui.Input, { ...formField, value: String(value != null ? value : ""), placeholder, disabled });
9366
- }
9367
-
9368
- const getWizardStyles = (theme) => ({
9369
- container: css.css({
9370
- position: "relative",
9371
- display: "flex",
9372
- flexDirection: "column",
9373
- gap: theme.spacing(1),
9374
- padding: theme.spacing(1.5),
9375
- backgroundColor: theme.colors.background.secondary,
9376
- borderRadius: theme.shape.radius.default,
9377
- border: `1px solid ${theme.colors.border.weak}`,
9378
- overflow: "hidden"
9379
- }),
9380
- overlay: css.css({
9381
- position: "absolute",
9382
- inset: 0,
9383
- display: "flex",
9384
- alignItems: "center",
9385
- justifyContent: "center",
9386
- gap: theme.spacing(1),
9387
- background: theme.colors.background.secondary,
9388
- borderRadius: theme.shape.radius.default,
9389
- zIndex: 1,
9390
- fontSize: theme.typography.bodySmall.fontSize,
9391
- color: theme.colors.text.primary,
9392
- opacity: 0.95
9393
- }),
9394
- readOnlyBanner: css.css({
9395
- display: "inline-flex",
9396
- alignItems: "center",
9397
- gap: theme.spacing(0.5),
9398
- padding: `${theme.spacing(0.25)} ${theme.spacing(0.75)}`,
9399
- fontSize: theme.typography.bodySmall.fontSize,
9400
- color: theme.colors.text.secondary,
9401
- backgroundColor: theme.colors.background.secondary,
9402
- borderRadius: theme.shape.radius.default,
9403
- border: `1px solid ${theme.colors.border.weak}`
9404
- }),
9405
- navBar: css.css({
9406
- display: "flex",
9407
- alignItems: "center",
9408
- justifyContent: "space-between"
9409
- }),
9410
- navTitle: css.css({
9411
- display: "inline-flex",
9412
- alignItems: "center",
9413
- gap: theme.spacing(0.5),
9414
- fontSize: theme.typography.body.fontSize,
9415
- fontWeight: theme.typography.fontWeightBold,
9416
- color: theme.colors.text.primary
9417
- }),
9418
- stepCount: css.css({
9419
- fontSize: "11px",
9420
- fontWeight: "normal",
9421
- color: theme.colors.text.secondary
9422
- }),
9423
- navActions: css.css({
9424
- display: "flex",
9425
- alignItems: "center",
9426
- gap: theme.spacing(0.25)
9427
- }),
9428
- form: css.css({
9429
- display: "flex",
9430
- flexDirection: "column",
9431
- gap: theme.spacing(0.75)
9432
- }),
9433
- buttons: css.css({
9434
- display: "flex",
9435
- gap: theme.spacing(1),
9436
- paddingTop: theme.spacing(0.25)
9437
- }),
9438
- fieldRow: css.css({
9439
- display: "grid",
9440
- gridTemplateColumns: "minmax(80px, 1fr) minmax(0, 2fr)",
9441
- gap: theme.spacing(0.75),
9442
- alignItems: "start"
9443
- }),
9444
- fieldRowCenter: css.css({
9445
- display: "grid",
9446
- gridTemplateColumns: "minmax(80px, 1fr) minmax(0, 2fr)",
9447
- gap: theme.spacing(0.75),
9448
- alignItems: "center",
9449
- padding: `${theme.spacing(0.5)} 0`
9450
- }),
9451
- fieldLabelRow: css.css({
9452
- display: "flex",
9453
- alignItems: "center",
9454
- gap: theme.spacing(0.5),
9455
- paddingTop: theme.spacing(0.5)
9456
- }),
9457
- fieldLabelRowCompact: css.css({
9458
- display: "flex",
9459
- alignItems: "center",
9460
- gap: theme.spacing(0.5)
9461
- }),
9462
- fieldLabel: css.css({
9463
- fontSize: theme.typography.bodySmall.fontSize,
9464
- fontWeight: theme.typography.fontWeightMedium,
9465
- color: theme.colors.text.primary
9466
- }),
9467
- fieldRequired: css.css({
9468
- color: theme.colors.error.text,
9469
- marginLeft: 2
9470
- }),
9471
- fieldInfoIcon: css.css({
9472
- color: theme.colors.text.disabled,
9473
- cursor: "help",
9474
- flexShrink: 0
9475
- }),
9476
- fieldInputCol: css.css({
9477
- display: "flex",
9478
- flexDirection: "column",
9479
- gap: theme.spacing(0.25),
9480
- minWidth: 0
9481
- }),
9482
- fieldError: css.css({
9483
- fontSize: "11px",
9484
- color: theme.colors.error.text
9485
- })
9486
- });
9487
-
9488
- function SchemaField({ field, control, errors, disabled, dsUid, watchedValues, fieldById }) {
9489
- const styles = ui.useStyles2(getWizardStyles);
9490
- const activeOverride = resolveActiveOverride(field, watchedValues, fieldById);
9491
- const fk = formKey(field);
9492
- if (field.key === "pdcInjected" && field.target === "jsonData") {
9585
+ if (field.valueType === "array" && ((_s = field.item) == null ? void 0 : _s.valueType) === "string") {
9493
9586
  return /* @__PURE__ */ React__default.default.createElement(
9494
- reactHookForm.Controller,
9587
+ StringArrayInput,
9495
9588
  {
9496
- name: fk,
9497
- control,
9498
- render: ({ field: formField }) => /* @__PURE__ */ React__default.default.createElement(
9499
- PdcFieldNote,
9500
- {
9501
- enabled: !!formField.value,
9502
- description: field.description,
9503
- configUrl: `/connections/datasources/edit/${dsUid}`
9504
- }
9505
- )
9589
+ value: Array.isArray(value) ? value : [],
9590
+ onChange: formField.onChange,
9591
+ placeholder,
9592
+ disabled,
9593
+ itemLabel: label.toLowerCase().replace(/s$/, "")
9506
9594
  }
9507
9595
  );
9508
9596
  }
9509
- const required = isFieldRequired(field, watchedValues, fieldById);
9510
- const validationRules = buildValidationRules(field, required);
9511
- return /* @__PURE__ */ React__default.default.createElement(
9512
- reactHookForm.Controller,
9513
- {
9514
- name: fk,
9515
- control,
9516
- rules: validationRules,
9517
- render: ({ field: formField }) => {
9518
- var _a, _b, _c, _d, _e;
9519
- const errorMessage = (_a = errors[fk]) == null ? void 0 : _a.message;
9520
- const label = (_b = field.label) != null ? _b : field.key;
9521
- const description = (_c = activeOverride == null ? void 0 : activeOverride.description) != null ? _c : field.description;
9522
- const effectiveField = activeOverride ? {
9523
- ...field,
9524
- ui: {
9525
- ...field.ui,
9526
- placeholder: (_e = activeOverride.placeholder) != null ? _e : (_d = field.ui) == null ? void 0 : _d.placeholder
9527
- }
9528
- } : field;
9529
- const isReadOnly = !!(activeOverride == null ? void 0 : activeOverride.readOnly);
9530
- const isBool = field.valueType === "boolean";
9531
- return /* @__PURE__ */ React__default.default.createElement("div", { className: isBool ? styles.fieldRowCenter : styles.fieldRow }, /* @__PURE__ */ React__default.default.createElement("div", { className: isBool ? styles.fieldLabelRowCompact : styles.fieldLabelRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldLabel }, label, required && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldRequired }, "*")), description && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: description }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs", className: styles.fieldInfoIcon }))), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldInputCol }, renderFieldInput(effectiveField, formField, disabled || isReadOnly), errorMessage && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldError }, errorMessage)));
9532
- }
9533
- }
9534
- );
9535
- }
9536
-
9537
- function AuthorizationHeaderField({
9538
- headersFieldKey,
9539
- control,
9540
- disabled,
9541
- watchedValues
9542
- }) {
9543
- const styles = ui.useStyles2(getWizardStyles);
9544
- const items = React.useMemo(
9545
- () => Array.isArray(watchedValues[headersFieldKey]) ? watchedValues[headersFieldKey] : [],
9546
- [watchedValues, headersFieldKey]
9547
- );
9548
- const authEntries = React.useMemo(() => {
9549
- const entries = [];
9550
- for (let i = 0; i < items.length; i++) {
9551
- if (items[i].name.toLowerCase() === "authorization") {
9552
- entries.push({ item: items[i], originalIdx: i });
9597
+ if (field.valueType === "array" && ((_t = field.item) == null ? void 0 : _t.valueType) === "object" && ((_u = field.item.fields) == null ? void 0 : _u.length)) {
9598
+ return /* @__PURE__ */ React__default.default.createElement(
9599
+ ObjectArrayEditor,
9600
+ {
9601
+ field,
9602
+ value,
9603
+ onChange: formField.onChange,
9604
+ disabled,
9605
+ errorMessage
9553
9606
  }
9554
- }
9555
- return entries;
9556
- }, [items]);
9557
- if (authEntries.length === 0) {
9558
- return null;
9607
+ );
9559
9608
  }
9560
- const authItems = authEntries.map((e) => e.item);
9561
- return /* @__PURE__ */ React__default.default.createElement(
9562
- reactHookForm.Controller,
9563
- {
9564
- name: headersFieldKey,
9565
- control,
9566
- render: ({ field: formField }) => {
9567
- const handleChange = (updatedAuthItems) => {
9568
- const updated = [...items];
9569
- for (let i = 0; i < authEntries.length; i++) {
9570
- if (i < updatedAuthItems.length) {
9571
- updated[authEntries[i].originalIdx] = updatedAuthItems[i];
9572
- }
9573
- }
9574
- formField.onChange(updated);
9575
- };
9576
- return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldRow }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldLabelRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldLabel }, "Custom HTTP Headers"), /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: "Authorization HTTP header(s) sent with every request." }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs", className: styles.fieldInfoIcon }))), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldInputCol }, /* @__PURE__ */ React__default.default.createElement(IndexedPairEditor, { value: authItems, onChange: handleChange, disabled, hideControls: true })));
9577
- }
9578
- }
9579
- );
9609
+ if (field.valueType === "object" || field.valueType === "map" || field.valueType === "array" && (((_v = field.item) == null ? void 0 : _v.valueType) === "object" || ((_w = field.item) == null ? void 0 : _w.valueType) === "map")) {
9610
+ const count = Array.isArray(value) ? value.length : 0;
9611
+ return /* @__PURE__ */ React__default.default.createElement(ComplexFieldNote, { count, label });
9612
+ }
9613
+ return /* @__PURE__ */ React__default.default.createElement(ui.Input, { ...formField, value: String(value != null ? value : ""), placeholder, disabled });
9580
9614
  }
9581
9615
 
9582
9616
  const getTabStyles = (theme) => ({
@@ -9627,7 +9661,7 @@ const getTabStyles = (theme) => ({
9627
9661
  width: 12,
9628
9662
  flexShrink: 0,
9629
9663
  alignSelf: "flex-start",
9630
- paddingTop: 4
9664
+ paddingTop: theme.spacing(0.5)
9631
9665
  }),
9632
9666
  navDot: css.css({
9633
9667
  width: 10,
@@ -9673,7 +9707,7 @@ const getTabStyles = (theme) => ({
9673
9707
  }),
9674
9708
  navLabel: css.css({
9675
9709
  fontSize: theme.typography.body.fontSize,
9676
- color: "rgba(204, 204, 220, 0.65)",
9710
+ color: theme.colors.text.secondary,
9677
9711
  lineHeight: 1.4
9678
9712
  }),
9679
9713
  navLabelActive: css.css({
@@ -9755,8 +9789,8 @@ const getTabStyles = (theme) => ({
9755
9789
  textAlign: "left"
9756
9790
  }),
9757
9791
  sectionBadge: css.css({
9758
- fontSize: "11px",
9759
- fontWeight: "normal",
9792
+ fontSize: theme.typography.bodySmall.fontSize,
9793
+ fontWeight: theme.typography.fontWeightRegular,
9760
9794
  color: theme.colors.text.disabled,
9761
9795
  border: `1px solid ${theme.colors.border.weak}`,
9762
9796
  borderRadius: theme.shape.radius.pill,
@@ -9815,6 +9849,226 @@ const getTabStyles = (theme) => ({
9815
9849
  marginBottom: theme.spacing(1)
9816
9850
  })
9817
9851
  });
9852
+ const getWizardStyles = (theme) => ({
9853
+ container: css.css({
9854
+ position: "relative",
9855
+ display: "flex",
9856
+ flexDirection: "column",
9857
+ gap: theme.spacing(1),
9858
+ padding: theme.spacing(1.5),
9859
+ backgroundColor: theme.colors.background.secondary,
9860
+ borderRadius: theme.shape.radius.default,
9861
+ border: `1px solid ${theme.colors.border.weak}`,
9862
+ overflow: "hidden"
9863
+ }),
9864
+ overlay: css.css({
9865
+ position: "absolute",
9866
+ inset: 0,
9867
+ display: "flex",
9868
+ alignItems: "center",
9869
+ justifyContent: "center",
9870
+ gap: theme.spacing(1),
9871
+ background: theme.colors.background.secondary,
9872
+ borderRadius: theme.shape.radius.default,
9873
+ zIndex: 1,
9874
+ fontSize: theme.typography.bodySmall.fontSize,
9875
+ color: theme.colors.text.primary,
9876
+ opacity: 0.95
9877
+ }),
9878
+ readOnlyBanner: css.css({
9879
+ display: "inline-flex",
9880
+ alignItems: "center",
9881
+ gap: theme.spacing(0.5),
9882
+ padding: `${theme.spacing(0.25)} ${theme.spacing(0.75)}`,
9883
+ fontSize: theme.typography.bodySmall.fontSize,
9884
+ color: theme.colors.text.secondary,
9885
+ backgroundColor: theme.colors.background.secondary,
9886
+ borderRadius: theme.shape.radius.default,
9887
+ border: `1px solid ${theme.colors.border.weak}`
9888
+ }),
9889
+ navBar: css.css({
9890
+ display: "flex",
9891
+ alignItems: "center",
9892
+ justifyContent: "space-between"
9893
+ }),
9894
+ navTitle: css.css({
9895
+ display: "inline-flex",
9896
+ alignItems: "center",
9897
+ gap: theme.spacing(0.5),
9898
+ fontSize: theme.typography.body.fontSize,
9899
+ fontWeight: theme.typography.fontWeightBold,
9900
+ color: theme.colors.text.primary
9901
+ }),
9902
+ stepCount: css.css({
9903
+ fontSize: theme.typography.bodySmall.fontSize,
9904
+ fontWeight: theme.typography.fontWeightRegular,
9905
+ color: theme.colors.text.secondary
9906
+ }),
9907
+ navActions: css.css({
9908
+ display: "flex",
9909
+ alignItems: "center",
9910
+ gap: theme.spacing(0.25)
9911
+ }),
9912
+ form: css.css({
9913
+ display: "flex",
9914
+ flexDirection: "column",
9915
+ gap: theme.spacing(0.75)
9916
+ }),
9917
+ buttons: css.css({
9918
+ display: "flex",
9919
+ gap: theme.spacing(1),
9920
+ paddingTop: theme.spacing(0.25)
9921
+ }),
9922
+ fieldRow: css.css({
9923
+ display: "grid",
9924
+ gridTemplateColumns: "minmax(80px, 1fr) minmax(0, 2fr)",
9925
+ gap: theme.spacing(0.75),
9926
+ alignItems: "start"
9927
+ }),
9928
+ fieldRowCenter: css.css({
9929
+ display: "grid",
9930
+ gridTemplateColumns: "minmax(80px, 1fr) minmax(0, 2fr)",
9931
+ gap: theme.spacing(0.75),
9932
+ alignItems: "center",
9933
+ padding: `${theme.spacing(0.5)} 0`
9934
+ }),
9935
+ fieldLabelRow: css.css({
9936
+ display: "flex",
9937
+ alignItems: "center",
9938
+ gap: theme.spacing(0.5),
9939
+ paddingTop: theme.spacing(0.5)
9940
+ }),
9941
+ fieldLabelRowCompact: css.css({
9942
+ display: "flex",
9943
+ alignItems: "center",
9944
+ gap: theme.spacing(0.5)
9945
+ }),
9946
+ fieldLabel: css.css({
9947
+ fontSize: theme.typography.bodySmall.fontSize,
9948
+ fontWeight: theme.typography.fontWeightMedium,
9949
+ color: theme.colors.text.primary
9950
+ }),
9951
+ fieldRequired: css.css({
9952
+ color: theme.colors.error.text,
9953
+ marginLeft: 2
9954
+ }),
9955
+ fieldInfoIcon: css.css({
9956
+ color: theme.colors.text.disabled,
9957
+ cursor: "help",
9958
+ flexShrink: 0
9959
+ }),
9960
+ fieldInputCol: css.css({
9961
+ display: "flex",
9962
+ flexDirection: "column",
9963
+ gap: theme.spacing(0.25),
9964
+ minWidth: 0
9965
+ }),
9966
+ fieldError: css.css({
9967
+ fontSize: theme.typography.bodySmall.fontSize,
9968
+ color: theme.colors.error.text
9969
+ })
9970
+ });
9971
+
9972
+ function SchemaField({
9973
+ field,
9974
+ control,
9975
+ errors,
9976
+ disabled,
9977
+ dsUid,
9978
+ watchedValues,
9979
+ fieldById,
9980
+ celContext,
9981
+ setValue
9982
+ }) {
9983
+ const styles = ui.useStyles2(getWizardStyles);
9984
+ const activeOverride = useDatasourceSchema.resolveActiveOverride(field, watchedValues, fieldById);
9985
+ const fk = useDatasourceSchema.formKey(field);
9986
+ if (field.key === "pdcInjected" && field.target === "jsonData") {
9987
+ return /* @__PURE__ */ React__default.default.createElement(
9988
+ reactHookForm.Controller,
9989
+ {
9990
+ name: fk,
9991
+ control,
9992
+ render: ({ field: formField }) => /* @__PURE__ */ React__default.default.createElement(
9993
+ PdcFieldNote,
9994
+ {
9995
+ enabled: !!formField.value,
9996
+ description: field.description,
9997
+ configUrl: `/connections/datasources/edit/${dsUid}`
9998
+ }
9999
+ )
10000
+ }
10001
+ );
10002
+ }
10003
+ const required = isFieldRequired(field, watchedValues, fieldById, celContext);
10004
+ const validationRules = buildValidationRules(field, required);
10005
+ return /* @__PURE__ */ React__default.default.createElement(
10006
+ reactHookForm.Controller,
10007
+ {
10008
+ name: fk,
10009
+ control,
10010
+ rules: validationRules,
10011
+ render: ({ field: formField }) => {
10012
+ var _a, _b, _c, _d, _e;
10013
+ const errorMessage = (_a = errors[fk]) == null ? void 0 : _a.message;
10014
+ const label = (_b = field.label) != null ? _b : field.key;
10015
+ const description = (_c = activeOverride == null ? void 0 : activeOverride.description) != null ? _c : field.description;
10016
+ const effectiveField = activeOverride ? {
10017
+ ...field,
10018
+ description,
10019
+ ui: {
10020
+ ...field.ui,
10021
+ placeholder: (_e = activeOverride.placeholder) != null ? _e : (_d = field.ui) == null ? void 0 : _d.placeholder
10022
+ }
10023
+ } : field;
10024
+ const isReadOnly = !!(activeOverride == null ? void 0 : activeOverride.readOnly);
10025
+ const isBool = field.valueType === "boolean";
10026
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: isBool ? styles.fieldRowCenter : styles.fieldRow }, /* @__PURE__ */ React__default.default.createElement("div", { className: isBool ? styles.fieldLabelRowCompact : styles.fieldLabelRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldLabel }, label, required && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldRequired }, "*")), description && /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: description }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs", className: styles.fieldInfoIcon }))), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldInputCol }, renderFieldInput(effectiveField, formField, disabled || isReadOnly, errorMessage, setValue), errorMessage && !parseItemErrors(errorMessage) && /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldError }, errorMessage)));
10027
+ }
10028
+ }
10029
+ );
10030
+ }
10031
+
10032
+ const AuthorizationHeaderField = (props) => {
10033
+ const { headersFieldKey, control, disabled, watchedValues } = props;
10034
+ const styles = ui.useStyles2(getWizardStyles);
10035
+ const items = React.useMemo(
10036
+ () => Array.isArray(watchedValues[headersFieldKey]) ? watchedValues[headersFieldKey] : [],
10037
+ [watchedValues, headersFieldKey]
10038
+ );
10039
+ const authEntries = React.useMemo(() => {
10040
+ const entries = [];
10041
+ for (let i = 0; i < items.length; i++) {
10042
+ if (items[i].name.toLowerCase() === "authorization") {
10043
+ entries.push({ item: items[i], originalIdx: i });
10044
+ }
10045
+ }
10046
+ return entries;
10047
+ }, [items]);
10048
+ if (authEntries.length === 0) {
10049
+ return null;
10050
+ }
10051
+ const authItems = authEntries.map((e) => e.item);
10052
+ return /* @__PURE__ */ React__default.default.createElement(
10053
+ reactHookForm.Controller,
10054
+ {
10055
+ name: headersFieldKey,
10056
+ control,
10057
+ render: ({ field: formField }) => {
10058
+ const handleChange = (updatedAuthItems) => {
10059
+ const updated = [...items];
10060
+ for (let i = 0; i < authEntries.length; i++) {
10061
+ if (i < updatedAuthItems.length) {
10062
+ updated[authEntries[i].originalIdx] = updatedAuthItems[i];
10063
+ }
10064
+ }
10065
+ formField.onChange(updated);
10066
+ };
10067
+ return /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldRow }, /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldLabelRow }, /* @__PURE__ */ React__default.default.createElement("span", { className: styles.fieldLabel }, "Custom HTTP Headers"), /* @__PURE__ */ React__default.default.createElement(ui.Tooltip, { content: "Authorization HTTP header(s) sent with every request." }, /* @__PURE__ */ React__default.default.createElement(ui.Icon, { name: "info-circle", size: "xs", className: styles.fieldInfoIcon }))), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.fieldInputCol }, /* @__PURE__ */ React__default.default.createElement(IndexedPairEditor, { value: authItems, onChange: handleChange, disabled, hideControls: true })));
10068
+ }
10069
+ }
10070
+ );
10071
+ };
9818
10072
 
9819
10073
  function SidebarNav({ groups, activeIndex, sectionStates, onSelect }) {
9820
10074
  const styles = ui.useStyles2(getTabStyles);
@@ -9874,15 +10128,18 @@ function TabLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderA
9874
10128
  handleSubmit,
9875
10129
  errors,
9876
10130
  watchedValues,
10131
+ celContext,
9877
10132
  initializing,
9878
10133
  fetchError,
9879
10134
  submitting,
9880
10135
  submitError,
9881
10136
  readOnly,
9882
10137
  isFieldVisible,
10138
+ isFieldDisabled,
9883
10139
  isGroupValid,
9884
10140
  groupHasData,
9885
- onSubmit
10141
+ onSubmit,
10142
+ setValue
9886
10143
  } = form;
9887
10144
  const displayGroups = React.useMemo(() => resolvedGroups.filter((g) => g.group.id !== "_required"), [resolvedGroups]);
9888
10145
  const [expandedSections, setExpandedSections] = React.useState(() => {
@@ -10006,19 +10263,21 @@ function TabLayout({ form, schema, dsUid, dsName, onRetest, healthError, renderA
10006
10263
  /* @__PURE__ */ React__default.default.createElement("div", { className: styles.sectionBody }, g.group.description && /* @__PURE__ */ React__default.default.createElement("div", { className: styles.sectionDescription }, g.group.description), visibleFields.map((field) => /* @__PURE__ */ React__default.default.createElement(
10007
10264
  SchemaField,
10008
10265
  {
10009
- key: formKey(field),
10266
+ key: useDatasourceSchema.formKey(field),
10010
10267
  field,
10011
10268
  control,
10012
10269
  errors,
10013
- disabled: allDisabled,
10270
+ disabled: allDisabled || isFieldDisabled(field),
10014
10271
  dsUid,
10015
10272
  watchedValues,
10016
- fieldById
10273
+ fieldById,
10274
+ celContext,
10275
+ setValue
10017
10276
  }
10018
10277
  )), showHeaders && /* @__PURE__ */ React__default.default.createElement(
10019
10278
  AuthorizationHeaderField,
10020
10279
  {
10021
- headersFieldKey: formKey(httpHeadersField),
10280
+ headersFieldKey: useDatasourceSchema.formKey(httpHeadersField),
10022
10281
  control,
10023
10282
  disabled: allDisabled,
10024
10283
  watchedValues
@@ -10037,8 +10296,8 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10037
10296
  const [detectedReadOnly, setDetectedReadOnly] = React.useState(false);
10038
10297
  const readOnly = detectedReadOnly;
10039
10298
  const resolvedGroups = React.useMemo(() => {
10040
- const groups = resolveGroups(schema);
10041
- const requiredGroup = resolveRequiredFieldsGroup(schema);
10299
+ const groups = useDatasourceSchema.resolveGroups(schema);
10300
+ const requiredGroup = useDatasourceSchema.resolveRequiredFieldsGroup(schema);
10042
10301
  if (!requiredGroup) {
10043
10302
  return groups;
10044
10303
  }
@@ -10084,10 +10343,10 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10084
10343
  when: eff.when,
10085
10344
  targets: Object.entries(eff.set).map(([targetId, val]) => {
10086
10345
  const targetField = fieldById.get(targetId);
10087
- return { key: targetField ? formKey(targetField) : targetId, value: val };
10346
+ return { key: targetField ? useDatasourceSchema.formKey(targetField) : targetId, value: val };
10088
10347
  })
10089
10348
  }));
10090
- result.push({ sourceKey: formKey(field), effects: mapped });
10349
+ result.push({ sourceKey: useDatasourceSchema.formKey(field), effects: mapped });
10091
10350
  }
10092
10351
  return result;
10093
10352
  }, [schema.fields, fieldById]);
@@ -10108,11 +10367,11 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10108
10367
  const defaults = {};
10109
10368
  for (const field of allStorageFields) {
10110
10369
  if (field.defaultValue !== void 0) {
10111
- defaults[formKey(field)] = field.defaultValue;
10370
+ defaults[useDatasourceSchema.formKey(field)] = field.defaultValue;
10112
10371
  }
10113
10372
  }
10114
10373
  const merged = { ...defaults, ...result.values };
10115
- const virtualValues = computeVirtualFieldValues(schema, merged);
10374
+ const virtualValues = useDatasourceSchema.computeVirtualFieldValues(schema, merged);
10116
10375
  reset({ ...merged, ...virtualValues });
10117
10376
  setInitializing(false);
10118
10377
  });
@@ -10127,7 +10386,7 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10127
10386
  return;
10128
10387
  }
10129
10388
  for (const { sourceKey, effects } of fieldsWithEffects) {
10130
- const currentVal = watchedValues[sourceKey];
10389
+ const currentVal = useDatasourceSchema.getWatchedValue(watchedValues, sourceKey);
10131
10390
  const prevVal = prevEffectValuesRef.current[sourceKey];
10132
10391
  if (currentVal === prevVal) {
10133
10392
  continue;
@@ -10150,19 +10409,20 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10150
10409
  continue;
10151
10410
  }
10152
10411
  const ovs = field.overrides.filter((ov) => ov.defaultValue !== void 0).map((ov) => {
10153
- const parsed = parseDependsOn(ov.when);
10412
+ const parsed = useDatasourceSchema.parseDependsOn(ov.when);
10154
10413
  if (!parsed) {
10155
10414
  return null;
10156
10415
  }
10157
10416
  const depField = fieldById.get(parsed.field);
10158
10417
  return {
10159
- depKey: depField ? formKey(depField) : parsed.field,
10418
+ depKey: depField ? useDatasourceSchema.formKey(depField) : parsed.field,
10160
10419
  depValue: parsed.value,
10420
+ negate: parsed.negate,
10161
10421
  defaultValue: ov.defaultValue
10162
10422
  };
10163
10423
  }).filter(Boolean);
10164
10424
  if (ovs.length > 0) {
10165
- result.push({ targetKey: formKey(field), fieldDefault: field.defaultValue, overrides: ovs });
10425
+ result.push({ targetKey: useDatasourceSchema.formKey(field), fieldDefault: field.defaultValue, overrides: ovs });
10166
10426
  }
10167
10427
  }
10168
10428
  return result;
@@ -10175,42 +10435,70 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10175
10435
  }
10176
10436
  for (const { targetKey, fieldDefault, overrides } of fieldsWithOverrideDefaults) {
10177
10437
  for (const ov of overrides) {
10178
- const currentDepVal = String((_a = watchedValues[ov.depKey]) != null ? _a : "");
10438
+ const currentDepVal = String((_a = useDatasourceSchema.getWatchedValue(watchedValues, ov.depKey)) != null ? _a : "");
10179
10439
  const trackKey = `${targetKey}::${ov.depKey}`;
10180
10440
  const prevDepVal = prevOverrideDepRef.current[trackKey];
10181
10441
  if (currentDepVal === prevDepVal) {
10182
10442
  continue;
10183
10443
  }
10184
10444
  prevOverrideDepRef.current[trackKey] = currentDepVal;
10185
- if (currentDepVal === ov.depValue) {
10445
+ const active = useDatasourceSchema.evaluateDependsOn({ value: ov.depValue, negate: ov.negate }, currentDepVal);
10446
+ const wasActive = prevDepVal !== void 0 && useDatasourceSchema.evaluateDependsOn({ value: ov.depValue, negate: ov.negate }, prevDepVal);
10447
+ if (active) {
10186
10448
  setValue(targetKey, ov.defaultValue);
10187
- } else if (prevDepVal === ov.depValue && fieldDefault !== void 0) {
10449
+ } else if (wasActive && fieldDefault !== void 0) {
10188
10450
  setValue(targetKey, fieldDefault);
10189
10451
  }
10190
10452
  }
10191
10453
  }
10192
10454
  }, [watchedValues, fieldsWithOverrideDefaults, initializing, setValue]);
10455
+ const celContext = React.useMemo(() => {
10456
+ const ctx = {};
10457
+ for (const f of fieldById.values()) {
10458
+ const fk = useDatasourceSchema.formKey(f);
10459
+ const val = useDatasourceSchema.getWatchedValue(watchedValues, fk);
10460
+ if (val !== void 0) {
10461
+ const parts = f.id.split(".");
10462
+ let current = ctx;
10463
+ for (let i = 0; i < parts.length - 1; i++) {
10464
+ if (!(parts[i] in current) || typeof current[parts[i]] !== "object" || current[parts[i]] === null) {
10465
+ current[parts[i]] = {};
10466
+ }
10467
+ current = current[parts[i]];
10468
+ }
10469
+ current[parts[parts.length - 1]] = val;
10470
+ }
10471
+ }
10472
+ return ctx;
10473
+ }, [watchedValues, fieldById]);
10193
10474
  const isFieldVisible = React.useCallback(
10194
10475
  (field) => {
10195
- var _a, _b;
10196
- if (field.kind === "virtual" && !field.ui) {
10197
- return false;
10198
- }
10199
- if ((_a = field.tags) == null ? void 0 : _a.some((t) => t.startsWith("managed-by:"))) {
10200
- return false;
10201
- }
10202
- if (!field.dependsOn) {
10203
- return true;
10204
- }
10205
- const parsed = parseDependsOn(field.dependsOn);
10206
- if (!parsed) {
10207
- return true;
10476
+ function check(f, visited) {
10477
+ var _a;
10478
+ if (f.kind === "virtual" && !f.ui) {
10479
+ return false;
10480
+ }
10481
+ if ((_a = f.tags) == null ? void 0 : _a.some((t) => t.startsWith("managed-by:"))) {
10482
+ return false;
10483
+ }
10484
+ if (!f.dependsOn) {
10485
+ return true;
10486
+ }
10487
+ const refs = useDatasourceSchema.extractFieldRefs(f.dependsOn);
10488
+ for (const ref of refs) {
10489
+ const depField = fieldById.get(ref);
10490
+ if (depField && !visited.has(depField.id)) {
10491
+ visited.add(f.id);
10492
+ if (!check(depField, visited)) {
10493
+ return false;
10494
+ }
10495
+ }
10496
+ }
10497
+ return useDatasourceSchema.evaluateCelExpression(f.dependsOn, celContext);
10208
10498
  }
10209
- const depField = fieldById.get(parsed.field);
10210
- const depKey = depField ? formKey(depField) : parsed.field;
10211
- return String((_b = watchedValues[depKey]) != null ? _b : "") === parsed.value;
10499
+ return check(field, /* @__PURE__ */ new Set());
10212
10500
  },
10213
- [watchedValues, fieldById]
10501
+ [celContext, fieldById]
10214
10502
  );
10215
10503
  const onSubmit = React.useCallback(
10216
10504
  async (data) => {
@@ -10224,11 +10512,11 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10224
10512
  const defaults = {};
10225
10513
  for (const field of allStorageFields) {
10226
10514
  if (field.defaultValue !== void 0) {
10227
- defaults[formKey(field)] = field.defaultValue;
10515
+ defaults[useDatasourceSchema.formKey(field)] = field.defaultValue;
10228
10516
  }
10229
10517
  }
10230
10518
  const merged = { ...defaults, ...refreshed.values };
10231
- const virtualValues = computeVirtualFieldValues(schema, merged);
10519
+ const virtualValues = useDatasourceSchema.computeVirtualFieldValues(schema, merged);
10232
10520
  reset({ ...merged, ...virtualValues });
10233
10521
  onSuccess("UPDATED", "Configuration saved.");
10234
10522
  } catch (err) {
@@ -10247,11 +10535,11 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10247
10535
  if (!isFieldVisible(field)) {
10248
10536
  continue;
10249
10537
  }
10250
- if (errors[formKey(field)]) {
10538
+ if (errors[useDatasourceSchema.formKey(field)]) {
10251
10539
  return false;
10252
10540
  }
10253
- if (isFieldRequired(field, watchedValues, fieldById)) {
10254
- const val = watchedValues[formKey(field)];
10541
+ if (isFieldRequired(field, watchedValues, fieldById, celContext)) {
10542
+ const val = useDatasourceSchema.getWatchedValue(watchedValues, useDatasourceSchema.formKey(field));
10255
10543
  if (val === SECURE_FIELD_CONFIGURED) {
10256
10544
  continue;
10257
10545
  }
@@ -10262,12 +10550,21 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10262
10550
  }
10263
10551
  return true;
10264
10552
  },
10265
- [errors, watchedValues, fieldById, isFieldVisible]
10553
+ [errors, watchedValues, fieldById, celContext, isFieldVisible]
10554
+ );
10555
+ const isFieldDisabled = React.useCallback(
10556
+ (field) => {
10557
+ if (!field.disabledWhen) {
10558
+ return false;
10559
+ }
10560
+ return useDatasourceSchema.evaluateCelExpression(field.disabledWhen, celContext);
10561
+ },
10562
+ [celContext]
10266
10563
  );
10267
10564
  const groupHasData = React.useCallback(
10268
10565
  (group) => {
10269
10566
  for (const field of group.fields) {
10270
- const val = watchedValues[formKey(field)];
10567
+ const val = useDatasourceSchema.getWatchedValue(watchedValues, useDatasourceSchema.formKey(field));
10271
10568
  if (val === void 0 || val === null || val === "" || val === false) {
10272
10569
  continue;
10273
10570
  }
@@ -10291,6 +10588,7 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10291
10588
  trigger,
10292
10589
  errors,
10293
10590
  watchedValues,
10591
+ celContext,
10294
10592
  // State
10295
10593
  initializing,
10296
10594
  fetchError,
@@ -10299,9 +10597,11 @@ function useDatasourceConfigForm({ schema, dsUid, onSuccess, onSaving }) {
10299
10597
  readOnly,
10300
10598
  // Callbacks
10301
10599
  isFieldVisible,
10600
+ isFieldDisabled,
10302
10601
  isGroupValid,
10303
10602
  groupHasData,
10304
- onSubmit
10603
+ onSubmit,
10604
+ setValue
10305
10605
  };
10306
10606
  }
10307
10607
 
@@ -10348,13 +10648,16 @@ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, rend
10348
10648
  trigger,
10349
10649
  errors,
10350
10650
  watchedValues,
10651
+ celContext,
10351
10652
  initializing,
10352
10653
  fetchError,
10353
10654
  submitting,
10354
10655
  submitError,
10355
10656
  readOnly,
10356
10657
  isFieldVisible,
10357
- onSubmit
10658
+ isFieldDisabled,
10659
+ onSubmit,
10660
+ setValue
10358
10661
  } = form;
10359
10662
  const arrowSteps = React.useMemo(() => {
10360
10663
  const requiredGroup = resolvedGroups.find((g) => g.group.id === "_required");
@@ -10397,11 +10700,11 @@ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, rend
10397
10700
  return true;
10398
10701
  }
10399
10702
  for (const field of visibleFieldsForStep) {
10400
- if (errors[formKey(field)]) {
10703
+ if (errors[useDatasourceSchema.formKey(field)]) {
10401
10704
  return false;
10402
10705
  }
10403
- if (isFieldRequired(field, watchedValues, fieldById)) {
10404
- const val = watchedValues[formKey(field)];
10706
+ if (isFieldRequired(field, watchedValues, fieldById, celContext)) {
10707
+ const val = useDatasourceSchema.getWatchedValue(watchedValues, useDatasourceSchema.formKey(field));
10405
10708
  if (val === SECURE_FIELD_CONFIGURED) {
10406
10709
  continue;
10407
10710
  }
@@ -10411,13 +10714,13 @@ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, rend
10411
10714
  }
10412
10715
  }
10413
10716
  return true;
10414
- }, [currentResolved, errors, visibleFieldsForStep, watchedValues, fieldById]);
10717
+ }, [currentResolved, errors, visibleFieldsForStep, watchedValues, fieldById, celContext]);
10415
10718
  const goNext = React.useCallback(async () => {
10416
10719
  if (!currentResolved) {
10417
10720
  return;
10418
10721
  }
10419
10722
  if (!readOnly) {
10420
- const visibleKeys = visibleFieldsForStep.map((f) => formKey(f));
10723
+ const visibleKeys = visibleFieldsForStep.map((f) => useDatasourceSchema.formKey(f));
10421
10724
  const valid = await trigger(visibleKeys);
10422
10725
  if (!valid) {
10423
10726
  return;
@@ -10501,19 +10804,21 @@ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, rend
10501
10804
  )))), currentResolved && /* @__PURE__ */ React__default.default.createElement("form", { onSubmit: handleSubmit(onSubmit), className: styles.form }, visibleFieldsForStep.map((field) => /* @__PURE__ */ React__default.default.createElement(
10502
10805
  SchemaField,
10503
10806
  {
10504
- key: formKey(field),
10807
+ key: useDatasourceSchema.formKey(field),
10505
10808
  field,
10506
10809
  control,
10507
10810
  errors,
10508
- disabled: allDisabled,
10811
+ disabled: allDisabled || isFieldDisabled(field),
10509
10812
  dsUid,
10510
10813
  watchedValues,
10511
- fieldById
10814
+ fieldById,
10815
+ celContext,
10816
+ setValue
10512
10817
  }
10513
10818
  )), (currentResolved.group.id === "_required" || currentResolved.group.id === "auth") && httpHeadersField && /* @__PURE__ */ React__default.default.createElement(
10514
10819
  AuthorizationHeaderField,
10515
10820
  {
10516
- headersFieldKey: formKey(httpHeadersField),
10821
+ headersFieldKey: useDatasourceSchema.formKey(httpHeadersField),
10517
10822
  control,
10518
10823
  disabled: allDisabled,
10519
10824
  watchedValues
@@ -10521,6 +10826,155 @@ function WizardLayout({ form, schema, dsUid, dsName, onRetest, healthError, rend
10521
10826
  ), submitError && /* @__PURE__ */ React__default.default.createElement(ui.Alert, { severity: "error", title: "Error" }, submitError), /* @__PURE__ */ React__default.default.createElement("div", { className: styles.buttons }, readOnly ? /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "primary", size: "sm", icon: "sync", onClick: onRetest, type: "button" }, "Test") : /* @__PURE__ */ React__default.default.createElement(ui.Button, { variant: "primary", size: "sm", disabled: submitting || !currentGroupValid, type: "submit" }, submitting ? "Saving..." : "Save & Test"), healthError && (renderActions == null ? void 0 : renderActions({ dsUid, dsName, dsType: schema.pluginType, healthError })))));
10522
10827
  }
10523
10828
 
10829
+ var __defProp$2 = Object.defineProperty;
10830
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10831
+ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, key + "" , value);
10832
+ class DatasourceErrorBoundary extends React.Component {
10833
+ constructor() {
10834
+ super(...arguments);
10835
+ __publicField$2(this, "state", { error: null });
10836
+ }
10837
+ static getDerivedStateFromError(error) {
10838
+ return { error };
10839
+ }
10840
+ componentDidCatch(error, info) {
10841
+ console.error("[DatasourceConfigWizard] Caught error:", error, info.componentStack);
10842
+ }
10843
+ render() {
10844
+ if (this.state.error) {
10845
+ return /* @__PURE__ */ React__default.default.createElement(ui.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.");
10846
+ }
10847
+ return this.props.children;
10848
+ }
10849
+ }
10850
+
10851
+ const MAX_CONCURRENCY = 5;
10852
+ function useHealthChecks() {
10853
+ const [healthMap, setHealthMap] = React.useState({});
10854
+ const queueRef = React.useRef([]);
10855
+ const activeRef = React.useRef(0);
10856
+ const mountedRef = React.useRef(true);
10857
+ const everQueuedRef = React.useRef(/* @__PURE__ */ new Set());
10858
+ const checkOne = React.useCallback(async (uid) => {
10859
+ if (!mountedRef.current) {
10860
+ return;
10861
+ }
10862
+ setHealthMap((prev) => ({ ...prev, [uid]: { state: "checking" } }));
10863
+ try {
10864
+ const result = await runtime.getBackendSrv().get(
10865
+ `/api/datasources/uid/${uid}/health`,
10866
+ void 0,
10867
+ void 0,
10868
+ { showErrorAlert: false }
10869
+ );
10870
+ if (!mountedRef.current) {
10871
+ return;
10872
+ }
10873
+ setHealthMap((prev) => {
10874
+ var _a;
10875
+ return {
10876
+ ...prev,
10877
+ [uid]: { state: "done", status: (_a = result.status) != null ? _a : "OK", message: result.message }
10878
+ };
10879
+ });
10880
+ } catch (error) {
10881
+ if (!mountedRef.current) {
10882
+ return;
10883
+ }
10884
+ let status = "ERROR";
10885
+ let message = "";
10886
+ if (error && typeof error === "object" && "data" in error) {
10887
+ const data = error.data;
10888
+ if (data == null ? void 0 : data.status) {
10889
+ status = data.status;
10890
+ }
10891
+ if (data == null ? void 0 : data.message) {
10892
+ message = data.message;
10893
+ }
10894
+ }
10895
+ if (!message) {
10896
+ message = error instanceof Error ? error.message : String(error);
10897
+ }
10898
+ setHealthMap((prev) => ({
10899
+ ...prev,
10900
+ [uid]: { state: "done", status, message }
10901
+ }));
10902
+ }
10903
+ }, []);
10904
+ const processQueue = React.useCallback(() => {
10905
+ while (activeRef.current < MAX_CONCURRENCY && queueRef.current.length > 0) {
10906
+ const uid = queueRef.current.shift();
10907
+ activeRef.current++;
10908
+ checkOne(uid).finally(() => {
10909
+ activeRef.current--;
10910
+ processQueue();
10911
+ });
10912
+ }
10913
+ }, [checkOne]);
10914
+ const checkUids = React.useCallback(
10915
+ (uids) => {
10916
+ const toCheck = [];
10917
+ for (const uid of uids) {
10918
+ if (everQueuedRef.current.has(uid)) {
10919
+ continue;
10920
+ }
10921
+ everQueuedRef.current.add(uid);
10922
+ toCheck.push(uid);
10923
+ }
10924
+ if (toCheck.length === 0) {
10925
+ return;
10926
+ }
10927
+ setHealthMap((prev) => {
10928
+ const next = { ...prev };
10929
+ for (const uid of toCheck) {
10930
+ next[uid] = { state: "pending" };
10931
+ }
10932
+ return next;
10933
+ });
10934
+ queueRef.current.push(...toCheck);
10935
+ processQueue();
10936
+ },
10937
+ [processQueue]
10938
+ );
10939
+ const retry = React.useCallback(
10940
+ (uid) => {
10941
+ everQueuedRef.current.delete(uid);
10942
+ everQueuedRef.current.add(uid);
10943
+ setHealthMap((prev) => ({ ...prev, [uid]: { state: "pending" } }));
10944
+ queueRef.current.push(uid);
10945
+ processQueue();
10946
+ },
10947
+ [processQueue]
10948
+ );
10949
+ return { healthMap, checkUids, retry };
10950
+ }
10951
+
10952
+ let pluginNameCache = null;
10953
+ function buildPluginNameCache() {
10954
+ var _a;
10955
+ if (pluginNameCache) {
10956
+ return pluginNameCache;
10957
+ }
10958
+ const map = /* @__PURE__ */ new Map();
10959
+ try {
10960
+ const list = runtime.getDataSourceSrv().getList();
10961
+ for (const ds of list) {
10962
+ if (((_a = ds.meta) == null ? void 0 : _a.name) && ds.type && !map.has(ds.type)) {
10963
+ map.set(ds.type, ds.meta.name);
10964
+ }
10965
+ }
10966
+ } catch (ex) {
10967
+ console.error(ex);
10968
+ }
10969
+ pluginNameCache = map;
10970
+ return map;
10971
+ }
10972
+ function resolvePluginName(pluginType) {
10973
+ var _a;
10974
+ const cache = buildPluginNameCache();
10975
+ return (_a = cache.get(pluginType)) != null ? _a : pluginType;
10976
+ }
10977
+
10524
10978
  var __defProp$1 = Object.defineProperty;
10525
10979
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10526
10980
  var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -11974,411 +12428,34 @@ const convertUnits = (queryStats) => {
11974
12428
  return text + suffix;
11975
12429
  };
11976
12430
 
11977
- function generateLLMHint(schema) {
11978
- var _a, _b, _c, _d;
11979
- const hints = [];
11980
- for (const field of schema.fields) {
11981
- if (((_a = field.ui) == null ? void 0 : _a.component) !== "select" || field.target !== "jsonData" || field.kind === "virtual") {
11982
- continue;
11983
- }
11984
- const options = (_c = (_b = field.ui) == null ? void 0 : _b.options) != null ? _c : [];
11985
- const values = options.map((opt) => {
11986
- const isDefault = field.defaultValue != null && String(opt.value) === String(field.defaultValue);
11987
- return isDefault ? `"${opt.value}" (default)` : `"${opt.value}"`;
11988
- }).join(", ");
11989
- if (values) {
11990
- hints.push(`- ${(_d = field.label) != null ? _d : field.key}: jsonData.${field.key} \u2014 values: ${values}`);
11991
- }
11992
- }
11993
- return hints.join("\n");
11994
- }
11995
- function generateTroubleshootingFields(schema) {
11996
- var _a, _b, _c;
11997
- const result = [];
11998
- for (const field of schema.fields) {
11999
- if (field.kind === "virtual" || field.isItemField) {
12000
- continue;
12001
- }
12002
- const entry = {
12003
- label: (_a = field.label) != null ? _a : field.key,
12004
- key: field.target === "root" ? field.key : `${field.target}.${field.key}`,
12005
- target: (_b = field.target) != null ? _b : "jsonData",
12006
- type: field.valueType,
12007
- required: !!field.required
12008
- };
12009
- if (field.description) {
12010
- entry.description = field.description;
12011
- }
12012
- if (field.defaultValue != null) {
12013
- entry.defaultValue = field.defaultValue;
12014
- }
12015
- if (((_c = field.ui) == null ? void 0 : _c.options) && field.ui.options.length > 0) {
12016
- entry.options = field.ui.options.map((o) => String(o.value));
12017
- }
12018
- if (field.section) {
12019
- entry.section = field.section;
12020
- }
12021
- if (field.dependsOn) {
12022
- entry.dependsOn = field.dependsOn;
12023
- }
12024
- result.push(entry);
12025
- }
12026
- return result;
12027
- }
12028
-
12029
- function yamlIndent(depth) {
12030
- return " ".repeat(depth);
12031
- }
12032
- function yamlString(value) {
12033
- if (value === null || value === void 0) {
12034
- return '""';
12035
- }
12036
- const s = String(value);
12037
- if (s === "") {
12038
- return '""';
12039
- }
12040
- return yaml__default.default.dump(s, { lineWidth: -1 }).trimEnd();
12041
- }
12042
- function yamlValue(value, depth) {
12043
- if (value === null || value === void 0) {
12044
- return '""';
12045
- }
12046
- if (typeof value === "boolean") {
12047
- return value ? "true" : "false";
12048
- }
12049
- if (typeof value === "number") {
12050
- return String(value);
12051
- }
12052
- if (typeof value === "string") {
12053
- return yamlString(value);
12054
- }
12055
- if (Array.isArray(value)) {
12056
- if (value.length === 0) {
12057
- return "[]";
12058
- }
12059
- const lines = value.map((item) => {
12060
- if (typeof item === "object" && item !== null && !Array.isArray(item)) {
12061
- const entries = Object.entries(item);
12062
- if (entries.length === 0) {
12063
- return `${yamlIndent(depth)}- {}`;
12064
- }
12065
- const [firstKey, firstVal] = entries[0];
12066
- const firstLine = `${yamlIndent(depth)}- ${yamlString(firstKey)}: ${yamlValue(firstVal, depth + 2)}`;
12067
- const rest = entries.slice(1).map(([k, v]) => `${yamlIndent(depth + 1)}${yamlString(k)}: ${yamlValue(v, depth + 2)}`);
12068
- return [firstLine, ...rest].join("\n");
12069
- }
12070
- return `${yamlIndent(depth)}- ${yamlValue(item, depth + 1)}`;
12071
- });
12072
- return "\n" + lines.join("\n");
12073
- }
12074
- if (typeof value === "object") {
12075
- const entries = Object.entries(value);
12076
- if (entries.length === 0) {
12077
- return "{}";
12078
- }
12079
- const lines = entries.map(([k, v]) => `${yamlIndent(depth)}${yamlString(k)}: ${yamlValue(v, depth + 1)}`);
12080
- return "\n" + lines.join("\n");
12081
- }
12082
- return yamlString(value);
12083
- }
12084
- function isCertField(field) {
12085
- var _a;
12086
- const k = field.key.toLowerCase();
12087
- return field.target === "secureJsonData" && (k.includes("cert") || k.includes("key") || ((_a = field.ui) == null ? void 0 : _a.component) === "textarea");
12088
- }
12089
- function isExcludedFromProvisioning(field) {
12090
- var _a, _b;
12091
- if (field.kind === "virtual") {
12092
- return true;
12093
- }
12094
- if (field.isItemField) {
12095
- return true;
12096
- }
12097
- if (((_a = field.tags) == null ? void 0 : _a.some((t) => t.startsWith("managed-by:"))) && field.target !== "root") {
12098
- return true;
12099
- }
12100
- if (((_b = field.storage) == null ? void 0 : _b.type) === "indexedPair") {
12101
- return true;
12102
- }
12103
- return false;
12104
- }
12105
- function secretPlaceholder(field) {
12106
- if (isCertField(field)) {
12107
- return "|\n xxxxxx";
12108
- }
12109
- return "xxxxxx";
12110
- }
12111
- function templateValue(field) {
12112
- var _a;
12113
- if (field.defaultValue !== void 0) {
12114
- return field.defaultValue;
12115
- }
12116
- if (((_a = field.ui) == null ? void 0 : _a.options) && field.ui.options.length > 0) {
12117
- return field.ui.options[0].value;
12118
- }
12119
- switch (field.valueType) {
12120
- case "string":
12121
- return "";
12122
- case "number":
12123
- return 0;
12124
- case "boolean":
12125
- return false;
12126
- case "array":
12127
- return [];
12128
- case "object":
12129
- case "map":
12130
- return {};
12131
- default:
12132
- return "";
12133
- }
12134
- }
12135
- function fieldComment(field, indent) {
12136
- var _a, _b, _c;
12137
- const parts = [];
12138
- const label = (_a = field.label) != null ? _a : field.key;
12139
- let line = label;
12140
- if (field.required) {
12141
- line += " (REQUIRED)";
12142
- }
12143
- if (field.description) {
12144
- line += ` \u2014 ${field.description}`;
12145
- }
12146
- parts.push(`${indent}# ${line}`);
12147
- const options = (_b = field.ui) == null ? void 0 : _b.options;
12148
- if (options && options.length > 0) {
12149
- const vals = options.map((o) => String(o.value)).join(", ");
12150
- parts.push(`${indent}# Allowed values: ${vals}`);
12151
- }
12152
- const allowedValuesRule = (_c = field.validations) == null ? void 0 : _c.find(
12153
- (v) => v.type === "allowedValues"
12154
- );
12155
- if (allowedValuesRule && !options) {
12156
- const vals = allowedValuesRule.values.map((v) => String(v)).join(", ");
12157
- parts.push(`${indent}# Allowed values: ${vals}`);
12158
- }
12159
- if (field.dependsOn) {
12160
- parts.push(`${indent}# Only when: ${field.dependsOn}`);
12161
- }
12162
- return parts.join("\n");
12163
- }
12164
- function toProvisioningYaml(schema, values, options) {
12165
- var _a, _b, _c, _d, _e, _f;
12166
- const isTemplate = !values;
12167
- const showComments = (_a = options == null ? void 0 : options.comments) != null ? _a : isTemplate;
12168
- const indent2 = " ";
12169
- const indent3 = " ";
12170
- const groups = resolveGroups(schema);
12171
- const rootFields = [];
12172
- const jsonDataFieldsByGroup = [];
12173
- const secureJsonDataFieldsByGroup = [];
12174
- const virtualFieldsWithOptions = [];
12175
- for (const { group, fields } of groups) {
12176
- const jd = [];
12177
- const sd = [];
12178
- for (const field of fields) {
12179
- if (field.kind === "virtual" && ((_b = field.ui) == null ? void 0 : _b.options) && field.ui.options.length > 0) {
12180
- virtualFieldsWithOptions.push(field);
12181
- continue;
12182
- }
12183
- if (isExcludedFromProvisioning(field)) {
12184
- continue;
12185
- }
12186
- switch (field.target) {
12187
- case "root":
12188
- rootFields.push(field);
12189
- break;
12190
- case "jsonData":
12191
- jd.push(field);
12192
- break;
12193
- case "secureJsonData":
12194
- sd.push(field);
12195
- break;
12196
- }
12197
- }
12198
- if (jd.length > 0) {
12199
- jsonDataFieldsByGroup.push({ group, fields: jd });
12200
- }
12201
- if (sd.length > 0) {
12202
- secureJsonDataFieldsByGroup.push({ group, fields: sd });
12203
- }
12204
- }
12205
- const allSecureJsonDataFields = secureJsonDataFieldsByGroup.flatMap((g) => g.fields);
12206
- const groupedFieldIds = new Set(groups.flatMap(({ group }) => group.fieldRefs));
12207
- for (const field of schema.fields) {
12208
- if (field.target === "root" && !groupedFieldIds.has(field.id) && !isExcludedFromProvisioning(field)) {
12209
- rootFields.push(field);
12210
- }
12211
- }
12212
- const lines = [];
12213
- lines.push("apiVersion: 1");
12214
- lines.push("");
12215
- lines.push("datasources:");
12216
- lines.push(`${indent2.slice(2)}- name: ${yamlString((_d = (_c = options == null ? void 0 : options.name) != null ? _c : values == null ? void 0 : values.name) != null ? _d : `my-${schema.pluginType}`)}`);
12217
- lines.push(`${indent2}type: ${schema.pluginType}`);
12218
- if (!isTemplate && (values == null ? void 0 : values.uid)) {
12219
- lines.push(`${indent2}uid: ${yamlString(values.uid)}`);
12220
- }
12221
- const ALREADY_EMITTED_ROOT = /* @__PURE__ */ new Set(["name", "type", "uid"]);
12222
- for (const field of rootFields) {
12223
- if (ALREADY_EMITTED_ROOT.has(field.key)) {
12224
- continue;
12225
- }
12226
- const val = values ? values[field.key] : templateValue(field);
12227
- if (val === void 0 || val === null) {
12228
- continue;
12229
- }
12230
- if (!isTemplate && val === false) {
12231
- continue;
12232
- }
12233
- if (showComments) {
12234
- lines.push(fieldComment(field, indent2));
12235
- }
12236
- lines.push(`${indent2}${field.key}: ${yamlValue(val, 3)}`);
12237
- }
12238
- if (showComments) {
12239
- for (const vf of virtualFieldsWithOptions) {
12240
- const label = (_e = vf.label) != null ? _e : vf.key;
12241
- const opts = vf.ui.options.map((o) => `${String(o.value)} (${o.label})`).join(", ");
12242
- lines.push(`${indent2}# ${label}: ${opts}`);
12243
- if (vf.description) {
12244
- lines.push(`${indent2}# ${vf.description}`);
12245
- }
12246
- }
12247
- }
12248
- const emittedJsonDataKeys = /* @__PURE__ */ new Set();
12249
- const emittedSecureJsonDataKeys = /* @__PURE__ */ new Set();
12250
- const jsonDataValues = values == null ? void 0 : values.jsonData;
12251
- const hasJsonDataFromSchema = jsonDataFieldsByGroup.length > 0;
12252
- const hasJsonDataFromValues = !isTemplate && jsonDataValues && Object.keys(jsonDataValues).length > 0;
12253
- if (hasJsonDataFromSchema || hasJsonDataFromValues) {
12254
- lines.push(`${indent2}jsonData:`);
12255
- for (const { group, fields: groupFields } of jsonDataFieldsByGroup) {
12256
- if (showComments && jsonDataFieldsByGroup.length > 1) {
12257
- lines.push(`${indent3}# --- ${group.title} ---`);
12258
- }
12259
- for (const field of groupFields) {
12260
- const val = values ? getNestedValue(values, "jsonData", field) : templateValue(field);
12261
- if (val === void 0 || val === null) {
12262
- continue;
12263
- }
12264
- if (!isTemplate && field.defaultValue !== void 0 && val === field.defaultValue) {
12265
- continue;
12266
- }
12267
- emittedJsonDataKeys.add(field.key);
12268
- if (showComments) {
12269
- lines.push(fieldComment(field, indent3));
12270
- }
12271
- const rendered = yamlValue(val, 4);
12272
- if (rendered.startsWith("\n")) {
12273
- lines.push(`${indent3}${field.key}:${rendered}`);
12274
- } else {
12275
- lines.push(`${indent3}${field.key}: ${rendered}`);
12276
- }
12277
- }
12278
- }
12279
- if (!isTemplate && jsonDataValues) {
12280
- for (const [key, val] of Object.entries(jsonDataValues)) {
12281
- if (emittedJsonDataKeys.has(key)) {
12282
- continue;
12283
- }
12284
- if (val === void 0 || val === null) {
12285
- continue;
12286
- }
12287
- const rendered = yamlValue(val, 4);
12288
- if (rendered.startsWith("\n")) {
12289
- lines.push(`${indent3}${key}:${rendered}`);
12290
- } else {
12291
- lines.push(`${indent3}${key}: ${rendered}`);
12292
- }
12293
- }
12294
- }
12295
- }
12296
- const secureJsonFields = (_f = values == null ? void 0 : values.secureJsonFields) != null ? _f : {};
12297
- const inferredSecureKeys = !isTemplate ? inferSecureJsonDataKeys(jsonDataValues) : [];
12298
- const activeSecureFields = isTemplate ? allSecureJsonDataFields : allSecureJsonDataFields.filter((f) => secureJsonFields[f.key] === true);
12299
- if (activeSecureFields.length > 0 || inferredSecureKeys.length > 0) {
12300
- lines.push(`${indent2}secureJsonData:`);
12301
- for (const field of activeSecureFields) {
12302
- emittedSecureJsonDataKeys.add(field.key);
12303
- if (showComments) {
12304
- lines.push(fieldComment(field, indent3));
12305
- }
12306
- lines.push(`${indent3}${field.key}: ${secretPlaceholder(field)}`);
12307
- }
12308
- for (const key of inferredSecureKeys) {
12309
- if (emittedSecureJsonDataKeys.has(key)) {
12310
- continue;
12311
- }
12312
- lines.push(`${indent3}${key}: xxxxxx`);
12313
- }
12314
- }
12315
- return lines.join("\n");
12316
- }
12317
- function inferSecureJsonDataKeys(jsonData) {
12318
- if (!jsonData) {
12319
- return [];
12320
- }
12321
- const keys = [];
12322
- for (const key of Object.keys(jsonData)) {
12323
- const match = key.match(/^httpHeaderName(\d+)$/);
12324
- if (match) {
12325
- keys.push(`httpHeaderValue${match[1]}`);
12326
- }
12327
- }
12328
- return keys;
12329
- }
12330
- function getNestedValue(values, target, field) {
12331
- const nested = values[target];
12332
- if (nested && typeof nested === "object") {
12333
- return nested[field.key];
12334
- }
12335
- return void 0;
12336
- }
12337
- function datasourceToProvisioningYaml(ds, schema) {
12338
- if (schema) {
12339
- return toProvisioningYaml(schema, ds, { comments: false });
12340
- }
12341
- const lines = [];
12342
- lines.push("apiVersion: 1");
12343
- lines.push("");
12344
- lines.push("datasources:");
12345
- lines.push(` - name: ${yamlString(ds.name)}`);
12346
- if (ds.uid) {
12347
- lines.push(` uid: ${yamlString(ds.uid)}`);
12348
- }
12349
- lines.push(` type: ${yamlString(ds.type)}`);
12350
- if (ds.url) {
12351
- lines.push(` url: ${yamlString(ds.url)}`);
12352
- }
12353
- if (ds.database) {
12354
- lines.push(` database: ${yamlString(ds.database)}`);
12355
- }
12356
- if (ds.isDefault) {
12357
- lines.push(" isDefault: true");
12358
- }
12359
- if (ds.basicAuth) {
12360
- lines.push(" basicAuth: true");
12361
- if (ds.basicAuthUser) {
12362
- lines.push(` basicAuthUser: ${yamlString(ds.basicAuthUser)}`);
12363
- }
12364
- }
12365
- const jsonData = ds.jsonData;
12366
- if (jsonData && Object.keys(jsonData).length > 0) {
12367
- lines.push(" jsonData:");
12368
- for (const [key, val] of Object.entries(jsonData)) {
12369
- const rendered = yamlValue(val, 4);
12370
- if (rendered.startsWith("\n")) {
12371
- lines.push(` ${key}:${rendered}`);
12372
- } else {
12373
- lines.push(` ${key}: ${rendered}`);
12374
- }
12375
- }
12376
- }
12377
- lines.push(" # secureJsonData: (secrets are not exported \u2014 add manually)");
12378
- lines.push(" # mySecret: xxxxxx");
12379
- return lines.join("\n");
12380
- }
12381
-
12431
+ exports.ROOT_CONFIG_FIELDS = useDatasourceSchema.ROOT_CONFIG_FIELDS;
12432
+ exports.buildCelContext = useDatasourceSchema.buildCelContext;
12433
+ exports.buildCloneDatasourcePayload = useDatasourceSchema.buildCloneDatasourcePayload;
12434
+ exports.buildCreateDatasourcePayload = useDatasourceSchema.buildCreateDatasourcePayload;
12435
+ exports.buildUpdateDatasourcePayload = useDatasourceSchema.buildUpdateDatasourcePayload;
12436
+ exports.clearExpressionCache = useDatasourceSchema.clearExpressionCache;
12437
+ exports.computeVirtualFieldValues = useDatasourceSchema.computeVirtualFieldValues;
12438
+ exports.configToYaml = useDatasourceSchema.configToYaml;
12439
+ exports.datasourceToProvisioningYaml = useDatasourceSchema.datasourceToProvisioningYaml;
12440
+ exports.evaluateCelDirect = useDatasourceSchema.evaluateCelDirect;
12441
+ exports.evaluateCelExpression = useDatasourceSchema.evaluateCelExpression;
12442
+ exports.evaluateComputedRead = useDatasourceSchema.evaluateComputedRead;
12443
+ exports.evaluateDependsOn = useDatasourceSchema.evaluateDependsOn;
12444
+ exports.extractFieldRefs = useDatasourceSchema.extractFieldRefs;
12445
+ exports.fetchConfigSchema = useDatasourceSchema.fetchConfigSchema;
12446
+ exports.formKey = useDatasourceSchema.formKey;
12447
+ exports.formatYamlDiff = useDatasourceSchema.formatYamlDiff;
12448
+ exports.generateLLMHint = useDatasourceSchema.generateLLMHint;
12449
+ exports.generateTroubleshootingFields = useDatasourceSchema.generateTroubleshootingFields;
12450
+ exports.getConfigSchema = useDatasourceSchema.getConfigSchema;
12451
+ exports.getWatchedValue = useDatasourceSchema.getWatchedValue;
12452
+ exports.isValidCelExpression = useDatasourceSchema.isValidCelExpression;
12453
+ exports.parseDependsOn = useDatasourceSchema.parseDependsOn;
12454
+ exports.resolveActiveOverride = useDatasourceSchema.resolveActiveOverride;
12455
+ exports.resolveGroups = useDatasourceSchema.resolveGroups;
12456
+ exports.resolveRequiredFieldsGroup = useDatasourceSchema.resolveRequiredFieldsGroup;
12457
+ exports.toProvisioningYaml = useDatasourceSchema.toProvisioningYaml;
12458
+ exports.useDatasourceSchema = useDatasourceSchema.useDatasourceSchema;
12382
12459
  exports.AccessoryButton = AccessoryButton;
12383
12460
  exports.AdvancedHttpSettings = AdvancedHttpSettings;
12384
12461
  exports.Auth = Auth;
@@ -12399,6 +12476,7 @@ exports.DataSourceDescription = DataSourceDescription;
12399
12476
  exports.DataSourcePicker = DataSourcePicker;
12400
12477
  exports.DatasetSelector = DatasetSelector;
12401
12478
  exports.DatasourceConfigWizard = DatasourceConfigWizard;
12479
+ exports.DatasourceErrorBoundary = DatasourceErrorBoundary;
12402
12480
  exports.DatePicker = DatePicker;
12403
12481
  exports.DatePickerWithInput = DatePickerWithInput;
12404
12482
  exports.DebounceInput = DebounceInput;
@@ -12434,7 +12512,6 @@ exports.QueryModellerBase = QueryModellerBase;
12434
12512
  exports.QueryOptionGroup = QueryOptionGroup;
12435
12513
  exports.RawQuery = RawQuery;
12436
12514
  exports.RunQueryButton = RunQueryButton;
12437
- exports.SECURE_FIELD_CONFIGURED = SECURE_FIELD_CONFIGURED;
12438
12515
  exports.SQLEditor = SQLEditor;
12439
12516
  exports.SQLEditorMode = SQLEditorMode;
12440
12517
  exports.SQLEditorTestUtils = SQLEditorTestUtils;
@@ -12448,26 +12525,12 @@ exports.SuggestionKind = SuggestionKind;
12448
12525
  exports.TLSSettings = TLSSettings;
12449
12526
  exports.TableSelector = TableSelector;
12450
12527
  exports.TokenType = TokenType;
12451
- exports.buildDatasourceConfigPayload = buildDatasourceConfigPayload;
12452
- exports.computeVirtualFieldValues = computeVirtualFieldValues;
12453
12528
  exports.convertLegacyAuthProps = convertLegacyAuthProps;
12454
- exports.datasourceToProvisioningYaml = datasourceToProvisioningYaml;
12455
- exports.evaluateComputedRead = evaluateComputedRead;
12456
- exports.expandIndexedPair = expandIndexedPair;
12457
- exports.fetchExistingValues = fetchExistingValues;
12458
- exports.flattenIndexedPair = flattenIndexedPair;
12459
- exports.formKey = formKey;
12460
12529
  exports.formatDate = formatDate;
12461
- exports.generateLLMHint = generateLLMHint;
12462
- exports.generateTroubleshootingFields = generateTroubleshootingFields;
12463
12530
  exports.getStandardSQLCompletionProvider = getStandardSQLCompletionProvider;
12464
12531
  exports.grafanaStandardSQLLanguage = language;
12465
12532
  exports.grafanaStandardSQLLanguageConf = conf;
12466
- exports.parseDependsOn = parseDependsOn;
12467
- exports.resolveActiveOverride = resolveActiveOverride;
12468
- exports.resolveGroups = resolveGroups;
12469
- exports.resolveRequiredFieldsGroup = resolveRequiredFieldsGroup;
12470
- exports.submitDatasourceConfig = submitDatasourceConfig;
12533
+ exports.resolvePluginName = resolvePluginName;
12471
12534
  exports.toOption = toOption;
12472
- exports.toProvisioningYaml = toProvisioningYaml;
12535
+ exports.useHealthChecks = useHealthChecks;
12473
12536
  //# sourceMappingURL=index.cjs.map