@lunora/studio 1.0.0-alpha.59 → 1.0.0-alpha.60

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 (381) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +1 -43
  3. package/dist/mount.js +1 -27
  4. package/dist/packem_chunks/ApiTab.js +1 -251
  5. package/dist/packem_chunks/AuditPanel.js +1 -200
  6. package/dist/packem_chunks/DeploymentHealthPanel.js +1 -664
  7. package/dist/packem_chunks/ExportImportPanel.js +3 -198
  8. package/dist/packem_chunks/FileBrowser.js +4 -2955
  9. package/dist/packem_chunks/FunctionRunner.js +1 -326
  10. package/dist/packem_chunks/FunctionStatsPanel.js +1 -377
  11. package/dist/packem_chunks/HealthPanel.js +1 -648
  12. package/dist/packem_chunks/InsightsPanel.js +1 -462
  13. package/dist/packem_chunks/LogsPanel.js +1 -1303
  14. package/dist/packem_chunks/MailPanel.js +2 -353
  15. package/dist/packem_chunks/MetricsPanel.js +1 -1960
  16. package/dist/packem_chunks/MigrationsPanel.js +1 -239
  17. package/dist/packem_chunks/NotificationsPanel.js +1 -306
  18. package/dist/packem_chunks/PitrPanel.js +1 -252
  19. package/dist/packem_chunks/SchemaViewer.js +1 -2512
  20. package/dist/packem_chunks/SecurityAdvisorPanel.js +1 -95
  21. package/dist/packem_chunks/SettingsPanel.js +1 -391
  22. package/dist/packem_chunks/SqlEditorPanel.js +4 -2340
  23. package/dist/packem_chunks/TableEditor.js +1 -290
  24. package/dist/packem_chunks/agents-panel.js +1 -326
  25. package/dist/packem_chunks/analytics-panel.js +1 -261
  26. package/dist/packem_chunks/auth-audit-panel.js +1 -247
  27. package/dist/packem_chunks/auth-config-panel.js +1 -365
  28. package/dist/packem_chunks/auth-sessions-panel.js +1 -175
  29. package/dist/packem_chunks/containers-panel.js +1 -261
  30. package/dist/packem_chunks/dashboards-panel.js +1 -781
  31. package/dist/packem_chunks/fanout-panel.js +1 -482
  32. package/dist/packem_chunks/flags-panel.js +1 -176
  33. package/dist/packem_chunks/issues-panel.js +1 -427
  34. package/dist/packem_chunks/kv-browser.js +1 -1896
  35. package/dist/packem_chunks/log-drains-panel.js +4 -273
  36. package/dist/packem_chunks/organizations-panel.js +1 -3209
  37. package/dist/packem_chunks/payments-panel.js +1 -213
  38. package/dist/packem_chunks/permissions-panel.js +1 -805
  39. package/dist/packem_chunks/queues-panel.js +1 -1075
  40. package/dist/packem_chunks/rls-panel.js +1 -315
  41. package/dist/packem_chunks/schedule-panel.js +1 -831
  42. package/dist/packem_chunks/sparkline.js +1 -79
  43. package/dist/packem_chunks/storage-rules-panel.js +1 -140
  44. package/dist/packem_chunks/subscriptions-panel.js +1 -238
  45. package/dist/packem_chunks/sync-client-panel.js +1 -0
  46. package/dist/packem_chunks/traces-panel.js +1 -747
  47. package/dist/packem_chunks/users-panel.js +1 -1731
  48. package/dist/packem_chunks/vector-browser.js +1 -281
  49. package/dist/packem_chunks/workflows-panel.js +1 -562
  50. package/dist/packem_shared/ADMIN_FUNCTIONS-BYNSbBVE.js +1 -0
  51. package/dist/packem_shared/ApiDocsPanel-eJYZlylw.js +2 -0
  52. package/dist/packem_shared/ApiReferencePanel-C42v1jr6.js +1 -0
  53. package/dist/packem_shared/CommandPalette-CVIaY3j8.js +1 -0
  54. package/dist/packem_shared/ConfirmButton-CTL3f3kr.js +1 -0
  55. package/dist/packem_shared/ConnectionBadge-DOk0CQWo.js +1 -0
  56. package/dist/packem_shared/DEFAULT_AUTO_REFRESH_MS-BCC8_4BQ.js +1 -0
  57. package/dist/packem_shared/DEFAULT_INSIGHT_THRESHOLDS-B-hcFVoi.js +1 -0
  58. package/dist/packem_shared/DEFAULT_LOCALE-BZ4NojpD.js +1 -0
  59. package/dist/packem_shared/DataBrowser-B8J5lHjP.js +1 -0
  60. package/dist/packem_shared/DataFilters-Csb30F0C.js +1 -0
  61. package/dist/packem_shared/ErrorBoundary-DvzYskH7.js +1 -0
  62. package/dist/packem_shared/GlobalDataBrowser-RLJ6NvOs.js +1 -0
  63. package/dist/packem_shared/HomePanel-DL1HupAN.js +1 -0
  64. package/dist/packem_shared/OpenRpcReferencePanel-sGsIgYWj.js +1 -0
  65. package/dist/packem_shared/STUDIO_ROOT_CLASS-C6MccdVk.js +1 -0
  66. package/dist/packem_shared/ScheduledJobs-DUbo6epc.js +1 -0
  67. package/dist/packem_shared/ShardInput-BVn2iCU0.js +1 -0
  68. package/dist/packem_shared/Studio-BWBclm_C.js +1 -0
  69. package/dist/packem_shared/StudioApp-BFm73yVr.js +1 -0
  70. package/dist/packem_shared/StudioI18nProvider-CZ5h4nrV.js +1 -0
  71. package/dist/packem_shared/advisor-view-DaCX9Jy5.js +1 -0
  72. package/dist/packem_shared/aggregateMetrics-BNfajLa2.js +1 -0
  73. package/dist/packem_shared/alert-CVcOFuDR.js +1 -0
  74. package/dist/packem_shared/badge-BbuuAio7.js +1 -0
  75. package/dist/packem_shared/bar-chart-AryFCeoa.js +9 -0
  76. package/dist/packem_shared/browser-storage-xjTyMKY0.js +1 -0
  77. package/dist/packem_shared/button-BkCrNcAs.js +1 -0
  78. package/dist/packem_shared/card-CIDGUN6K.js +1 -0
  79. package/dist/packem_shared/cf-links-gbDy51nR.js +1 -0
  80. package/dist/packem_shared/checkbox-StT4Gob6.js +1 -0
  81. package/dist/packem_shared/data-grid-BMBKzMEJ.js +1 -0
  82. package/dist/packem_shared/data-view-params-C8T3bW1z.js +1 -0
  83. package/dist/packem_shared/dropdown-menu-C3RQ_HlW.js +2 -0
  84. package/dist/packem_shared/empty-state-Cg7t_8qu.js +1 -0
  85. package/dist/packem_shared/error-alert-B59DnrDI.js +1 -0
  86. package/dist/packem_shared/grid-features-uZCUj955.js +6 -0
  87. package/dist/packem_shared/home-panel-B-8BCffw.js +3 -0
  88. package/dist/packem_shared/input-JHu63lTv.js +1 -0
  89. package/dist/packem_shared/internal-AtZ4bTal.js +2 -0
  90. package/dist/packem_shared/label-6uP1obNF.js +1 -0
  91. package/dist/packem_shared/live-status-CGW2JHf_.js +1 -0
  92. package/dist/packem_shared/log-fields-CoL3hsIQ.js +1 -0
  93. package/dist/packem_shared/modal-shell-CUwwWC2o.js +1 -0
  94. package/dist/packem_shared/reference-view-KvhektwF.js +12 -0
  95. package/dist/packem_shared/result-chart-CwKhhKM0.js +1 -0
  96. package/dist/packem_shared/scroll-area-DTEq6Jec.js +2 -0
  97. package/dist/packem_shared/select-Bul-DeII.js +2 -0
  98. package/dist/packem_shared/shard-history-DMEW5VBE.js +1 -0
  99. package/dist/packem_shared/skeleton-C1wQ9M5t.js +1 -0
  100. package/dist/packem_shared/sparkline-DtcZoU48.js +1 -0
  101. package/dist/packem_shared/storage-tier-DznqOf-q.js +1 -0
  102. package/dist/packem_shared/studio-BHA7hnI3.js +2 -0
  103. package/dist/packem_shared/table-DdJBrClo.js +2 -0
  104. package/dist/packem_shared/table-list-sidebar-CMCcNALK.js +1 -0
  105. package/dist/packem_shared/textarea-Bu2-jKAs.js +1 -0
  106. package/dist/packem_shared/trace-handoff-Dw7mwjxu.js +1 -0
  107. package/dist/packem_shared/use-admin-query-Di3fLE8H.js +1 -0
  108. package/dist/packem_shared/use-async-submit-H68GHPz8.js +1 -0
  109. package/dist/packem_shared/useDebounced-Ihdiid_k.js +1 -0
  110. package/dist/packem_shared/utils-bhneXptQ.js +1 -0
  111. package/dist/packem_shared/virtual-rect-1o1veP7R.js +1 -0
  112. package/dist/standalone/chunk-23HKRH5H.js +13 -0
  113. package/dist/standalone/chunk-2A4RKII2.js +1 -0
  114. package/dist/standalone/chunk-3DTM4GI5.js +1 -0
  115. package/dist/standalone/chunk-3MHKT76P.js +1 -0
  116. package/dist/standalone/chunk-46IB4C4Q.js +1 -0
  117. package/dist/standalone/chunk-4AYEV5UN.js +1 -0
  118. package/dist/standalone/chunk-4FNHHFWR.js +1 -0
  119. package/dist/standalone/chunk-6CLVIOCB.js +1 -0
  120. package/dist/standalone/chunk-6I62RSI5.js +1 -0
  121. package/dist/standalone/chunk-6OKDCV7J.js +1 -0
  122. package/dist/standalone/chunk-6P7HIPUE.js +1 -0
  123. package/dist/standalone/chunk-6UYILUSX.js +1 -0
  124. package/dist/standalone/chunk-725RLB7D.js +1 -0
  125. package/dist/standalone/chunk-7AZZ7OJO.js +1 -0
  126. package/dist/standalone/chunk-7CRLAMGB.js +1 -0
  127. package/dist/standalone/chunk-7Z5QEFR4.js +2 -0
  128. package/dist/standalone/chunk-AGVJJQFL.js +1 -0
  129. package/dist/standalone/chunk-AKTGRZXN.js +1 -0
  130. package/dist/standalone/chunk-BAIN7UJ4.js +1 -0
  131. package/dist/standalone/chunk-BHWSIIDT.js +1 -0
  132. package/dist/standalone/{chunk-L7SK4ZZD.js → chunk-C4O5UR4Y.js} +1 -1
  133. package/dist/standalone/chunk-C4VURT57.js +1 -0
  134. package/dist/standalone/chunk-CKO3F55C.js +4 -0
  135. package/dist/standalone/chunk-CVMRZUF5.js +4 -0
  136. package/dist/standalone/chunk-CWWGDW4V.js +1 -0
  137. package/dist/standalone/chunk-CYET4BRZ.js +1 -0
  138. package/dist/standalone/chunk-CZEUVNCQ.js +1 -0
  139. package/dist/standalone/chunk-FXFK4M4E.js +1 -0
  140. package/dist/standalone/chunk-FYAJPWE7.js +1 -0
  141. package/dist/standalone/chunk-GS7OBQO5.js +1 -0
  142. package/dist/standalone/chunk-GTXVH7I5.js +1 -0
  143. package/dist/standalone/chunk-H6SIM4BT.js +1 -0
  144. package/dist/standalone/chunk-H6WOFY6A.js +8 -0
  145. package/dist/standalone/chunk-HA34GYEX.js +1 -0
  146. package/dist/standalone/chunk-HMIOF5GV.js +1 -0
  147. package/dist/standalone/chunk-HY46NTNW.js +6 -0
  148. package/dist/standalone/chunk-IBCKC2BO.js +1 -0
  149. package/dist/standalone/chunk-ICKBVXPP.js +1 -0
  150. package/dist/standalone/chunk-IE4ROTQD.js +1 -0
  151. package/dist/standalone/chunk-IYYTWZ2E.js +2 -0
  152. package/dist/standalone/chunk-J2LMP2A7.js +1 -0
  153. package/dist/standalone/chunk-JC6WYIHM.js +1 -0
  154. package/dist/standalone/chunk-JKPK25JO.js +1 -0
  155. package/dist/standalone/chunk-JLFCXBNQ.js +1 -0
  156. package/dist/standalone/chunk-JRWBGR5B.js +1 -0
  157. package/dist/standalone/chunk-K5PFWU5J.js +1 -0
  158. package/dist/standalone/chunk-KJTLW5W2.js +11 -0
  159. package/dist/standalone/{chunk-HBGS4SEX.js → chunk-KLLYGWNF.js} +9 -9
  160. package/dist/standalone/chunk-KNN3ZEQ7.js +1 -0
  161. package/dist/standalone/{chunk-4QHKBC77.js → chunk-KOC5KV3E.js} +1 -1
  162. package/dist/standalone/chunk-KSRXMTBV.js +1 -0
  163. package/dist/standalone/chunk-KYCAYNXM.js +1 -0
  164. package/dist/standalone/chunk-KZ2YUNMR.js +1 -0
  165. package/dist/standalone/chunk-LKHUVEHX.js +1 -0
  166. package/dist/standalone/chunk-LPOKAJT4.js +4 -0
  167. package/dist/standalone/chunk-MZEK4SGD.js +1 -0
  168. package/dist/standalone/chunk-NCCUM26H.js +1 -0
  169. package/dist/standalone/chunk-O62HJZV3.js +1 -0
  170. package/dist/standalone/chunk-OTJOI23O.js +62 -0
  171. package/dist/standalone/chunk-P2NBOUGZ.js +1 -0
  172. package/dist/standalone/chunk-P4J6XNG3.js +1 -0
  173. package/dist/standalone/chunk-PGDWFWH5.js +1 -0
  174. package/dist/standalone/chunk-PR2SE2MD.js +1 -0
  175. package/dist/standalone/chunk-PTTDIYGP.js +1 -0
  176. package/dist/standalone/chunk-PWDMXMRD.js +1 -0
  177. package/dist/standalone/chunk-Q34MSC2F.js +1 -0
  178. package/dist/standalone/chunk-Q5WXTZWX.js +1 -0
  179. package/dist/standalone/chunk-QC5HCNJZ.js +4 -0
  180. package/dist/standalone/chunk-QJKRHZYV.js +1 -0
  181. package/dist/standalone/chunk-R43KHQDA.js +1 -0
  182. package/dist/standalone/chunk-RC2K5RBE.js +1 -0
  183. package/dist/standalone/chunk-RE6UWCMG.js +1 -0
  184. package/dist/standalone/chunk-RUP3M2GF.js +3 -0
  185. package/dist/standalone/chunk-SA6MBPBL.js +1 -0
  186. package/dist/standalone/{chunk-BJGBHGK3.js → chunk-SEDZDNQF.js} +1 -1
  187. package/dist/standalone/chunk-SKHEGARW.js +1 -0
  188. package/dist/standalone/chunk-SKJZDOHG.js +1 -0
  189. package/dist/standalone/chunk-SNDYNCAA.js +1 -0
  190. package/dist/standalone/chunk-SZUHZ2OG.js +1 -0
  191. package/dist/standalone/chunk-TAE2H7PU.js +1 -0
  192. package/dist/standalone/chunk-TEIBKU46.js +1 -0
  193. package/dist/standalone/chunk-TO6NLVFD.js +1 -0
  194. package/dist/standalone/chunk-TYTJDFX2.js +1 -0
  195. package/dist/standalone/{chunk-LXULVPEM.js → chunk-UDZY7MKE.js} +3 -3
  196. package/dist/standalone/chunk-UHHTEBC3.js +1 -0
  197. package/dist/standalone/chunk-UNDFOYRI.js +1 -0
  198. package/dist/standalone/chunk-UNN4CESU.js +1 -0
  199. package/dist/standalone/chunk-UNXX5GQH.js +1 -0
  200. package/dist/standalone/{chunk-ZHVTQ37P.js → chunk-UREY4GLG.js} +1 -1
  201. package/dist/standalone/chunk-UWF5DOGV.js +1 -0
  202. package/dist/standalone/chunk-UY2Y5CXB.js +1 -0
  203. package/dist/standalone/{chunk-VLXV72QE.js → chunk-UZYGEOWY.js} +1 -1
  204. package/dist/standalone/chunk-V66TSUKV.js +1 -0
  205. package/dist/standalone/chunk-VEFNSN7P.js +1 -0
  206. package/dist/standalone/chunk-VUJGR4PB.js +1 -0
  207. package/dist/standalone/chunk-VUXJER3D.js +1 -0
  208. package/dist/standalone/chunk-W572365D.js +1 -0
  209. package/dist/standalone/chunk-WYFLGXZ3.js +3 -0
  210. package/dist/standalone/chunk-XDKFPBIL.js +1 -0
  211. package/dist/standalone/chunk-XRKCGQM2.js +1 -0
  212. package/dist/standalone/chunk-YNBJ6ICE.js +1 -0
  213. package/dist/standalone/chunk-YQ5PILIJ.js +1 -0
  214. package/dist/standalone/chunk-YT7VXQVX.js +1 -0
  215. package/dist/standalone/chunk-Z7MUQMLE.js +1 -0
  216. package/dist/standalone/chunk-ZFWEPGWG.js +1 -0
  217. package/dist/standalone/chunk-ZMFZRGAN.js +1 -0
  218. package/dist/standalone/studio.js +9 -214
  219. package/package.json +4 -4
  220. package/dist/packem_shared/ADMIN_FUNCTIONS-P2UzJscH.js +0 -62
  221. package/dist/packem_shared/ApiDocsPanel-DNDpeR5O.js +0 -842
  222. package/dist/packem_shared/ApiReferencePanel-ChlRsAXU.js +0 -230
  223. package/dist/packem_shared/CommandPalette-BpkopP5f.js +0 -373
  224. package/dist/packem_shared/ConfirmButton-C2eVi2Qv.js +0 -59
  225. package/dist/packem_shared/ConnectionBadge-B2DDM2Tn.js +0 -111
  226. package/dist/packem_shared/DEFAULT_AUTO_REFRESH_MS-Vxwaxx51.js +0 -50
  227. package/dist/packem_shared/DEFAULT_INSIGHT_THRESHOLDS-DjF0h-gA.js +0 -89
  228. package/dist/packem_shared/DEFAULT_LOCALE-CiX4W7Kr.js +0 -27
  229. package/dist/packem_shared/DataBrowser-obTn4sKX.js +0 -4493
  230. package/dist/packem_shared/DataFilters-B1Q7mrt7.js +0 -253
  231. package/dist/packem_shared/ErrorBoundary-BzAApI7J.js +0 -66
  232. package/dist/packem_shared/GlobalDataBrowser-BCaohHZ5.js +0 -293
  233. package/dist/packem_shared/HomePanel-DCRj3hGB.js +0 -14
  234. package/dist/packem_shared/OpenRpcReferencePanel-CIeQE1aE.js +0 -192
  235. package/dist/packem_shared/STUDIO_ROOT_CLASS-D12gX2dV.js +0 -3
  236. package/dist/packem_shared/ScheduledJobs-BQzQo84k.js +0 -262
  237. package/dist/packem_shared/ShardInput-CZnpHILL.js +0 -107
  238. package/dist/packem_shared/Studio-DnlPCbID.js +0 -16
  239. package/dist/packem_shared/StudioApp-CzqlB4zO.js +0 -708
  240. package/dist/packem_shared/StudioI18nProvider-B-tDCZIi.js +0 -48
  241. package/dist/packem_shared/advisor-view-D95sN-wO.js +0 -159
  242. package/dist/packem_shared/aggregateMetrics-D4nUHEKU.js +0 -108
  243. package/dist/packem_shared/alert-CdAET2K_.js +0 -68
  244. package/dist/packem_shared/badge-B2PKA1-5.js +0 -49
  245. package/dist/packem_shared/bar-chart-DSwcWIRy.js +0 -3246
  246. package/dist/packem_shared/browser-storage-L4gOP5gJ.js +0 -105
  247. package/dist/packem_shared/button-BhsN2uZH.js +0 -49
  248. package/dist/packem_shared/card-F2vH_aj2.js +0 -175
  249. package/dist/packem_shared/cf-links-SIbyi4Y1.js +0 -8
  250. package/dist/packem_shared/checkbox-UNkzAxl-.js +0 -63
  251. package/dist/packem_shared/data-grid-BywzWfek.js +0 -183
  252. package/dist/packem_shared/data-view-params-Cd6yRVbv.js +0 -96
  253. package/dist/packem_shared/dropdown-menu-WY4B_eJO.js +0 -280
  254. package/dist/packem_shared/empty-state-DY_oe0k6.js +0 -98
  255. package/dist/packem_shared/error-alert-D9uIFJUS.js +0 -114
  256. package/dist/packem_shared/grid-features-ZOLhHKrR.js +0 -809
  257. package/dist/packem_shared/home-panel-BRAA2UlM.js +0 -1889
  258. package/dist/packem_shared/input-XH4r1Pt1.js +0 -53
  259. package/dist/packem_shared/internal-DzHCc2Rq.js +0 -131
  260. package/dist/packem_shared/label-D8ykjn5J.js +0 -46
  261. package/dist/packem_shared/live-status-FZ0psC1z.js +0 -44
  262. package/dist/packem_shared/log-fields-jEH83H2G.js +0 -18
  263. package/dist/packem_shared/modal-shell-hyaJvIJ6.js +0 -100
  264. package/dist/packem_shared/reference-view-DfXN7oWP.js +0 -2127
  265. package/dist/packem_shared/result-chart-Bf9mbCIo.js +0 -119
  266. package/dist/packem_shared/scroll-area-DLhcy-ml.js +0 -93
  267. package/dist/packem_shared/select-D9OwHEch.js +0 -273
  268. package/dist/packem_shared/shard-history-AxiJ1WPP.js +0 -16
  269. package/dist/packem_shared/skeleton-CGhL0p20.js +0 -45
  270. package/dist/packem_shared/sparkline-BnA1kC9X.js +0 -93
  271. package/dist/packem_shared/storage-tier-CL98eOvn.js +0 -85
  272. package/dist/packem_shared/studio-8QSXbZ98.js +0 -4192
  273. package/dist/packem_shared/table-DsCa9Qp9.js +0 -246
  274. package/dist/packem_shared/table-list-sidebar-gCE17v9B.js +0 -842
  275. package/dist/packem_shared/textarea-D3gaCU_-.js +0 -46
  276. package/dist/packem_shared/trace-handoff-CGolF3KS.js +0 -38
  277. package/dist/packem_shared/use-admin-query-C7JNuQp-.js +0 -106
  278. package/dist/packem_shared/use-async-submit-rnSk_jXl.js +0 -91
  279. package/dist/packem_shared/useDebounced-Dxncpg6z.js +0 -32
  280. package/dist/packem_shared/utils-B05Dmz_H.js +0 -8
  281. package/dist/packem_shared/virtual-rect-CVMUskSm.js +0 -10
  282. package/dist/standalone/chunk-2K47A3P6.js +0 -1
  283. package/dist/standalone/chunk-2MLA6WFH.js +0 -1
  284. package/dist/standalone/chunk-2NGUNNGW.js +0 -1
  285. package/dist/standalone/chunk-2TJVFKD2.js +0 -1
  286. package/dist/standalone/chunk-2YTF6LJ6.js +0 -1
  287. package/dist/standalone/chunk-3GXGLNKW.js +0 -1
  288. package/dist/standalone/chunk-3HGNPZBN.js +0 -1
  289. package/dist/standalone/chunk-3LJEGSMK.js +0 -11
  290. package/dist/standalone/chunk-3OA7PECS.js +0 -6
  291. package/dist/standalone/chunk-4PC7IXNY.js +0 -1
  292. package/dist/standalone/chunk-56XQYNUJ.js +0 -1
  293. package/dist/standalone/chunk-5OIBXYZM.js +0 -1
  294. package/dist/standalone/chunk-5QT5JRXD.js +0 -3
  295. package/dist/standalone/chunk-6RLPR7PL.js +0 -1
  296. package/dist/standalone/chunk-6V74EUPK.js +0 -1
  297. package/dist/standalone/chunk-7EE33WLB.js +0 -1
  298. package/dist/standalone/chunk-7TJJXVSE.js +0 -1
  299. package/dist/standalone/chunk-AHILM3ZP.js +0 -1
  300. package/dist/standalone/chunk-AN4RKMKW.js +0 -1
  301. package/dist/standalone/chunk-APSSZB6Z.js +0 -1
  302. package/dist/standalone/chunk-AXNGWSBM.js +0 -1
  303. package/dist/standalone/chunk-AXZILWRM.js +0 -1
  304. package/dist/standalone/chunk-C7RHEBOH.js +0 -1
  305. package/dist/standalone/chunk-CKSHCYGC.js +0 -2
  306. package/dist/standalone/chunk-CSWIYOB3.js +0 -1
  307. package/dist/standalone/chunk-D3VAON25.js +0 -1
  308. package/dist/standalone/chunk-DDLQN67F.js +0 -1
  309. package/dist/standalone/chunk-DGHW5JG5.js +0 -1
  310. package/dist/standalone/chunk-DMCSOTAE.js +0 -3
  311. package/dist/standalone/chunk-E3BKETAS.js +0 -1
  312. package/dist/standalone/chunk-E3OXNN6O.js +0 -1
  313. package/dist/standalone/chunk-E6BOGDIS.js +0 -1
  314. package/dist/standalone/chunk-F2YMCQ6B.js +0 -1
  315. package/dist/standalone/chunk-F7GE4X2U.js +0 -1
  316. package/dist/standalone/chunk-FAVUOGJR.js +0 -1
  317. package/dist/standalone/chunk-FXP6256Q.js +0 -1
  318. package/dist/standalone/chunk-G6CTAYHJ.js +0 -1
  319. package/dist/standalone/chunk-GTM65MVX.js +0 -1
  320. package/dist/standalone/chunk-H42W62SE.js +0 -1
  321. package/dist/standalone/chunk-HTF5ZX4I.js +0 -8
  322. package/dist/standalone/chunk-HV7G6DFP.js +0 -5
  323. package/dist/standalone/chunk-I2PS4L74.js +0 -1
  324. package/dist/standalone/chunk-IYHPYY4A.js +0 -1
  325. package/dist/standalone/chunk-J6J54MBP.js +0 -1
  326. package/dist/standalone/chunk-J7OGP4NN.js +0 -1
  327. package/dist/standalone/chunk-JSEXCW5Q.js +0 -1
  328. package/dist/standalone/chunk-JZLGLG4T.js +0 -1
  329. package/dist/standalone/chunk-KEGAWN6Y.js +0 -1
  330. package/dist/standalone/chunk-KZ6INM5M.js +0 -1
  331. package/dist/standalone/chunk-L2LN3MK4.js +0 -4
  332. package/dist/standalone/chunk-LT3FH6MW.js +0 -1
  333. package/dist/standalone/chunk-LZUWZBPE.js +0 -1
  334. package/dist/standalone/chunk-M4JM3TOY.js +0 -1
  335. package/dist/standalone/chunk-MLA5ZAEB.js +0 -1
  336. package/dist/standalone/chunk-MRBI5HNQ.js +0 -1
  337. package/dist/standalone/chunk-N5XX4HOL.js +0 -6
  338. package/dist/standalone/chunk-N7SVJOHN.js +0 -1
  339. package/dist/standalone/chunk-NKFXMDOD.js +0 -1
  340. package/dist/standalone/chunk-NPSNKFHE.js +0 -1
  341. package/dist/standalone/chunk-O3NAGRTR.js +0 -1
  342. package/dist/standalone/chunk-O7FVPUCO.js +0 -1
  343. package/dist/standalone/chunk-OKQXTLFX.js +0 -1
  344. package/dist/standalone/chunk-OXHHSUXO.js +0 -1
  345. package/dist/standalone/chunk-QAFAJBAW.js +0 -1
  346. package/dist/standalone/chunk-QAIM6KWT.js +0 -1
  347. package/dist/standalone/chunk-QCPMTB6W.js +0 -1
  348. package/dist/standalone/chunk-QQ2LOSZL.js +0 -1
  349. package/dist/standalone/chunk-QVIPA6UJ.js +0 -1
  350. package/dist/standalone/chunk-QVUQXJCT.js +0 -4
  351. package/dist/standalone/chunk-R2GMHLJY.js +0 -1
  352. package/dist/standalone/chunk-RD5UG2YL.js +0 -1
  353. package/dist/standalone/chunk-RJTIP3WF.js +0 -1
  354. package/dist/standalone/chunk-RRCPZMC2.js +0 -22
  355. package/dist/standalone/chunk-SHERR7ZP.js +0 -1
  356. package/dist/standalone/chunk-SOC5CY3F.js +0 -1
  357. package/dist/standalone/chunk-SS7JLF2I.js +0 -4
  358. package/dist/standalone/chunk-SWWYUGPL.js +0 -2
  359. package/dist/standalone/chunk-TAD43CG5.js +0 -1
  360. package/dist/standalone/chunk-TTXRHJUP.js +0 -4
  361. package/dist/standalone/chunk-UK64ZSUW.js +0 -1
  362. package/dist/standalone/chunk-UKDHGVOC.js +0 -1
  363. package/dist/standalone/chunk-UPNTMJFF.js +0 -1
  364. package/dist/standalone/chunk-V43BLH4J.js +0 -1
  365. package/dist/standalone/chunk-VL23Y44O.js +0 -4
  366. package/dist/standalone/chunk-VXM5H542.js +0 -4
  367. package/dist/standalone/chunk-WMDH2CIZ.js +0 -1
  368. package/dist/standalone/chunk-WVTPZ6CM.js +0 -1
  369. package/dist/standalone/chunk-XN6QYJQ6.js +0 -13
  370. package/dist/standalone/chunk-XNJNSCLM.js +0 -1
  371. package/dist/standalone/chunk-Y4U6CC22.js +0 -1
  372. package/dist/standalone/chunk-Y572GMZE.js +0 -1
  373. package/dist/standalone/chunk-Y7PD5KP4.js +0 -76
  374. package/dist/standalone/chunk-YFIPHCEC.js +0 -1
  375. package/dist/standalone/chunk-YJXOWLFJ.js +0 -1
  376. package/dist/standalone/chunk-YNN6NFRZ.js +0 -1
  377. package/dist/standalone/chunk-YUGHRVPD.js +0 -1
  378. package/dist/standalone/chunk-ZIGWVHCS.js +0 -1
  379. package/dist/standalone/chunk-ZPP2KOR4.js +0 -1
  380. package/dist/standalone/chunk-ZPUO7FNI.js +0 -1
  381. /package/dist/standalone/{chunk-TEWVD66F.js → chunk-GXZAXNZI.js} +0 -0
@@ -1,2340 +1,4 @@
1
- import { c } from 'react/compiler-runtime';
2
- import { useLunora } from '@lunora/react';
3
- import { useState, useRef, useEffect, useId } from 'react';
4
- import { S as SqlResultChart } from '../packem_shared/result-chart-Bf9mbCIo.js';
5
- import { ShardInput } from '../packem_shared/ShardInput-CZnpHILL.js';
6
- import { A as Alert } from '../packem_shared/alert-CdAET2K_.js';
7
- import { c as TableHead, a as TableHeader, b as TableRow, e as TableCell, d as TableBody, T as Table } from '../packem_shared/table-DsCa9Qp9.js';
8
- import { useT } from '../packem_shared/DEFAULT_LOCALE-CiX4W7Kr.js';
9
- import { ADMIN_FUNCTIONS } from '../packem_shared/ADMIN_FUNCTIONS-P2UzJscH.js';
10
- import { u as usePersistedList, n as newId, b as usePersistedValue } from '../packem_shared/browser-storage-L4gOP5gJ.js';
11
- import { f as fireAndForget, c as callOptions, a as adminRef, e as errorMessage } from '../packem_shared/internal-DzHCc2Rq.js';
12
- import { r as recordShard } from '../packem_shared/shard-history-AxiJ1WPP.js';
13
- import { C as CellValue } from '../packem_shared/data-grid-BywzWfek.js';
14
- import { E as ExportMenu } from '../packem_shared/grid-features-ZOLhHKrR.js';
15
- import { c as cn } from '../packem_shared/utils-B05Dmz_H.js';
16
- import { jsxDEV, Fragment } from 'react/jsx-dev-runtime';
17
-
18
- const SQL_KEYWORDS = ["ORDER BY", "GROUP BY", "LEFT JOIN", "RIGHT JOIN", "INNER JOIN", "OUTER JOIN", "CROSS JOIN", "EXPLAIN QUERY PLAN", "SELECT", "DISTINCT", "FROM", "WHERE", "HAVING", "LIMIT", "OFFSET", "JOIN", "ON", "AND", "OR", "AS", "ASC", "DESC", "WITH", "UNION", "EXPLAIN"];
19
- const SQL_NEWLINE_CLAUSES = ["FROM", "WHERE", "ORDER BY", "GROUP BY", "HAVING", "LIMIT", "OFFSET", "UNION", "JOIN", "LEFT JOIN", "RIGHT JOIN", "INNER JOIN", "OUTER JOIN", "CROSS JOIN"];
20
- const SENTINEL = String.fromCodePoint(0);
21
- const RESTORE_RE = new RegExp(`${SENTINEL}${String.raw`(\d+)`}${SENTINEL}`, "gu");
22
- const KEYWORD_PATTERNS = SQL_KEYWORDS.map((keyword) => {
23
- return {
24
- pattern: new RegExp(String.raw`\b${keyword.replaceAll(" ", String.raw`\s+`)}\b`, "giu"),
25
- replacement: keyword
26
- };
27
- });
28
- const CLAUSE_PATTERNS = SQL_NEWLINE_CLAUSES.map((clause) => {
29
- return {
30
- pattern: new RegExp(String.raw`\s+${clause.replaceAll(" ", String.raw`\s+`)}\b`, "gu"),
31
- replacement: `
32
- ${clause}`
33
- };
34
- });
35
- const formatSql = (sql) => {
36
- const literals = [];
37
- const withPlaceholders = sql.replaceAll(/'(?:[^']|'')*'/gu, (match) => {
38
- literals.push(match);
39
- return `${SENTINEL}${(literals.length - 1).toString()}${SENTINEL}`;
40
- });
41
- let out = withPlaceholders.replaceAll(/\s+/gu, " ").trim();
42
- for (const {
43
- pattern,
44
- replacement
45
- } of KEYWORD_PATTERNS) {
46
- out = out.replaceAll(pattern, replacement);
47
- }
48
- for (const {
49
- pattern,
50
- replacement
51
- } of CLAUSE_PATTERNS) {
52
- out = out.replaceAll(pattern, replacement);
53
- }
54
- out = out.replaceAll(RESTORE_RE, (_match, index) => literals[Number(index)] ?? "");
55
- return out;
56
- };
57
-
58
- const MAX_SUGGESTIONS = 8;
59
- const KEYWORDS = ["AND", "ASC", "AS", "BY", "COUNT", "DESC", "DISTINCT", "EXPLAIN", "FROM", "GROUP", "HAVING", "INNER", "JOIN", "LEFT", "LIKE", "LIMIT", "NOT", "NULL", "OFFSET", "ON", "ORDER", "OR", "QUERY", "SELECT", "WHERE", "WITH"];
60
- const COLUMN_CLAUSES = /* @__PURE__ */ new Set(["AND", "BY", "HAVING", "ON", "OR", "SELECT", "WHERE"]);
61
- const WORD_CHAR = /[\w$]/;
62
- const isWordChar = (char) => char !== void 0 && WORD_CHAR.test(char);
63
- const trailingWord = (text) => {
64
- let start = text.length;
65
- while (start > 0 && isWordChar(text[start - 1])) {
66
- start -= 1;
67
- }
68
- return text.slice(start);
69
- };
70
- const tokenAt = (value, caret) => {
71
- let start = caret;
72
- while (start > 0 && isWordChar(value[start - 1])) {
73
- start -= 1;
74
- }
75
- return {
76
- end: caret,
77
- start,
78
- text: value.slice(start, caret)
79
- };
80
- };
81
- const prefersColumns = (value, start) => {
82
- const before = value.slice(0, start).trimEnd();
83
- return before.endsWith(".") || COLUMN_CLAUSES.has(trailingWord(before).toUpperCase());
84
- };
85
- const qualifierTable = (value, start) => {
86
- const before = value.slice(0, start);
87
- if (!before.endsWith(".")) {
88
- return void 0;
89
- }
90
- const name = trailingWord(before.slice(0, -1));
91
- return name === "" ? void 0 : name;
92
- };
93
- const matches = (candidate, needle) => candidate.toLowerCase().startsWith(needle.toLowerCase());
94
- const takeMatches = (names, needle, max, make) => {
95
- const out = [];
96
- for (const name of names) {
97
- if (matches(name, needle)) {
98
- out.push(make(name));
99
- if (out.length >= max) {
100
- break;
101
- }
102
- }
103
- }
104
- return out;
105
- };
106
- const takeColumnMatches = (schema, needle, max) => {
107
- const seen = /* @__PURE__ */ new Map();
108
- for (const [table, columns] of Object.entries(schema.columns)) {
109
- for (const column of columns) {
110
- if (matches(column, needle) && !seen.has(column)) {
111
- seen.set(column, table);
112
- if (seen.size >= max) {
113
- return [...seen].map(([column_, table_]) => {
114
- return {
115
- detail: table_,
116
- kind: "column",
117
- label: column_
118
- };
119
- });
120
- }
121
- }
122
- }
123
- }
124
- return [...seen].map(([column, table]) => {
125
- return {
126
- detail: table,
127
- kind: "column",
128
- label: column
129
- };
130
- });
131
- };
132
- const suggestionsFor = (value, caret, schema) => {
133
- const span = tokenAt(value, caret);
134
- const qualifier = qualifierTable(value, span.start);
135
- if (qualifier !== void 0) {
136
- const owned = schema.columns[qualifier] ?? schema.columns[qualifier.toLowerCase()] ?? [];
137
- return takeMatches(owned, span.text, MAX_SUGGESTIONS, (column) => {
138
- return {
139
- detail: qualifier,
140
- kind: "column",
141
- label: column
142
- };
143
- });
144
- }
145
- if (span.text === "" && !prefersColumns(value, span.start)) {
146
- return [];
147
- }
148
- const tableHits = takeMatches(schema.tables, span.text, MAX_SUGGESTIONS, (table) => {
149
- return {
150
- kind: "table",
151
- label: table
152
- };
153
- });
154
- const columnHits = takeColumnMatches(schema, span.text, MAX_SUGGESTIONS);
155
- const keywordHits = KEYWORDS.filter((keyword) => span.text !== "" && matches(keyword, span.text) && keyword.toLowerCase() !== span.text.toLowerCase()).map((keyword) => {
156
- return {
157
- kind: "keyword",
158
- label: keyword
159
- };
160
- });
161
- const ordered = prefersColumns(value, span.start) ? [...columnHits, ...tableHits, ...keywordHits] : [...tableHits, ...columnHits, ...keywordHits];
162
- return ordered.slice(0, MAX_SUGGESTIONS);
163
- };
164
- const acceptSuggestion = (value, caret, suggestion) => {
165
- const span = tokenAt(value, caret);
166
- const next = value.slice(0, span.start) + suggestion.label + value.slice(span.end);
167
- return {
168
- caret: span.start + suggestion.label.length,
169
- value: next
170
- };
171
- };
172
-
173
- const MIRROR_PROPS = ["boxSizing", "borderBottomWidth", "borderLeftWidth", "borderRightWidth", "borderTopWidth", "fontFamily", "fontSize", "fontStyle", "fontWeight", "letterSpacing", "lineHeight", "paddingBottom", "paddingLeft", "paddingRight", "paddingTop", "tabSize", "textIndent", "textTransform", "width", "wordSpacing"];
174
- const caretOffset = (textarea, caret) => {
175
- const computed = globalThis.getComputedStyle(textarea);
176
- const mirror = globalThis.document.createElement("div");
177
- const {
178
- style
179
- } = mirror;
180
- style.position = "absolute";
181
- style.visibility = "hidden";
182
- style.whiteSpace = "pre-wrap";
183
- style.overflowWrap = "break-word";
184
- for (const property of MIRROR_PROPS) {
185
- style[property] = computed[property];
186
- }
187
- mirror.textContent = textarea.value.slice(0, Math.max(0, caret));
188
- const marker = globalThis.document.createElement("span");
189
- marker.textContent = textarea.value.slice(Math.max(0, caret)) || ".";
190
- mirror.append(marker);
191
- globalThis.document.body.append(mirror);
192
- const left = marker.offsetLeft - textarea.scrollLeft;
193
- const top = marker.offsetTop - textarea.scrollTop;
194
- mirror.remove();
195
- return {
196
- left,
197
- top
198
- };
199
- };
200
- const useSqlAutocomplete = (schema, textareaRef, setValue) => {
201
- const $ = c(13);
202
- const [state, setState] = useState(null);
203
- let t0;
204
- if ($[0] !== schema || $[1] !== textareaRef) {
205
- t0 = (value, caret) => {
206
- const suggestions = suggestionsFor(value, caret, schema);
207
- if (suggestions.length === 0) {
208
- setState(null);
209
- return;
210
- }
211
- const node = textareaRef.current;
212
- const {
213
- left,
214
- top
215
- } = node === null ? {
216
- left: 0,
217
- top: 0
218
- } : caretOffset(node, caret);
219
- setState((current) => {
220
- const unchanged = current !== null && current.active === 0 && current.left === left && current.top === top && current.suggestions.length === suggestions.length && current.suggestions.every((existing, index) => {
221
- const next = suggestions.at(index);
222
- return existing.kind === next?.kind && existing.label === next.label && existing.detail === next.detail;
223
- });
224
- return unchanged ? current : {
225
- active: 0,
226
- left,
227
- suggestions,
228
- top
229
- };
230
- });
231
- };
232
- $[0] = schema;
233
- $[1] = textareaRef;
234
- $[2] = t0;
235
- } else {
236
- t0 = $[2];
237
- }
238
- const refresh = t0;
239
- let t1;
240
- if ($[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
241
- t1 = () => {
242
- setState(null);
243
- };
244
- $[3] = t1;
245
- } else {
246
- t1 = $[3];
247
- }
248
- const close = t1;
249
- let t2;
250
- if ($[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
251
- t2 = (delta) => {
252
- setState((current_0) => {
253
- if (current_0 === null) {
254
- return current_0;
255
- }
256
- const count = current_0.suggestions.length;
257
- const active = (current_0.active + delta + count) % count;
258
- return {
259
- ...current_0,
260
- active
261
- };
262
- });
263
- };
264
- $[4] = t2;
265
- } else {
266
- t2 = $[4];
267
- }
268
- const move = t2;
269
- let t3;
270
- if ($[5] !== setValue || $[6] !== state || $[7] !== textareaRef) {
271
- t3 = () => {
272
- const textarea = textareaRef.current;
273
- if (state === null || textarea === null) {
274
- return false;
275
- }
276
- const chosen = state.suggestions[state.active];
277
- if (chosen === void 0) {
278
- return false;
279
- }
280
- const next_0 = acceptSuggestion(textarea.value, textarea.selectionStart, chosen);
281
- setValue(next_0.value);
282
- setState(null);
283
- requestAnimationFrame(() => {
284
- const node_0 = textareaRef.current;
285
- if (node_0 !== null) {
286
- node_0.focus();
287
- node_0.setSelectionRange(next_0.caret, next_0.caret);
288
- }
289
- });
290
- return true;
291
- };
292
- $[5] = setValue;
293
- $[6] = state;
294
- $[7] = textareaRef;
295
- $[8] = t3;
296
- } else {
297
- t3 = $[8];
298
- }
299
- const commit = t3;
300
- let t4;
301
- if ($[9] !== commit || $[10] !== refresh || $[11] !== state) {
302
- t4 = {
303
- close,
304
- commit,
305
- move,
306
- refresh,
307
- state
308
- };
309
- $[9] = commit;
310
- $[10] = refresh;
311
- $[11] = state;
312
- $[12] = t4;
313
- } else {
314
- t4 = $[12];
315
- }
316
- return t4;
317
- };
318
- const KIND_LABEL = {
319
- column: "column",
320
- keyword: "keyword",
321
- table: "table"
322
- };
323
- const CARET_LINE_OFFSET = 20;
324
- const AutocompletePopover = (t0) => {
325
- const $ = c(17);
326
- const {
327
- listboxId,
328
- onPick,
329
- state
330
- } = t0;
331
- const t = useT();
332
- let t1;
333
- if ($[0] !== state) {
334
- t1 = state === null ? void 0 : {
335
- left: state.left,
336
- top: state.top + CARET_LINE_OFFSET
337
- };
338
- $[0] = state;
339
- $[1] = t1;
340
- } else {
341
- t1 = $[1];
342
- }
343
- const style = t1;
344
- if (state === null) {
345
- return null;
346
- }
347
- let t2;
348
- if ($[2] !== listboxId || $[3] !== onPick || $[4] !== state.active || $[5] !== state.suggestions || $[6] !== t) {
349
- let t32;
350
- if ($[8] !== listboxId || $[9] !== onPick || $[10] !== state.active || $[11] !== t) {
351
- t32 = (suggestion, index) => /* @__PURE__ */ jsxDEV("li", {
352
- "aria-selected": index === state.active,
353
- className: cn("flex cursor-pointer items-center gap-2 px-2 py-1 text-[13px]", index === state.active ? "bg-accent text-accent-foreground" : "text-foreground"),
354
- "data-testid": "sql-autocomplete-item",
355
- id: `${listboxId}-opt-${index.toString()}`,
356
- onMouseDown: (event) => {
357
- event.preventDefault();
358
- onPick(index);
359
- },
360
- role: "option",
361
- children: [/* @__PURE__ */ jsxDEV("span", {
362
- className: "truncate font-mono",
363
- children: suggestion.label
364
- }, void 0, false), suggestion.detail !== void 0 && /* @__PURE__ */ jsxDEV("span", {
365
- className: "ms-auto truncate text-xs text-muted-foreground",
366
- children: suggestion.detail
367
- }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
368
- className: "shrink-0 font-mono text-[10px] tracking-wide text-muted-foreground/70 uppercase",
369
- children: t(KIND_LABEL[suggestion.kind])
370
- }, void 0, false)]
371
- }, `${suggestion.kind}:${suggestion.label}`, true);
372
- $[8] = listboxId;
373
- $[9] = onPick;
374
- $[10] = state.active;
375
- $[11] = t;
376
- $[12] = t32;
377
- } else {
378
- t32 = $[12];
379
- }
380
- t2 = state.suggestions.map(t32);
381
- $[2] = listboxId;
382
- $[3] = onPick;
383
- $[4] = state.active;
384
- $[5] = state.suggestions;
385
- $[6] = t;
386
- $[7] = t2;
387
- } else {
388
- t2 = $[7];
389
- }
390
- let t3;
391
- if ($[13] !== listboxId || $[14] !== style || $[15] !== t2) {
392
- t3 = /* @__PURE__ */ jsxDEV("ul", {
393
- className: "absolute z-30 max-h-56 w-72 overflow-auto rounded-md border border-border bg-popover py-1 text-popover-foreground shadow-md",
394
- "data-testid": "sql-autocomplete",
395
- id: listboxId,
396
- role: "listbox",
397
- style,
398
- children: t2
399
- }, void 0, false);
400
- $[13] = listboxId;
401
- $[14] = style;
402
- $[15] = t2;
403
- $[16] = t3;
404
- } else {
405
- t3 = $[16];
406
- }
407
- return t3;
408
- };
409
-
410
- const TEMPLATES = [{
411
- label: "List tables",
412
- sql: "SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name;"
413
- }, {
414
- label: "Table row count",
415
- sql: "SELECT COUNT(*) AS rows FROM messages;"
416
- }, {
417
- label: "Recent rows",
418
- sql: "SELECT id, _creationTime, __doc__ FROM messages ORDER BY _creationTime DESC LIMIT 50;"
419
- }, {
420
- label: "Index list",
421
- sql: "SELECT name, tbl_name FROM sqlite_master WHERE type = 'index' ORDER BY tbl_name;"
422
- }];
423
- const QueryRow = (t0) => {
424
- const $ = c(29);
425
- const {
426
- active,
427
- onDelete,
428
- onSelect,
429
- query
430
- } = t0;
431
- const t = useT();
432
- let t1;
433
- if ($[0] !== onSelect || $[1] !== query.id) {
434
- t1 = () => {
435
- onSelect(query.id);
436
- };
437
- $[0] = onSelect;
438
- $[1] = query.id;
439
- $[2] = t1;
440
- } else {
441
- t1 = $[2];
442
- }
443
- const onClick = t1;
444
- let t2;
445
- if ($[3] !== onDelete || $[4] !== query.id) {
446
- t2 = (event) => {
447
- event.stopPropagation();
448
- onDelete(query.id);
449
- };
450
- $[3] = onDelete;
451
- $[4] = query.id;
452
- $[5] = t2;
453
- } else {
454
- t2 = $[5];
455
- }
456
- const onDeleteClick = t2;
457
- const t3 = active ? "bg-sidebar-accent font-medium text-foreground" : "text-muted-foreground";
458
- let t4;
459
- if ($[6] !== t3) {
460
- t4 = cn("flex min-w-0 flex-1 items-center gap-2 rounded-md px-2 py-1.5 text-start text-[13px] outline-none transition-colors hover:bg-sidebar-accent focus-visible:bg-sidebar-accent", t3);
461
- $[6] = t3;
462
- $[7] = t4;
463
- } else {
464
- t4 = $[7];
465
- }
466
- const t5 = `sql-query-${query.id}`;
467
- let t6;
468
- if ($[8] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
469
- t6 = /* @__PURE__ */ jsxDEV("svg", {
470
- "aria-hidden": "true",
471
- className: "size-3.5 shrink-0 opacity-70",
472
- fill: "none",
473
- stroke: "currentColor",
474
- strokeLinecap: "round",
475
- strokeLinejoin: "round",
476
- strokeWidth: 1.6,
477
- viewBox: "0 0 24 24",
478
- children: /* @__PURE__ */ jsxDEV("path", {
479
- d: "M4 6h16M4 12h10M4 18h7"
480
- }, void 0, false)
481
- }, void 0, false);
482
- $[8] = t6;
483
- } else {
484
- t6 = $[8];
485
- }
486
- let t7;
487
- if ($[9] !== query.name) {
488
- t7 = /* @__PURE__ */ jsxDEV("span", {
489
- className: "truncate",
490
- children: query.name
491
- }, void 0, false);
492
- $[9] = query.name;
493
- $[10] = t7;
494
- } else {
495
- t7 = $[10];
496
- }
497
- let t8;
498
- if ($[11] !== active || $[12] !== onClick || $[13] !== t4 || $[14] !== t5 || $[15] !== t7) {
499
- t8 = /* @__PURE__ */ jsxDEV("button", {
500
- "aria-pressed": active,
501
- className: t4,
502
- "data-testid": t5,
503
- onClick,
504
- type: "button",
505
- children: [t6, t7]
506
- }, void 0, true);
507
- $[11] = active;
508
- $[12] = onClick;
509
- $[13] = t4;
510
- $[14] = t5;
511
- $[15] = t7;
512
- $[16] = t8;
513
- } else {
514
- t8 = $[16];
515
- }
516
- let t9;
517
- if ($[17] !== t) {
518
- t9 = t("Delete query");
519
- $[17] = t;
520
- $[18] = t9;
521
- } else {
522
- t9 = $[18];
523
- }
524
- let t10;
525
- if ($[19] !== t) {
526
- t10 = t("Delete query");
527
- $[19] = t;
528
- $[20] = t10;
529
- } else {
530
- t10 = $[20];
531
- }
532
- let t11;
533
- if ($[21] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
534
- t11 = /* @__PURE__ */ jsxDEV("svg", {
535
- "aria-hidden": "true",
536
- className: "size-3.5",
537
- fill: "none",
538
- stroke: "currentColor",
539
- strokeLinecap: "round",
540
- strokeLinejoin: "round",
541
- strokeWidth: 1.6,
542
- viewBox: "0 0 24 24",
543
- children: /* @__PURE__ */ jsxDEV("path", {
544
- d: "M5 7h14M9 7V5h6v2m-1 0v12H10V7M7 7v13h10V7"
545
- }, void 0, false)
546
- }, void 0, false);
547
- $[21] = t11;
548
- } else {
549
- t11 = $[21];
550
- }
551
- let t12;
552
- if ($[22] !== onDeleteClick || $[23] !== t10 || $[24] !== t9) {
553
- t12 = /* @__PURE__ */ jsxDEV("button", {
554
- "aria-label": t9,
555
- className: "me-1 hidden size-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive group-hover/q:flex",
556
- onClick: onDeleteClick,
557
- title: t10,
558
- type: "button",
559
- children: t11
560
- }, void 0, false);
561
- $[22] = onDeleteClick;
562
- $[23] = t10;
563
- $[24] = t9;
564
- $[25] = t12;
565
- } else {
566
- t12 = $[25];
567
- }
568
- let t13;
569
- if ($[26] !== t12 || $[27] !== t8) {
570
- t13 = /* @__PURE__ */ jsxDEV("li", {
571
- className: "group/q flex items-center",
572
- children: [t8, t12]
573
- }, void 0, true);
574
- $[26] = t12;
575
- $[27] = t8;
576
- $[28] = t13;
577
- } else {
578
- t13 = $[28];
579
- }
580
- return t13;
581
- };
582
- const SqlQuerySidebar = (t0) => {
583
- const $ = c(58);
584
- const {
585
- activeId,
586
- history,
587
- listRef,
588
- onClearHistory,
589
- onDelete,
590
- onLoadHistory,
591
- onLoadTemplate,
592
- onNew,
593
- onSearchChange,
594
- onSelect,
595
- queries,
596
- search
597
- } = t0;
598
- const t = useT();
599
- let t1;
600
- if ($[0] !== queries || $[1] !== search) {
601
- const needle = search.trim().toLowerCase();
602
- t1 = needle === "" ? [...queries] : queries.filter((query) => query.name.toLowerCase().includes(needle));
603
- $[0] = queries;
604
- $[1] = search;
605
- $[2] = t1;
606
- } else {
607
- t1 = $[2];
608
- }
609
- const filtered = t1;
610
- let t2;
611
- if ($[3] !== t) {
612
- t2 = t("Search queries…");
613
- $[3] = t;
614
- $[4] = t2;
615
- } else {
616
- t2 = $[4];
617
- }
618
- let t3;
619
- if ($[5] !== onSearchChange || $[6] !== search || $[7] !== t2) {
620
- t3 = /* @__PURE__ */ jsxDEV("input", {
621
- className: "h-8 min-w-0 flex-1 rounded-md border border-border bg-background px-2 text-xs outline-none focus-visible:border-ring",
622
- "data-testid": "sql-search",
623
- onChange: onSearchChange,
624
- placeholder: t2,
625
- type: "text",
626
- value: search
627
- }, void 0, false);
628
- $[5] = onSearchChange;
629
- $[6] = search;
630
- $[7] = t2;
631
- $[8] = t3;
632
- } else {
633
- t3 = $[8];
634
- }
635
- let t4;
636
- if ($[9] !== t) {
637
- t4 = t("New query");
638
- $[9] = t;
639
- $[10] = t4;
640
- } else {
641
- t4 = $[10];
642
- }
643
- let t5;
644
- if ($[11] !== t) {
645
- t5 = t("New query");
646
- $[11] = t;
647
- $[12] = t5;
648
- } else {
649
- t5 = $[12];
650
- }
651
- let t6;
652
- if ($[13] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
653
- t6 = /* @__PURE__ */ jsxDEV("svg", {
654
- "aria-hidden": "true",
655
- className: "size-4",
656
- fill: "none",
657
- stroke: "currentColor",
658
- strokeLinecap: "round",
659
- strokeLinejoin: "round",
660
- strokeWidth: 1.7,
661
- viewBox: "0 0 24 24",
662
- children: /* @__PURE__ */ jsxDEV("path", {
663
- d: "M12 5v14M5 12h14"
664
- }, void 0, false)
665
- }, void 0, false);
666
- $[13] = t6;
667
- } else {
668
- t6 = $[13];
669
- }
670
- let t7;
671
- if ($[14] !== onNew || $[15] !== t4 || $[16] !== t5) {
672
- t7 = /* @__PURE__ */ jsxDEV("button", {
673
- "aria-label": t4,
674
- className: "flex size-8 shrink-0 items-center justify-center rounded-md border border-border text-foreground outline-none transition-colors hover:bg-accent focus-visible:bg-accent",
675
- "data-testid": "sql-new",
676
- onClick: onNew,
677
- title: t5,
678
- type: "button",
679
- children: t6
680
- }, void 0, false);
681
- $[14] = onNew;
682
- $[15] = t4;
683
- $[16] = t5;
684
- $[17] = t7;
685
- } else {
686
- t7 = $[17];
687
- }
688
- let t8;
689
- if ($[18] !== t3 || $[19] !== t7) {
690
- t8 = /* @__PURE__ */ jsxDEV("div", {
691
- className: "flex shrink-0 items-center gap-2 border-b border-border p-2",
692
- children: [t3, t7]
693
- }, void 0, true);
694
- $[18] = t3;
695
- $[19] = t7;
696
- $[20] = t8;
697
- } else {
698
- t8 = $[20];
699
- }
700
- let t9;
701
- if ($[21] !== t) {
702
- t9 = t("Private");
703
- $[21] = t;
704
- $[22] = t9;
705
- } else {
706
- t9 = $[22];
707
- }
708
- let t10;
709
- if ($[23] !== t9) {
710
- t10 = /* @__PURE__ */ jsxDEV("p", {
711
- className: "px-1 pb-1 font-mono text-[11px] tracking-wide text-muted-foreground uppercase",
712
- children: t9
713
- }, void 0, false);
714
- $[23] = t9;
715
- $[24] = t10;
716
- } else {
717
- t10 = $[24];
718
- }
719
- let t11;
720
- if ($[25] !== activeId || $[26] !== filtered || $[27] !== listRef || $[28] !== onDelete || $[29] !== onSelect || $[30] !== t) {
721
- t11 = filtered.length === 0 ? /* @__PURE__ */ jsxDEV("p", {
722
- className: "px-1 py-2 text-xs text-muted-foreground",
723
- "data-testid": "sql-private-empty",
724
- children: t("No saved queries yet — they save to this browser as you type.")
725
- }, void 0, false) : /* @__PURE__ */ jsxDEV("ul", {
726
- className: "flex flex-col gap-px",
727
- "data-testid": "sql-private",
728
- ref: listRef,
729
- children: filtered.map((query_0) => /* @__PURE__ */ jsxDEV(QueryRow, {
730
- active: activeId === query_0.id,
731
- onDelete,
732
- onSelect,
733
- query: query_0
734
- }, query_0.id, false))
735
- }, void 0, false);
736
- $[25] = activeId;
737
- $[26] = filtered;
738
- $[27] = listRef;
739
- $[28] = onDelete;
740
- $[29] = onSelect;
741
- $[30] = t;
742
- $[31] = t11;
743
- } else {
744
- t11 = $[31];
745
- }
746
- let t12;
747
- if ($[32] !== t10 || $[33] !== t11) {
748
- t12 = /* @__PURE__ */ jsxDEV("div", {
749
- children: [t10, t11]
750
- }, void 0, true);
751
- $[32] = t10;
752
- $[33] = t11;
753
- $[34] = t12;
754
- } else {
755
- t12 = $[34];
756
- }
757
- let t13;
758
- if ($[35] !== t) {
759
- t13 = t("Reference");
760
- $[35] = t;
761
- $[36] = t13;
762
- } else {
763
- t13 = $[36];
764
- }
765
- let t14;
766
- if ($[37] !== t13) {
767
- t14 = /* @__PURE__ */ jsxDEV("p", {
768
- className: "px-1 pb-1 font-mono text-[11px] tracking-wide text-muted-foreground uppercase",
769
- children: t13
770
- }, void 0, false);
771
- $[37] = t13;
772
- $[38] = t14;
773
- } else {
774
- t14 = $[38];
775
- }
776
- let t15;
777
- if ($[39] !== onLoadTemplate) {
778
- t15 = TEMPLATES.map((template) => /* @__PURE__ */ jsxDEV("li", {
779
- children: /* @__PURE__ */ jsxDEV("button", {
780
- className: "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-start text-[13px] text-muted-foreground outline-none transition-colors hover:bg-sidebar-accent hover:text-foreground focus-visible:bg-sidebar-accent",
781
- "data-sql": template.sql,
782
- onClick: onLoadTemplate,
783
- type: "button",
784
- children: [/* @__PURE__ */ jsxDEV("svg", {
785
- "aria-hidden": "true",
786
- className: "size-3.5 shrink-0 opacity-70",
787
- fill: "none",
788
- stroke: "currentColor",
789
- strokeLinecap: "round",
790
- strokeLinejoin: "round",
791
- strokeWidth: 1.6,
792
- viewBox: "0 0 24 24",
793
- children: /* @__PURE__ */ jsxDEV("path", {
794
- d: "M7 4h7l4 4v12H7zM14 4v4h4"
795
- }, void 0, false)
796
- }, void 0, false), template.label]
797
- }, void 0, true)
798
- }, template.label, false));
799
- $[39] = onLoadTemplate;
800
- $[40] = t15;
801
- } else {
802
- t15 = $[40];
803
- }
804
- let t16;
805
- if ($[41] !== t15) {
806
- t16 = /* @__PURE__ */ jsxDEV("ul", {
807
- className: "flex flex-col gap-px",
808
- children: t15
809
- }, void 0, false);
810
- $[41] = t15;
811
- $[42] = t16;
812
- } else {
813
- t16 = $[42];
814
- }
815
- let t17;
816
- if ($[43] !== t14 || $[44] !== t16) {
817
- t17 = /* @__PURE__ */ jsxDEV("div", {
818
- children: [t14, t16]
819
- }, void 0, true);
820
- $[43] = t14;
821
- $[44] = t16;
822
- $[45] = t17;
823
- } else {
824
- t17 = $[45];
825
- }
826
- let t18;
827
- if ($[46] !== history || $[47] !== onClearHistory || $[48] !== onLoadHistory || $[49] !== t) {
828
- t18 = history.length > 0 && /* @__PURE__ */ jsxDEV("div", {
829
- children: [/* @__PURE__ */ jsxDEV("div", {
830
- className: "flex items-center justify-between px-1 pb-1",
831
- children: [/* @__PURE__ */ jsxDEV("p", {
832
- className: "font-mono text-[11px] tracking-wide text-muted-foreground uppercase",
833
- children: t("History")
834
- }, void 0, false), /* @__PURE__ */ jsxDEV("button", {
835
- className: "rounded px-1 text-[11px] text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:text-foreground",
836
- "data-testid": "sql-history-clear",
837
- onClick: onClearHistory,
838
- type: "button",
839
- children: t("Clear history")
840
- }, void 0, false)]
841
- }, void 0, true), /* @__PURE__ */ jsxDEV("ul", {
842
- className: "flex flex-col gap-px",
843
- "data-testid": "sql-history",
844
- children: history.map((entry) => /* @__PURE__ */ jsxDEV("li", {
845
- children: /* @__PURE__ */ jsxDEV("button", {
846
- className: "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-start text-[13px] text-muted-foreground outline-none transition-colors hover:bg-sidebar-accent hover:text-foreground focus-visible:bg-sidebar-accent",
847
- "data-sql": entry.sql,
848
- "data-testid": "sql-history-item",
849
- onClick: onLoadHistory,
850
- title: entry.sql,
851
- type: "button",
852
- children: [/* @__PURE__ */ jsxDEV("svg", {
853
- "aria-hidden": "true",
854
- className: "size-3.5 shrink-0 opacity-70",
855
- fill: "none",
856
- stroke: "currentColor",
857
- strokeLinecap: "round",
858
- strokeLinejoin: "round",
859
- strokeWidth: 1.6,
860
- viewBox: "0 0 24 24",
861
- children: /* @__PURE__ */ jsxDEV("path", {
862
- d: "M12 8v4l3 2M12 21a9 9 0 1 1 0-18 9 9 0 0 1 0 18Z"
863
- }, void 0, false)
864
- }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
865
- className: "truncate font-mono",
866
- children: entry.sql
867
- }, void 0, false)]
868
- }, void 0, true)
869
- }, `${entry.at.toString()}:${entry.sql}`, false))
870
- }, void 0, false)]
871
- }, void 0, true);
872
- $[46] = history;
873
- $[47] = onClearHistory;
874
- $[48] = onLoadHistory;
875
- $[49] = t;
876
- $[50] = t18;
877
- } else {
878
- t18 = $[50];
879
- }
880
- let t19;
881
- if ($[51] !== t12 || $[52] !== t17 || $[53] !== t18) {
882
- t19 = /* @__PURE__ */ jsxDEV("div", {
883
- className: "flex flex-1 flex-col gap-4 overflow-y-auto p-2",
884
- children: [t12, t17, t18]
885
- }, void 0, true);
886
- $[51] = t12;
887
- $[52] = t17;
888
- $[53] = t18;
889
- $[54] = t19;
890
- } else {
891
- t19 = $[54];
892
- }
893
- let t20;
894
- if ($[55] !== t19 || $[56] !== t8) {
895
- t20 = /* @__PURE__ */ jsxDEV("aside", {
896
- className: "flex h-full w-64 shrink-0 flex-col border-e border-border bg-sidebar",
897
- children: [t8, t19]
898
- }, void 0, true);
899
- $[55] = t19;
900
- $[56] = t8;
901
- $[57] = t20;
902
- } else {
903
- t20 = $[57];
904
- }
905
- return t20;
906
- };
907
-
908
- const LIST_TABLES = adminRef(ADMIN_FUNCTIONS.listTables);
909
- const READ_TABLE_PAGE = adminRef(ADMIN_FUNCTIONS.readTablePage);
910
- const useSqlSchema = (shardKey) => {
911
- const $ = c(16);
912
- const client = useLunora();
913
- let t0;
914
- if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
915
- t0 = [];
916
- $[0] = t0;
917
- } else {
918
- t0 = $[0];
919
- }
920
- const [tables, setTables] = useState(t0);
921
- let t1;
922
- if ($[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
923
- t1 = {};
924
- $[1] = t1;
925
- } else {
926
- t1 = $[1];
927
- }
928
- const [columns, setColumns] = useState(t1);
929
- let t2;
930
- if ($[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
931
- t2 = /* @__PURE__ */ new Set();
932
- $[2] = t2;
933
- } else {
934
- t2 = $[2];
935
- }
936
- const probed = useRef(t2);
937
- let t3;
938
- let t4;
939
- if ($[3] !== client || $[4] !== shardKey) {
940
- t3 = () => {
941
- const token = {
942
- cancelled: false
943
- };
944
- const load = async () => {
945
- try {
946
- const result = await client.query(LIST_TABLES, {}, callOptions(shardKey));
947
- if (!token.cancelled) {
948
- setTables(result.map(_temp$2));
949
- setColumns({});
950
- probed.current = /* @__PURE__ */ new Set();
951
- }
952
- } catch {
953
- if (!token.cancelled) {
954
- setTables([]);
955
- setColumns({});
956
- probed.current = /* @__PURE__ */ new Set();
957
- }
958
- }
959
- };
960
- fireAndForget(load());
961
- return () => {
962
- token.cancelled = true;
963
- };
964
- };
965
- t4 = [client, shardKey];
966
- $[3] = client;
967
- $[4] = shardKey;
968
- $[5] = t3;
969
- $[6] = t4;
970
- } else {
971
- t3 = $[5];
972
- t4 = $[6];
973
- }
974
- useEffect(t3, t4);
975
- let t5;
976
- if ($[7] !== client || $[8] !== shardKey) {
977
- t5 = (table_0) => {
978
- if (probed.current.has(table_0)) {
979
- return;
980
- }
981
- probed.current.add(table_0);
982
- const fetchColumns = async () => {
983
- try {
984
- const page = await client.query(READ_TABLE_PAGE, {
985
- limit: 1,
986
- offset: 0,
987
- table: table_0
988
- }, callOptions(shardKey));
989
- setColumns((previous) => ({
990
- ...previous,
991
- [table_0]: page.columns
992
- }));
993
- } catch {
994
- probed.current.delete(table_0);
995
- }
996
- };
997
- fireAndForget(fetchColumns());
998
- };
999
- $[7] = client;
1000
- $[8] = shardKey;
1001
- $[9] = t5;
1002
- } else {
1003
- t5 = $[9];
1004
- }
1005
- const probe = t5;
1006
- let t6;
1007
- if ($[10] !== columns || $[11] !== tables) {
1008
- t6 = {
1009
- columns,
1010
- tables
1011
- };
1012
- $[10] = columns;
1013
- $[11] = tables;
1014
- $[12] = t6;
1015
- } else {
1016
- t6 = $[12];
1017
- }
1018
- const schema = t6;
1019
- let t7;
1020
- if ($[13] !== probe || $[14] !== schema) {
1021
- t7 = {
1022
- probe,
1023
- schema
1024
- };
1025
- $[13] = probe;
1026
- $[14] = schema;
1027
- $[15] = t7;
1028
- } else {
1029
- t7 = $[15];
1030
- }
1031
- return t7;
1032
- };
1033
- const TABLE_REF = /\b(?:from|join|update|into)\s+([a-z_][\w$]*)|\b([a-z_][\w$]*)\s*\./gi;
1034
- const referencedTables = (sql) => {
1035
- const names = /* @__PURE__ */ new Set();
1036
- TABLE_REF.lastIndex = 0;
1037
- let match = TABLE_REF.exec(sql);
1038
- while (match !== null) {
1039
- names.add(match[1] ?? match[2]);
1040
- match = TABLE_REF.exec(sql);
1041
- }
1042
- return [...names];
1043
- };
1044
- function _temp$2(table) {
1045
- return table.name;
1046
- }
1047
-
1048
- const TABS_KEY = "lunora-studio-sql-tabs";
1049
- const ACTIVE_KEY = "lunora-studio-sql-active-tab";
1050
- const MAX_TABS = 12;
1051
- const makeTab = (sql = "", name = "") => {
1052
- return {
1053
- activeId: null,
1054
- id: newId("tab"),
1055
- name,
1056
- sql
1057
- };
1058
- };
1059
- const usePersistedActive = () => {
1060
- return usePersistedValue(ACTIVE_KEY, "");
1061
- };
1062
- const usePersistedTabs = (seed) => {
1063
- const [stored, setTabs] = usePersistedList(TABS_KEY);
1064
- const [activeRaw, setActiveId] = usePersistedActive();
1065
- const seedTab = useRef(null);
1066
- if (stored.length === 0 && seedTab.current === null) {
1067
- seedTab.current = seed();
1068
- }
1069
- useEffect(() => {
1070
- if (stored.length === 0 && seedTab.current !== null) {
1071
- const initial = seedTab.current;
1072
- setTabs([initial]);
1073
- }
1074
- }, [setTabs, stored.length]);
1075
- const tabs = stored.length === 0 && seedTab.current !== null ? [seedTab.current] : stored;
1076
- const activeId = tabs.some((tab) => tab.id === activeRaw) ? activeRaw : tabs[0]?.id ?? "";
1077
- return {
1078
- activeId,
1079
- setActiveId,
1080
- setTabs,
1081
- tabs
1082
- };
1083
- };
1084
- const isDirty = (tab) => tab.activeId === null && tab.sql.trim() !== "";
1085
- const addTab = (tabs, tab) => [...tabs, tab].slice(-MAX_TABS);
1086
- const closeTab = (tabs, id, makeEmpty) => {
1087
- const index = tabs.findIndex((tab) => tab.id === id);
1088
- if (index === -1) {
1089
- return {
1090
- activeId: tabs[0]?.id ?? "",
1091
- tabs: [...tabs]
1092
- };
1093
- }
1094
- const remaining = tabs.filter((tab) => tab.id !== id);
1095
- if (remaining.length === 0) {
1096
- const fresh = makeEmpty();
1097
- return {
1098
- activeId: fresh.id,
1099
- tabs: [fresh]
1100
- };
1101
- }
1102
- const neighbour = remaining[Math.min(index, remaining.length - 1)];
1103
- return {
1104
- activeId: neighbour.id,
1105
- tabs: remaining
1106
- };
1107
- };
1108
- const closeOtherTabs = (tabs, id) => {
1109
- const kept = tabs.filter((tab) => tab.id === id);
1110
- return kept.length === 0 ? {
1111
- activeId: tabs[0]?.id ?? "",
1112
- tabs: [...tabs]
1113
- } : {
1114
- activeId: id,
1115
- tabs: kept
1116
- };
1117
- };
1118
- const closeTabsToRight = (tabs, id, activeId) => {
1119
- const index = tabs.findIndex((tab) => tab.id === id);
1120
- if (index === -1) {
1121
- return {
1122
- activeId,
1123
- tabs: [...tabs]
1124
- };
1125
- }
1126
- const kept = tabs.slice(0, index + 1);
1127
- return {
1128
- activeId: kept.some((tab) => tab.id === activeId) ? activeId : id,
1129
- tabs: kept
1130
- };
1131
- };
1132
- const closeAllTabs = (makeEmpty) => {
1133
- const fresh = makeEmpty();
1134
- return {
1135
- activeId: fresh.id,
1136
- tabs: [fresh]
1137
- };
1138
- };
1139
- const tabsClosedBy = (op, tabs, id) => {
1140
- if (op === "others") {
1141
- return tabs.filter((tab) => tab.id !== id);
1142
- }
1143
- if (op === "right") {
1144
- const index = tabs.findIndex((tab) => tab.id === id);
1145
- return index === -1 ? [] : tabs.slice(index + 1);
1146
- }
1147
- return [...tabs];
1148
- };
1149
-
1150
- const derivedTabLabel = (sql, untitled) => sql.trim() === "" ? untitled : (sql.split("\n")[0] ?? sql).slice(0, 24);
1151
- const TabRenameInput = (t0) => {
1152
- const $ = c(14);
1153
- const {
1154
- initial,
1155
- onCancel,
1156
- onCommit,
1157
- placeholder,
1158
- testId
1159
- } = t0;
1160
- const t = useT();
1161
- const focusOnMount = _temp$1;
1162
- let t1;
1163
- if ($[0] !== onCommit) {
1164
- t1 = (event) => {
1165
- onCommit(event.currentTarget.value.trim());
1166
- };
1167
- $[0] = onCommit;
1168
- $[1] = t1;
1169
- } else {
1170
- t1 = $[1];
1171
- }
1172
- const onBlur = t1;
1173
- let t2;
1174
- if ($[2] !== onCancel || $[3] !== onCommit) {
1175
- t2 = (event_0) => {
1176
- if (event_0.key === "Enter") {
1177
- onCommit(event_0.currentTarget.value.trim());
1178
- } else {
1179
- if (event_0.key === "Escape") {
1180
- onCancel();
1181
- }
1182
- }
1183
- };
1184
- $[2] = onCancel;
1185
- $[3] = onCommit;
1186
- $[4] = t2;
1187
- } else {
1188
- t2 = $[4];
1189
- }
1190
- const onKeyDown = t2;
1191
- let t3;
1192
- if ($[5] !== t) {
1193
- t3 = t("Tab title");
1194
- $[5] = t;
1195
- $[6] = t3;
1196
- } else {
1197
- t3 = $[6];
1198
- }
1199
- let t4;
1200
- if ($[7] !== initial || $[8] !== onBlur || $[9] !== onKeyDown || $[10] !== placeholder || $[11] !== t3 || $[12] !== testId) {
1201
- t4 = /* @__PURE__ */ jsxDEV("input", {
1202
- "aria-label": t3,
1203
- className: "w-40 rounded border border-ring bg-background px-1 py-0.5 text-xs outline-none",
1204
- "data-testid": testId,
1205
- defaultValue: initial,
1206
- onBlur,
1207
- onKeyDown,
1208
- placeholder,
1209
- ref: focusOnMount,
1210
- type: "text"
1211
- }, void 0, false);
1212
- $[7] = initial;
1213
- $[8] = onBlur;
1214
- $[9] = onKeyDown;
1215
- $[10] = placeholder;
1216
- $[11] = t3;
1217
- $[12] = testId;
1218
- $[13] = t4;
1219
- } else {
1220
- t4 = $[13];
1221
- }
1222
- return t4;
1223
- };
1224
- const TabCloseConfirm = (t0) => {
1225
- const $ = c(29);
1226
- const {
1227
- idBase,
1228
- onDiscard,
1229
- onKeep
1230
- } = t0;
1231
- const t = useT();
1232
- const t1 = `sql-tab-close-prompt-${idBase}`;
1233
- let t2;
1234
- if ($[0] !== t) {
1235
- t2 = t("Discard?");
1236
- $[0] = t;
1237
- $[1] = t2;
1238
- } else {
1239
- t2 = $[1];
1240
- }
1241
- let t3;
1242
- if ($[2] !== t2) {
1243
- t3 = /* @__PURE__ */ jsxDEV("span", {
1244
- className: "text-[11px] text-muted-foreground",
1245
- children: t2
1246
- }, void 0, false);
1247
- $[2] = t2;
1248
- $[3] = t3;
1249
- } else {
1250
- t3 = $[3];
1251
- }
1252
- let t4;
1253
- if ($[4] !== t) {
1254
- t4 = t("Discard changes");
1255
- $[4] = t;
1256
- $[5] = t4;
1257
- } else {
1258
- t4 = $[5];
1259
- }
1260
- const t5 = `sql-tab-close-confirm-${idBase}`;
1261
- let t6;
1262
- if ($[6] !== t) {
1263
- t6 = t("Discard changes");
1264
- $[6] = t;
1265
- $[7] = t6;
1266
- } else {
1267
- t6 = $[7];
1268
- }
1269
- let t7;
1270
- if ($[8] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1271
- t7 = /* @__PURE__ */ jsxDEV("svg", {
1272
- "aria-hidden": "true",
1273
- className: "size-3",
1274
- fill: "none",
1275
- stroke: "currentColor",
1276
- strokeLinecap: "round",
1277
- strokeLinejoin: "round",
1278
- strokeWidth: 2.4,
1279
- viewBox: "0 0 24 24",
1280
- children: /* @__PURE__ */ jsxDEV("path", {
1281
- d: "M5 13l4 4L19 7"
1282
- }, void 0, false)
1283
- }, void 0, false);
1284
- $[8] = t7;
1285
- } else {
1286
- t7 = $[8];
1287
- }
1288
- let t8;
1289
- if ($[9] !== onDiscard || $[10] !== t4 || $[11] !== t5 || $[12] !== t6) {
1290
- t8 = /* @__PURE__ */ jsxDEV("button", {
1291
- "aria-label": t4,
1292
- className: "flex size-5 items-center justify-center rounded text-destructive hover:bg-destructive/10",
1293
- "data-testid": t5,
1294
- onClick: onDiscard,
1295
- title: t6,
1296
- type: "button",
1297
- children: t7
1298
- }, void 0, false);
1299
- $[9] = onDiscard;
1300
- $[10] = t4;
1301
- $[11] = t5;
1302
- $[12] = t6;
1303
- $[13] = t8;
1304
- } else {
1305
- t8 = $[13];
1306
- }
1307
- let t9;
1308
- if ($[14] !== t) {
1309
- t9 = t("Keep editing");
1310
- $[14] = t;
1311
- $[15] = t9;
1312
- } else {
1313
- t9 = $[15];
1314
- }
1315
- const t10 = `sql-tab-close-cancel-${idBase}`;
1316
- let t11;
1317
- if ($[16] !== t) {
1318
- t11 = t("Keep editing");
1319
- $[16] = t;
1320
- $[17] = t11;
1321
- } else {
1322
- t11 = $[17];
1323
- }
1324
- let t12;
1325
- if ($[18] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1326
- t12 = /* @__PURE__ */ jsxDEV("svg", {
1327
- "aria-hidden": "true",
1328
- className: "size-3",
1329
- fill: "none",
1330
- stroke: "currentColor",
1331
- strokeLinecap: "round",
1332
- strokeLinejoin: "round",
1333
- strokeWidth: 2.4,
1334
- viewBox: "0 0 24 24",
1335
- children: /* @__PURE__ */ jsxDEV("path", {
1336
- d: "M6 6l12 12M18 6 6 18"
1337
- }, void 0, false)
1338
- }, void 0, false);
1339
- $[18] = t12;
1340
- } else {
1341
- t12 = $[18];
1342
- }
1343
- let t13;
1344
- if ($[19] !== onKeep || $[20] !== t10 || $[21] !== t11 || $[22] !== t9) {
1345
- t13 = /* @__PURE__ */ jsxDEV("button", {
1346
- "aria-label": t9,
1347
- className: "flex size-5 items-center justify-center rounded text-muted-foreground hover:bg-accent",
1348
- "data-testid": t10,
1349
- onClick: onKeep,
1350
- title: t11,
1351
- type: "button",
1352
- children: t12
1353
- }, void 0, false);
1354
- $[19] = onKeep;
1355
- $[20] = t10;
1356
- $[21] = t11;
1357
- $[22] = t9;
1358
- $[23] = t13;
1359
- } else {
1360
- t13 = $[23];
1361
- }
1362
- let t14;
1363
- if ($[24] !== t1 || $[25] !== t13 || $[26] !== t3 || $[27] !== t8) {
1364
- t14 = /* @__PURE__ */ jsxDEV("span", {
1365
- className: "flex shrink-0 items-center gap-1",
1366
- "data-testid": t1,
1367
- role: "group",
1368
- children: [t3, t8, t13]
1369
- }, void 0, true);
1370
- $[24] = t1;
1371
- $[25] = t13;
1372
- $[26] = t3;
1373
- $[27] = t8;
1374
- $[28] = t14;
1375
- } else {
1376
- t14 = $[28];
1377
- }
1378
- return t14;
1379
- };
1380
- const TabButton = (t0) => {
1381
- const $ = c(47);
1382
- const {
1383
- active,
1384
- canClose,
1385
- onClose,
1386
- onMenu,
1387
- onRename,
1388
- onSelect,
1389
- tab
1390
- } = t0;
1391
- const t = useT();
1392
- const [editing, setEditing] = useState(false);
1393
- const [confirmingClose, setConfirmingClose] = useState(false);
1394
- let t1;
1395
- if ($[0] !== onMenu || $[1] !== tab.id) {
1396
- t1 = (event) => {
1397
- onMenu(tab.id, event);
1398
- };
1399
- $[0] = onMenu;
1400
- $[1] = tab.id;
1401
- $[2] = t1;
1402
- } else {
1403
- t1 = $[2];
1404
- }
1405
- const onContextMenu = t1;
1406
- let t2;
1407
- if ($[3] !== onSelect || $[4] !== tab.id) {
1408
- t2 = () => {
1409
- onSelect(tab.id);
1410
- };
1411
- $[3] = onSelect;
1412
- $[4] = tab.id;
1413
- $[5] = t2;
1414
- } else {
1415
- t2 = $[5];
1416
- }
1417
- const onClick = t2;
1418
- let t3;
1419
- if ($[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1420
- t3 = () => {
1421
- setEditing(true);
1422
- };
1423
- $[6] = t3;
1424
- } else {
1425
- t3 = $[6];
1426
- }
1427
- const startEditing = t3;
1428
- let t4;
1429
- if ($[7] !== onClose || $[8] !== tab) {
1430
- t4 = (event_0) => {
1431
- event_0.stopPropagation();
1432
- if (isDirty(tab)) {
1433
- setConfirmingClose(true);
1434
- } else {
1435
- onClose(tab.id);
1436
- }
1437
- };
1438
- $[7] = onClose;
1439
- $[8] = tab;
1440
- $[9] = t4;
1441
- } else {
1442
- t4 = $[9];
1443
- }
1444
- const onCloseClick = t4;
1445
- let t5;
1446
- if ($[10] !== onClose || $[11] !== tab.id) {
1447
- t5 = (event_1) => {
1448
- event_1.stopPropagation();
1449
- setConfirmingClose(false);
1450
- onClose(tab.id);
1451
- };
1452
- $[10] = onClose;
1453
- $[11] = tab.id;
1454
- $[12] = t5;
1455
- } else {
1456
- t5 = $[12];
1457
- }
1458
- const confirmClose = t5;
1459
- let t6;
1460
- if ($[13] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1461
- t6 = (event_2) => {
1462
- event_2.stopPropagation();
1463
- setConfirmingClose(false);
1464
- };
1465
- $[13] = t6;
1466
- } else {
1467
- t6 = $[13];
1468
- }
1469
- const cancelClose = t6;
1470
- let t7;
1471
- if ($[14] !== onRename || $[15] !== tab.id) {
1472
- t7 = (name) => {
1473
- onRename(tab.id, name);
1474
- setEditing(false);
1475
- };
1476
- $[14] = onRename;
1477
- $[15] = tab.id;
1478
- $[16] = t7;
1479
- } else {
1480
- t7 = $[16];
1481
- }
1482
- const commitRename = t7;
1483
- let t8;
1484
- if ($[17] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1485
- t8 = () => {
1486
- setEditing(false);
1487
- };
1488
- $[17] = t8;
1489
- } else {
1490
- t8 = $[17];
1491
- }
1492
- const cancelRename = t8;
1493
- let t9;
1494
- if ($[18] !== tab.name) {
1495
- t9 = tab.name.trim();
1496
- $[18] = tab.name;
1497
- $[19] = t9;
1498
- } else {
1499
- t9 = $[19];
1500
- }
1501
- const custom = t9;
1502
- let t10;
1503
- if ($[20] !== t || $[21] !== tab.sql) {
1504
- t10 = derivedTabLabel(tab.sql, t("Untitled"));
1505
- $[20] = t;
1506
- $[21] = tab.sql;
1507
- $[22] = t10;
1508
- } else {
1509
- t10 = $[22];
1510
- }
1511
- const derived = t10;
1512
- const t11 = active ? "bg-background text-foreground" : "bg-muted/40 text-muted-foreground hover:text-foreground";
1513
- let t12;
1514
- if ($[23] !== t11) {
1515
- t12 = cn("group/tab flex shrink-0 items-center gap-1 border-e border-border ps-3 pe-1.5 text-xs", t11);
1516
- $[23] = t11;
1517
- $[24] = t12;
1518
- } else {
1519
- t12 = $[24];
1520
- }
1521
- const t13 = `sql-tab-${tab.id}`;
1522
- let t14;
1523
- if ($[25] !== active || $[26] !== commitRename || $[27] !== custom || $[28] !== derived || $[29] !== editing || $[30] !== onClick || $[31] !== t || $[32] !== tab.id) {
1524
- t14 = editing ? /* @__PURE__ */ jsxDEV(TabRenameInput, {
1525
- initial: custom,
1526
- onCancel: cancelRename,
1527
- onCommit: commitRename,
1528
- placeholder: derived,
1529
- testId: `sql-tab-rename-${tab.id}`
1530
- }, void 0, false) : /* @__PURE__ */ jsxDEV("button", {
1531
- "aria-pressed": active,
1532
- className: "max-w-40 truncate py-1.5 outline-none",
1533
- "data-testid": `sql-tab-select-${tab.id}`,
1534
- onClick,
1535
- onDoubleClick: startEditing,
1536
- title: t("Double-click to rename"),
1537
- type: "button",
1538
- children: custom === "" ? derived : custom
1539
- }, void 0, false);
1540
- $[25] = active;
1541
- $[26] = commitRename;
1542
- $[27] = custom;
1543
- $[28] = derived;
1544
- $[29] = editing;
1545
- $[30] = onClick;
1546
- $[31] = t;
1547
- $[32] = tab.id;
1548
- $[33] = t14;
1549
- } else {
1550
- t14 = $[33];
1551
- }
1552
- let t15;
1553
- if ($[34] !== canClose || $[35] !== confirmClose || $[36] !== confirmingClose || $[37] !== onCloseClick || $[38] !== t || $[39] !== tab.id) {
1554
- t15 = canClose && (confirmingClose ? /* @__PURE__ */ jsxDEV(TabCloseConfirm, {
1555
- idBase: tab.id,
1556
- onDiscard: confirmClose,
1557
- onKeep: cancelClose
1558
- }, void 0, false) : /* @__PURE__ */ jsxDEV("button", {
1559
- "aria-label": t("Close tab"),
1560
- className: "flex size-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive",
1561
- "data-testid": `sql-tab-close-${tab.id}`,
1562
- onClick: onCloseClick,
1563
- title: t("Close tab"),
1564
- type: "button",
1565
- children: /* @__PURE__ */ jsxDEV("svg", {
1566
- "aria-hidden": "true",
1567
- className: "size-3",
1568
- fill: "none",
1569
- stroke: "currentColor",
1570
- strokeLinecap: "round",
1571
- strokeLinejoin: "round",
1572
- strokeWidth: 2,
1573
- viewBox: "0 0 24 24",
1574
- children: /* @__PURE__ */ jsxDEV("path", {
1575
- d: "M6 6l12 12M18 6 6 18"
1576
- }, void 0, false)
1577
- }, void 0, false)
1578
- }, void 0, false));
1579
- $[34] = canClose;
1580
- $[35] = confirmClose;
1581
- $[36] = confirmingClose;
1582
- $[37] = onCloseClick;
1583
- $[38] = t;
1584
- $[39] = tab.id;
1585
- $[40] = t15;
1586
- } else {
1587
- t15 = $[40];
1588
- }
1589
- let t16;
1590
- if ($[41] !== onContextMenu || $[42] !== t12 || $[43] !== t13 || $[44] !== t14 || $[45] !== t15) {
1591
- t16 = /* @__PURE__ */ jsxDEV("div", {
1592
- className: t12,
1593
- "data-testid": t13,
1594
- onContextMenu,
1595
- children: [t14, t15]
1596
- }, void 0, true);
1597
- $[41] = onContextMenu;
1598
- $[42] = t12;
1599
- $[43] = t13;
1600
- $[44] = t14;
1601
- $[45] = t15;
1602
- $[46] = t16;
1603
- } else {
1604
- t16 = $[46];
1605
- }
1606
- return t16;
1607
- };
1608
- function _temp$1(node) {
1609
- node?.focus();
1610
- node?.select();
1611
- }
1612
-
1613
- const RUN_SQL = adminRef(ADMIN_FUNCTIONS.runSql);
1614
- const STORAGE_KEY = "lunora-studio-sql-queries";
1615
- const HISTORY_KEY = "lunora-studio-sql-history";
1616
- const SPLIT_VIEW_KEY = "lunora-studio-sql-split-view";
1617
- const HISTORY_LIMIT = 25;
1618
- const GUTTER_STYLE = {
1619
- minWidth: "2.75rem",
1620
- paddingInline: "0.5rem"
1621
- };
1622
- const DEFAULT_TAB_OUTPUT = {
1623
- error: null,
1624
- pane: "results",
1625
- result: null
1626
- };
1627
- const SqlResultTable = (t0) => {
1628
- const $ = c(16);
1629
- const {
1630
- result
1631
- } = t0;
1632
- if (result.columns.length === 0) {
1633
- const t12 = result.rowCount === 0 ? "0 rows" : "";
1634
- let t22;
1635
- if ($[0] !== t12) {
1636
- t22 = /* @__PURE__ */ jsxDEV("p", {
1637
- className: "p-4 text-sm text-muted-foreground",
1638
- children: t12
1639
- }, void 0, false);
1640
- $[0] = t12;
1641
- $[1] = t22;
1642
- } else {
1643
- t22 = $[1];
1644
- }
1645
- return t22;
1646
- }
1647
- let t1;
1648
- if ($[2] !== result.columns) {
1649
- t1 = result.columns.map(_temp);
1650
- $[2] = result.columns;
1651
- $[3] = t1;
1652
- } else {
1653
- t1 = $[3];
1654
- }
1655
- let t2;
1656
- if ($[4] !== t1) {
1657
- t2 = /* @__PURE__ */ jsxDEV(TableHeader, {
1658
- className: "sticky top-0 z-10 bg-muted",
1659
- children: /* @__PURE__ */ jsxDEV(TableRow, {
1660
- children: t1
1661
- }, void 0, false)
1662
- }, void 0, false);
1663
- $[4] = t1;
1664
- $[5] = t2;
1665
- } else {
1666
- t2 = $[5];
1667
- }
1668
- let t3;
1669
- if ($[6] !== result.columns || $[7] !== result.rows) {
1670
- let t42;
1671
- if ($[9] !== result.columns) {
1672
- t42 = (row, rowIndex) => /* @__PURE__ */ jsxDEV(TableRow, {
1673
- "data-testid": "sql-row",
1674
- children: result.columns.map((column_0) => /* @__PURE__ */ jsxDEV(TableCell, {
1675
- className: "max-w-md truncate font-mono text-xs",
1676
- children: /* @__PURE__ */ jsxDEV(CellValue, {
1677
- value: row[column_0]
1678
- }, void 0, false)
1679
- }, column_0, false))
1680
- }, rowIndex, false);
1681
- $[9] = result.columns;
1682
- $[10] = t42;
1683
- } else {
1684
- t42 = $[10];
1685
- }
1686
- t3 = result.rows.map(t42);
1687
- $[6] = result.columns;
1688
- $[7] = result.rows;
1689
- $[8] = t3;
1690
- } else {
1691
- t3 = $[8];
1692
- }
1693
- let t4;
1694
- if ($[11] !== t3) {
1695
- t4 = /* @__PURE__ */ jsxDEV(TableBody, {
1696
- children: t3
1697
- }, void 0, false);
1698
- $[11] = t3;
1699
- $[12] = t4;
1700
- } else {
1701
- t4 = $[12];
1702
- }
1703
- let t5;
1704
- if ($[13] !== t2 || $[14] !== t4) {
1705
- t5 = /* @__PURE__ */ jsxDEV(Table, {
1706
- "data-testid": "sql-rows",
1707
- children: [t2, t4]
1708
- }, void 0, true);
1709
- $[13] = t2;
1710
- $[14] = t4;
1711
- $[15] = t5;
1712
- } else {
1713
- t5 = $[15];
1714
- }
1715
- return t5;
1716
- };
1717
- const SqlEditorPanel = ({
1718
- initialShardKey
1719
- }) => {
1720
- const client = useLunora();
1721
- const t = useT();
1722
- const [queries, setQueries] = usePersistedList(STORAGE_KEY);
1723
- const [history, setHistory] = usePersistedList(HISTORY_KEY);
1724
- const [search, setSearch] = useState("");
1725
- const seedTab = () => makeTab(TEMPLATES[0]?.sql ?? "");
1726
- const {
1727
- activeId: activeTabId,
1728
- setActiveId: setActiveTabId,
1729
- setTabs,
1730
- tabs
1731
- } = usePersistedTabs(seedTab);
1732
- const [outputs, setOutputs] = useState({});
1733
- const [shardKey, setShardKey] = useState(initialShardKey ?? "");
1734
- const [running, setRunning] = useState(false);
1735
- const [splitView, setSplitView] = usePersistedValue(SPLIT_VIEW_KEY, false);
1736
- const [tabMenu, setTabMenu] = useState(null);
1737
- const [pendingBulk, setPendingBulk] = useState(null);
1738
- const gutterRef = useRef(null);
1739
- const editorRef = useRef(null);
1740
- const privateListRef = useRef(null);
1741
- const listboxId = useId();
1742
- const {
1743
- probe,
1744
- schema
1745
- } = useSqlSchema(shardKey);
1746
- const activeTab = tabs.find((each) => each.id === activeTabId) ?? tabs[0] ?? makeTab();
1747
- const draft = activeTab.sql;
1748
- const {
1749
- activeId
1750
- } = activeTab;
1751
- const output = outputs[activeTab.id] ?? DEFAULT_TAB_OUTPUT;
1752
- const {
1753
- error,
1754
- result
1755
- } = output;
1756
- const tab = output.pane;
1757
- const patchActiveTab = (patch) => {
1758
- setTabs((current) => current.map((each_0) => each_0.id === activeTab.id ? {
1759
- ...each_0,
1760
- ...patch
1761
- } : each_0));
1762
- };
1763
- const setActiveOutput = (next) => {
1764
- setOutputs((current_0) => {
1765
- const previous = current_0[activeTab.id] ?? DEFAULT_TAB_OUTPUT;
1766
- return {
1767
- ...current_0,
1768
- [activeTab.id]: {
1769
- error: next.error,
1770
- pane: next.pane ?? previous.pane,
1771
- result: next.result
1772
- }
1773
- };
1774
- });
1775
- };
1776
- const setActivePane = (pane) => {
1777
- setOutputs((current_1) => {
1778
- const previous_0 = current_1[activeTab.id] ?? DEFAULT_TAB_OUTPUT;
1779
- return {
1780
- ...current_1,
1781
- [activeTab.id]: {
1782
- ...previous_0,
1783
- pane
1784
- }
1785
- };
1786
- });
1787
- };
1788
- const setDraft = (value) => {
1789
- patchActiveTab({
1790
- sql: value
1791
- });
1792
- if (activeId !== null) {
1793
- setQueries((current_2) => current_2.map((query) => query.id === activeId ? {
1794
- ...query,
1795
- sql: value
1796
- } : query));
1797
- }
1798
- };
1799
- const autocomplete = useSqlAutocomplete(schema, editorRef, setDraft);
1800
- const {
1801
- close: closeAutocomplete,
1802
- commit: commitAutocomplete,
1803
- move: moveAutocomplete,
1804
- refresh: refreshAutocomplete,
1805
- state: autocompleteState
1806
- } = autocomplete;
1807
- const onPickSuggestion = (index) => {
1808
- moveAutocomplete(index - (autocompleteState?.active ?? 0));
1809
- commitAutocomplete();
1810
- };
1811
- useEffect(() => {
1812
- const node = editorRef.current;
1813
- if (node !== null && node === document.activeElement) {
1814
- refreshAutocomplete(node.value, node.selectionStart);
1815
- }
1816
- }, [refreshAutocomplete, schema]);
1817
- const recordHistory = (sql) => {
1818
- setHistory((current_3) => {
1819
- if (current_3[0]?.sql === sql) {
1820
- return current_3;
1821
- }
1822
- const next_0 = [{
1823
- at: Date.now(),
1824
- sql
1825
- }, ...current_3.filter((entry) => entry.sql !== sql)];
1826
- return next_0.slice(0, HISTORY_LIMIT);
1827
- });
1828
- };
1829
- const run = async (mode) => {
1830
- if (draft.trim() === "") {
1831
- return;
1832
- }
1833
- setRunning(true);
1834
- const sql_0 = mode === "explain" ? `EXPLAIN QUERY PLAN ${draft}` : draft;
1835
- try {
1836
- const next_1 = await client.query(RUN_SQL, {
1837
- sql: sql_0
1838
- }, callOptions(shardKey));
1839
- setActiveOutput({
1840
- error: null,
1841
- pane: mode,
1842
- result: next_1
1843
- });
1844
- recordShard(shardKey);
1845
- recordHistory(sql_0);
1846
- } catch (error_) {
1847
- setActiveOutput({
1848
- error: errorMessage(error_),
1849
- pane: mode,
1850
- result: null
1851
- });
1852
- } finally {
1853
- setRunning(false);
1854
- }
1855
- };
1856
- const onRun = () => {
1857
- fireAndForget(run("results"));
1858
- };
1859
- const onDraftChange = (event) => {
1860
- const {
1861
- selectionStart,
1862
- value: value_0
1863
- } = event.target;
1864
- setDraft(value_0);
1865
- for (const table of referencedTables(value_0)) {
1866
- probe(table);
1867
- }
1868
- refreshAutocomplete(value_0, selectionStart);
1869
- };
1870
- const onEditorSelect = (event_0) => {
1871
- const node_0 = event_0.currentTarget;
1872
- refreshAutocomplete(node_0.value, node_0.selectionStart);
1873
- };
1874
- const onEditorKeyDown = (event_1) => {
1875
- if (autocompleteState !== null) {
1876
- if (event_1.key === "ArrowDown") {
1877
- event_1.preventDefault();
1878
- moveAutocomplete(1);
1879
- return;
1880
- }
1881
- if (event_1.key === "ArrowUp") {
1882
- event_1.preventDefault();
1883
- moveAutocomplete(-1);
1884
- return;
1885
- }
1886
- if (event_1.key === "Escape") {
1887
- event_1.preventDefault();
1888
- closeAutocomplete();
1889
- return;
1890
- }
1891
- if ((event_1.key === "Enter" || event_1.key === "Tab") && !event_1.metaKey && !event_1.ctrlKey && commitAutocomplete()) {
1892
- event_1.preventDefault();
1893
- return;
1894
- }
1895
- }
1896
- if ((event_1.metaKey || event_1.ctrlKey) && event_1.key === "Enter") {
1897
- event_1.preventDefault();
1898
- fireAndForget(run(tab));
1899
- }
1900
- };
1901
- const onEditorBlur = () => {
1902
- requestAnimationFrame(() => {
1903
- closeAutocomplete();
1904
- });
1905
- };
1906
- const onEditorScroll = (event_2) => {
1907
- if (gutterRef.current !== null) {
1908
- gutterRef.current.scrollTop = event_2.currentTarget.scrollTop;
1909
- }
1910
- };
1911
- const loadIntoActiveTab = (sql_1, savedId) => {
1912
- setTabs((current_4) => current_4.map((each_1) => each_1.id === activeTab.id ? {
1913
- ...each_1,
1914
- activeId: savedId,
1915
- sql: sql_1
1916
- } : each_1));
1917
- setActiveOutput({
1918
- error: null,
1919
- result: null
1920
- });
1921
- };
1922
- const newQuery = () => {
1923
- const query_0 = {
1924
- id: newId("q"),
1925
- name: t("Untitled query"),
1926
- sql: ""
1927
- };
1928
- setQueries((current_5) => [query_0, ...current_5]);
1929
- loadIntoActiveTab("", query_0.id);
1930
- };
1931
- const selectQuery = (id) => {
1932
- const found = queries.find((query_1) => query_1.id === id);
1933
- if (found !== void 0) {
1934
- loadIntoActiveTab(found.sql, id);
1935
- privateListRef.current?.querySelector(`[data-testid="sql-query-${id}"]`)?.scrollIntoView({
1936
- block: "nearest"
1937
- });
1938
- }
1939
- };
1940
- const deleteQuery = (id_0) => {
1941
- setQueries((current_6) => current_6.filter((query_2) => query_2.id !== id_0));
1942
- setTabs((current_7) => current_7.map((each_2) => each_2.activeId === id_0 ? {
1943
- ...each_2,
1944
- activeId: null
1945
- } : each_2));
1946
- };
1947
- const loadTemplate = (event_3) => {
1948
- loadIntoActiveTab(event_3.currentTarget.dataset.sql ?? "", null);
1949
- };
1950
- const loadFromHistory = (event_4) => {
1951
- loadIntoActiveTab(event_4.currentTarget.dataset.sql ?? "", null);
1952
- };
1953
- const clearHistory = () => {
1954
- setHistory([]);
1955
- };
1956
- const formatDraft = () => {
1957
- setDraft(formatSql(draft));
1958
- };
1959
- const addEditorTab = () => {
1960
- if (tabs.length >= MAX_TABS) {
1961
- return;
1962
- }
1963
- const fresh = makeTab();
1964
- setTabs((current_8) => addTab(current_8, fresh));
1965
- setActiveTabId(fresh.id);
1966
- };
1967
- const commitTabs = (next_2) => {
1968
- setTabMenu(null);
1969
- setPendingBulk(null);
1970
- setTabs(next_2.tabs);
1971
- setActiveTabId(next_2.activeId);
1972
- const openIds = new Set(next_2.tabs.map((each_3) => each_3.id));
1973
- setOutputs((current_9) => Object.fromEntries(Object.entries(current_9).filter(([key]) => openIds.has(key))));
1974
- };
1975
- const closeEditorTab = (id_1) => {
1976
- commitTabs(closeTab(tabs, id_1, makeTab));
1977
- };
1978
- const applyBulk = (op, id_2) => {
1979
- if (op === "others") {
1980
- commitTabs(closeOtherTabs(tabs, id_2));
1981
- } else if (op === "right") {
1982
- commitTabs(closeTabsToRight(tabs, id_2, activeTabId));
1983
- } else {
1984
- commitTabs(closeAllTabs(makeTab));
1985
- }
1986
- };
1987
- const requestBulk = (op_0) => {
1988
- if (tabMenu === null) {
1989
- return;
1990
- }
1991
- if (tabsClosedBy(op_0, tabs, tabMenu.id).some((each_4) => isDirty(each_4))) {
1992
- setPendingBulk(op_0);
1993
- } else {
1994
- applyBulk(op_0, tabMenu.id);
1995
- }
1996
- };
1997
- const openTabMenu = (id_3, event_5) => {
1998
- event_5.preventDefault();
1999
- setPendingBulk(null);
2000
- setTabMenu({
2001
- id: id_3,
2002
- x: event_5.clientX,
2003
- y: event_5.clientY
2004
- });
2005
- };
2006
- const closeTabMenu = () => {
2007
- setTabMenu(null);
2008
- setPendingBulk(null);
2009
- };
2010
- const onBackdropContextMenu = (event_6) => {
2011
- event_6.preventDefault();
2012
- setTabMenu(null);
2013
- setPendingBulk(null);
2014
- };
2015
- const onCloseOthers = () => {
2016
- requestBulk("others");
2017
- };
2018
- const onCloseToRight = () => {
2019
- requestBulk("right");
2020
- };
2021
- const onCloseAll = () => {
2022
- requestBulk("all");
2023
- };
2024
- const confirmBulk = () => {
2025
- if (tabMenu !== null && pendingBulk !== null) {
2026
- applyBulk(pendingBulk, tabMenu.id);
2027
- }
2028
- setPendingBulk(null);
2029
- };
2030
- const cancelBulk = () => {
2031
- setPendingBulk(null);
2032
- };
2033
- const tabMenuStyle = tabMenu === null ? void 0 : {
2034
- left: tabMenu.x,
2035
- top: tabMenu.y
2036
- };
2037
- const selectTab = (id_4) => {
2038
- closeAutocomplete();
2039
- setActiveTabId(id_4);
2040
- };
2041
- const renameTab = (id_5, name) => {
2042
- setTabs((current_10) => current_10.map((each_5) => each_5.id === id_5 ? {
2043
- ...each_5,
2044
- name
2045
- } : each_5));
2046
- };
2047
- const showResults = () => {
2048
- setActivePane("results");
2049
- };
2050
- const showExplain = () => {
2051
- fireAndForget(run("explain"));
2052
- };
2053
- const showChart = () => {
2054
- setActivePane("chart");
2055
- };
2056
- const toggleSplit = () => {
2057
- setSplitView(!splitView);
2058
- };
2059
- const lineCount = draft.split("\n").length;
2060
- const onSearchChange = (event_7) => {
2061
- setSearch(event_7.target.value);
2062
- };
2063
- const tabClass = (selected) => `border-b-2 px-3 py-2 text-sm outline-none transition-colors ${selected ? "border-foreground font-medium text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"}`;
2064
- const workspaceClass = splitView ? "flex min-h-0 flex-1 flex-row" : "flex min-h-0 flex-1 flex-col";
2065
- const resultsClass = splitView ? "flex w-2/5 min-h-0 min-w-0 shrink-0 flex-col border-s border-border" : "flex h-2/5 min-h-0 shrink-0 flex-col border-t border-border";
2066
- return /* @__PURE__ */ jsxDEV("div", {
2067
- className: "flex h-full min-w-0",
2068
- "data-testid": "lunora-sql-editor",
2069
- children: [/* @__PURE__ */ jsxDEV(SqlQuerySidebar, {
2070
- activeId,
2071
- history,
2072
- listRef: privateListRef,
2073
- onClearHistory: clearHistory,
2074
- onDelete: deleteQuery,
2075
- onLoadHistory: loadFromHistory,
2076
- onLoadTemplate: loadTemplate,
2077
- onNew: newQuery,
2078
- onSearchChange,
2079
- onSelect: selectQuery,
2080
- queries,
2081
- search
2082
- }, void 0, false), /* @__PURE__ */ jsxDEV("div", {
2083
- className: "flex min-w-0 flex-1 flex-col",
2084
- children: [/* @__PURE__ */ jsxDEV("div", {
2085
- className: "flex shrink-0 items-stretch overflow-x-auto border-b border-border bg-muted/30",
2086
- "data-testid": "sql-tab-strip",
2087
- role: "tablist",
2088
- children: [tabs.map((each_6) => /* @__PURE__ */ jsxDEV(TabButton, {
2089
- active: each_6.id === activeTab.id,
2090
- canClose: tabs.length > 1,
2091
- onClose: closeEditorTab,
2092
- onMenu: openTabMenu,
2093
- onRename: renameTab,
2094
- onSelect: selectTab,
2095
- tab: each_6
2096
- }, each_6.id, false)), /* @__PURE__ */ jsxDEV("button", {
2097
- "aria-label": t("New tab"),
2098
- className: "flex size-8 shrink-0 items-center justify-center text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-foreground focus-visible:bg-accent disabled:pointer-events-none disabled:opacity-40",
2099
- "data-testid": "sql-tab-add",
2100
- disabled: tabs.length >= MAX_TABS,
2101
- onClick: addEditorTab,
2102
- title: t("New tab"),
2103
- type: "button",
2104
- children: /* @__PURE__ */ jsxDEV("svg", {
2105
- "aria-hidden": "true",
2106
- className: "size-4",
2107
- fill: "none",
2108
- stroke: "currentColor",
2109
- strokeLinecap: "round",
2110
- strokeLinejoin: "round",
2111
- strokeWidth: 1.7,
2112
- viewBox: "0 0 24 24",
2113
- children: /* @__PURE__ */ jsxDEV("path", {
2114
- d: "M12 5v14M5 12h14"
2115
- }, void 0, false)
2116
- }, void 0, false)
2117
- }, void 0, false)]
2118
- }, void 0, true), tabMenu !== null && /* @__PURE__ */ jsxDEV(Fragment, {
2119
- children: [/* @__PURE__ */ jsxDEV("div", {
2120
- className: "fixed inset-0 z-40",
2121
- "data-testid": "sql-tab-menu-backdrop",
2122
- onClick: closeTabMenu,
2123
- onContextMenu: onBackdropContextMenu,
2124
- role: "presentation"
2125
- }, void 0, false), /* @__PURE__ */ jsxDEV("div", {
2126
- className: "fixed z-50 min-w-44 rounded-md border border-border bg-popover py-1 text-popover-foreground shadow-md",
2127
- "data-testid": "sql-tab-menu",
2128
- role: "menu",
2129
- style: tabMenuStyle,
2130
- children: pendingBulk === null ? /* @__PURE__ */ jsxDEV(Fragment, {
2131
- children: [/* @__PURE__ */ jsxDEV("button", {
2132
- className: "flex w-full items-center px-3 py-1.5 text-start text-xs outline-none hover:bg-accent focus-visible:bg-accent disabled:pointer-events-none disabled:opacity-40",
2133
- "data-testid": "sql-tab-menu-close-others",
2134
- disabled: tabs.length <= 1,
2135
- onClick: onCloseOthers,
2136
- role: "menuitem",
2137
- type: "button",
2138
- children: t("Close other tabs")
2139
- }, void 0, false), /* @__PURE__ */ jsxDEV("button", {
2140
- className: "flex w-full items-center px-3 py-1.5 text-start text-xs outline-none hover:bg-accent focus-visible:bg-accent disabled:pointer-events-none disabled:opacity-40",
2141
- "data-testid": "sql-tab-menu-close-right",
2142
- disabled: tabs.findIndex((each_7) => each_7.id === tabMenu.id) >= tabs.length - 1,
2143
- onClick: onCloseToRight,
2144
- role: "menuitem",
2145
- type: "button",
2146
- children: t("Close tabs to the right")
2147
- }, void 0, false), /* @__PURE__ */ jsxDEV("button", {
2148
- className: "flex w-full items-center px-3 py-1.5 text-start text-xs outline-none hover:bg-accent focus-visible:bg-accent",
2149
- "data-testid": "sql-tab-menu-close-all",
2150
- onClick: onCloseAll,
2151
- role: "menuitem",
2152
- type: "button",
2153
- children: t("Close all tabs")
2154
- }, void 0, false)]
2155
- }, void 0, true) : (
2156
- // Discard confirm: the chosen bulk close would drop a tab with unsaved work.
2157
- /* @__PURE__ */ jsxDEV("div", {
2158
- className: "px-3 py-1.5",
2159
- "data-testid": "sql-tab-menu-confirm",
2160
- children: [/* @__PURE__ */ jsxDEV("p", {
2161
- className: "pb-1.5 text-xs text-muted-foreground",
2162
- children: t("Discard unsaved tabs?")
2163
- }, void 0, false), /* @__PURE__ */ jsxDEV("div", {
2164
- className: "flex items-center gap-1.5",
2165
- children: [/* @__PURE__ */ jsxDEV("button", {
2166
- className: "rounded px-2 py-1 text-xs font-medium text-destructive outline-none hover:bg-destructive/10 focus-visible:bg-destructive/10",
2167
- "data-testid": "sql-tab-menu-confirm-discard",
2168
- onClick: confirmBulk,
2169
- type: "button",
2170
- children: t("Discard")
2171
- }, void 0, false), /* @__PURE__ */ jsxDEV("button", {
2172
- className: "rounded px-2 py-1 text-xs text-muted-foreground outline-none hover:bg-accent focus-visible:bg-accent",
2173
- "data-testid": "sql-tab-menu-confirm-cancel",
2174
- onClick: cancelBulk,
2175
- type: "button",
2176
- children: t("Cancel")
2177
- }, void 0, false)]
2178
- }, void 0, true)]
2179
- }, void 0, true)
2180
- )
2181
- }, void 0, false)]
2182
- }, void 0, true), /* @__PURE__ */ jsxDEV("div", {
2183
- className: workspaceClass,
2184
- children: [/* @__PURE__ */ jsxDEV("div", {
2185
- className: "flex min-h-0 min-w-0 flex-1",
2186
- children: [/* @__PURE__ */ jsxDEV("div", {
2187
- "aria-hidden": "true",
2188
- className: "shrink-0 select-none overflow-hidden border-e border-border bg-muted/30 py-3 text-end font-mono text-xs leading-5 text-muted-foreground/60",
2189
- ref: gutterRef,
2190
- style: GUTTER_STYLE,
2191
- children: Array.from({
2192
- length: lineCount
2193
- }, (_, index_0) => /* @__PURE__ */ jsxDEV("div", {
2194
- children: index_0 + 1
2195
- }, index_0, false))
2196
- }, void 0, false), /* @__PURE__ */ jsxDEV("div", {
2197
- className: "relative min-w-0 flex-1",
2198
- children: [/* @__PURE__ */ jsxDEV("textarea", {
2199
- "aria-activedescendant": autocompleteState === null ? void 0 : `${listboxId}-opt-${autocompleteState.active.toString()}`,
2200
- "aria-autocomplete": "list",
2201
- "aria-controls": autocompleteState === null ? void 0 : listboxId,
2202
- "aria-expanded": autocompleteState !== null,
2203
- "aria-label": t("SQL query"),
2204
- className: "size-full resize-none bg-background p-3 font-mono text-xs leading-5 outline-none",
2205
- "data-testid": "sql-input",
2206
- onBlur: onEditorBlur,
2207
- onChange: onDraftChange,
2208
- onKeyDown: onEditorKeyDown,
2209
- onScroll: onEditorScroll,
2210
- onSelect: onEditorSelect,
2211
- placeholder: "SELECT * FROM …",
2212
- ref: editorRef,
2213
- role: "combobox",
2214
- spellCheck: false,
2215
- value: draft
2216
- }, void 0, false), /* @__PURE__ */ jsxDEV(AutocompletePopover, {
2217
- listboxId,
2218
- onPick: onPickSuggestion,
2219
- state: autocompleteState
2220
- }, void 0, false)]
2221
- }, void 0, true)]
2222
- }, void 0, true), /* @__PURE__ */ jsxDEV("div", {
2223
- className: resultsClass,
2224
- children: [/* @__PURE__ */ jsxDEV("div", {
2225
- className: "flex shrink-0 items-center gap-2 border-b border-border pe-2",
2226
- children: [/* @__PURE__ */ jsxDEV("button", {
2227
- className: tabClass(tab === "results"),
2228
- "data-testid": "sql-tab-results",
2229
- onClick: showResults,
2230
- type: "button",
2231
- children: t("Results")
2232
- }, void 0, false), /* @__PURE__ */ jsxDEV("button", {
2233
- className: tabClass(tab === "chart"),
2234
- "data-testid": "sql-tab-chart",
2235
- onClick: showChart,
2236
- type: "button",
2237
- children: t("Chart")
2238
- }, void 0, false), /* @__PURE__ */ jsxDEV("button", {
2239
- className: tabClass(tab === "explain"),
2240
- "data-testid": "sql-tab-explain",
2241
- onClick: showExplain,
2242
- type: "button",
2243
- children: t("Explain")
2244
- }, void 0, false), /* @__PURE__ */ jsxDEV("div", {
2245
- className: "ms-auto flex items-center gap-2",
2246
- children: [/* @__PURE__ */ jsxDEV("button", {
2247
- "aria-label": t("Split editor and results"),
2248
- "aria-pressed": splitView,
2249
- className: `inline-flex items-center rounded-md border border-border px-2 py-1.5 outline-none transition-colors hover:bg-accent focus-visible:bg-accent ${splitView ? "bg-accent text-foreground" : "text-muted-foreground"}`,
2250
- "data-testid": "sql-split-toggle",
2251
- onClick: toggleSplit,
2252
- title: t("Split editor and results"),
2253
- type: "button",
2254
- children: /* @__PURE__ */ jsxDEV("svg", {
2255
- "aria-hidden": "true",
2256
- className: "size-4",
2257
- fill: "none",
2258
- stroke: "currentColor",
2259
- strokeLinecap: "round",
2260
- strokeLinejoin: "round",
2261
- strokeWidth: 1.7,
2262
- viewBox: "0 0 24 24",
2263
- children: [/* @__PURE__ */ jsxDEV("rect", {
2264
- height: "16",
2265
- rx: "2",
2266
- width: "18",
2267
- x: "3",
2268
- y: "4"
2269
- }, void 0, false), /* @__PURE__ */ jsxDEV("path", {
2270
- d: "M12 4v16"
2271
- }, void 0, false)]
2272
- }, void 0, true)
2273
- }, void 0, false), result !== null && result.columns.length > 0 && /* @__PURE__ */ jsxDEV(ExportMenu, {
2274
- columns: result.columns,
2275
- name: "query-result",
2276
- rows: result.rows
2277
- }, void 0, false), /* @__PURE__ */ jsxDEV("button", {
2278
- className: "inline-flex items-center rounded-md border border-border px-3 py-1.5 text-xs font-medium text-foreground outline-none transition-colors hover:bg-accent focus-visible:bg-accent disabled:pointer-events-none disabled:opacity-50",
2279
- "data-testid": "sql-format",
2280
- disabled: running,
2281
- onClick: formatDraft,
2282
- type: "button",
2283
- children: t("Format")
2284
- }, void 0, false), /* @__PURE__ */ jsxDEV(ShardInput, {
2285
- onChange: setShardKey,
2286
- testId: "sql-shard-input",
2287
- value: shardKey
2288
- }, void 0, false), /* @__PURE__ */ jsxDEV("button", {
2289
- className: "inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground outline-none transition-colors hover:bg-primary/90 focus-visible:bg-primary/90 disabled:pointer-events-none disabled:opacity-50",
2290
- "data-testid": "sql-run",
2291
- disabled: running,
2292
- onClick: onRun,
2293
- type: "button",
2294
- children: [running ? t("Running…") : t("Run"), /* @__PURE__ */ jsxDEV("kbd", {
2295
- className: "rounded border border-primary-foreground/30 px-1 font-sans text-[10px]",
2296
- children: "⌘↵"
2297
- }, void 0, false)]
2298
- }, void 0, true)]
2299
- }, void 0, true)]
2300
- }, void 0, true), /* @__PURE__ */ jsxDEV("div", {
2301
- className: "min-h-0 flex-1 overflow-auto",
2302
- children: [error !== null && /* @__PURE__ */ jsxDEV(Alert, {
2303
- className: "m-3 font-mono text-xs",
2304
- testId: "sql-error",
2305
- variant: "destructive",
2306
- children: error
2307
- }, void 0, false), error === null && result === null && /* @__PURE__ */ jsxDEV("p", {
2308
- className: "p-4 text-sm text-muted-foreground",
2309
- "data-testid": "sql-empty",
2310
- children: t("Click Run to execute your query.")
2311
- }, void 0, false), error === null && result !== null && /* @__PURE__ */ jsxDEV("div", {
2312
- "data-testid": "sql-result",
2313
- children: [tab === "chart" ? /* @__PURE__ */ jsxDEV(SqlResultChart, {
2314
- result
2315
- }, void 0, false) : /* @__PURE__ */ jsxDEV(SqlResultTable, {
2316
- result
2317
- }, void 0, false), /* @__PURE__ */ jsxDEV("p", {
2318
- className: "border-t border-border px-3 py-1.5 text-xs text-muted-foreground",
2319
- "data-testid": "sql-count",
2320
- children: result.truncated ? t("Showing the first {max} of {count} rows.", {
2321
- count: result.rowCount,
2322
- max: result.rows.length
2323
- }) : t("{count} rows", {
2324
- count: result.rowCount
2325
- })
2326
- }, void 0, false)]
2327
- }, void 0, true)]
2328
- }, void 0, true)]
2329
- }, void 0, true)]
2330
- }, void 0, true)]
2331
- }, void 0, true)]
2332
- }, void 0, true);
2333
- };
2334
- function _temp(column) {
2335
- return /* @__PURE__ */ jsxDEV(TableHead, {
2336
- children: column
2337
- }, column, false);
2338
- }
2339
-
2340
- export { SqlEditorPanel };
1
+ import{c as K}from"react/compiler-runtime";import{useLunora as Ie}from"@lunora/react";import{useState as J,useRef as X,useEffect as fe,useId as gt}from"react";import{j as vt}from"../packem_shared/result-chart-CwKhhKM0.js";import{ShardInput as yt}from"../packem_shared/ShardInput-BVn2iCU0.js";import{A as Nt}from"../packem_shared/alert-CVcOFuDR.js";import{d as kt,m as we,f as wt,n as qt,p as Ct,u as St}from"../packem_shared/table-DdJBrClo.js";import{useT as V}from"../packem_shared/DEFAULT_LOCALE-BZ4NojpD.js";import{ADMIN_FUNCTIONS as be}from"../packem_shared/ADMIN_FUNCTIONS-BYNSbBVE.js";import{u as ue,n as $e,b as Ee}from"../packem_shared/browser-storage-xjTyMKY0.js";import{f as Z,c as me,a as he,e as It}from"../packem_shared/internal-AtZ4bTal.js";import{r as $t}from"../packem_shared/shard-history-DMEW5VBE.js";import{y as Et}from"../packem_shared/data-grid-BMBKzMEJ.js";import{J as Tt}from"../packem_shared/grid-features-uZCUj955.js";import{c as xe}from"../packem_shared/utils-bhneXptQ.js";import{jsx as a,jsxs as w,Fragment as qe}from"react/jsx-runtime";const Lt=["ORDER BY","GROUP BY","LEFT JOIN","RIGHT JOIN","INNER JOIN","OUTER JOIN","CROSS JOIN","EXPLAIN QUERY PLAN","SELECT","DISTINCT","FROM","WHERE","HAVING","LIMIT","OFFSET","JOIN","ON","AND","OR","AS","ASC","DESC","WITH","UNION","EXPLAIN"],Rt=["FROM","WHERE","ORDER BY","GROUP BY","HAVING","LIMIT","OFFSET","UNION","JOIN","LEFT JOIN","RIGHT JOIN","INNER JOIN","OUTER JOIN","CROSS JOIN"],ne=String.fromCodePoint(0),Ot=new RegExp(`${ne}${String.raw`(\d+)`}${ne}`,"gu"),Dt=Lt.map(r=>({pattern:new RegExp(String.raw`\b${r.replaceAll(" ",String.raw`\s+`)}\b`,"giu"),replacement:r})),Mt=Rt.map(r=>({pattern:new RegExp(String.raw`\s+${r.replaceAll(" ",String.raw`\s+`)}\b`,"gu"),replacement:`
2
+ ${r}`})),_t=r=>{const e=[];let t=r.replaceAll(/'(?:[^']|'')*'/gu,n=>(e.push(n),`${ne}${(e.length-1).toString()}${ne}`)).replaceAll(/\s+/gu," ").trim();for(const{pattern:n,replacement:l}of Dt)t=t.replaceAll(n,l);for(const{pattern:n,replacement:l}of Mt)t=t.replaceAll(n,l);return t=t.replaceAll(Ot,(n,l)=>e[Number(l)]??""),t},At=["AND","ASC","AS","BY","COUNT","DESC","DISTINCT","EXPLAIN","FROM","GROUP","HAVING","INNER","JOIN","LEFT","LIKE","LIMIT","NOT","NULL","OFFSET","ON","ORDER","OR","QUERY","SELECT","WHERE","WITH"],zt=new Set(["AND","BY","HAVING","ON","OR","SELECT","WHERE"]),jt=/[\w$]/,Te=r=>r!==void 0&&jt.test(r),Le=r=>{let e=r.length;for(;e>0&&Te(r[e-1]);)e-=1;return r.slice(e)},Re=(r,e)=>{let t=e;for(;t>0&&Te(r[t-1]);)t-=1;return{end:e,start:t,text:r.slice(t,e)}},Ce=(r,e)=>{const t=r.slice(0,e).trimEnd();return t.endsWith(".")||zt.has(Le(t).toUpperCase())},Bt=(r,e)=>{const t=r.slice(0,e);if(!t.endsWith("."))return;const n=Le(t.slice(0,-1));return n===""?void 0:n},ge=(r,e)=>r.toLowerCase().startsWith(e.toLowerCase()),Se=(r,e,t,n)=>{const l=[];for(const s of r)if(ge(s,e)&&(l.push(n(s)),l.length>=t))break;return l},Wt=(r,e,t)=>{const n=new Map;for(const[l,s]of Object.entries(r.columns))for(const c of s)if(ge(c,e)&&!n.has(c)&&(n.set(c,l),n.size>=t))return[...n].map(([m,i])=>({detail:i,kind:"column",label:m}));return[...n].map(([l,s])=>({detail:s,kind:"column",label:l}))},Ft=(r,e,t)=>{const n=Re(r,e),l=Bt(r,n.start);if(l!==void 0){const i=t.columns[l]??t.columns[l.toLowerCase()]??[];return Se(i,n.text,8,u=>({detail:l,kind:"column",label:u}))}if(n.text===""&&!Ce(r,n.start))return[];const s=Se(t.tables,n.text,8,i=>({kind:"table",label:i})),c=Wt(t,n.text,8),m=At.filter(i=>n.text!==""&&ge(i,n.text)&&i.toLowerCase()!==n.text.toLowerCase()).map(i=>({kind:"keyword",label:i}));return(Ce(r,n.start)?[...c,...s,...m]:[...s,...c,...m]).slice(0,8)},Ht=(r,e,t)=>{const n=Re(r,e),l=r.slice(0,n.start)+t.label+r.slice(n.end);return{caret:n.start+t.label.length,value:l}},Pt=["boxSizing","borderBottomWidth","borderLeftWidth","borderRightWidth","borderTopWidth","fontFamily","fontSize","fontStyle","fontWeight","letterSpacing","lineHeight","paddingBottom","paddingLeft","paddingRight","paddingTop","tabSize","textIndent","textTransform","width","wordSpacing"],Ut=(r,e)=>{const t=globalThis.getComputedStyle(r),n=globalThis.document.createElement("div"),{style:l}=n;l.position="absolute",l.visibility="hidden",l.whiteSpace="pre-wrap",l.overflowWrap="break-word";for(const i of Pt)l[i]=t[i];n.textContent=r.value.slice(0,Math.max(0,e));const s=globalThis.document.createElement("span");s.textContent=r.value.slice(Math.max(0,e))||".",n.append(s),globalThis.document.body.append(n);const c=s.offsetLeft-r.scrollLeft,m=s.offsetTop-r.scrollTop;return n.remove(),{left:c,top:m}},Jt=(r,e,t)=>{const n=K(13),[l,s]=J(null);let c;n[0]!==r||n[1]!==e?(c=(v,g)=>{const y=Ft(v,g,r);if(y.length===0){s(null);return}const b=e.current,{left:C,top:q}=b===null?{left:0,top:0}:Ut(b,g);s($=>$!==null&&$.active===0&&$.left===C&&$.top===q&&$.suggestions.length===y.length&&$.suggestions.every((S,O)=>{const L=y.at(O);return S.kind===L?.kind&&S.label===L.label&&S.detail===L.detail})?$:{active:0,left:C,suggestions:y,top:q})},n[0]=r,n[1]=e,n[2]=c):c=n[2];const m=c;let i;n[3]===Symbol.for("react.memo_cache_sentinel")?(i=()=>{s(null)},n[3]=i):i=n[3];const u=i;let N;n[4]===Symbol.for("react.memo_cache_sentinel")?(N=v=>{s(g=>{if(g===null)return g;const y=g.suggestions.length,b=(g.active+v+y)%y;return{...g,active:b}})},n[4]=N):N=n[4];const x=N;let h;n[5]!==t||n[6]!==l||n[7]!==e?(h=()=>{const v=e.current;if(l===null||v===null)return!1;const g=l.suggestions[l.active];if(g===void 0)return!1;const y=Ht(v.value,v.selectionStart,g);return t(y.value),s(null),requestAnimationFrame(()=>{const b=e.current;b!==null&&(b.focus(),b.setSelectionRange(y.caret,y.caret))}),!0},n[5]=t,n[6]=l,n[7]=e,n[8]=h):h=n[8];const p=h;let d;return n[9]!==p||n[10]!==m||n[11]!==l?(d={close:u,commit:p,move:x,refresh:m,state:l},n[9]=p,n[10]=m,n[11]=l,n[12]=d):d=n[12],d},Kt={column:"column",keyword:"keyword",table:"table"},Yt=20,Vt=r=>{const e=K(17),{listboxId:t,onPick:n,state:l}=r,s=V();let c;e[0]!==l?(c=l===null?void 0:{left:l.left,top:l.top+Yt},e[0]=l,e[1]=c):c=e[1];const m=c;if(l===null)return null;let i;if(e[2]!==t||e[3]!==n||e[4]!==l.active||e[5]!==l.suggestions||e[6]!==s){let N;e[8]!==t||e[9]!==n||e[10]!==l.active||e[11]!==s?(N=(x,h)=>w("li",{"aria-selected":h===l.active,className:xe("flex cursor-pointer items-center gap-2 px-2 py-1 text-[13px]",h===l.active?"bg-accent text-accent-foreground":"text-foreground"),"data-testid":"sql-autocomplete-item",id:`${t}-opt-${h.toString()}`,onMouseDown:p=>{p.preventDefault(),n(h)},role:"option",children:[a("span",{className:"truncate font-mono",children:x.label}),x.detail!==void 0&&a("span",{className:"ms-auto truncate text-xs text-muted-foreground",children:x.detail}),a("span",{className:"shrink-0 font-mono text-[10px] tracking-wide text-muted-foreground/70 uppercase",children:s(Kt[x.kind])})]},`${x.kind}:${x.label}`),e[8]=t,e[9]=n,e[10]=l.active,e[11]=s,e[12]=N):N=e[12],i=l.suggestions.map(N),e[2]=t,e[3]=n,e[4]=l.active,e[5]=l.suggestions,e[6]=s,e[7]=i}else i=e[7];let u;return e[13]!==t||e[14]!==m||e[15]!==i?(u=a("ul",{className:"absolute z-30 max-h-56 w-72 overflow-auto rounded-md border border-border bg-popover py-1 text-popover-foreground shadow-md","data-testid":"sql-autocomplete",id:t,role:"listbox",style:m,children:i}),e[13]=t,e[14]=m,e[15]=i,e[16]=u):u=e[16],u},Oe=[{label:"List tables",sql:"SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name;"},{label:"Table row count",sql:"SELECT COUNT(*) AS rows FROM messages;"},{label:"Recent rows",sql:"SELECT id, _creationTime, __doc__ FROM messages ORDER BY _creationTime DESC LIMIT 50;"},{label:"Index list",sql:"SELECT name, tbl_name FROM sqlite_master WHERE type = 'index' ORDER BY tbl_name;"}],Gt=r=>{const e=K(29),{active:t,onDelete:n,onSelect:l,query:s}=r,c=V();let m;e[0]!==l||e[1]!==s.id?(m=()=>{l(s.id)},e[0]=l,e[1]=s.id,e[2]=m):m=e[2];const i=m;let u;e[3]!==n||e[4]!==s.id?(u=S=>{S.stopPropagation(),n(s.id)},e[3]=n,e[4]=s.id,e[5]=u):u=e[5];const N=u,x=t?"bg-sidebar-accent font-medium text-foreground":"text-muted-foreground";let h;e[6]!==x?(h=xe("flex min-w-0 flex-1 items-center gap-2 rounded-md px-2 py-1.5 text-start text-[13px] outline-none transition-colors hover:bg-sidebar-accent focus-visible:bg-sidebar-accent",x),e[6]=x,e[7]=h):h=e[7];const p=`sql-query-${s.id}`;let d;e[8]===Symbol.for("react.memo_cache_sentinel")?(d=a("svg",{"aria-hidden":"true",className:"size-3.5 shrink-0 opacity-70",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:a("path",{d:"M4 6h16M4 12h10M4 18h7"})}),e[8]=d):d=e[8];let v;e[9]!==s.name?(v=a("span",{className:"truncate",children:s.name}),e[9]=s.name,e[10]=v):v=e[10];let g;e[11]!==t||e[12]!==i||e[13]!==h||e[14]!==p||e[15]!==v?(g=w("button",{"aria-pressed":t,className:h,"data-testid":p,onClick:i,type:"button",children:[d,v]}),e[11]=t,e[12]=i,e[13]=h,e[14]=p,e[15]=v,e[16]=g):g=e[16];let y;e[17]!==c?(y=c("Delete query"),e[17]=c,e[18]=y):y=e[18];let b;e[19]!==c?(b=c("Delete query"),e[19]=c,e[20]=b):b=e[20];let C;e[21]===Symbol.for("react.memo_cache_sentinel")?(C=a("svg",{"aria-hidden":"true",className:"size-3.5",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:a("path",{d:"M5 7h14M9 7V5h6v2m-1 0v12H10V7M7 7v13h10V7"})}),e[21]=C):C=e[21];let q;e[22]!==N||e[23]!==b||e[24]!==y?(q=a("button",{"aria-label":y,className:"me-1 hidden size-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive group-hover/q:flex",onClick:N,title:b,type:"button",children:C}),e[22]=N,e[23]=b,e[24]=y,e[25]=q):q=e[25];let $;return e[26]!==q||e[27]!==g?($=w("li",{className:"group/q flex items-center",children:[g,q]}),e[26]=q,e[27]=g,e[28]=$):$=e[28],$},Qt=r=>{const e=K(58),{activeId:t,history:n,listRef:l,onClearHistory:s,onDelete:c,onLoadHistory:m,onLoadTemplate:i,onNew:u,onSearchChange:N,onSelect:x,queries:h,search:p}=r,d=V();let v;if(e[0]!==h||e[1]!==p){const I=p.trim().toLowerCase();v=I===""?[...h]:h.filter(T=>T.name.toLowerCase().includes(I)),e[0]=h,e[1]=p,e[2]=v}else v=e[2];const g=v;let y;e[3]!==d?(y=d("Search queries…"),e[3]=d,e[4]=y):y=e[4];let b;e[5]!==N||e[6]!==p||e[7]!==y?(b=a("input",{className:"h-8 min-w-0 flex-1 rounded-md border border-border bg-background px-2 text-xs outline-none focus-visible:border-ring","data-testid":"sql-search",onChange:N,placeholder:y,type:"text",value:p}),e[5]=N,e[6]=p,e[7]=y,e[8]=b):b=e[8];let C;e[9]!==d?(C=d("New query"),e[9]=d,e[10]=C):C=e[10];let q;e[11]!==d?(q=d("New query"),e[11]=d,e[12]=q):q=e[12];let $;e[13]===Symbol.for("react.memo_cache_sentinel")?($=a("svg",{"aria-hidden":"true",className:"size-4",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.7,viewBox:"0 0 24 24",children:a("path",{d:"M12 5v14M5 12h14"})}),e[13]=$):$=e[13];let S;e[14]!==u||e[15]!==C||e[16]!==q?(S=a("button",{"aria-label":C,className:"flex size-8 shrink-0 items-center justify-center rounded-md border border-border text-foreground outline-none transition-colors hover:bg-accent focus-visible:bg-accent","data-testid":"sql-new",onClick:u,title:q,type:"button",children:$}),e[14]=u,e[15]=C,e[16]=q,e[17]=S):S=e[17];let O;e[18]!==b||e[19]!==S?(O=w("div",{className:"flex shrink-0 items-center gap-2 border-b border-border p-2",children:[b,S]}),e[18]=b,e[19]=S,e[20]=O):O=e[20];let L;e[21]!==d?(L=d("Private"),e[21]=d,e[22]=L):L=e[22];let D;e[23]!==L?(D=a("p",{className:"px-1 pb-1 font-mono text-[11px] tracking-wide text-muted-foreground uppercase",children:L}),e[23]=L,e[24]=D):D=e[24];let M;e[25]!==t||e[26]!==g||e[27]!==l||e[28]!==c||e[29]!==x||e[30]!==d?(M=g.length===0?a("p",{className:"px-1 py-2 text-xs text-muted-foreground","data-testid":"sql-private-empty",children:d("No saved queries yet — they save to this browser as you type.")}):a("ul",{className:"flex flex-col gap-px","data-testid":"sql-private",ref:l,children:g.map(I=>a(Gt,{active:t===I.id,onDelete:c,onSelect:x,query:I},I.id))}),e[25]=t,e[26]=g,e[27]=l,e[28]=c,e[29]=x,e[30]=d,e[31]=M):M=e[31];let A;e[32]!==D||e[33]!==M?(A=w("div",{children:[D,M]}),e[32]=D,e[33]=M,e[34]=A):A=e[34];let z;e[35]!==d?(z=d("Reference"),e[35]=d,e[36]=z):z=e[36];let H;e[37]!==z?(H=a("p",{className:"px-1 pb-1 font-mono text-[11px] tracking-wide text-muted-foreground uppercase",children:z}),e[37]=z,e[38]=H):H=e[38];let W;e[39]!==i?(W=Oe.map(I=>a("li",{children:w("button",{className:"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-start text-[13px] text-muted-foreground outline-none transition-colors hover:bg-sidebar-accent hover:text-foreground focus-visible:bg-sidebar-accent","data-sql":I.sql,onClick:i,type:"button",children:[a("svg",{"aria-hidden":"true",className:"size-3.5 shrink-0 opacity-70",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:a("path",{d:"M7 4h7l4 4v12H7zM14 4v4h4"})}),I.label]})},I.label)),e[39]=i,e[40]=W):W=e[40];let _;e[41]!==W?(_=a("ul",{className:"flex flex-col gap-px",children:W}),e[41]=W,e[42]=_):_=e[42];let E;e[43]!==H||e[44]!==_?(E=w("div",{children:[H,_]}),e[43]=H,e[44]=_,e[45]=E):E=e[45];let R;e[46]!==n||e[47]!==s||e[48]!==m||e[49]!==d?(R=n.length>0&&w("div",{children:[w("div",{className:"flex items-center justify-between px-1 pb-1",children:[a("p",{className:"font-mono text-[11px] tracking-wide text-muted-foreground uppercase",children:d("History")}),a("button",{className:"rounded px-1 text-[11px] text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:text-foreground","data-testid":"sql-history-clear",onClick:s,type:"button",children:d("Clear history")})]}),a("ul",{className:"flex flex-col gap-px","data-testid":"sql-history",children:n.map(I=>a("li",{children:w("button",{className:"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-start text-[13px] text-muted-foreground outline-none transition-colors hover:bg-sidebar-accent hover:text-foreground focus-visible:bg-sidebar-accent","data-sql":I.sql,"data-testid":"sql-history-item",onClick:m,title:I.sql,type:"button",children:[a("svg",{"aria-hidden":"true",className:"size-3.5 shrink-0 opacity-70",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:a("path",{d:"M12 8v4l3 2M12 21a9 9 0 1 1 0-18 9 9 0 0 1 0 18Z"})}),a("span",{className:"truncate font-mono",children:I.sql})]})},`${I.at.toString()}:${I.sql}`))})]}),e[46]=n,e[47]=s,e[48]=m,e[49]=d,e[50]=R):R=e[50];let j;e[51]!==A||e[52]!==E||e[53]!==R?(j=w("div",{className:"flex flex-1 flex-col gap-4 overflow-y-auto p-2",children:[A,E,R]}),e[51]=A,e[52]=E,e[53]=R,e[54]=j):j=e[54];let B;return e[55]!==j||e[56]!==O?(B=w("aside",{className:"flex h-full w-64 shrink-0 flex-col border-e border-border bg-sidebar",children:[O,j]}),e[55]=j,e[56]=O,e[57]=B):B=e[57],B},Xt=he(be.listTables),Zt=he(be.readTablePage),en=r=>{const e=K(16),t=Ie();let n;e[0]===Symbol.for("react.memo_cache_sentinel")?(n=[],e[0]=n):n=e[0];const[l,s]=J(n);let c;e[1]===Symbol.for("react.memo_cache_sentinel")?(c={},e[1]=c):c=e[1];const[m,i]=J(c);let u;e[2]===Symbol.for("react.memo_cache_sentinel")?(u=new Set,e[2]=u):u=e[2];const N=X(u);let x,h;e[3]!==t||e[4]!==r?(x=()=>{const b={cancelled:!1};return Z((async()=>{try{const C=await t.query(Xt,{},me(r));b.cancelled||(s(C.map(nn)),i({}),N.current=new Set)}catch{b.cancelled||(s([]),i({}),N.current=new Set)}})()),()=>{b.cancelled=!0}},h=[t,r],e[3]=t,e[4]=r,e[5]=x,e[6]=h):(x=e[5],h=e[6]),fe(x,h);let p;e[7]!==t||e[8]!==r?(p=b=>{N.current.has(b)||(N.current.add(b),Z((async()=>{try{const C=await t.query(Zt,{limit:1,offset:0,table:b},me(r));i(q=>({...q,[b]:C.columns}))}catch{N.current.delete(b)}})()))},e[7]=t,e[8]=r,e[9]=p):p=e[9];const d=p;let v;e[10]!==m||e[11]!==l?(v={columns:m,tables:l},e[10]=m,e[11]=l,e[12]=v):v=e[12];const g=v;let y;return e[13]!==d||e[14]!==g?(y={probe:d,schema:g},e[13]=d,e[14]=g,e[15]=y):y=e[15],y},ce=/\b(?:from|join|update|into)\s+([a-z_][\w$]*)|\b([a-z_][\w$]*)\s*\./gi,tn=r=>{const e=new Set;ce.lastIndex=0;let t=ce.exec(r);for(;t!==null;)e.add(t[1]??t[2]),t=ce.exec(r);return[...e]};function nn(r){return r.name}const rn="lunora-studio-sql-tabs",ln="lunora-studio-sql-active-tab",pe=12,Q=(r="",e="")=>({activeId:null,id:$e("tab"),name:e,sql:r}),on=()=>Ee(ln,""),sn=r=>{const[e,t]=ue(rn),[n,l]=on(),s=X(null);e.length===0&&s.current===null&&(s.current=r()),fe(()=>{if(e.length===0&&s.current!==null){const m=s.current;t([m])}},[t,e.length]);const c=e.length===0&&s.current!==null?[s.current]:e;return{activeId:c.some(m=>m.id===n)?n:c[0]?.id??"",setActiveId:l,setTabs:t,tabs:c}},De=r=>r.activeId===null&&r.sql.trim()!=="",an=(r,e)=>[...r,e].slice(-pe),cn=(r,e,t)=>{const n=r.findIndex(s=>s.id===e);if(n===-1)return{activeId:r[0]?.id??"",tabs:[...r]};const l=r.filter(s=>s.id!==e);if(l.length===0){const s=t();return{activeId:s.id,tabs:[s]}}return{activeId:l[Math.min(n,l.length-1)].id,tabs:l}},dn=(r,e)=>{const t=r.filter(n=>n.id===e);return t.length===0?{activeId:r[0]?.id??"",tabs:[...r]}:{activeId:e,tabs:t}},un=(r,e,t)=>{const n=r.findIndex(s=>s.id===e);if(n===-1)return{activeId:t,tabs:[...r]};const l=r.slice(0,n+1);return{activeId:l.some(s=>s.id===t)?t:e,tabs:l}},mn=r=>{const e=r();return{activeId:e.id,tabs:[e]}},pn=(r,e,t)=>{if(r==="others")return e.filter(n=>n.id!==t);if(r==="right"){const n=e.findIndex(l=>l.id===t);return n===-1?[]:e.slice(n+1)}return[...e]},fn=(r,e)=>r.trim()===""?e:(r.split(`
3
+ `)[0]??r).slice(0,24),bn=r=>{const e=K(14),{initial:t,onCancel:n,onCommit:l,placeholder:s,testId:c}=r,m=V(),i=gn;let u;e[0]!==l?(u=v=>{l(v.currentTarget.value.trim())},e[0]=l,e[1]=u):u=e[1];const N=u;let x;e[2]!==n||e[3]!==l?(x=v=>{v.key==="Enter"?l(v.currentTarget.value.trim()):v.key==="Escape"&&n()},e[2]=n,e[3]=l,e[4]=x):x=e[4];const h=x;let p;e[5]!==m?(p=m("Tab title"),e[5]=m,e[6]=p):p=e[6];let d;return e[7]!==t||e[8]!==N||e[9]!==h||e[10]!==s||e[11]!==p||e[12]!==c?(d=a("input",{"aria-label":p,className:"w-40 rounded border border-ring bg-background px-1 py-0.5 text-xs outline-none","data-testid":c,defaultValue:t,onBlur:N,onKeyDown:h,placeholder:s,ref:i,type:"text"}),e[7]=t,e[8]=N,e[9]=h,e[10]=s,e[11]=p,e[12]=c,e[13]=d):d=e[13],d},hn=r=>{const e=K(29),{idBase:t,onDiscard:n,onKeep:l}=r,s=V(),c=`sql-tab-close-prompt-${t}`;let m;e[0]!==s?(m=s("Discard?"),e[0]=s,e[1]=m):m=e[1];let i;e[2]!==m?(i=a("span",{className:"text-[11px] text-muted-foreground",children:m}),e[2]=m,e[3]=i):i=e[3];let u;e[4]!==s?(u=s("Discard changes"),e[4]=s,e[5]=u):u=e[5];const N=`sql-tab-close-confirm-${t}`;let x;e[6]!==s?(x=s("Discard changes"),e[6]=s,e[7]=x):x=e[7];let h;e[8]===Symbol.for("react.memo_cache_sentinel")?(h=a("svg",{"aria-hidden":"true",className:"size-3",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2.4,viewBox:"0 0 24 24",children:a("path",{d:"M5 13l4 4L19 7"})}),e[8]=h):h=e[8];let p;e[9]!==n||e[10]!==u||e[11]!==N||e[12]!==x?(p=a("button",{"aria-label":u,className:"flex size-5 items-center justify-center rounded text-destructive hover:bg-destructive/10","data-testid":N,onClick:n,title:x,type:"button",children:h}),e[9]=n,e[10]=u,e[11]=N,e[12]=x,e[13]=p):p=e[13];let d;e[14]!==s?(d=s("Keep editing"),e[14]=s,e[15]=d):d=e[15];const v=`sql-tab-close-cancel-${t}`;let g;e[16]!==s?(g=s("Keep editing"),e[16]=s,e[17]=g):g=e[17];let y;e[18]===Symbol.for("react.memo_cache_sentinel")?(y=a("svg",{"aria-hidden":"true",className:"size-3",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2.4,viewBox:"0 0 24 24",children:a("path",{d:"M6 6l12 12M18 6 6 18"})}),e[18]=y):y=e[18];let b;e[19]!==l||e[20]!==v||e[21]!==g||e[22]!==d?(b=a("button",{"aria-label":d,className:"flex size-5 items-center justify-center rounded text-muted-foreground hover:bg-accent","data-testid":v,onClick:l,title:g,type:"button",children:y}),e[19]=l,e[20]=v,e[21]=g,e[22]=d,e[23]=b):b=e[23];let C;return e[24]!==c||e[25]!==b||e[26]!==i||e[27]!==p?(C=w("span",{className:"flex shrink-0 items-center gap-1","data-testid":c,role:"group",children:[i,p,b]}),e[24]=c,e[25]=b,e[26]=i,e[27]=p,e[28]=C):C=e[28],C},xn=r=>{const e=K(47),{active:t,canClose:n,onClose:l,onMenu:s,onRename:c,onSelect:m,tab:i}=r,u=V(),[N,x]=J(!1),[h,p]=J(!1);let d;e[0]!==s||e[1]!==i.id?(d=F=>{s(i.id,F)},e[0]=s,e[1]=i.id,e[2]=d):d=e[2];const v=d;let g;e[3]!==m||e[4]!==i.id?(g=()=>{m(i.id)},e[3]=m,e[4]=i.id,e[5]=g):g=e[5];const y=g;let b;e[6]===Symbol.for("react.memo_cache_sentinel")?(b=()=>{x(!0)},e[6]=b):b=e[6];const C=b;let q;e[7]!==l||e[8]!==i?(q=F=>{F.stopPropagation(),De(i)?p(!0):l(i.id)},e[7]=l,e[8]=i,e[9]=q):q=e[9];const $=q;let S;e[10]!==l||e[11]!==i.id?(S=F=>{F.stopPropagation(),p(!1),l(i.id)},e[10]=l,e[11]=i.id,e[12]=S):S=e[12];const O=S;let L;e[13]===Symbol.for("react.memo_cache_sentinel")?(L=F=>{F.stopPropagation(),p(!1)},e[13]=L):L=e[13];const D=L;let M;e[14]!==c||e[15]!==i.id?(M=F=>{c(i.id,F),x(!1)},e[14]=c,e[15]=i.id,e[16]=M):M=e[16];const A=M;let z;e[17]===Symbol.for("react.memo_cache_sentinel")?(z=()=>{x(!1)},e[17]=z):z=e[17];const H=z;let W;e[18]!==i.name?(W=i.name.trim(),e[18]=i.name,e[19]=W):W=e[19];const _=W;let E;e[20]!==u||e[21]!==i.sql?(E=fn(i.sql,u("Untitled")),e[20]=u,e[21]=i.sql,e[22]=E):E=e[22];const R=E,j=t?"bg-background text-foreground":"bg-muted/40 text-muted-foreground hover:text-foreground";let B;e[23]!==j?(B=xe("group/tab flex shrink-0 items-center gap-1 border-e border-border ps-3 pe-1.5 text-xs",j),e[23]=j,e[24]=B):B=e[24];const I=`sql-tab-${i.id}`;let T;e[25]!==t||e[26]!==A||e[27]!==_||e[28]!==R||e[29]!==N||e[30]!==y||e[31]!==u||e[32]!==i.id?(T=N?a(bn,{initial:_,onCancel:H,onCommit:A,placeholder:R,testId:`sql-tab-rename-${i.id}`}):a("button",{"aria-pressed":t,className:"max-w-40 truncate py-1.5 outline-none","data-testid":`sql-tab-select-${i.id}`,onClick:y,onDoubleClick:C,title:u("Double-click to rename"),type:"button",children:_===""?R:_}),e[25]=t,e[26]=A,e[27]=_,e[28]=R,e[29]=N,e[30]=y,e[31]=u,e[32]=i.id,e[33]=T):T=e[33];let P;e[34]!==n||e[35]!==O||e[36]!==h||e[37]!==$||e[38]!==u||e[39]!==i.id?(P=n&&(h?a(hn,{idBase:i.id,onDiscard:O,onKeep:D}):a("button",{"aria-label":u("Close tab"),className:"flex size-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive","data-testid":`sql-tab-close-${i.id}`,onClick:$,title:u("Close tab"),type:"button",children:a("svg",{"aria-hidden":"true",className:"size-3",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,viewBox:"0 0 24 24",children:a("path",{d:"M6 6l12 12M18 6 6 18"})})})),e[34]=n,e[35]=O,e[36]=h,e[37]=$,e[38]=u,e[39]=i.id,e[40]=P):P=e[40];let G;return e[41]!==v||e[42]!==B||e[43]!==I||e[44]!==T||e[45]!==P?(G=w("div",{className:B,"data-testid":I,onContextMenu:v,children:[T,P]}),e[41]=v,e[42]=B,e[43]=I,e[44]=T,e[45]=P,e[46]=G):G=e[46],G};function gn(r){r?.focus(),r?.select()}const vn=he(be.runSql),yn="lunora-studio-sql-queries",Nn="lunora-studio-sql-history",kn="lunora-studio-sql-split-view",wn=25,qn={minWidth:"2.75rem",paddingInline:"0.5rem"},de={error:null,pane:"results",result:null},Cn=r=>{const e=K(16),{result:t}=r;if(t.columns.length===0){const i=t.rowCount===0?"0 rows":"";let u;return e[0]!==i?(u=a("p",{className:"p-4 text-sm text-muted-foreground",children:i}),e[0]=i,e[1]=u):u=e[1],u}let n;e[2]!==t.columns?(n=t.columns.map(Sn),e[2]=t.columns,e[3]=n):n=e[3];let l;e[4]!==n?(l=a(kt,{className:"sticky top-0 z-10 bg-muted",children:a(we,{children:n})}),e[4]=n,e[5]=l):l=e[5];let s;if(e[6]!==t.columns||e[7]!==t.rows){let i;e[9]!==t.columns?(i=(u,N)=>a(we,{"data-testid":"sql-row",children:t.columns.map(x=>a(St,{className:"max-w-md truncate font-mono text-xs",children:a(Et,{value:u[x]})},x))},N),e[9]=t.columns,e[10]=i):i=e[10],s=t.rows.map(i),e[6]=t.columns,e[7]=t.rows,e[8]=s}else s=e[8];let c;e[11]!==s?(c=a(wt,{children:s}),e[11]=s,e[12]=c):c=e[12];let m;return e[13]!==l||e[14]!==c?(m=w(qt,{"data-testid":"sql-rows",children:[l,c]}),e[13]=l,e[14]=c,e[15]=m):m=e[15],m},Hn=({initialShardKey:r})=>{const e=Ie(),t=V(),[n,l]=ue(yn),[s,c]=ue(Nn),[m,i]=J(""),u=()=>Q(Oe[0]?.sql??""),{activeId:N,setActiveId:x,setTabs:h,tabs:p}=sn(u),[d,v]=J({}),[g,y]=J(r??""),[b,C]=J(!1),[q,$]=Ee(kn,!1),[S,O]=J(null),[L,D]=J(null),M=X(null),A=X(null),z=X(null),H=gt(),{probe:W,schema:_}=en(g),E=p.find(o=>o.id===N)??p[0]??Q(),R=E.sql,{activeId:j}=E,B=d[E.id]??de,{error:I,result:T}=B,P=B.pane,G=o=>{h(f=>f.map(k=>k.id===E.id?{...k,...o}:k))},F=o=>{v(f=>{const k=f[E.id]??de;return{...f,[E.id]:{error:o.error,pane:o.pane??k.pane,result:o.result}}})},ve=o=>{v(f=>{const k=f[E.id]??de;return{...f,[E.id]:{...k,pane:o}}})},re=o=>{G({sql:o}),j!==null&&l(f=>f.map(k=>k.id===j?{...k,sql:o}:k))},Me=Jt(_,A,re),{close:le,commit:ye,move:oe,refresh:ee,state:Y}=Me,_e=o=>{oe(o-(Y?.active??0)),ye()};fe(()=>{const o=A.current;o!==null&&o===document.activeElement&&ee(o.value,o.selectionStart)},[ee,_]);const Ae=o=>{c(f=>f[0]?.sql===o?f:[{at:Date.now(),sql:o},...f.filter(k=>k.sql!==o)].slice(0,wn))},se=async o=>{if(R.trim()==="")return;C(!0);const f=o==="explain"?`EXPLAIN QUERY PLAN ${R}`:R;try{const k=await e.query(vn,{sql:f},me(g));F({error:null,pane:o,result:k}),$t(g),Ae(f)}catch(k){F({error:It(k),pane:o,result:null})}finally{C(!1)}},ze=()=>{Z(se("results"))},je=o=>{const{selectionStart:f,value:k}=o.target;re(k);for(const U of tn(k))W(U);ee(k,f)},Be=o=>{const f=o.currentTarget;ee(f.value,f.selectionStart)},We=o=>{if(Y!==null){if(o.key==="ArrowDown"){o.preventDefault(),oe(1);return}if(o.key==="ArrowUp"){o.preventDefault(),oe(-1);return}if(o.key==="Escape"){o.preventDefault(),le();return}if((o.key==="Enter"||o.key==="Tab")&&!o.metaKey&&!o.ctrlKey&&ye()){o.preventDefault();return}}(o.metaKey||o.ctrlKey)&&o.key==="Enter"&&(o.preventDefault(),Z(se(P)))},Fe=()=>{requestAnimationFrame(()=>{le()})},He=o=>{M.current!==null&&(M.current.scrollTop=o.currentTarget.scrollTop)},te=(o,f)=>{h(k=>k.map(U=>U.id===E.id?{...U,activeId:f,sql:o}:U)),F({error:null,result:null})},Pe=()=>{const o={id:$e("q"),name:t("Untitled query"),sql:""};l(f=>[o,...f]),te("",o.id)},Ue=o=>{const f=n.find(k=>k.id===o);f!==void 0&&(te(f.sql,o),z.current?.querySelector(`[data-testid="sql-query-${o}"]`)?.scrollIntoView({block:"nearest"}))},Je=o=>{l(f=>f.filter(k=>k.id!==o)),h(f=>f.map(k=>k.activeId===o?{...k,activeId:null}:k))},Ke=o=>{te(o.currentTarget.dataset.sql??"",null)},Ye=o=>{te(o.currentTarget.dataset.sql??"",null)},Ve=()=>{c([])},Ge=()=>{re(_t(R))},Qe=()=>{if(p.length>=pe)return;const o=Q();h(f=>an(f,o)),x(o.id)},Ne=o=>{O(null),D(null),h(o.tabs),x(o.activeId);const f=new Set(o.tabs.map(k=>k.id));v(k=>Object.fromEntries(Object.entries(k).filter(([U])=>f.has(U))))},Xe=o=>{Ne(cn(p,o,Q))},ke=(o,f)=>{Ne(o==="others"?dn(p,f):o==="right"?un(p,f,N):mn(Q))},ie=o=>{S!==null&&(pn(o,p,S.id).some(f=>De(f))?D(o):ke(o,S.id))},Ze=(o,f)=>{f.preventDefault(),D(null),O({id:o,x:f.clientX,y:f.clientY})},et=()=>{O(null),D(null)},tt=o=>{o.preventDefault(),O(null),D(null)},nt=()=>{ie("others")},rt=()=>{ie("right")},lt=()=>{ie("all")},ot=()=>{S!==null&&L!==null&&ke(L,S.id),D(null)},st=()=>{D(null)},it=S===null?void 0:{left:S.x,top:S.y},at=o=>{le(),x(o)},ct=(o,f)=>{h(k=>k.map(U=>U.id===o?{...U,name:f}:U))},dt=()=>{ve("results")},ut=()=>{Z(se("explain"))},mt=()=>{ve("chart")},pt=()=>{$(!q)},ft=R.split(`
4
+ `).length,bt=o=>{i(o.target.value)},ae=o=>`border-b-2 px-3 py-2 text-sm outline-none transition-colors ${o?"border-foreground font-medium text-foreground":"border-transparent text-muted-foreground hover:text-foreground"}`,ht=q?"flex min-h-0 flex-1 flex-row":"flex min-h-0 flex-1 flex-col",xt=q?"flex w-2/5 min-h-0 min-w-0 shrink-0 flex-col border-s border-border":"flex h-2/5 min-h-0 shrink-0 flex-col border-t border-border";return w("div",{className:"flex h-full min-w-0","data-testid":"lunora-sql-editor",children:[a(Qt,{activeId:j,history:s,listRef:z,onClearHistory:Ve,onDelete:Je,onLoadHistory:Ye,onLoadTemplate:Ke,onNew:Pe,onSearchChange:bt,onSelect:Ue,queries:n,search:m}),w("div",{className:"flex min-w-0 flex-1 flex-col",children:[w("div",{className:"flex shrink-0 items-stretch overflow-x-auto border-b border-border bg-muted/30","data-testid":"sql-tab-strip",role:"tablist",children:[p.map(o=>a(xn,{active:o.id===E.id,canClose:p.length>1,onClose:Xe,onMenu:Ze,onRename:ct,onSelect:at,tab:o},o.id)),a("button",{"aria-label":t("New tab"),className:"flex size-8 shrink-0 items-center justify-center text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-foreground focus-visible:bg-accent disabled:pointer-events-none disabled:opacity-40","data-testid":"sql-tab-add",disabled:p.length>=pe,onClick:Qe,title:t("New tab"),type:"button",children:a("svg",{"aria-hidden":"true",className:"size-4",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.7,viewBox:"0 0 24 24",children:a("path",{d:"M12 5v14M5 12h14"})})})]}),S!==null&&w(qe,{children:[a("div",{className:"fixed inset-0 z-40","data-testid":"sql-tab-menu-backdrop",onClick:et,onContextMenu:tt,role:"presentation"}),a("div",{className:"fixed z-50 min-w-44 rounded-md border border-border bg-popover py-1 text-popover-foreground shadow-md","data-testid":"sql-tab-menu",role:"menu",style:it,children:L===null?w(qe,{children:[a("button",{className:"flex w-full items-center px-3 py-1.5 text-start text-xs outline-none hover:bg-accent focus-visible:bg-accent disabled:pointer-events-none disabled:opacity-40","data-testid":"sql-tab-menu-close-others",disabled:p.length<=1,onClick:nt,role:"menuitem",type:"button",children:t("Close other tabs")}),a("button",{className:"flex w-full items-center px-3 py-1.5 text-start text-xs outline-none hover:bg-accent focus-visible:bg-accent disabled:pointer-events-none disabled:opacity-40","data-testid":"sql-tab-menu-close-right",disabled:p.findIndex(o=>o.id===S.id)>=p.length-1,onClick:rt,role:"menuitem",type:"button",children:t("Close tabs to the right")}),a("button",{className:"flex w-full items-center px-3 py-1.5 text-start text-xs outline-none hover:bg-accent focus-visible:bg-accent","data-testid":"sql-tab-menu-close-all",onClick:lt,role:"menuitem",type:"button",children:t("Close all tabs")})]}):w("div",{className:"px-3 py-1.5","data-testid":"sql-tab-menu-confirm",children:[a("p",{className:"pb-1.5 text-xs text-muted-foreground",children:t("Discard unsaved tabs?")}),w("div",{className:"flex items-center gap-1.5",children:[a("button",{className:"rounded px-2 py-1 text-xs font-medium text-destructive outline-none hover:bg-destructive/10 focus-visible:bg-destructive/10","data-testid":"sql-tab-menu-confirm-discard",onClick:ot,type:"button",children:t("Discard")}),a("button",{className:"rounded px-2 py-1 text-xs text-muted-foreground outline-none hover:bg-accent focus-visible:bg-accent","data-testid":"sql-tab-menu-confirm-cancel",onClick:st,type:"button",children:t("Cancel")})]})]})})]}),w("div",{className:ht,children:[w("div",{className:"flex min-h-0 min-w-0 flex-1",children:[a("div",{"aria-hidden":"true",className:"shrink-0 select-none overflow-hidden border-e border-border bg-muted/30 py-3 text-end font-mono text-xs leading-5 text-muted-foreground/60",ref:M,style:qn,children:Array.from({length:ft},(o,f)=>a("div",{children:f+1},f))}),w("div",{className:"relative min-w-0 flex-1",children:[a("textarea",{"aria-activedescendant":Y===null?void 0:`${H}-opt-${Y.active.toString()}`,"aria-autocomplete":"list","aria-controls":Y===null?void 0:H,"aria-expanded":Y!==null,"aria-label":t("SQL query"),className:"size-full resize-none bg-background p-3 font-mono text-xs leading-5 outline-none","data-testid":"sql-input",onBlur:Fe,onChange:je,onKeyDown:We,onScroll:He,onSelect:Be,placeholder:"SELECT * FROM …",ref:A,role:"combobox",spellCheck:!1,value:R}),a(Vt,{listboxId:H,onPick:_e,state:Y})]})]}),w("div",{className:xt,children:[w("div",{className:"flex shrink-0 items-center gap-2 border-b border-border pe-2",children:[a("button",{className:ae(P==="results"),"data-testid":"sql-tab-results",onClick:dt,type:"button",children:t("Results")}),a("button",{className:ae(P==="chart"),"data-testid":"sql-tab-chart",onClick:mt,type:"button",children:t("Chart")}),a("button",{className:ae(P==="explain"),"data-testid":"sql-tab-explain",onClick:ut,type:"button",children:t("Explain")}),w("div",{className:"ms-auto flex items-center gap-2",children:[a("button",{"aria-label":t("Split editor and results"),"aria-pressed":q,className:`inline-flex items-center rounded-md border border-border px-2 py-1.5 outline-none transition-colors hover:bg-accent focus-visible:bg-accent ${q?"bg-accent text-foreground":"text-muted-foreground"}`,"data-testid":"sql-split-toggle",onClick:pt,title:t("Split editor and results"),type:"button",children:w("svg",{"aria-hidden":"true",className:"size-4",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.7,viewBox:"0 0 24 24",children:[a("rect",{height:"16",rx:"2",width:"18",x:"3",y:"4"}),a("path",{d:"M12 4v16"})]})}),T!==null&&T.columns.length>0&&a(Tt,{columns:T.columns,name:"query-result",rows:T.rows}),a("button",{className:"inline-flex items-center rounded-md border border-border px-3 py-1.5 text-xs font-medium text-foreground outline-none transition-colors hover:bg-accent focus-visible:bg-accent disabled:pointer-events-none disabled:opacity-50","data-testid":"sql-format",disabled:b,onClick:Ge,type:"button",children:t("Format")}),a(yt,{onChange:y,testId:"sql-shard-input",value:g}),w("button",{className:"inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground outline-none transition-colors hover:bg-primary/90 focus-visible:bg-primary/90 disabled:pointer-events-none disabled:opacity-50","data-testid":"sql-run",disabled:b,onClick:ze,type:"button",children:[t(b?"Running…":"Run"),a("kbd",{className:"rounded border border-primary-foreground/30 px-1 font-sans text-[10px]",children:"⌘↵"})]})]})]}),w("div",{className:"min-h-0 flex-1 overflow-auto",children:[I!==null&&a(Nt,{className:"m-3 font-mono text-xs",testId:"sql-error",variant:"destructive",children:I}),I===null&&T===null&&a("p",{className:"p-4 text-sm text-muted-foreground","data-testid":"sql-empty",children:t("Click Run to execute your query.")}),I===null&&T!==null&&w("div",{"data-testid":"sql-result",children:[P==="chart"?a(vt,{result:T}):a(Cn,{result:T}),a("p",{className:"border-t border-border px-3 py-1.5 text-xs text-muted-foreground","data-testid":"sql-count",children:T.truncated?t("Showing the first {max} of {count} rows.",{count:T.rowCount,max:T.rows.length}):t("{count} rows",{count:T.rowCount})})]})]})]})]})]})]})};function Sn(r){return a(Ct,{children:r},r)}export{Hn as SqlEditorPanel};