@lunora/studio 1.0.0-alpha.7 → 1.0.0-alpha.71

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 (295) hide show
  1. package/LICENSE.md +6 -0
  2. package/dist/index.d.ts +762 -779
  3. package/dist/index.js +1 -41
  4. package/dist/mount.d.ts +10 -10
  5. package/dist/mount.js +1 -26
  6. package/dist/packem_chunks/ApiTab.js +1 -0
  7. package/dist/packem_chunks/AuditPanel.js +1 -0
  8. package/dist/packem_chunks/DeploymentHealthPanel.js +1 -0
  9. package/dist/packem_chunks/ExportImportPanel.js +3 -0
  10. package/dist/packem_chunks/FileBrowser.js +4 -0
  11. package/dist/packem_chunks/FunctionRunner.js +1 -0
  12. package/dist/packem_chunks/FunctionStatsPanel.js +1 -0
  13. package/dist/packem_chunks/HealthPanel.js +1 -0
  14. package/dist/packem_chunks/InsightsPanel.js +1 -0
  15. package/dist/packem_chunks/LogsPanel.js +1 -0
  16. package/dist/packem_chunks/MailPanel.js +2 -0
  17. package/dist/packem_chunks/MetricsPanel.js +1 -0
  18. package/dist/packem_chunks/MigrationsPanel.js +1 -0
  19. package/dist/packem_chunks/NotificationsPanel.js +1 -0
  20. package/dist/packem_chunks/PitrPanel.js +1 -0
  21. package/dist/packem_chunks/SchemaViewer.js +2 -0
  22. package/dist/packem_chunks/SecurityAdvisorPanel.js +1 -0
  23. package/dist/packem_chunks/SettingsPanel.js +1 -0
  24. package/dist/packem_chunks/SqlEditorPanel.js +4 -0
  25. package/dist/packem_chunks/TableEditor.js +1 -0
  26. package/dist/packem_chunks/agents-panel.js +1 -0
  27. package/dist/packem_chunks/analytics-panel.js +1 -0
  28. package/dist/packem_chunks/auth-audit-panel.js +1 -0
  29. package/dist/packem_chunks/auth-config-panel.js +1 -0
  30. package/dist/packem_chunks/auth-sessions-panel.js +1 -0
  31. package/dist/packem_chunks/containers-panel.js +1 -0
  32. package/dist/packem_chunks/dashboards-panel.js +1 -0
  33. package/dist/packem_chunks/fanout-panel.js +1 -0
  34. package/dist/packem_chunks/flags-panel.js +1 -0
  35. package/dist/packem_chunks/issues-panel.js +1 -0
  36. package/dist/packem_chunks/kv-browser.js +1 -0
  37. package/dist/packem_chunks/log-drains-panel.js +4 -0
  38. package/dist/packem_chunks/organizations-panel.js +1 -0
  39. package/dist/packem_chunks/payments-panel.js +1 -0
  40. package/dist/packem_chunks/permissions-panel.js +1 -0
  41. package/dist/packem_chunks/queues-panel.js +1 -0
  42. package/dist/packem_chunks/rls-panel.js +1 -0
  43. package/dist/packem_chunks/schedule-panel.js +1 -0
  44. package/dist/packem_chunks/sparkline.js +1 -0
  45. package/dist/packem_chunks/storage-rules-panel.js +1 -0
  46. package/dist/packem_chunks/subscriptions-panel.js +1 -0
  47. package/dist/packem_chunks/sync-client-panel.js +1 -0
  48. package/dist/packem_chunks/traces-panel.js +1 -0
  49. package/dist/packem_chunks/users-panel.js +1 -0
  50. package/dist/packem_chunks/vector-browser.js +1 -0
  51. package/dist/packem_chunks/workflows-panel.js +1 -0
  52. package/dist/packem_shared/ADMIN_FUNCTIONS-BYNSbBVE.js +1 -0
  53. package/dist/packem_shared/ApiDocsPanel-eJYZlylw.js +2 -0
  54. package/dist/packem_shared/ApiReferencePanel-C42v1jr6.js +1 -0
  55. package/dist/packem_shared/CommandPalette-CVIaY3j8.js +1 -0
  56. package/dist/packem_shared/ConfirmButton-CTL3f3kr.js +1 -0
  57. package/dist/packem_shared/ConnectionBadge-DOk0CQWo.js +1 -0
  58. package/dist/packem_shared/DEFAULT_AUTO_REFRESH_MS-BCC8_4BQ.js +1 -0
  59. package/dist/packem_shared/DEFAULT_INSIGHT_THRESHOLDS-B-hcFVoi.js +1 -0
  60. package/dist/packem_shared/DEFAULT_LOCALE-BZ4NojpD.js +1 -0
  61. package/dist/packem_shared/DataBrowser-B8J5lHjP.js +1 -0
  62. package/dist/packem_shared/DataFilters-Csb30F0C.js +1 -0
  63. package/dist/packem_shared/ErrorBoundary-DvzYskH7.js +1 -0
  64. package/dist/packem_shared/GlobalDataBrowser-RLJ6NvOs.js +1 -0
  65. package/dist/packem_shared/HomePanel-DL1HupAN.js +1 -0
  66. package/dist/packem_shared/OpenRpcReferencePanel-sGsIgYWj.js +1 -0
  67. package/dist/packem_shared/STUDIO_ROOT_CLASS-C6MccdVk.js +1 -0
  68. package/dist/packem_shared/ScheduledJobs-DUbo6epc.js +1 -0
  69. package/dist/packem_shared/ShardInput-BVn2iCU0.js +1 -0
  70. package/dist/packem_shared/Studio-BWBclm_C.js +1 -0
  71. package/dist/packem_shared/StudioApp-BFm73yVr.js +1 -0
  72. package/dist/packem_shared/StudioI18nProvider-CZ5h4nrV.js +1 -0
  73. package/dist/packem_shared/advisor-view-DaCX9Jy5.js +1 -0
  74. package/dist/packem_shared/aggregateMetrics-BNfajLa2.js +1 -0
  75. package/dist/packem_shared/alert-CVcOFuDR.js +1 -0
  76. package/dist/packem_shared/app.d-bRPJhby-.d.ts +254 -0
  77. package/dist/packem_shared/badge-BbuuAio7.js +1 -0
  78. package/dist/packem_shared/bar-chart-AryFCeoa.js +9 -0
  79. package/dist/packem_shared/browser-storage-xjTyMKY0.js +1 -0
  80. package/dist/packem_shared/button-BkCrNcAs.js +1 -0
  81. package/dist/packem_shared/card-CIDGUN6K.js +1 -0
  82. package/dist/packem_shared/cf-links-gbDy51nR.js +1 -0
  83. package/dist/packem_shared/checkbox-StT4Gob6.js +1 -0
  84. package/dist/packem_shared/data-grid-BMBKzMEJ.js +1 -0
  85. package/dist/packem_shared/data-view-params-C8T3bW1z.js +1 -0
  86. package/dist/packem_shared/dropdown-menu-C3RQ_HlW.js +2 -0
  87. package/dist/packem_shared/empty-state-Cg7t_8qu.js +1 -0
  88. package/dist/packem_shared/error-alert-B59DnrDI.js +1 -0
  89. package/dist/packem_shared/grid-features-uZCUj955.js +6 -0
  90. package/dist/packem_shared/home-panel-B-8BCffw.js +3 -0
  91. package/dist/packem_shared/input-JHu63lTv.js +1 -0
  92. package/dist/packem_shared/internal-AtZ4bTal.js +2 -0
  93. package/dist/packem_shared/label-6uP1obNF.js +1 -0
  94. package/dist/packem_shared/live-status-CGW2JHf_.js +1 -0
  95. package/dist/packem_shared/log-fields-CoL3hsIQ.js +1 -0
  96. package/dist/packem_shared/modal-shell-CUwwWC2o.js +1 -0
  97. package/dist/packem_shared/reference-view-KvhektwF.js +12 -0
  98. package/dist/packem_shared/result-chart-CwKhhKM0.js +1 -0
  99. package/dist/packem_shared/scroll-area-DTEq6Jec.js +2 -0
  100. package/dist/packem_shared/select-Bul-DeII.js +2 -0
  101. package/dist/packem_shared/shard-history-DMEW5VBE.js +1 -0
  102. package/dist/packem_shared/skeleton-C1wQ9M5t.js +1 -0
  103. package/dist/packem_shared/sparkline-DtcZoU48.js +1 -0
  104. package/dist/packem_shared/storage-tier-DznqOf-q.js +1 -0
  105. package/dist/packem_shared/studio-BHA7hnI3.js +2 -0
  106. package/dist/packem_shared/table-DdJBrClo.js +2 -0
  107. package/dist/packem_shared/table-list-sidebar-CMCcNALK.js +1 -0
  108. package/dist/packem_shared/textarea-Bu2-jKAs.js +1 -0
  109. package/dist/packem_shared/trace-handoff-Dw7mwjxu.js +1 -0
  110. package/dist/packem_shared/use-admin-query-Di3fLE8H.js +1 -0
  111. package/dist/packem_shared/use-async-submit-H68GHPz8.js +1 -0
  112. package/dist/packem_shared/useDebounced-Ihdiid_k.js +1 -0
  113. package/dist/packem_shared/utils-bhneXptQ.js +1 -0
  114. package/dist/packem_shared/virtual-rect-1o1veP7R.js +1 -0
  115. package/dist/standalone/chunk-2F7G7IWQ.js +1 -0
  116. package/dist/standalone/chunk-2OUPA2WJ.js +1 -0
  117. package/dist/standalone/chunk-2PJNAWB3.js +1 -0
  118. package/dist/standalone/chunk-2Y36BVVM.js +4 -0
  119. package/dist/standalone/chunk-34UVAASH.js +1 -0
  120. package/dist/standalone/chunk-35II7U25.js +11 -0
  121. package/dist/standalone/chunk-3FUFEZ65.js +1 -0
  122. package/dist/standalone/chunk-3QRTYSSX.js +1 -0
  123. package/dist/standalone/chunk-3RTTXLMU.js +1 -0
  124. package/dist/standalone/chunk-3XIESWL4.js +1 -0
  125. package/dist/standalone/chunk-4CGALXS3.js +19 -0
  126. package/dist/standalone/chunk-4UOFSGUS.js +1 -0
  127. package/dist/standalone/chunk-4WLYA3XE.js +1 -0
  128. package/dist/standalone/chunk-54MMVNPT.js +1 -0
  129. package/dist/standalone/chunk-5L2MD6F6.js +1 -0
  130. package/dist/standalone/chunk-5OWIOACV.js +13 -0
  131. package/dist/standalone/chunk-5RF4QDDA.js +6 -0
  132. package/dist/standalone/chunk-5U2THBI7.js +1 -0
  133. package/dist/standalone/chunk-5Y3QLNWX.js +1 -0
  134. package/dist/standalone/chunk-65OTWFS3.js +1 -0
  135. package/dist/standalone/chunk-6DWCIIHE.js +1 -0
  136. package/dist/standalone/chunk-6ST5ECQA.js +1 -0
  137. package/dist/standalone/chunk-7J5N6DGQ.js +1 -0
  138. package/dist/standalone/chunk-7LQWFOEU.js +1 -0
  139. package/dist/standalone/chunk-7QIFDWQV.js +1 -0
  140. package/dist/standalone/chunk-7RXOPYR5.js +1 -0
  141. package/dist/standalone/chunk-7T7UOTYK.js +1 -0
  142. package/dist/standalone/chunk-7YEFOSPH.js +1 -0
  143. package/dist/standalone/chunk-AVAC26HJ.js +1 -0
  144. package/dist/standalone/chunk-B43FTQJ7.js +1 -0
  145. package/dist/standalone/chunk-BEH5N5ZA.js +1 -0
  146. package/dist/standalone/chunk-BGBLQ563.js +1 -0
  147. package/dist/standalone/chunk-BNUJ7QMG.js +3 -0
  148. package/dist/standalone/chunk-C43X4M5U.js +1 -0
  149. package/dist/standalone/chunk-CFPZYHPY.js +2 -0
  150. package/dist/standalone/chunk-D7XXWV4E.js +1 -0
  151. package/dist/standalone/chunk-DVOBKIUX.js +1 -0
  152. package/dist/standalone/chunk-EKRN4ZQM.js +1 -0
  153. package/dist/standalone/chunk-ESVP44Y3.js +1 -0
  154. package/dist/standalone/chunk-EVN46TVV.js +1 -0
  155. package/dist/standalone/chunk-EXFBIISG.js +2 -0
  156. package/dist/standalone/chunk-F5QWLENA.js +1 -0
  157. package/dist/standalone/chunk-F6GOKFMU.js +3 -0
  158. package/dist/standalone/chunk-FGTK44LR.js +1 -0
  159. package/dist/standalone/chunk-FXCBF4XT.js +1 -0
  160. package/dist/standalone/chunk-GMR677FL.js +1 -0
  161. package/dist/standalone/chunk-GRL5MG3Z.js +1 -0
  162. package/dist/standalone/chunk-GSPTEMYN.js +1 -0
  163. package/dist/standalone/chunk-GXZAXNZI.js +1 -0
  164. package/dist/standalone/chunk-H7NIIBHH.js +1 -0
  165. package/dist/standalone/chunk-HP2UCWND.js +1 -0
  166. package/dist/standalone/chunk-HPFLBYRI.js +1 -0
  167. package/dist/standalone/chunk-IC4L6G56.js +1 -0
  168. package/dist/standalone/chunk-IDNNI63H.js +1 -0
  169. package/dist/standalone/chunk-ILNELDFC.js +1 -0
  170. package/dist/standalone/chunk-IVFHIQOT.js +1 -0
  171. package/dist/standalone/chunk-JN2Y24PY.js +1 -0
  172. package/dist/standalone/chunk-KDOC2DP5.js +1 -0
  173. package/dist/standalone/chunk-KUVMORDQ.js +1 -0
  174. package/dist/standalone/chunk-KYF2E5CJ.js +1 -0
  175. package/dist/standalone/chunk-L7N7F3DA.js +1 -0
  176. package/dist/standalone/chunk-LE56LPNH.js +13 -0
  177. package/dist/standalone/chunk-LEDWUPXM.js +1 -0
  178. package/dist/standalone/chunk-LFKCLLPT.js +1 -0
  179. package/dist/standalone/chunk-LFXFP4IF.js +1 -0
  180. package/dist/standalone/chunk-LJDP7NRB.js +1 -0
  181. package/dist/standalone/chunk-LLXFYRGQ.js +1 -0
  182. package/dist/standalone/chunk-M536Y2KX.js +1 -0
  183. package/dist/standalone/chunk-MIQTKZAR.js +1 -0
  184. package/dist/standalone/chunk-OHKRN65U.js +1 -0
  185. package/dist/standalone/chunk-P24JBHEZ.js +4 -0
  186. package/dist/standalone/chunk-PF7V3G2Z.js +62 -0
  187. package/dist/standalone/chunk-PWWHP76O.js +1 -0
  188. package/dist/standalone/chunk-QBWRC5YX.js +1 -0
  189. package/dist/standalone/chunk-QGKAJTQQ.js +1 -0
  190. package/dist/standalone/chunk-QLJJ5YYZ.js +1 -0
  191. package/dist/standalone/chunk-QVEHPYA5.js +1 -0
  192. package/dist/standalone/chunk-QWGT25SE.js +1 -0
  193. package/dist/standalone/chunk-QWJ3NPE3.js +1 -0
  194. package/dist/standalone/chunk-RAA2RGG6.js +1 -0
  195. package/dist/standalone/chunk-RBU52M5T.js +1 -0
  196. package/dist/standalone/chunk-SA3MDZC3.js +1 -0
  197. package/dist/standalone/chunk-SD4BERSA.js +1 -0
  198. package/dist/standalone/chunk-SFDOII3B.js +1 -0
  199. package/dist/standalone/chunk-SKHEGARW.js +1 -0
  200. package/dist/standalone/chunk-SMIESS7P.js +1 -0
  201. package/dist/standalone/chunk-T2JIUFOD.js +4 -0
  202. package/dist/standalone/chunk-T6VMSOBB.js +1 -0
  203. package/dist/standalone/chunk-THIXMMZD.js +1 -0
  204. package/dist/standalone/chunk-TJ2WZ5OP.js +1 -0
  205. package/dist/standalone/chunk-TLHJRWNK.js +1 -0
  206. package/dist/standalone/chunk-UIS34ZPB.js +8 -0
  207. package/dist/standalone/chunk-UNUU7CJJ.js +1 -0
  208. package/dist/standalone/chunk-UZERI5YC.js +1 -0
  209. package/dist/standalone/chunk-V53KNYRN.js +1 -0
  210. package/dist/standalone/chunk-VPAXCQ2Y.js +4 -0
  211. package/dist/standalone/chunk-X2FQ6B5V.js +1 -0
  212. package/dist/standalone/chunk-XBDKZZ67.js +1 -0
  213. package/dist/standalone/chunk-XEDU5FO4.js +1 -0
  214. package/dist/standalone/chunk-XQBTNJUQ.js +1 -0
  215. package/dist/standalone/chunk-XQCVZAGU.js +1 -0
  216. package/dist/standalone/chunk-XQGANNLS.js +1 -0
  217. package/dist/standalone/chunk-XSD4Y6SQ.js +1 -0
  218. package/dist/standalone/chunk-XXQUMVWH.js +1 -0
  219. package/dist/standalone/chunk-YD5NF6UT.js +1 -0
  220. package/dist/standalone/chunk-YI3WYUXK.js +1 -0
  221. package/dist/standalone/chunk-ZJGP6EKR.js +1 -0
  222. package/dist/standalone/chunk-ZNNAGR6N.js +1 -0
  223. package/dist/standalone/studio.js +9 -356
  224. package/dist/styles.css +2 -2
  225. package/package.json +17 -15
  226. package/dist/packem_shared/ADMIN_FUNCTIONS-DmBqMZ-z.js +0 -45
  227. package/dist/packem_shared/ApiDocsPanel-C5-yJ1p7.js +0 -842
  228. package/dist/packem_shared/ApiReferencePanel-1vubqG5s.js +0 -229
  229. package/dist/packem_shared/ApiTab-W3no0KOj.js +0 -251
  230. package/dist/packem_shared/AuditPanel-Bq4o_IqT.js +0 -212
  231. package/dist/packem_shared/CommandPalette-BtgkBzZI.js +0 -373
  232. package/dist/packem_shared/ConfirmButton-C2eVi2Qv.js +0 -59
  233. package/dist/packem_shared/ConnectionBadge-B2DDM2Tn.js +0 -111
  234. package/dist/packem_shared/DEFAULT_AUTO_REFRESH_MS-Vxwaxx51.js +0 -50
  235. package/dist/packem_shared/DEFAULT_INSIGHT_THRESHOLDS-DjF0h-gA.js +0 -89
  236. package/dist/packem_shared/DEFAULT_LOCALE-CiX4W7Kr.js +0 -27
  237. package/dist/packem_shared/DataBrowser-CtBe1So9.js +0 -4542
  238. package/dist/packem_shared/DataFilters-FNquMaiu.js +0 -249
  239. package/dist/packem_shared/ErrorBoundary-BzAApI7J.js +0 -66
  240. package/dist/packem_shared/ExportImportPanel-dxY56TDF.js +0 -193
  241. package/dist/packem_shared/FileBrowser-Dhy4zES8.js +0 -2932
  242. package/dist/packem_shared/FunctionRunner--fQJRPAD.js +0 -343
  243. package/dist/packem_shared/FunctionStatsPanel-BjRUA_G3.js +0 -432
  244. package/dist/packem_shared/GlobalDataBrowser-BTEmGrph.js +0 -318
  245. package/dist/packem_shared/HealthPanel-PxclMWmA.js +0 -640
  246. package/dist/packem_shared/HomePanel-Cw16stjq.js +0 -1273
  247. package/dist/packem_shared/InsightsPanel-CWS_C-xW.js +0 -423
  248. package/dist/packem_shared/LogsPanel-CTW8CFcM.js +0 -839
  249. package/dist/packem_shared/MailPanel-BwkvfIHF.js +0 -447
  250. package/dist/packem_shared/MetricsPanel-BLuOhZQ4.js +0 -1625
  251. package/dist/packem_shared/MigrationsPanel-DT3lnwHF.js +0 -246
  252. package/dist/packem_shared/OpenRpcReferencePanel-vbcYbv3V.js +0 -191
  253. package/dist/packem_shared/PitrPanel-CdErL7EJ.js +0 -252
  254. package/dist/packem_shared/STUDIO_ROOT_CLASS-D12gX2dV.js +0 -3
  255. package/dist/packem_shared/ScheduledJobs-CabfKbyM.js +0 -159
  256. package/dist/packem_shared/SchemaViewer-LJDcmNIO.js +0 -2512
  257. package/dist/packem_shared/SecurityAdvisorPanel-C_ETsPih.js +0 -79
  258. package/dist/packem_shared/SettingsPanel-C0uLRf5P.js +0 -176
  259. package/dist/packem_shared/ShardInput-gx_DZXXn.js +0 -107
  260. package/dist/packem_shared/SqlEditorPanel-CguV7otm.js +0 -13
  261. package/dist/packem_shared/Studio-BmSGSIuY.js +0 -33
  262. package/dist/packem_shared/StudioApp-D4azxYBu.js +0 -657
  263. package/dist/packem_shared/StudioI18nProvider-B-tDCZIi.js +0 -48
  264. package/dist/packem_shared/TableEditor-ChfUOZec.js +0 -371
  265. package/dist/packem_shared/advisor-view-CGcfMiPq.js +0 -159
  266. package/dist/packem_shared/aggregateMetrics-D4nUHEKU.js +0 -108
  267. package/dist/packem_shared/app.d-CCmwDEVs.d.ts +0 -300
  268. package/dist/packem_shared/badge-B2PKA1-5.js +0 -49
  269. package/dist/packem_shared/bar-chart-CzJAgqkp.js +0 -3245
  270. package/dist/packem_shared/button-BhsN2uZH.js +0 -49
  271. package/dist/packem_shared/card-DURq3ElK.js +0 -175
  272. package/dist/packem_shared/cf-links-2cktDedA.js +0 -8
  273. package/dist/packem_shared/checkbox-UNkzAxl-.js +0 -63
  274. package/dist/packem_shared/data-grid-B5CaV3wS.js +0 -183
  275. package/dist/packem_shared/dropdown-menu-WY4B_eJO.js +0 -280
  276. package/dist/packem_shared/empty-state-DY_oe0k6.js +0 -98
  277. package/dist/packem_shared/grid-features-CzUfqgsM.js +0 -840
  278. package/dist/packem_shared/input-XH4r1Pt1.js +0 -53
  279. package/dist/packem_shared/internal-rXJEAhXS.js +0 -68
  280. package/dist/packem_shared/label-D8ykjn5J.js +0 -46
  281. package/dist/packem_shared/live-status-FZ0psC1z.js +0 -44
  282. package/dist/packem_shared/reference-view-B4E49Lip.js +0 -2180
  283. package/dist/packem_shared/shard-history-DyebH1R5.js +0 -38
  284. package/dist/packem_shared/sparkline-10dG-_f0.js +0 -93
  285. package/dist/packem_shared/sql-editor-panel-BFRpzj6r.js +0 -2562
  286. package/dist/packem_shared/storage-tier-CL98eOvn.js +0 -85
  287. package/dist/packem_shared/studio-H9fuQgSj.js +0 -10303
  288. package/dist/packem_shared/table-_RzNvy3R.js +0 -246
  289. package/dist/packem_shared/table-list-sidebar-Bg7uzbvC.js +0 -832
  290. package/dist/packem_shared/textarea-D3gaCU_-.js +0 -46
  291. package/dist/packem_shared/use-live-admin-Dq6g3daN.js +0 -73
  292. package/dist/packem_shared/use-live-shard-seed-Cuk3dnH0.js +0 -76
  293. package/dist/packem_shared/useDebounced-Dxncpg6z.js +0 -32
  294. package/dist/packem_shared/utils-B05Dmz_H.js +0 -8
  295. package/dist/packem_shared/virtual-rect-CVMUskSm.js +0 -10
@@ -1,2512 +0,0 @@
1
- 'use client';
2
- import { c } from 'react/compiler-runtime';
3
- import { useLunora } from '@lunora/react';
4
- import { useState, useRef, useEffect } from 'react';
5
- import { ShardInput } from './ShardInput-gx_DZXXn.js';
6
- import { S as StorageTierBadge, T as TIER_META } from './storage-tier-CL98eOvn.js';
7
- import { B as Badge } from './badge-B2PKA1-5.js';
8
- import { B as Button } from './button-BhsN2uZH.js';
9
- import { C as Card, b as CardHeader, c as CardTitle, d as CardDescription, a as CardContent } from './card-DURq3ElK.js';
10
- import { E as EmptyState } from './empty-state-DY_oe0k6.js';
11
- import { I as Input } from './input-XH4r1Pt1.js';
12
- import useDebounced from './useDebounced-Dxncpg6z.js';
13
- import { useT } from './DEFAULT_LOCALE-CiX4W7Kr.js';
14
- import { ADMIN_FUNCTIONS } from './ADMIN_FUNCTIONS-DmBqMZ-z.js';
15
- import { f as fireAndForget, c as callOptions, e as errorMessage, a as adminRef } from './internal-rXJEAhXS.js';
16
- import { r as recordShard } from './shard-history-DyebH1R5.js';
17
- import { c as cn } from './utils-B05Dmz_H.js';
18
- import { Download01Icon } from '@hugeicons/core-free-icons';
19
- import { HugeiconsIcon } from '@hugeicons/react';
20
- import { Handle, Position, getNodesBounds, getViewportForBounds, useNodesState, useEdgesState, Background, Panel, Controls, MiniMap, ReactFlow, useNodes, useReactFlow } from '@xyflow/react';
21
- import { d as DropdownMenu, D as DropdownMenuTrigger, c as DropdownMenuContent, b as DropdownMenuItem } from './dropdown-menu-WY4B_eJO.js';
22
- import { jsxDEV } from 'react/jsx-dev-runtime';
23
- import { toBlob, toSvg } from 'html-to-image';
24
- import { useNavigate } from '@tanstack/react-router';
25
- import { L as Label } from './label-D8ykjn5J.js';
26
-
27
- function BaseNode(t0) {
28
- const $ = c(10);
29
- let className;
30
- let props;
31
- let selected;
32
- if ($[0] !== t0) {
33
- ({
34
- className,
35
- selected,
36
- ...props
37
- } = t0);
38
- $[0] = t0;
39
- $[1] = className;
40
- $[2] = props;
41
- $[3] = selected;
42
- } else {
43
- className = $[1];
44
- props = $[2];
45
- selected = $[3];
46
- }
47
- const t1 = selected === true ? "" : void 0;
48
- let t2;
49
- if ($[4] !== className) {
50
- t2 = cn("rounded-md border border-border bg-card text-card-foreground shadow-sm transition-colors", "data-[selected]:border-ring data-[selected]:ring-[3px] data-[selected]:ring-ring/30", className);
51
- $[4] = className;
52
- $[5] = t2;
53
- } else {
54
- t2 = $[5];
55
- }
56
- let t3;
57
- if ($[6] !== props || $[7] !== t1 || $[8] !== t2) {
58
- t3 = /* @__PURE__ */ jsxDEV("div", {
59
- "data-slot": "base-node",
60
- "data-selected": t1,
61
- className: t2,
62
- ...props
63
- }, void 0, false);
64
- $[6] = props;
65
- $[7] = t1;
66
- $[8] = t2;
67
- $[9] = t3;
68
- } else {
69
- t3 = $[9];
70
- }
71
- return t3;
72
- }
73
- function BaseNodeHeader(t0) {
74
- const $ = c(8);
75
- let className;
76
- let props;
77
- if ($[0] !== t0) {
78
- ({
79
- className,
80
- ...props
81
- } = t0);
82
- $[0] = t0;
83
- $[1] = className;
84
- $[2] = props;
85
- } else {
86
- className = $[1];
87
- props = $[2];
88
- }
89
- let t1;
90
- if ($[3] !== className) {
91
- t1 = cn("flex items-center gap-2 rounded-t-md bg-muted/50 px-3 py-1.5", className);
92
- $[3] = className;
93
- $[4] = t1;
94
- } else {
95
- t1 = $[4];
96
- }
97
- let t2;
98
- if ($[5] !== props || $[6] !== t1) {
99
- t2 = /* @__PURE__ */ jsxDEV("div", {
100
- "data-slot": "base-node-header",
101
- className: t1,
102
- ...props
103
- }, void 0, false);
104
- $[5] = props;
105
- $[6] = t1;
106
- $[7] = t2;
107
- } else {
108
- t2 = $[7];
109
- }
110
- return t2;
111
- }
112
- function BaseNodeContent(t0) {
113
- const $ = c(8);
114
- let className;
115
- let props;
116
- if ($[0] !== t0) {
117
- ({
118
- className,
119
- ...props
120
- } = t0);
121
- $[0] = t0;
122
- $[1] = className;
123
- $[2] = props;
124
- } else {
125
- className = $[1];
126
- props = $[2];
127
- }
128
- let t1;
129
- if ($[3] !== className) {
130
- t1 = cn("flex flex-col", className);
131
- $[3] = className;
132
- $[4] = t1;
133
- } else {
134
- t1 = $[4];
135
- }
136
- let t2;
137
- if ($[5] !== props || $[6] !== t1) {
138
- t2 = /* @__PURE__ */ jsxDEV("div", {
139
- "data-slot": "base-node-content",
140
- className: t1,
141
- ...props
142
- }, void 0, false);
143
- $[5] = props;
144
- $[6] = t1;
145
- $[7] = t2;
146
- } else {
147
- t2 = $[7];
148
- }
149
- return t2;
150
- }
151
-
152
- const typeLabel = (column) => {
153
- const base = column.ref === void 0 ? column.type : `${column.type} → ${column.ref}`;
154
- return column.optional === true ? `${base}?` : base;
155
- };
156
- const DatabaseSchemaNode = (t0) => {
157
- const $ = c(22);
158
- const {
159
- data,
160
- selected
161
- } = t0;
162
- const t = useT();
163
- let t1;
164
- if ($[0] !== data.label || $[1] !== data.loadError || $[2] !== t) {
165
- t1 = data.loadError === true ? /* @__PURE__ */ jsxDEV("span", {
166
- className: "px-3 py-1.5 text-xs text-destructive",
167
- "data-testid": `sd-node-${data.label}-error`,
168
- children: t("Columns unavailable")
169
- }, void 0, false) : /* @__PURE__ */ jsxDEV("span", {
170
- className: "px-3 py-1.5 text-xs text-muted-foreground",
171
- children: "—"
172
- }, void 0, false);
173
- $[0] = data.label;
174
- $[1] = data.loadError;
175
- $[2] = t;
176
- $[3] = t1;
177
- } else {
178
- t1 = $[3];
179
- }
180
- const emptyPlaceholder = t1;
181
- const t2 = `sd-node-${data.label}`;
182
- let t3;
183
- if ($[4] !== data.label) {
184
- t3 = /* @__PURE__ */ jsxDEV("span", {
185
- className: "truncate font-mono text-xs font-semibold",
186
- title: data.label,
187
- children: data.label
188
- }, void 0, false);
189
- $[4] = data.label;
190
- $[5] = t3;
191
- } else {
192
- t3 = $[5];
193
- }
194
- let t4;
195
- if ($[6] !== data.tier) {
196
- t4 = /* @__PURE__ */ jsxDEV("span", {
197
- className: "ms-auto",
198
- children: /* @__PURE__ */ jsxDEV(StorageTierBadge, {
199
- tier: data.tier
200
- }, void 0, false)
201
- }, void 0, false);
202
- $[6] = data.tier;
203
- $[7] = t4;
204
- } else {
205
- t4 = $[7];
206
- }
207
- let t5;
208
- if ($[8] !== t3 || $[9] !== t4) {
209
- t5 = /* @__PURE__ */ jsxDEV(BaseNodeHeader, {
210
- children: [t3, t4]
211
- }, void 0, true);
212
- $[8] = t3;
213
- $[9] = t4;
214
- $[10] = t5;
215
- } else {
216
- t5 = $[10];
217
- }
218
- let t6;
219
- if ($[11] !== data.columns || $[12] !== data.label || $[13] !== emptyPlaceholder) {
220
- t6 = data.columns.length === 0 ? emptyPlaceholder : data.columns.map((column) => /* @__PURE__ */ jsxDEV("div", {
221
- className: cn("relative flex items-center gap-2 border-t border-border px-3 py-1.5 text-xs first:border-t-0", column.pk === true && "bg-muted/30"),
222
- "data-testid": `sd-col-${data.label}-${column.name}`,
223
- children: [/* @__PURE__ */ jsxDEV(Handle, {
224
- className: "!h-2 !w-2 !-left-1 !border-border !bg-muted-foreground/70",
225
- id: column.name,
226
- isConnectable: false,
227
- position: Position.Left,
228
- type: "target"
229
- }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
230
- className: "truncate font-mono",
231
- title: column.name,
232
- children: column.name
233
- }, void 0, false), column.pk === true && /* @__PURE__ */ jsxDEV(Badge, {
234
- className: "px-1 py-0 text-[10px] leading-tight",
235
- variant: "secondary",
236
- children: "PK"
237
- }, void 0, false), column.ref !== void 0 && /* @__PURE__ */ jsxDEV(Badge, {
238
- className: "px-1 py-0 text-[10px] leading-tight",
239
- variant: "outline",
240
- children: "FK"
241
- }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
242
- className: "ms-auto truncate text-muted-foreground",
243
- title: typeLabel(column),
244
- children: typeLabel(column)
245
- }, void 0, false), /* @__PURE__ */ jsxDEV(Handle, {
246
- className: "!h-2 !w-2 !-right-1 !border-border !bg-muted-foreground/70",
247
- id: column.name,
248
- isConnectable: false,
249
- position: Position.Right,
250
- type: "source"
251
- }, void 0, false)]
252
- }, column.name, true));
253
- $[11] = data.columns;
254
- $[12] = data.label;
255
- $[13] = emptyPlaceholder;
256
- $[14] = t6;
257
- } else {
258
- t6 = $[14];
259
- }
260
- let t7;
261
- if ($[15] !== t6) {
262
- t7 = /* @__PURE__ */ jsxDEV(BaseNodeContent, {
263
- children: t6
264
- }, void 0, false);
265
- $[15] = t6;
266
- $[16] = t7;
267
- } else {
268
- t7 = $[16];
269
- }
270
- let t8;
271
- if ($[17] !== selected || $[18] !== t2 || $[19] !== t5 || $[20] !== t7) {
272
- t8 = /* @__PURE__ */ jsxDEV(BaseNode, {
273
- className: "w-64 overflow-hidden",
274
- "data-testid": t2,
275
- selected,
276
- children: [t5, t7]
277
- }, void 0, true);
278
- $[17] = selected;
279
- $[18] = t2;
280
- $[19] = t5;
281
- $[20] = t7;
282
- $[21] = t8;
283
- } else {
284
- t8 = $[21];
285
- }
286
- return t8;
287
- };
288
-
289
- const IMAGE_WIDTH = 1920;
290
- const IMAGE_HEIGHT = 1080;
291
- const IMAGE_PADDING = 32;
292
- const triggerDownload = (href, filename) => {
293
- const link = globalThis.document.createElement("a");
294
- link.href = href;
295
- link.download = filename;
296
- globalThis.document.body.append(link);
297
- link.click();
298
- link.remove();
299
- };
300
- const exportDiagramAsJson = (nodes, edges, filename = "schema-diagram.json") => {
301
- const payload = {
302
- edges,
303
- exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
304
- nodes
305
- };
306
- const json = JSON.stringify(payload, void 0, 2);
307
- const url = globalThis.URL.createObjectURL(new globalThis.Blob([json], {
308
- type: "application/json"
309
- }));
310
- triggerDownload(url, filename);
311
- globalThis.setTimeout(() => {
312
- globalThis.URL.revokeObjectURL(url);
313
- }, 0);
314
- };
315
- const viewportForExport = (nodes, width, height, padding) => {
316
- const bounds = getNodesBounds(nodes);
317
- const {
318
- x,
319
- y,
320
- zoom
321
- } = getViewportForBounds(bounds, width, height, 0.1, 2, padding);
322
- return {
323
- transform: [x, y, zoom],
324
- zoom
325
- };
326
- };
327
- const exportDiagramAsPng = async (viewportElement, nodes, filename = "schema-diagram.png") => {
328
- const {
329
- transform
330
- } = viewportForExport(nodes, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_PADDING);
331
- const [tx, ty, scale] = transform;
332
- const blob = await toBlob(viewportElement, {
333
- backgroundColor: "#ffffff",
334
- height: IMAGE_HEIGHT,
335
- style: {
336
- transform: `translate(${tx.toString()}px, ${ty.toString()}px) scale(${scale.toString()})`,
337
- transformOrigin: "top left",
338
- width: `${IMAGE_WIDTH.toString()}px`
339
- },
340
- width: IMAGE_WIDTH
341
- });
342
- if (blob === null) {
343
- throw new Error("html-to-image produced no blob");
344
- }
345
- const url = globalThis.URL.createObjectURL(blob);
346
- triggerDownload(url, filename);
347
- globalThis.setTimeout(() => {
348
- globalThis.URL.revokeObjectURL(url);
349
- }, 0);
350
- };
351
- const exportDiagramAsSvg = async (viewportElement, nodes, filename = "schema-diagram.svg") => {
352
- const {
353
- transform
354
- } = viewportForExport(nodes, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_PADDING);
355
- const [tx, ty, scale] = transform;
356
- const svgDataUrl = await toSvg(viewportElement, {
357
- backgroundColor: "#ffffff",
358
- height: IMAGE_HEIGHT,
359
- style: {
360
- transform: `translate(${tx.toString()}px, ${ty.toString()}px) scale(${scale.toString()})`,
361
- transformOrigin: "top left",
362
- width: `${IMAGE_WIDTH.toString()}px`
363
- },
364
- width: IMAGE_WIDTH
365
- });
366
- triggerDownload(svgDataUrl, filename);
367
- };
368
-
369
- const NODE_WIDTH = 256;
370
- const COLUMN_GAP = 112;
371
- const ROW_GAP = 36;
372
- const PADDING = 24;
373
- const HEADER_HEIGHT = 38;
374
- const ROW_HEIGHT = 28;
375
- const nodeHeight = (columnCount) => HEADER_HEIGHT + Math.max(1, columnCount) * ROW_HEIGHT;
376
- const computeDepths = (tables, edges) => {
377
- const targetsOf = /* @__PURE__ */ new Map();
378
- for (const table of tables) {
379
- targetsOf.set(table, []);
380
- }
381
- for (const edge of edges) {
382
- if (edge.to !== edge.from && targetsOf.has(edge.from) && targetsOf.has(edge.to)) {
383
- targetsOf.get(edge.from)?.push(edge.to);
384
- }
385
- }
386
- const depth = /* @__PURE__ */ new Map();
387
- const visiting = /* @__PURE__ */ new Set();
388
- const resolve = (table) => {
389
- const cached = depth.get(table);
390
- if (cached !== void 0) {
391
- return cached;
392
- }
393
- if (visiting.has(table)) {
394
- return 0;
395
- }
396
- visiting.add(table);
397
- let deepest = 0;
398
- for (const target of targetsOf.get(table) ?? []) {
399
- deepest = Math.max(deepest, resolve(target) + 1);
400
- }
401
- visiting.delete(table);
402
- depth.set(table, deepest);
403
- return deepest;
404
- };
405
- for (const table of tables) {
406
- resolve(table);
407
- }
408
- return depth;
409
- };
410
- const computeLayout = (tables, edges, columnCounts) => {
411
- const depth = computeDepths(tables, edges);
412
- const offsetByColumn = /* @__PURE__ */ new Map();
413
- const nodes = [];
414
- for (const name of tables) {
415
- const column = depth.get(name) ?? 0;
416
- const y = offsetByColumn.get(column) ?? PADDING;
417
- nodes.push({
418
- name,
419
- x: PADDING + column * (NODE_WIDTH + COLUMN_GAP),
420
- y
421
- });
422
- offsetByColumn.set(column, y + nodeHeight(columnCounts.get(name) ?? 0) + ROW_GAP);
423
- }
424
- return nodes;
425
- };
426
-
427
- const NODE_TYPES = {
428
- databaseSchema: DatabaseSchemaNode
429
- };
430
- const SHARD_DOT_STYLE = {
431
- backgroundColor: TIER_META.shard.color
432
- };
433
- const GLOBAL_DOT_STYLE = {
434
- backgroundColor: TIER_META.global.color
435
- };
436
- const ALL_TIERS = {
437
- global: true,
438
- shard: true
439
- };
440
- const pkColumnOf = (columns) => {
441
- const flagged = columns.find((column) => column.pk === true)?.name;
442
- if (flagged !== void 0) {
443
- return flagged;
444
- }
445
- if (columns.some((column) => column.name === "_id")) {
446
- return "_id";
447
- }
448
- if (columns.some((column) => column.name === "id")) {
449
- return "id";
450
- }
451
- return columns[0]?.name ?? "_id";
452
- };
453
- const deriveEdges = (tables) => tables.flatMap((table) => table.columns.filter((column) => column.ref !== void 0).map((column) => {
454
- return {
455
- column: column.name,
456
- from: table.name,
457
- to: column.ref
458
- };
459
- }));
460
- const buildNodes = (tables, columnsError) => {
461
- const names = tables.map((table) => table.name);
462
- const counts = new Map(tables.map((table) => [table.name, table.columns.length]));
463
- const positions = computeLayout(names, deriveEdges(tables), counts);
464
- const byName = new Map(tables.map((table) => [table.name, table]));
465
- return positions.flatMap(({
466
- name,
467
- x,
468
- y
469
- }) => {
470
- const table = byName.get(name);
471
- if (table === void 0) {
472
- return [];
473
- }
474
- return [{
475
- data: {
476
- columns: table.columns,
477
- label: name,
478
- loadError: columnsError,
479
- tier: table.tier
480
- },
481
- id: name,
482
- position: {
483
- x,
484
- y
485
- },
486
- type: "databaseSchema"
487
- }];
488
- });
489
- };
490
- const buildEdges = (tables) => {
491
- const columnsByTable = new Map(tables.map((table) => [table.name, table.columns]));
492
- return deriveEdges(tables).flatMap((edge) => {
493
- const targetColumns = columnsByTable.get(edge.to) ?? [];
494
- const sourceColumns = columnsByTable.get(edge.from) ?? [];
495
- const pk = pkColumnOf(targetColumns);
496
- if (!targetColumns.some((column) => column.name === pk) || !sourceColumns.some((column) => column.name === edge.column)) {
497
- return [];
498
- }
499
- return [{
500
- id: `${edge.from}.${edge.column}->${edge.to}`,
501
- source: edge.to,
502
- sourceHandle: pk,
503
- target: edge.from,
504
- targetHandle: edge.column
505
- }];
506
- });
507
- };
508
- const Legend = () => {
509
- const $ = c(15);
510
- const t = useT();
511
- let t0;
512
- if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
513
- t0 = /* @__PURE__ */ jsxDEV("span", {
514
- className: "flex items-center gap-1",
515
- children: [/* @__PURE__ */ jsxDEV("span", {
516
- "aria-hidden": "true",
517
- className: "size-1.5 rounded-full",
518
- style: SHARD_DOT_STYLE
519
- }, void 0, false), TIER_META.shard.label]
520
- }, void 0, true);
521
- $[0] = t0;
522
- } else {
523
- t0 = $[0];
524
- }
525
- let t1;
526
- if ($[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
527
- t1 = /* @__PURE__ */ jsxDEV("span", {
528
- className: "flex items-center gap-1",
529
- children: [/* @__PURE__ */ jsxDEV("span", {
530
- "aria-hidden": "true",
531
- className: "size-1.5 rounded-full",
532
- style: GLOBAL_DOT_STYLE
533
- }, void 0, false), TIER_META.global.label]
534
- }, void 0, true);
535
- $[1] = t1;
536
- } else {
537
- t1 = $[1];
538
- }
539
- let t2;
540
- if ($[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
541
- t2 = /* @__PURE__ */ jsxDEV(Badge, {
542
- className: "px-1 py-0 text-[10px] leading-tight",
543
- variant: "secondary",
544
- children: "PK"
545
- }, void 0, false);
546
- $[2] = t2;
547
- } else {
548
- t2 = $[2];
549
- }
550
- let t3;
551
- if ($[3] !== t) {
552
- t3 = t("Primary key");
553
- $[3] = t;
554
- $[4] = t3;
555
- } else {
556
- t3 = $[4];
557
- }
558
- let t4;
559
- if ($[5] !== t3) {
560
- t4 = /* @__PURE__ */ jsxDEV("span", {
561
- className: "flex items-center gap-1",
562
- children: [t2, t3]
563
- }, void 0, true);
564
- $[5] = t3;
565
- $[6] = t4;
566
- } else {
567
- t4 = $[6];
568
- }
569
- let t5;
570
- if ($[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
571
- t5 = /* @__PURE__ */ jsxDEV(Badge, {
572
- className: "px-1 py-0 text-[10px] leading-tight",
573
- variant: "outline",
574
- children: "FK"
575
- }, void 0, false);
576
- $[7] = t5;
577
- } else {
578
- t5 = $[7];
579
- }
580
- let t6;
581
- if ($[8] !== t) {
582
- t6 = t("Foreign key");
583
- $[8] = t;
584
- $[9] = t6;
585
- } else {
586
- t6 = $[9];
587
- }
588
- let t7;
589
- if ($[10] !== t6) {
590
- t7 = /* @__PURE__ */ jsxDEV("span", {
591
- className: "flex items-center gap-1",
592
- children: [t5, t6]
593
- }, void 0, true);
594
- $[10] = t6;
595
- $[11] = t7;
596
- } else {
597
- t7 = $[11];
598
- }
599
- let t8;
600
- if ($[12] !== t4 || $[13] !== t7) {
601
- t8 = /* @__PURE__ */ jsxDEV("div", {
602
- className: "flex flex-wrap items-center gap-x-3 gap-y-1 rounded-xl border border-border bg-card/95 px-2.5 py-1.5 text-[11px] text-muted-foreground shadow-xs",
603
- children: [t0, t1, t4, t7]
604
- }, void 0, true);
605
- $[12] = t4;
606
- $[13] = t7;
607
- $[14] = t8;
608
- } else {
609
- t8 = $[14];
610
- }
611
- return t8;
612
- };
613
- const DiagramExportPanel = ({
614
- containerRef,
615
- testIdPrefix
616
- }) => {
617
- const t = useT();
618
- const nodes = useNodes();
619
- const {
620
- getEdges
621
- } = useReactFlow();
622
- const [exporting, setExporting] = useState(null);
623
- const handlePng = async () => {
624
- const viewport = containerRef.current?.querySelector(".react-flow__viewport");
625
- if (!viewport) {
626
- return;
627
- }
628
- setExporting("png");
629
- try {
630
- await exportDiagramAsPng(viewport, nodes, `${testIdPrefix}-schema-diagram.png`);
631
- } finally {
632
- setExporting(null);
633
- }
634
- };
635
- const handleSvg = async () => {
636
- const viewport_0 = containerRef.current?.querySelector(".react-flow__viewport");
637
- if (!viewport_0) {
638
- return;
639
- }
640
- setExporting("svg");
641
- try {
642
- await exportDiagramAsSvg(viewport_0, nodes, `${testIdPrefix}-schema-diagram.svg`);
643
- } finally {
644
- setExporting(null);
645
- }
646
- };
647
- const handleJson = () => {
648
- setExporting("json");
649
- try {
650
- exportDiagramAsJson(nodes, getEdges(), `${testIdPrefix}-schema-diagram.json`);
651
- } finally {
652
- setExporting(null);
653
- }
654
- };
655
- const onClickPng = () => {
656
- fireAndForget(handlePng());
657
- };
658
- const onClickSvg = () => {
659
- fireAndForget(handleSvg());
660
- };
661
- return /* @__PURE__ */ jsxDEV(Panel, {
662
- position: "top-right",
663
- children: /* @__PURE__ */ jsxDEV(DropdownMenu, {
664
- children: [/* @__PURE__ */ jsxDEV(DropdownMenuTrigger, {
665
- className: "group/button inline-flex shrink-0 cursor-pointer items-center justify-center gap-1 rounded-md border border-border bg-background px-2 text-xs font-medium whitespace-nowrap hover:bg-muted disabled:pointer-events-none disabled:opacity-50",
666
- "data-testid": `${testIdPrefix}-export-trigger`,
667
- disabled: exporting !== null,
668
- children: [/* @__PURE__ */ jsxDEV(HugeiconsIcon, {
669
- className: "size-3.5",
670
- icon: Download01Icon,
671
- strokeWidth: 2
672
- }, void 0, false), t("Export")]
673
- }, void 0, true), /* @__PURE__ */ jsxDEV(DropdownMenuContent, {
674
- align: "end",
675
- children: [/* @__PURE__ */ jsxDEV(DropdownMenuItem, {
676
- "data-testid": `${testIdPrefix}-export-png`,
677
- disabled: exporting !== null,
678
- onClick: onClickPng,
679
- children: t("PNG")
680
- }, void 0, false), /* @__PURE__ */ jsxDEV(DropdownMenuItem, {
681
- "data-testid": `${testIdPrefix}-export-svg`,
682
- disabled: exporting !== null,
683
- onClick: onClickSvg,
684
- children: t("SVG")
685
- }, void 0, false), /* @__PURE__ */ jsxDEV(DropdownMenuItem, {
686
- "data-testid": `${testIdPrefix}-export-json`,
687
- disabled: exporting !== null,
688
- onClick: handleJson,
689
- children: t("JSON")
690
- }, void 0, false)]
691
- }, void 0, true)]
692
- }, void 0, true)
693
- }, void 0, false);
694
- };
695
- const SchemaDiagram = (t0) => {
696
- const $ = c(75);
697
- const {
698
- columnsError,
699
- tables,
700
- testIdPrefix
701
- } = t0;
702
- const t = useT();
703
- const [tierFilter, setTierFilter] = useState(ALL_TIERS);
704
- const [query, setQuery] = useState("");
705
- let t1;
706
- if ($[0] !== query || $[1] !== tables || $[2] !== tierFilter) {
707
- const needle = query.trim().toLowerCase();
708
- t1 = tables.filter((table) => tierFilter[table.tier] && table.name.toLowerCase().includes(needle));
709
- $[0] = query;
710
- $[1] = tables;
711
- $[2] = tierFilter;
712
- $[3] = t1;
713
- } else {
714
- t1 = $[3];
715
- }
716
- const visibleTables = t1;
717
- const t2 = columnsError ?? false;
718
- let t3;
719
- if ($[4] !== t2 || $[5] !== visibleTables) {
720
- t3 = buildNodes(visibleTables, t2);
721
- $[4] = t2;
722
- $[5] = visibleTables;
723
- $[6] = t3;
724
- } else {
725
- t3 = $[6];
726
- }
727
- const seededNodes = t3;
728
- let t4;
729
- if ($[7] !== visibleTables) {
730
- t4 = buildEdges(visibleTables);
731
- $[7] = visibleTables;
732
- $[8] = t4;
733
- } else {
734
- t4 = $[8];
735
- }
736
- const seededEdges = t4;
737
- const [nodes, setNodes, onNodesChange] = useNodesState(seededNodes);
738
- const [flowEdges, setEdges, onEdgesChange] = useEdgesState(seededEdges);
739
- const canvasRef = useRef(null);
740
- let t5;
741
- let t6;
742
- if ($[9] !== seededNodes || $[10] !== setNodes) {
743
- t5 = () => {
744
- setNodes(seededNodes);
745
- };
746
- t6 = [seededNodes, setNodes];
747
- $[9] = seededNodes;
748
- $[10] = setNodes;
749
- $[11] = t5;
750
- $[12] = t6;
751
- } else {
752
- t5 = $[11];
753
- t6 = $[12];
754
- }
755
- useEffect(t5, t6);
756
- let t7;
757
- let t8;
758
- if ($[13] !== seededEdges || $[14] !== setEdges) {
759
- t7 = () => {
760
- setEdges(seededEdges);
761
- };
762
- t8 = [seededEdges, setEdges];
763
- $[13] = seededEdges;
764
- $[14] = setEdges;
765
- $[15] = t7;
766
- $[16] = t8;
767
- } else {
768
- t7 = $[15];
769
- t8 = $[16];
770
- }
771
- useEffect(t7, t8);
772
- let t9;
773
- if ($[17] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
774
- t9 = (event) => {
775
- setQuery(event.target.value);
776
- };
777
- $[17] = t9;
778
- } else {
779
- t9 = $[17];
780
- }
781
- const onQueryChange = t9;
782
- let t10;
783
- if ($[18] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
784
- t10 = () => {
785
- setTierFilter(_temp$1);
786
- };
787
- $[18] = t10;
788
- } else {
789
- t10 = $[18];
790
- }
791
- const toggleShard = t10;
792
- let t11;
793
- if ($[19] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
794
- t11 = () => {
795
- setTierFilter(_temp2$1);
796
- };
797
- $[19] = t11;
798
- } else {
799
- t11 = $[19];
800
- }
801
- const toggleGlobal = t11;
802
- if (tables.length === 0) {
803
- const t122 = `${testIdPrefix}-section`;
804
- const t132 = `${testIdPrefix}-empty`;
805
- let t142;
806
- if ($[20] !== t) {
807
- t142 = t("No tables to graph.");
808
- $[20] = t;
809
- $[21] = t142;
810
- } else {
811
- t142 = $[21];
812
- }
813
- let t152;
814
- if ($[22] !== t132 || $[23] !== t142) {
815
- t152 = /* @__PURE__ */ jsxDEV("p", {
816
- className: "text-sm text-muted-foreground",
817
- "data-testid": t132,
818
- children: t142
819
- }, void 0, false);
820
- $[22] = t132;
821
- $[23] = t142;
822
- $[24] = t152;
823
- } else {
824
- t152 = $[24];
825
- }
826
- let t162;
827
- if ($[25] !== t122 || $[26] !== t152) {
828
- t162 = /* @__PURE__ */ jsxDEV("section", {
829
- className: "flex flex-col gap-2",
830
- "data-testid": t122,
831
- children: t152
832
- }, void 0, false);
833
- $[25] = t122;
834
- $[26] = t152;
835
- $[27] = t162;
836
- } else {
837
- t162 = $[27];
838
- }
839
- return t162;
840
- }
841
- const t12 = `${testIdPrefix}-section`;
842
- const t13 = `${testIdPrefix}-canvas`;
843
- let t14;
844
- if ($[28] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
845
- t14 = /* @__PURE__ */ jsxDEV(Background, {}, void 0, false);
846
- $[28] = t14;
847
- } else {
848
- t14 = $[28];
849
- }
850
- let t15;
851
- if ($[29] !== t) {
852
- t15 = t("Find table…");
853
- $[29] = t;
854
- $[30] = t15;
855
- } else {
856
- t15 = $[30];
857
- }
858
- const t16 = `${testIdPrefix}-find`;
859
- let t17;
860
- if ($[31] !== t) {
861
- t17 = t("Find table…");
862
- $[31] = t;
863
- $[32] = t17;
864
- } else {
865
- t17 = $[32];
866
- }
867
- let t18;
868
- if ($[33] !== query || $[34] !== t15 || $[35] !== t16 || $[36] !== t17) {
869
- t18 = /* @__PURE__ */ jsxDEV(Input, {
870
- "aria-label": t15,
871
- className: "h-7 w-44 text-xs",
872
- "data-testid": t16,
873
- onChange: onQueryChange,
874
- placeholder: t17,
875
- value: query
876
- }, void 0, false);
877
- $[33] = query;
878
- $[34] = t15;
879
- $[35] = t16;
880
- $[36] = t17;
881
- $[37] = t18;
882
- } else {
883
- t18 = $[37];
884
- }
885
- let t19;
886
- if ($[38] !== t) {
887
- t19 = t("Storage tiers");
888
- $[38] = t;
889
- $[39] = t19;
890
- } else {
891
- t19 = $[39];
892
- }
893
- const t20 = `${testIdPrefix}-tier-shard`;
894
- const t21 = tierFilter.shard ? "default" : "outline";
895
- let t22;
896
- if ($[40] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
897
- t22 = /* @__PURE__ */ jsxDEV("span", {
898
- "aria-hidden": "true",
899
- className: "size-1.5 rounded-full",
900
- style: SHARD_DOT_STYLE
901
- }, void 0, false);
902
- $[40] = t22;
903
- } else {
904
- t22 = $[40];
905
- }
906
- let t23;
907
- if ($[41] !== t20 || $[42] !== t21 || $[43] !== tierFilter.shard) {
908
- t23 = /* @__PURE__ */ jsxDEV(Button, {
909
- "aria-pressed": tierFilter.shard,
910
- className: "gap-1.5",
911
- "data-testid": t20,
912
- onClick: toggleShard,
913
- size: "xs",
914
- type: "button",
915
- variant: t21,
916
- children: [t22, TIER_META.shard.label]
917
- }, void 0, true);
918
- $[41] = t20;
919
- $[42] = t21;
920
- $[43] = tierFilter.shard;
921
- $[44] = t23;
922
- } else {
923
- t23 = $[44];
924
- }
925
- const t24 = `${testIdPrefix}-tier-global`;
926
- const t25 = tierFilter.global ? "default" : "outline";
927
- let t26;
928
- if ($[45] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
929
- t26 = /* @__PURE__ */ jsxDEV("span", {
930
- "aria-hidden": "true",
931
- className: "size-1.5 rounded-full",
932
- style: GLOBAL_DOT_STYLE
933
- }, void 0, false);
934
- $[45] = t26;
935
- } else {
936
- t26 = $[45];
937
- }
938
- let t27;
939
- if ($[46] !== t24 || $[47] !== t25 || $[48] !== tierFilter.global) {
940
- t27 = /* @__PURE__ */ jsxDEV(Button, {
941
- "aria-pressed": tierFilter.global,
942
- className: "gap-1.5",
943
- "data-testid": t24,
944
- onClick: toggleGlobal,
945
- size: "xs",
946
- type: "button",
947
- variant: t25,
948
- children: [t26, TIER_META.global.label]
949
- }, void 0, true);
950
- $[46] = t24;
951
- $[47] = t25;
952
- $[48] = tierFilter.global;
953
- $[49] = t27;
954
- } else {
955
- t27 = $[49];
956
- }
957
- let t28;
958
- if ($[50] !== t19 || $[51] !== t23 || $[52] !== t27) {
959
- t28 = /* @__PURE__ */ jsxDEV("div", {
960
- "aria-label": t19,
961
- className: "flex items-center gap-1.5",
962
- role: "group",
963
- children: [t23, t27]
964
- }, void 0, true);
965
- $[50] = t19;
966
- $[51] = t23;
967
- $[52] = t27;
968
- $[53] = t28;
969
- } else {
970
- t28 = $[53];
971
- }
972
- let t29;
973
- if ($[54] !== t18 || $[55] !== t28) {
974
- t29 = /* @__PURE__ */ jsxDEV(Panel, {
975
- position: "top-left",
976
- children: /* @__PURE__ */ jsxDEV("div", {
977
- className: "flex flex-col gap-2 rounded-xl border border-border bg-card/95 p-2 shadow-xs",
978
- children: [t18, t28]
979
- }, void 0, true)
980
- }, void 0, false);
981
- $[54] = t18;
982
- $[55] = t28;
983
- $[56] = t29;
984
- } else {
985
- t29 = $[56];
986
- }
987
- let t30;
988
- let t31;
989
- let t32;
990
- if ($[57] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
991
- t30 = /* @__PURE__ */ jsxDEV(Panel, {
992
- position: "bottom-left",
993
- children: /* @__PURE__ */ jsxDEV(Legend, {}, void 0, false)
994
- }, void 0, false);
995
- t31 = /* @__PURE__ */ jsxDEV(Controls, {
996
- showInteractive: false
997
- }, void 0, false);
998
- t32 = /* @__PURE__ */ jsxDEV(MiniMap, {
999
- pannable: true,
1000
- zoomable: true
1001
- }, void 0, false);
1002
- $[57] = t30;
1003
- $[58] = t31;
1004
- $[59] = t32;
1005
- } else {
1006
- t30 = $[57];
1007
- t31 = $[58];
1008
- t32 = $[59];
1009
- }
1010
- let t33;
1011
- if ($[60] !== testIdPrefix) {
1012
- t33 = /* @__PURE__ */ jsxDEV(DiagramExportPanel, {
1013
- containerRef: canvasRef,
1014
- testIdPrefix
1015
- }, void 0, false);
1016
- $[60] = testIdPrefix;
1017
- $[61] = t33;
1018
- } else {
1019
- t33 = $[61];
1020
- }
1021
- let t34;
1022
- if ($[62] !== flowEdges || $[63] !== nodes || $[64] !== onEdgesChange || $[65] !== onNodesChange || $[66] !== t29 || $[67] !== t33) {
1023
- t34 = /* @__PURE__ */ jsxDEV(ReactFlow, {
1024
- edges: flowEdges,
1025
- elementsSelectable: true,
1026
- fitView: true,
1027
- minZoom: 0.2,
1028
- nodes,
1029
- nodesConnectable: false,
1030
- nodeTypes: NODE_TYPES,
1031
- onEdgesChange,
1032
- onNodesChange,
1033
- children: [t14, t29, t30, t31, t32, t33]
1034
- }, void 0, true);
1035
- $[62] = flowEdges;
1036
- $[63] = nodes;
1037
- $[64] = onEdgesChange;
1038
- $[65] = onNodesChange;
1039
- $[66] = t29;
1040
- $[67] = t33;
1041
- $[68] = t34;
1042
- } else {
1043
- t34 = $[68];
1044
- }
1045
- let t35;
1046
- if ($[69] !== t13 || $[70] !== t34) {
1047
- t35 = /* @__PURE__ */ jsxDEV("div", {
1048
- className: "h-[560px] w-full overflow-hidden rounded-xl border border-border bg-muted/20 shadow-xs",
1049
- "data-testid": t13,
1050
- ref: canvasRef,
1051
- children: t34
1052
- }, void 0, false);
1053
- $[69] = t13;
1054
- $[70] = t34;
1055
- $[71] = t35;
1056
- } else {
1057
- t35 = $[71];
1058
- }
1059
- let t36;
1060
- if ($[72] !== t12 || $[73] !== t35) {
1061
- t36 = /* @__PURE__ */ jsxDEV("section", {
1062
- className: "flex flex-col gap-2",
1063
- "data-testid": t12,
1064
- children: t35
1065
- }, void 0, false);
1066
- $[72] = t12;
1067
- $[73] = t35;
1068
- $[74] = t36;
1069
- } else {
1070
- t36 = $[74];
1071
- }
1072
- return t36;
1073
- };
1074
- function _temp$1(previous) {
1075
- return {
1076
- ...previous,
1077
- shard: !previous.shard
1078
- };
1079
- }
1080
- function _temp2$1(previous_0) {
1081
- return {
1082
- ...previous_0,
1083
- global: !previous_0.global
1084
- };
1085
- }
1086
-
1087
- const SCHEMA_EDIT_ENDPOINT = "/__lunora/schema-edit";
1088
- const applyEdit = async (edit) => {
1089
- const response = await fetch(SCHEMA_EDIT_ENDPOINT, {
1090
- body: JSON.stringify(edit),
1091
- // `Content-Type: application/json` is non-simple and forces a CORS preflight
1092
- // for cross-origin fetches, preventing CSRF via the browser's same-origin
1093
- // policy. `X-Lunora-Studio` is an additional custom header that also triggers
1094
- // a preflight and lets the server-side guard identify studio traffic; both
1095
- // headers are checked by the `@lunora/config` `csrfRejectionReason` guard.
1096
- headers: {
1097
- "Content-Type": "application/json",
1098
- "X-Lunora-Studio": "1"
1099
- },
1100
- method: "POST"
1101
- });
1102
- const body = await response.json();
1103
- if (body.needsMigration === true) {
1104
- return {
1105
- kind: "needs-migration",
1106
- message: body.message ?? "This edit needs a migration."
1107
- };
1108
- }
1109
- if (response.ok && body.tables !== void 0) {
1110
- return {
1111
- diagnostics: body.diagnostics ?? [],
1112
- kind: "ok",
1113
- tables: body.tables
1114
- };
1115
- }
1116
- return {
1117
- kind: "error",
1118
- message: body.error ?? `schema edit failed (${String(response.status)})`
1119
- };
1120
- };
1121
-
1122
- const COLUMN_TYPES = [{
1123
- label: "string",
1124
- validator: "v.string()"
1125
- }, {
1126
- label: "number",
1127
- validator: "v.number()"
1128
- }, {
1129
- label: "boolean",
1130
- validator: "v.boolean()"
1131
- }, {
1132
- label: "bigint",
1133
- validator: "v.int64()"
1134
- }, {
1135
- label: "bytes",
1136
- validator: "v.bytes()"
1137
- }, {
1138
- label: "any",
1139
- validator: "v.any()"
1140
- }];
1141
- const DEFAULT_VALIDATOR = "v.string()";
1142
- const splitFields = (raw) => raw.split(",").map((field) => field.trim()).filter((field) => field !== "");
1143
- const SchemaEditorOverlay = ({
1144
- onApplied,
1145
- tableNames
1146
- }) => {
1147
- const t = useT();
1148
- const navigate = useNavigate();
1149
- const [mode, setMode] = useState(null);
1150
- const [busy, setBusy] = useState(false);
1151
- const [result, setResult] = useState(null);
1152
- const [tableName, setTableName] = useState("");
1153
- const [columnName, setColumnName] = useState("");
1154
- const [validator, setValidator] = useState(DEFAULT_VALIDATOR);
1155
- const [targetTable, setTargetTable] = useState(tableNames[0] ?? "");
1156
- const [indexName, setIndexName] = useState("");
1157
- const [indexFields, setIndexFields] = useState("");
1158
- const [unique, setUnique] = useState(false);
1159
- const reset = () => {
1160
- setMode(null);
1161
- setTableName("");
1162
- setColumnName("");
1163
- setIndexName("");
1164
- setIndexFields("");
1165
- setUnique(false);
1166
- };
1167
- const submit = async (edit) => {
1168
- setBusy(true);
1169
- setResult(null);
1170
- try {
1171
- const outcome = await applyEdit(edit);
1172
- setResult(outcome);
1173
- if (outcome.kind === "ok") {
1174
- onApplied(outcome.tables);
1175
- reset();
1176
- }
1177
- } catch (error) {
1178
- setResult({
1179
- kind: "error",
1180
- message: error instanceof Error ? error.message : String(error)
1181
- });
1182
- } finally {
1183
- setBusy(false);
1184
- }
1185
- };
1186
- const onSubmitTable = () => {
1187
- fireAndForget(submit({
1188
- kind: "addTable",
1189
- table: tableName.trim()
1190
- }));
1191
- };
1192
- const onSubmitColumn = () => {
1193
- fireAndForget(submit({
1194
- column: columnName.trim(),
1195
- kind: "addOptionalColumn",
1196
- table: targetTable,
1197
- validator
1198
- }));
1199
- };
1200
- const onSubmitIndex = () => {
1201
- fireAndForget(submit({
1202
- fields: splitFields(indexFields),
1203
- kind: "addIndex",
1204
- name: indexName.trim(),
1205
- table: targetTable,
1206
- unique
1207
- }));
1208
- };
1209
- const openTable = () => {
1210
- setResult(null);
1211
- setMode("addTable");
1212
- };
1213
- const openColumn = () => {
1214
- setResult(null);
1215
- setMode("addColumn");
1216
- };
1217
- const openIndex = () => {
1218
- setResult(null);
1219
- setMode("addIndex");
1220
- };
1221
- const openDestructive = () => {
1222
- setMode("destructive");
1223
- setResult({
1224
- kind: "needs-migration",
1225
- message: t("This edit changes stored data and must go through a migration. Review the migration before applying.")
1226
- });
1227
- };
1228
- const onTableNameChange = (event) => {
1229
- setTableName(event.target.value);
1230
- };
1231
- const onColumnNameChange = (event_0) => {
1232
- setColumnName(event_0.target.value);
1233
- };
1234
- const onValidatorChange = (event_1) => {
1235
- setValidator(event_1.target.value);
1236
- };
1237
- const onTargetTableChange = (event_2) => {
1238
- setTargetTable(event_2.target.value);
1239
- };
1240
- const onIndexNameChange = (event_3) => {
1241
- setIndexName(event_3.target.value);
1242
- };
1243
- const onIndexFieldsChange = (event_4) => {
1244
- setIndexFields(event_4.target.value);
1245
- };
1246
- const onUniqueChange = (event_5) => {
1247
- setUnique(event_5.target.checked);
1248
- };
1249
- const onOpenMigrations = () => {
1250
- fireAndForget(navigate({
1251
- to: "/migrations"
1252
- }));
1253
- };
1254
- return /* @__PURE__ */ jsxDEV(Card, {
1255
- "data-testid": "sc-editor",
1256
- size: "sm",
1257
- children: [/* @__PURE__ */ jsxDEV(CardHeader, {
1258
- children: [/* @__PURE__ */ jsxDEV(CardTitle, {
1259
- children: t("Edit schema")
1260
- }, void 0, false), /* @__PURE__ */ jsxDEV(CardDescription, {
1261
- children: t("Adds a table, column, or index to lunora/schema.ts and reruns codegen.")
1262
- }, void 0, false)]
1263
- }, void 0, true), /* @__PURE__ */ jsxDEV(CardContent, {
1264
- children: [/* @__PURE__ */ jsxDEV("div", {
1265
- className: "flex flex-wrap gap-2",
1266
- children: [/* @__PURE__ */ jsxDEV(Button, {
1267
- "data-testid": "sc-editor-add-table",
1268
- onClick: openTable,
1269
- size: "xs",
1270
- type: "button",
1271
- variant: mode === "addTable" ? "default" : "outline",
1272
- children: t("Add table")
1273
- }, void 0, false), /* @__PURE__ */ jsxDEV(Button, {
1274
- "data-testid": "sc-editor-add-column",
1275
- disabled: tableNames.length === 0,
1276
- onClick: openColumn,
1277
- size: "xs",
1278
- type: "button",
1279
- variant: mode === "addColumn" ? "default" : "outline",
1280
- children: t("Add column")
1281
- }, void 0, false), /* @__PURE__ */ jsxDEV(Button, {
1282
- "data-testid": "sc-editor-add-index",
1283
- disabled: tableNames.length === 0,
1284
- onClick: openIndex,
1285
- size: "xs",
1286
- type: "button",
1287
- variant: mode === "addIndex" ? "default" : "outline",
1288
- children: t("Add index")
1289
- }, void 0, false), /* @__PURE__ */ jsxDEV(Button, {
1290
- "data-testid": "sc-editor-destructive",
1291
- disabled: tableNames.length === 0,
1292
- onClick: openDestructive,
1293
- size: "xs",
1294
- type: "button",
1295
- variant: mode === "destructive" ? "default" : "ghost",
1296
- children: t("Rename / drop / change type…")
1297
- }, void 0, false)]
1298
- }, void 0, true), mode === "addTable" && /* @__PURE__ */ jsxDEV("div", {
1299
- className: "mt-3 flex flex-wrap items-end gap-2",
1300
- "data-testid": "sc-editor-table-form",
1301
- children: [/* @__PURE__ */ jsxDEV("div", {
1302
- className: "flex flex-col gap-1 text-xs",
1303
- children: [/* @__PURE__ */ jsxDEV(Label, {
1304
- htmlFor: "sc-editor-table-name",
1305
- children: t("Table name")
1306
- }, void 0, false), /* @__PURE__ */ jsxDEV(Input, {
1307
- "data-testid": "sc-editor-table-name",
1308
- id: "sc-editor-table-name",
1309
- onChange: onTableNameChange,
1310
- value: tableName
1311
- }, void 0, false)]
1312
- }, void 0, true), /* @__PURE__ */ jsxDEV(Button, {
1313
- "data-testid": "sc-editor-table-apply",
1314
- disabled: busy || tableName.trim() === "",
1315
- onClick: onSubmitTable,
1316
- size: "xs",
1317
- type: "button",
1318
- children: busy ? t("Applying…") : t("Apply")
1319
- }, void 0, false), /* @__PURE__ */ jsxDEV(Button, {
1320
- onClick: reset,
1321
- size: "xs",
1322
- type: "button",
1323
- variant: "ghost",
1324
- children: t("Cancel")
1325
- }, void 0, false)]
1326
- }, void 0, true), mode === "addColumn" && /* @__PURE__ */ jsxDEV("div", {
1327
- className: "mt-3 flex flex-wrap items-end gap-2",
1328
- "data-testid": "sc-editor-column-form",
1329
- children: [/* @__PURE__ */ jsxDEV("div", {
1330
- className: "flex flex-col gap-1 text-xs",
1331
- children: [/* @__PURE__ */ jsxDEV(Label, {
1332
- htmlFor: "sc-editor-column-table",
1333
- children: t("Table name")
1334
- }, void 0, false), /* @__PURE__ */ jsxDEV("select", {
1335
- className: "h-8 rounded-md border border-input bg-transparent px-2 text-xs",
1336
- "data-testid": "sc-editor-column-table",
1337
- id: "sc-editor-column-table",
1338
- onChange: onTargetTableChange,
1339
- value: targetTable,
1340
- children: tableNames.map((name) => /* @__PURE__ */ jsxDEV("option", {
1341
- value: name,
1342
- children: name
1343
- }, name, false))
1344
- }, void 0, false)]
1345
- }, void 0, true), /* @__PURE__ */ jsxDEV("div", {
1346
- className: "flex flex-col gap-1 text-xs",
1347
- children: [/* @__PURE__ */ jsxDEV(Label, {
1348
- htmlFor: "sc-editor-column-name",
1349
- children: t("Column name")
1350
- }, void 0, false), /* @__PURE__ */ jsxDEV(Input, {
1351
- "data-testid": "sc-editor-column-name",
1352
- id: "sc-editor-column-name",
1353
- onChange: onColumnNameChange,
1354
- value: columnName
1355
- }, void 0, false)]
1356
- }, void 0, true), /* @__PURE__ */ jsxDEV("div", {
1357
- className: "flex flex-col gap-1 text-xs",
1358
- children: [/* @__PURE__ */ jsxDEV(Label, {
1359
- htmlFor: "sc-editor-column-type",
1360
- children: t("Column type")
1361
- }, void 0, false), /* @__PURE__ */ jsxDEV("select", {
1362
- className: "h-8 rounded-md border border-input bg-transparent px-2 text-xs",
1363
- "data-testid": "sc-editor-column-type",
1364
- id: "sc-editor-column-type",
1365
- onChange: onValidatorChange,
1366
- value: validator,
1367
- children: COLUMN_TYPES.map((type) => /* @__PURE__ */ jsxDEV("option", {
1368
- value: type.validator,
1369
- children: type.label
1370
- }, type.validator, false))
1371
- }, void 0, false)]
1372
- }, void 0, true), /* @__PURE__ */ jsxDEV("span", {
1373
- className: "text-[11px] text-muted-foreground",
1374
- children: t("Optional")
1375
- }, void 0, false), /* @__PURE__ */ jsxDEV(Button, {
1376
- "data-testid": "sc-editor-column-apply",
1377
- disabled: busy || columnName.trim() === "" || targetTable === "",
1378
- onClick: onSubmitColumn,
1379
- size: "xs",
1380
- type: "button",
1381
- children: busy ? t("Applying…") : t("Apply")
1382
- }, void 0, false), /* @__PURE__ */ jsxDEV(Button, {
1383
- onClick: reset,
1384
- size: "xs",
1385
- type: "button",
1386
- variant: "ghost",
1387
- children: t("Cancel")
1388
- }, void 0, false)]
1389
- }, void 0, true), mode === "addIndex" && /* @__PURE__ */ jsxDEV("div", {
1390
- className: "mt-3 flex flex-wrap items-end gap-2",
1391
- "data-testid": "sc-editor-index-form",
1392
- children: [/* @__PURE__ */ jsxDEV("div", {
1393
- className: "flex flex-col gap-1 text-xs",
1394
- children: [/* @__PURE__ */ jsxDEV(Label, {
1395
- htmlFor: "sc-editor-index-table",
1396
- children: t("Table name")
1397
- }, void 0, false), /* @__PURE__ */ jsxDEV("select", {
1398
- className: "h-8 rounded-md border border-input bg-transparent px-2 text-xs",
1399
- "data-testid": "sc-editor-index-table",
1400
- id: "sc-editor-index-table",
1401
- onChange: onTargetTableChange,
1402
- value: targetTable,
1403
- children: tableNames.map((name_0) => /* @__PURE__ */ jsxDEV("option", {
1404
- value: name_0,
1405
- children: name_0
1406
- }, name_0, false))
1407
- }, void 0, false)]
1408
- }, void 0, true), /* @__PURE__ */ jsxDEV("div", {
1409
- className: "flex flex-col gap-1 text-xs",
1410
- children: [/* @__PURE__ */ jsxDEV(Label, {
1411
- htmlFor: "sc-editor-index-name",
1412
- children: t("Index name")
1413
- }, void 0, false), /* @__PURE__ */ jsxDEV(Input, {
1414
- "data-testid": "sc-editor-index-name",
1415
- id: "sc-editor-index-name",
1416
- onChange: onIndexNameChange,
1417
- value: indexName
1418
- }, void 0, false)]
1419
- }, void 0, true), /* @__PURE__ */ jsxDEV("div", {
1420
- className: "flex flex-col gap-1 text-xs",
1421
- children: [/* @__PURE__ */ jsxDEV(Label, {
1422
- htmlFor: "sc-editor-index-fields",
1423
- children: t("Index fields (comma-separated)")
1424
- }, void 0, false), /* @__PURE__ */ jsxDEV(Input, {
1425
- "data-testid": "sc-editor-index-fields",
1426
- id: "sc-editor-index-fields",
1427
- onChange: onIndexFieldsChange,
1428
- value: indexFields
1429
- }, void 0, false)]
1430
- }, void 0, true), /* @__PURE__ */ jsxDEV(Label, {
1431
- className: "flex items-center gap-1 text-xs",
1432
- htmlFor: "sc-editor-index-unique",
1433
- children: [/* @__PURE__ */ jsxDEV("input", {
1434
- checked: unique,
1435
- "data-testid": "sc-editor-index-unique",
1436
- id: "sc-editor-index-unique",
1437
- onChange: onUniqueChange,
1438
- type: "checkbox"
1439
- }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
1440
- className: "text-muted-foreground",
1441
- children: t("Unique")
1442
- }, void 0, false)]
1443
- }, void 0, true), /* @__PURE__ */ jsxDEV(Button, {
1444
- "data-testid": "sc-editor-index-apply",
1445
- disabled: busy || indexName.trim() === "" || indexFields.trim() === "",
1446
- onClick: onSubmitIndex,
1447
- size: "xs",
1448
- type: "button",
1449
- children: busy ? t("Applying…") : t("Apply")
1450
- }, void 0, false), /* @__PURE__ */ jsxDEV(Button, {
1451
- onClick: reset,
1452
- size: "xs",
1453
- type: "button",
1454
- variant: "ghost",
1455
- children: t("Cancel")
1456
- }, void 0, false)]
1457
- }, void 0, true), result?.kind === "error" && /* @__PURE__ */ jsxDEV("p", {
1458
- className: "mt-3 text-sm text-destructive",
1459
- "data-testid": "sc-editor-error",
1460
- role: "alert",
1461
- children: result.message
1462
- }, void 0, false), result?.kind === "needs-migration" && /* @__PURE__ */ jsxDEV("div", {
1463
- className: "mt-3 flex flex-col gap-2",
1464
- "data-testid": "sc-editor-needs-migration",
1465
- children: [/* @__PURE__ */ jsxDEV("p", {
1466
- className: "text-sm text-warning",
1467
- role: "alert",
1468
- children: t("This edit changes stored data and must go through a migration. Review the migration before applying.")
1469
- }, void 0, false), /* @__PURE__ */ jsxDEV(Button, {
1470
- className: "self-start",
1471
- "data-testid": "sc-editor-open-migrations",
1472
- onClick: onOpenMigrations,
1473
- size: "xs",
1474
- type: "button",
1475
- variant: "outline",
1476
- children: t("Open Migrations")
1477
- }, void 0, false)]
1478
- }, void 0, true), result?.kind === "ok" && result.diagnostics.length > 0 && /* @__PURE__ */ jsxDEV("div", {
1479
- className: "mt-3 flex flex-col gap-1",
1480
- "data-testid": "sc-editor-diagnostics",
1481
- children: [/* @__PURE__ */ jsxDEV("p", {
1482
- className: "text-sm text-destructive",
1483
- role: "alert",
1484
- children: t("Codegen reported diagnostics:")
1485
- }, void 0, false), /* @__PURE__ */ jsxDEV("ul", {
1486
- className: "flex flex-col gap-0.5",
1487
- children: result.diagnostics.map((diagnostic) => /* @__PURE__ */ jsxDEV("li", {
1488
- className: "font-mono text-[11px] text-destructive",
1489
- children: diagnostic
1490
- }, diagnostic, false))
1491
- }, void 0, false)]
1492
- }, void 0, true)]
1493
- }, void 0, true)]
1494
- }, void 0, true);
1495
- };
1496
-
1497
- const LIST_TABLES = adminRef(ADMIN_FUNCTIONS.listTables);
1498
- const LIST_TABLE_INDEXES = adminRef(ADMIN_FUNCTIONS.listTableIndexes);
1499
- const READ_TABLE_PAGE = adminRef(ADMIN_FUNCTIONS.readTablePage);
1500
- const DESCRIBE_TABLES = adminRef(ADMIN_FUNCTIONS.describeTables);
1501
- const EMPTY_COLUMNS = {};
1502
- const EMPTY_COLUMN_NAMES = [];
1503
- const EMPTY_COLUMN_META = [];
1504
- const ChevronIcon = (t0) => {
1505
- const $ = c(5);
1506
- const {
1507
- open
1508
- } = t0;
1509
- const t1 = open && "rotate-90";
1510
- let t2;
1511
- if ($[0] !== t1) {
1512
- t2 = cn("size-3.5 shrink-0 text-muted-foreground transition-transform duration-150", t1);
1513
- $[0] = t1;
1514
- $[1] = t2;
1515
- } else {
1516
- t2 = $[1];
1517
- }
1518
- let t3;
1519
- if ($[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1520
- t3 = /* @__PURE__ */ jsxDEV("path", {
1521
- d: "m9 6 6 6-6 6"
1522
- }, void 0, false);
1523
- $[2] = t3;
1524
- } else {
1525
- t3 = $[2];
1526
- }
1527
- let t4;
1528
- if ($[3] !== t2) {
1529
- t4 = /* @__PURE__ */ jsxDEV("svg", {
1530
- "aria-hidden": "true",
1531
- className: t2,
1532
- fill: "none",
1533
- stroke: "currentColor",
1534
- strokeLinecap: "round",
1535
- strokeLinejoin: "round",
1536
- strokeWidth: 1.8,
1537
- viewBox: "0 0 24 24",
1538
- children: t3
1539
- }, void 0, false);
1540
- $[3] = t2;
1541
- $[4] = t4;
1542
- } else {
1543
- t4 = $[4];
1544
- }
1545
- return t4;
1546
- };
1547
- const TableEntry = (t0) => {
1548
- const $ = c(20);
1549
- const {
1550
- children,
1551
- expanded,
1552
- name,
1553
- onToggle,
1554
- rowCount,
1555
- rowTestId,
1556
- toggleTestId
1557
- } = t0;
1558
- let t1;
1559
- if ($[0] !== expanded) {
1560
- t1 = /* @__PURE__ */ jsxDEV(ChevronIcon, {
1561
- open: expanded
1562
- }, void 0, false);
1563
- $[0] = expanded;
1564
- $[1] = t1;
1565
- } else {
1566
- t1 = $[1];
1567
- }
1568
- let t2;
1569
- if ($[2] !== name) {
1570
- t2 = /* @__PURE__ */ jsxDEV("span", {
1571
- className: "truncate font-mono text-xs text-foreground",
1572
- title: name,
1573
- children: name
1574
- }, void 0, false);
1575
- $[2] = name;
1576
- $[3] = t2;
1577
- } else {
1578
- t2 = $[3];
1579
- }
1580
- let t3;
1581
- if ($[4] !== rowCount) {
1582
- t3 = /* @__PURE__ */ jsxDEV("span", {
1583
- className: "ms-auto shrink-0 text-xs text-muted-foreground tabular-nums",
1584
- children: ["(", rowCount, ")"]
1585
- }, void 0, true);
1586
- $[4] = rowCount;
1587
- $[5] = t3;
1588
- } else {
1589
- t3 = $[5];
1590
- }
1591
- let t4;
1592
- if ($[6] !== expanded || $[7] !== onToggle || $[8] !== t1 || $[9] !== t2 || $[10] !== t3 || $[11] !== toggleTestId) {
1593
- t4 = /* @__PURE__ */ jsxDEV("button", {
1594
- "aria-expanded": expanded,
1595
- className: "flex w-full items-center gap-2 px-3 py-2 text-start transition-colors hover:bg-muted/50 aria-expanded:bg-muted/40",
1596
- "data-testid": toggleTestId,
1597
- onClick: onToggle,
1598
- type: "button",
1599
- children: [t1, t2, " ", t3]
1600
- }, void 0, true);
1601
- $[6] = expanded;
1602
- $[7] = onToggle;
1603
- $[8] = t1;
1604
- $[9] = t2;
1605
- $[10] = t3;
1606
- $[11] = toggleTestId;
1607
- $[12] = t4;
1608
- } else {
1609
- t4 = $[12];
1610
- }
1611
- let t5;
1612
- if ($[13] !== children || $[14] !== expanded) {
1613
- t5 = expanded && /* @__PURE__ */ jsxDEV("div", {
1614
- className: "px-3 pb-3 ps-8",
1615
- children
1616
- }, void 0, false);
1617
- $[13] = children;
1618
- $[14] = expanded;
1619
- $[15] = t5;
1620
- } else {
1621
- t5 = $[15];
1622
- }
1623
- let t6;
1624
- if ($[16] !== rowTestId || $[17] !== t4 || $[18] !== t5) {
1625
- t6 = /* @__PURE__ */ jsxDEV("li", {
1626
- className: "border-t border-border/60 first:border-t-0",
1627
- "data-testid": rowTestId,
1628
- children: [t4, t5]
1629
- }, void 0, true);
1630
- $[16] = rowTestId;
1631
- $[17] = t4;
1632
- $[18] = t5;
1633
- $[19] = t6;
1634
- } else {
1635
- t6 = $[19];
1636
- }
1637
- return t6;
1638
- };
1639
- const ColumnChips = (t0) => {
1640
- const $ = c(5);
1641
- const {
1642
- columns,
1643
- testId
1644
- } = t0;
1645
- let t1;
1646
- if ($[0] !== columns) {
1647
- t1 = columns.map(_temp);
1648
- $[0] = columns;
1649
- $[1] = t1;
1650
- } else {
1651
- t1 = $[1];
1652
- }
1653
- let t2;
1654
- if ($[2] !== t1 || $[3] !== testId) {
1655
- t2 = /* @__PURE__ */ jsxDEV("ul", {
1656
- className: "flex flex-wrap gap-1.5 pt-1",
1657
- "data-testid": testId,
1658
- children: t1
1659
- }, void 0, false);
1660
- $[2] = t1;
1661
- $[3] = testId;
1662
- $[4] = t2;
1663
- } else {
1664
- t2 = $[4];
1665
- }
1666
- return t2;
1667
- };
1668
- const IndexList = (t0) => {
1669
- const $ = c(10);
1670
- const {
1671
- heading,
1672
- indexes,
1673
- testId
1674
- } = t0;
1675
- let t1;
1676
- if ($[0] !== heading) {
1677
- t1 = /* @__PURE__ */ jsxDEV("p", {
1678
- className: "mb-1.5 font-mono text-[10px] tracking-wide text-muted-foreground uppercase",
1679
- children: heading
1680
- }, void 0, false);
1681
- $[0] = heading;
1682
- $[1] = t1;
1683
- } else {
1684
- t1 = $[1];
1685
- }
1686
- let t2;
1687
- if ($[2] !== indexes) {
1688
- t2 = indexes.map(_temp2);
1689
- $[2] = indexes;
1690
- $[3] = t2;
1691
- } else {
1692
- t2 = $[3];
1693
- }
1694
- let t3;
1695
- if ($[4] !== t2 || $[5] !== testId) {
1696
- t3 = /* @__PURE__ */ jsxDEV("ul", {
1697
- className: "flex flex-col gap-1",
1698
- "data-testid": testId,
1699
- children: t2
1700
- }, void 0, false);
1701
- $[4] = t2;
1702
- $[5] = testId;
1703
- $[6] = t3;
1704
- } else {
1705
- t3 = $[6];
1706
- }
1707
- let t4;
1708
- if ($[7] !== t1 || $[8] !== t3) {
1709
- t4 = /* @__PURE__ */ jsxDEV("div", {
1710
- className: "pt-3",
1711
- children: [t1, t3]
1712
- }, void 0, true);
1713
- $[7] = t1;
1714
- $[8] = t3;
1715
- $[9] = t4;
1716
- } else {
1717
- t4 = $[9];
1718
- }
1719
- return t4;
1720
- };
1721
- const SchemaViewer = (t0) => {
1722
- const $ = c(126);
1723
- const {
1724
- initialShardKey,
1725
- initialTable,
1726
- schemaEditable
1727
- } = t0;
1728
- const client = useLunora();
1729
- const t = useT();
1730
- const [view, setView] = useState("list");
1731
- const [shardKey, setShardKey] = useState(initialShardKey ?? "");
1732
- const [tableFilter, setTableFilter] = useState("");
1733
- const [tables, setTables] = useState(null);
1734
- const [error, setError] = useState(null);
1735
- let t1;
1736
- if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1737
- t1 = {};
1738
- $[0] = t1;
1739
- } else {
1740
- t1 = $[0];
1741
- }
1742
- const [columns, setColumns] = useState(t1);
1743
- let t2;
1744
- if ($[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1745
- t2 = {};
1746
- $[1] = t2;
1747
- } else {
1748
- t2 = $[1];
1749
- }
1750
- const [indexes, setIndexes] = useState(t2);
1751
- const [expanded, setExpanded] = useState(null);
1752
- let t3;
1753
- if ($[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1754
- t3 = {};
1755
- $[2] = t3;
1756
- } else {
1757
- t3 = $[2];
1758
- }
1759
- const [shardColumns, setShardColumns] = useState(t3);
1760
- let t4;
1761
- if ($[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1762
- t4 = {};
1763
- $[3] = t4;
1764
- } else {
1765
- t4 = $[3];
1766
- }
1767
- const [shardColumnsError, setShardColumnsError] = useState(t4);
1768
- const [globalTables, setGlobalTables] = useState(null);
1769
- const [globalError, setGlobalError] = useState(null);
1770
- let t5;
1771
- if ($[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1772
- t5 = {};
1773
- $[4] = t5;
1774
- } else {
1775
- t5 = $[4];
1776
- }
1777
- const [globalColumns, setGlobalColumns] = useState(t5);
1778
- const [globalExpanded, setGlobalExpanded] = useState(null);
1779
- let t6;
1780
- if ($[5] !== client) {
1781
- t6 = async (shard) => {
1782
- setError(null);
1783
- try {
1784
- const result = await client.query(LIST_TABLES, {}, callOptions(shard));
1785
- recordShard(shard);
1786
- setTables(result);
1787
- setColumns({});
1788
- setIndexes({});
1789
- setExpanded(null);
1790
- setShardColumns((previous) => Object.fromEntries(Object.entries(previous).filter((t82) => {
1791
- const [cachedShard] = t82;
1792
- return cachedShard !== shard;
1793
- })));
1794
- setShardColumnsError((previous_0) => Object.fromEntries(Object.entries(previous_0).filter((t92) => {
1795
- const [cachedShard_0] = t92;
1796
- return cachedShard_0 !== shard;
1797
- })));
1798
- } catch (t72) {
1799
- const error_ = t72;
1800
- setTables(null);
1801
- setError(errorMessage(error_));
1802
- }
1803
- };
1804
- $[5] = client;
1805
- $[6] = t6;
1806
- } else {
1807
- t6 = $[6];
1808
- }
1809
- const refresh = t6;
1810
- let t7;
1811
- if ($[7] !== client) {
1812
- t7 = async () => {
1813
- setGlobalError(null);
1814
- try {
1815
- setGlobalTables(await client.listGlobalTables());
1816
- } catch (t82) {
1817
- const error__0 = t82;
1818
- setGlobalTables(null);
1819
- setGlobalError(errorMessage(error__0));
1820
- }
1821
- };
1822
- $[7] = client;
1823
- $[8] = t7;
1824
- } else {
1825
- t7 = $[8];
1826
- }
1827
- const refreshGlobal = t7;
1828
- let t8;
1829
- if ($[9] !== shardKey) {
1830
- t8 = shardKey.trim();
1831
- $[9] = shardKey;
1832
- $[10] = t8;
1833
- } else {
1834
- t8 = $[10];
1835
- }
1836
- const debouncedShard = useDebounced(t8, 400);
1837
- let t10;
1838
- let t9;
1839
- if ($[11] !== debouncedShard || $[12] !== refresh || $[13] !== refreshGlobal) {
1840
- t9 = () => {
1841
- fireAndForget(refresh(debouncedShard));
1842
- fireAndForget(refreshGlobal());
1843
- };
1844
- t10 = [refresh, refreshGlobal, debouncedShard];
1845
- $[11] = debouncedShard;
1846
- $[12] = refresh;
1847
- $[13] = refreshGlobal;
1848
- $[14] = t10;
1849
- $[15] = t9;
1850
- } else {
1851
- t10 = $[14];
1852
- t9 = $[15];
1853
- }
1854
- useEffect(t9, t10);
1855
- let t11;
1856
- if ($[16] !== client || $[17] !== columns || $[18] !== expanded || $[19] !== shardKey) {
1857
- t11 = async (table) => {
1858
- if (expanded === table) {
1859
- setExpanded(null);
1860
- return;
1861
- }
1862
- setExpanded(table);
1863
- const cacheKey = `${shardKey}:${table}`;
1864
- if (columns[cacheKey] !== void 0) {
1865
- return;
1866
- }
1867
- const [page, indexResult] = await Promise.allSettled([client.query(READ_TABLE_PAGE, {
1868
- limit: 1,
1869
- offset: 0,
1870
- table
1871
- }, callOptions(shardKey)), client.query(LIST_TABLE_INDEXES, {
1872
- table
1873
- }, callOptions(shardKey))]);
1874
- if (page.status === "fulfilled") {
1875
- setColumns((previous_1) => ({
1876
- ...previous_1,
1877
- [cacheKey]: page.value.columns
1878
- }));
1879
- } else {
1880
- setError(errorMessage(page.reason));
1881
- }
1882
- if (indexResult.status === "fulfilled") {
1883
- setIndexes((previous_2) => ({
1884
- ...previous_2,
1885
- [cacheKey]: indexResult.value.indexes
1886
- }));
1887
- }
1888
- };
1889
- $[16] = client;
1890
- $[17] = columns;
1891
- $[18] = expanded;
1892
- $[19] = shardKey;
1893
- $[20] = t11;
1894
- } else {
1895
- t11 = $[20];
1896
- }
1897
- const toggle = t11;
1898
- let t12;
1899
- if ($[21] !== client || $[22] !== globalColumns || $[23] !== globalExpanded) {
1900
- t12 = async (table_0) => {
1901
- if (globalExpanded === table_0) {
1902
- setGlobalExpanded(null);
1903
- return;
1904
- }
1905
- setGlobalExpanded(table_0);
1906
- if (globalColumns[table_0] !== void 0) {
1907
- return;
1908
- }
1909
- try {
1910
- const page_0 = await client.readGlobalTablePage({
1911
- limit: 1,
1912
- offset: 0,
1913
- table: table_0
1914
- });
1915
- setGlobalColumns((previous_3) => ({
1916
- ...previous_3,
1917
- [table_0]: page_0.columns
1918
- }));
1919
- } catch (t132) {
1920
- const error__1 = t132;
1921
- setGlobalError(errorMessage(error__1));
1922
- }
1923
- };
1924
- $[21] = client;
1925
- $[22] = globalColumns;
1926
- $[23] = globalExpanded;
1927
- $[24] = t12;
1928
- } else {
1929
- t12 = $[24];
1930
- }
1931
- const toggleGlobal = t12;
1932
- const appliedTable = useRef(void 0);
1933
- let t13;
1934
- let t14;
1935
- if ($[25] !== initialTable || $[26] !== tables || $[27] !== toggle) {
1936
- t13 = () => {
1937
- if (initialTable === void 0 || tables === null || appliedTable.current === initialTable) {
1938
- return;
1939
- }
1940
- if (tables.some((table_1) => table_1.name === initialTable)) {
1941
- appliedTable.current = initialTable;
1942
- fireAndForget(toggle(initialTable));
1943
- }
1944
- };
1945
- t14 = [initialTable, tables, toggle];
1946
- $[25] = initialTable;
1947
- $[26] = tables;
1948
- $[27] = toggle;
1949
- $[28] = t13;
1950
- $[29] = t14;
1951
- } else {
1952
- t13 = $[28];
1953
- t14 = $[29];
1954
- }
1955
- useEffect(t13, t14);
1956
- let t15;
1957
- if ($[30] !== client) {
1958
- t15 = async (shard_0, shardNames, globalNames) => {
1959
- const [described, globalPages] = await Promise.all([Promise.allSettled([client.query(DESCRIBE_TABLES, {
1960
- tables: [...shardNames, ...globalNames]
1961
- }, callOptions(shard_0))]), Promise.all(globalNames.map(async (table_2) => {
1962
- const page_1 = await Promise.allSettled([client.readGlobalTablePage({
1963
- limit: 1,
1964
- offset: 0,
1965
- table: table_2
1966
- })]);
1967
- const value = page_1[0].status === "fulfilled" ? page_1[0].value : void 0;
1968
- return {
1969
- columns: value?.columns ?? [],
1970
- refs: value?.refs ?? {},
1971
- table: table_2
1972
- };
1973
- }))]);
1974
- const typedColumns = described[0].status === "fulfilled" ? described[0].value?.columnsByTable ?? {} : {};
1975
- const columnsFailed = described[0].status === "rejected";
1976
- const globalFallback = new Map(globalPages.map(_temp3));
1977
- const resolved = [...shardNames, ...globalNames].map((table_4) => {
1978
- const typed = typedColumns[table_4] ?? [];
1979
- return [table_4, typed.length > 0 ? typed : globalFallback.get(table_4) ?? []];
1980
- });
1981
- setShardColumns((previous_4) => ({
1982
- ...previous_4,
1983
- [shard_0]: Object.fromEntries(resolved)
1984
- }));
1985
- setShardColumnsError((previous_5) => ({
1986
- ...previous_5,
1987
- [shard_0]: columnsFailed
1988
- }));
1989
- };
1990
- $[30] = client;
1991
- $[31] = t15;
1992
- } else {
1993
- t15 = $[31];
1994
- }
1995
- const probeSchema = t15;
1996
- let t16;
1997
- let t17;
1998
- if ($[32] !== globalError || $[33] !== globalTables || $[34] !== probeSchema || $[35] !== shardColumns || $[36] !== shardKey || $[37] !== tables || $[38] !== view) {
1999
- t16 = () => {
2000
- if (view !== "graph" || tables === null || globalTables === null && globalError === null || shardColumns[shardKey] !== void 0) {
2001
- return;
2002
- }
2003
- fireAndForget(probeSchema(shardKey, tables.map(_temp4), (globalTables ?? []).map(_temp5)));
2004
- };
2005
- t17 = [view, tables, globalTables, globalError, shardKey, shardColumns, probeSchema];
2006
- $[32] = globalError;
2007
- $[33] = globalTables;
2008
- $[34] = probeSchema;
2009
- $[35] = shardColumns;
2010
- $[36] = shardKey;
2011
- $[37] = tables;
2012
- $[38] = view;
2013
- $[39] = t16;
2014
- $[40] = t17;
2015
- } else {
2016
- t16 = $[39];
2017
- t17 = $[40];
2018
- }
2019
- useEffect(t16, t17);
2020
- const columnsForShard = shardColumns[shardKey] ?? EMPTY_COLUMNS;
2021
- let t18;
2022
- if ($[41] !== columnsForShard || $[42] !== globalTables || $[43] !== tables) {
2023
- let t192;
2024
- if ($[45] !== columnsForShard) {
2025
- t192 = (table_7) => ({
2026
- columns: columnsForShard[table_7.name] ?? EMPTY_COLUMN_META,
2027
- name: table_7.name,
2028
- tier: "shard"
2029
- });
2030
- $[45] = columnsForShard;
2031
- $[46] = t192;
2032
- } else {
2033
- t192 = $[46];
2034
- }
2035
- const shardOnes = (tables ?? []).map(t192);
2036
- let t202;
2037
- if ($[47] !== columnsForShard) {
2038
- t202 = (table_8) => ({
2039
- columns: columnsForShard[table_8.name] ?? EMPTY_COLUMN_META,
2040
- name: table_8.name,
2041
- tier: "global"
2042
- });
2043
- $[47] = columnsForShard;
2044
- $[48] = t202;
2045
- } else {
2046
- t202 = $[48];
2047
- }
2048
- const globalOnes = (globalTables ?? []).map(t202);
2049
- t18 = [...shardOnes, ...globalOnes];
2050
- $[41] = columnsForShard;
2051
- $[42] = globalTables;
2052
- $[43] = tables;
2053
- $[44] = t18;
2054
- } else {
2055
- t18 = $[44];
2056
- }
2057
- const diagramTables = t18;
2058
- let t19;
2059
- if ($[49] !== tableFilter || $[50] !== tables) {
2060
- const needle = tableFilter.trim().toLowerCase();
2061
- t19 = (tables ?? []).filter((table_9) => table_9.name.toLowerCase().includes(needle));
2062
- $[49] = tableFilter;
2063
- $[50] = tables;
2064
- $[51] = t19;
2065
- } else {
2066
- t19 = $[51];
2067
- }
2068
- const filteredTables = t19;
2069
- let t20;
2070
- if ($[52] !== globalTables || $[53] !== tableFilter) {
2071
- const needle_0 = tableFilter.trim().toLowerCase();
2072
- t20 = (globalTables ?? []).filter((table_10) => table_10.name.toLowerCase().includes(needle_0));
2073
- $[52] = globalTables;
2074
- $[53] = tableFilter;
2075
- $[54] = t20;
2076
- } else {
2077
- t20 = $[54];
2078
- }
2079
- const filteredGlobalTables = t20;
2080
- let t21;
2081
- if ($[55] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2082
- t21 = () => {
2083
- setView("list");
2084
- };
2085
- $[55] = t21;
2086
- } else {
2087
- t21 = $[55];
2088
- }
2089
- const showList = t21;
2090
- let t22;
2091
- if ($[56] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2092
- t22 = () => {
2093
- setView("graph");
2094
- };
2095
- $[56] = t22;
2096
- } else {
2097
- t22 = $[56];
2098
- }
2099
- const showGraph = t22;
2100
- let t23;
2101
- if ($[57] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2102
- t23 = (event) => {
2103
- setTableFilter(event.target.value);
2104
- };
2105
- $[57] = t23;
2106
- } else {
2107
- t23 = $[57];
2108
- }
2109
- const onFilterChange = t23;
2110
- let t24;
2111
- if ($[58] !== refresh || $[59] !== shardKey) {
2112
- t24 = (_tables) => {
2113
- fireAndForget(refresh(shardKey));
2114
- };
2115
- $[58] = refresh;
2116
- $[59] = shardKey;
2117
- $[60] = t24;
2118
- } else {
2119
- t24 = $[60];
2120
- }
2121
- const onSchemaApplied = t24;
2122
- let t25;
2123
- if ($[61] !== tables) {
2124
- t25 = tables ?? [];
2125
- $[61] = tables;
2126
- $[62] = t25;
2127
- } else {
2128
- t25 = $[62];
2129
- }
2130
- let t26;
2131
- if ($[63] !== t25) {
2132
- t26 = t25.map(_temp6);
2133
- $[63] = t25;
2134
- $[64] = t26;
2135
- } else {
2136
- t26 = $[64];
2137
- }
2138
- const shardTableNames = t26;
2139
- let t27;
2140
- if ($[65] !== shardKey) {
2141
- t27 = /* @__PURE__ */ jsxDEV(ShardInput, {
2142
- onChange: setShardKey,
2143
- testId: "sc-shard-input",
2144
- value: shardKey
2145
- }, void 0, false);
2146
- $[65] = shardKey;
2147
- $[66] = t27;
2148
- } else {
2149
- t27 = $[66];
2150
- }
2151
- let t28;
2152
- if ($[67] !== t) {
2153
- t28 = t("Schema view");
2154
- $[67] = t;
2155
- $[68] = t28;
2156
- } else {
2157
- t28 = $[68];
2158
- }
2159
- const t29 = view === "list";
2160
- const t30 = view === "list" ? "default" : "outline";
2161
- let t31;
2162
- if ($[69] !== t) {
2163
- t31 = t("Table list");
2164
- $[69] = t;
2165
- $[70] = t31;
2166
- } else {
2167
- t31 = $[70];
2168
- }
2169
- let t32;
2170
- if ($[71] !== t29 || $[72] !== t30 || $[73] !== t31) {
2171
- t32 = /* @__PURE__ */ jsxDEV(Button, {
2172
- "aria-pressed": t29,
2173
- "data-testid": "sc-view-list",
2174
- onClick: showList,
2175
- size: "xs",
2176
- type: "button",
2177
- variant: t30,
2178
- children: t31
2179
- }, void 0, false);
2180
- $[71] = t29;
2181
- $[72] = t30;
2182
- $[73] = t31;
2183
- $[74] = t32;
2184
- } else {
2185
- t32 = $[74];
2186
- }
2187
- const t33 = view === "graph";
2188
- const t34 = view === "graph" ? "default" : "outline";
2189
- let t35;
2190
- if ($[75] !== t) {
2191
- t35 = t("Graph");
2192
- $[75] = t;
2193
- $[76] = t35;
2194
- } else {
2195
- t35 = $[76];
2196
- }
2197
- let t36;
2198
- if ($[77] !== t33 || $[78] !== t34 || $[79] !== t35) {
2199
- t36 = /* @__PURE__ */ jsxDEV(Button, {
2200
- "aria-pressed": t33,
2201
- "data-testid": "sc-view-graph",
2202
- onClick: showGraph,
2203
- size: "xs",
2204
- type: "button",
2205
- variant: t34,
2206
- children: t35
2207
- }, void 0, false);
2208
- $[77] = t33;
2209
- $[78] = t34;
2210
- $[79] = t35;
2211
- $[80] = t36;
2212
- } else {
2213
- t36 = $[80];
2214
- }
2215
- let t37;
2216
- if ($[81] !== t28 || $[82] !== t32 || $[83] !== t36) {
2217
- t37 = /* @__PURE__ */ jsxDEV("div", {
2218
- "aria-label": t28,
2219
- className: "flex gap-1.5",
2220
- "data-testid": "sc-view-toggle",
2221
- role: "group",
2222
- children: [t32, t36]
2223
- }, void 0, true);
2224
- $[81] = t28;
2225
- $[82] = t32;
2226
- $[83] = t36;
2227
- $[84] = t37;
2228
- } else {
2229
- t37 = $[84];
2230
- }
2231
- let t38;
2232
- if ($[85] !== t27 || $[86] !== t37) {
2233
- t38 = /* @__PURE__ */ jsxDEV("div", {
2234
- className: "flex flex-wrap items-center gap-3",
2235
- children: [t27, t37]
2236
- }, void 0, true);
2237
- $[85] = t27;
2238
- $[86] = t37;
2239
- $[87] = t38;
2240
- } else {
2241
- t38 = $[87];
2242
- }
2243
- let t39;
2244
- if ($[88] !== onSchemaApplied || $[89] !== schemaEditable || $[90] !== shardTableNames) {
2245
- t39 = schemaEditable === true && /* @__PURE__ */ jsxDEV(SchemaEditorOverlay, {
2246
- onApplied: onSchemaApplied,
2247
- tableNames: shardTableNames
2248
- }, void 0, false);
2249
- $[88] = onSchemaApplied;
2250
- $[89] = schemaEditable;
2251
- $[90] = shardTableNames;
2252
- $[91] = t39;
2253
- } else {
2254
- t39 = $[91];
2255
- }
2256
- let t40;
2257
- if ($[92] !== t || $[93] !== tableFilter || $[94] !== view) {
2258
- t40 = view === "list" && /* @__PURE__ */ jsxDEV(Input, {
2259
- "aria-label": t("Filter tables"),
2260
- className: "h-8 max-w-xs",
2261
- "data-testid": "sc-filter",
2262
- onChange: onFilterChange,
2263
- placeholder: t("Filter tables"),
2264
- value: tableFilter
2265
- }, void 0, false);
2266
- $[92] = t;
2267
- $[93] = tableFilter;
2268
- $[94] = view;
2269
- $[95] = t40;
2270
- } else {
2271
- t40 = $[95];
2272
- }
2273
- let t41;
2274
- if ($[96] !== diagramTables || $[97] !== error || $[98] !== globalError || $[99] !== shardColumnsError || $[100] !== shardKey || $[101] !== view) {
2275
- t41 = view === "graph" && /* @__PURE__ */ jsxDEV("div", {
2276
- className: "flex flex-col gap-2",
2277
- "data-testid": "sc-graph-view",
2278
- children: [error !== null && /* @__PURE__ */ jsxDEV("p", {
2279
- className: "text-sm text-destructive",
2280
- "data-testid": "sc-error",
2281
- role: "alert",
2282
- children: error
2283
- }, void 0, false), globalError !== null && /* @__PURE__ */ jsxDEV("p", {
2284
- className: "text-sm text-destructive",
2285
- "data-testid": "sc-global-error",
2286
- role: "alert",
2287
- children: globalError
2288
- }, void 0, false), /* @__PURE__ */ jsxDEV(SchemaDiagram, {
2289
- columnsError: shardColumnsError[shardKey] === true,
2290
- tables: diagramTables,
2291
- testIdPrefix: "sc-graph"
2292
- }, void 0, false)]
2293
- }, void 0, true);
2294
- $[96] = diagramTables;
2295
- $[97] = error;
2296
- $[98] = globalError;
2297
- $[99] = shardColumnsError;
2298
- $[100] = shardKey;
2299
- $[101] = view;
2300
- $[102] = t41;
2301
- } else {
2302
- t41 = $[102];
2303
- }
2304
- let t42;
2305
- if ($[103] !== columns || $[104] !== error || $[105] !== expanded || $[106] !== filteredGlobalTables || $[107] !== filteredTables || $[108] !== globalColumns || $[109] !== globalError || $[110] !== globalExpanded || $[111] !== globalTables || $[112] !== indexes || $[113] !== shardKey || $[114] !== t || $[115] !== tables || $[116] !== toggle || $[117] !== toggleGlobal || $[118] !== view) {
2306
- t42 = view === "list" && /* @__PURE__ */ jsxDEV("div", {
2307
- className: "flex flex-col gap-4",
2308
- children: [/* @__PURE__ */ jsxDEV(Card, {
2309
- "data-testid": "sc-shard-section",
2310
- size: "sm",
2311
- children: [/* @__PURE__ */ jsxDEV(CardHeader, {
2312
- children: [/* @__PURE__ */ jsxDEV("div", {
2313
- className: "flex items-center gap-2",
2314
- children: [/* @__PURE__ */ jsxDEV(StorageTierBadge, {
2315
- tier: "shard"
2316
- }, void 0, false), /* @__PURE__ */ jsxDEV(CardTitle, {
2317
- children: t("Shard tables")
2318
- }, void 0, false), tables !== null && /* @__PURE__ */ jsxDEV(Badge, {
2319
- className: "ms-auto tabular-nums",
2320
- variant: "outline",
2321
- children: filteredTables.length
2322
- }, void 0, false)]
2323
- }, void 0, true), /* @__PURE__ */ jsxDEV(CardDescription, {
2324
- children: TIER_META.shard.hint
2325
- }, void 0, false)]
2326
- }, void 0, true), /* @__PURE__ */ jsxDEV(CardContent, {
2327
- children: [error !== null && /* @__PURE__ */ jsxDEV("p", {
2328
- className: "text-sm text-destructive",
2329
- "data-testid": "sc-error",
2330
- role: "alert",
2331
- children: error
2332
- }, void 0, false), tables !== null && tables.length === 0 && /* @__PURE__ */ jsxDEV("p", {
2333
- className: "text-sm text-muted-foreground",
2334
- "data-testid": "sc-empty",
2335
- children: t("No tables in this shard.")
2336
- }, void 0, false), tables !== null && tables.length > 0 && filteredTables.length === 0 && /* @__PURE__ */ jsxDEV("p", {
2337
- className: "text-sm text-muted-foreground",
2338
- "data-testid": "sc-no-match",
2339
- children: t("No tables match your filter.")
2340
- }, void 0, false), filteredTables.length > 0 && /* @__PURE__ */ jsxDEV("ul", {
2341
- className: "-mx-3 overflow-hidden border-t border-border",
2342
- "data-testid": "sc-table-list",
2343
- children: filteredTables.map((table_12) => {
2344
- const cacheKey_0 = `${shardKey}:${table_12.name}`;
2345
- const tableIndexes = indexes[cacheKey_0] ?? [];
2346
- return /* @__PURE__ */ jsxDEV(TableEntry, {
2347
- expanded: expanded === table_12.name,
2348
- name: table_12.name,
2349
- onToggle: () => {
2350
- fireAndForget(toggle(table_12.name));
2351
- },
2352
- rowCount: table_12.rowCount,
2353
- rowTestId: `sc-table-${table_12.name}`,
2354
- toggleTestId: `sc-toggle-${table_12.name}`,
2355
- children: [/* @__PURE__ */ jsxDEV(ColumnChips, {
2356
- columns: columns[cacheKey_0] ?? EMPTY_COLUMN_NAMES,
2357
- testId: `sc-columns-${table_12.name}`
2358
- }, void 0, false), tableIndexes.length > 0 && /* @__PURE__ */ jsxDEV(IndexList, {
2359
- heading: t("Indexes"),
2360
- indexes: tableIndexes,
2361
- testId: `sc-indexes-${table_12.name}`
2362
- }, void 0, false)]
2363
- }, table_12.name, true);
2364
- })
2365
- }, void 0, false)]
2366
- }, void 0, true)]
2367
- }, void 0, true), /* @__PURE__ */ jsxDEV(Card, {
2368
- "data-testid": "sc-global-section",
2369
- size: "sm",
2370
- children: [/* @__PURE__ */ jsxDEV(CardHeader, {
2371
- children: [/* @__PURE__ */ jsxDEV("div", {
2372
- className: "flex items-center gap-2",
2373
- children: [/* @__PURE__ */ jsxDEV(StorageTierBadge, {
2374
- tier: "global"
2375
- }, void 0, false), /* @__PURE__ */ jsxDEV(CardTitle, {
2376
- children: t("Global tables (D1)")
2377
- }, void 0, false), globalTables !== null && /* @__PURE__ */ jsxDEV(Badge, {
2378
- className: "ms-auto tabular-nums",
2379
- variant: "outline",
2380
- children: filteredGlobalTables.length
2381
- }, void 0, false)]
2382
- }, void 0, true), /* @__PURE__ */ jsxDEV(CardDescription, {
2383
- children: TIER_META.global.hint
2384
- }, void 0, false)]
2385
- }, void 0, true), /* @__PURE__ */ jsxDEV(CardContent, {
2386
- children: [globalError !== null && /* @__PURE__ */ jsxDEV("p", {
2387
- className: "text-sm text-destructive",
2388
- "data-testid": "sc-global-error",
2389
- role: "alert",
2390
- children: globalError
2391
- }, void 0, false), globalTables !== null && globalTables.length === 0 && /* @__PURE__ */ jsxDEV(EmptyState, {
2392
- description: TIER_META.global.hint,
2393
- testId: "sc-global-empty",
2394
- title: t("No global tables.")
2395
- }, void 0, false), globalTables !== null && globalTables.length > 0 && filteredGlobalTables.length === 0 && /* @__PURE__ */ jsxDEV("p", {
2396
- className: "text-sm text-muted-foreground",
2397
- "data-testid": "sc-global-no-match",
2398
- children: t("No tables match your filter.")
2399
- }, void 0, false), filteredGlobalTables.length > 0 && /* @__PURE__ */ jsxDEV("ul", {
2400
- className: "-mx-3 overflow-hidden border-t border-border",
2401
- "data-testid": "sc-global-table-list",
2402
- children: filteredGlobalTables.map((table_13) => /* @__PURE__ */ jsxDEV(TableEntry, {
2403
- expanded: globalExpanded === table_13.name,
2404
- name: table_13.name,
2405
- onToggle: () => {
2406
- fireAndForget(toggleGlobal(table_13.name));
2407
- },
2408
- rowCount: table_13.rowCount,
2409
- rowTestId: `sc-global-table-${table_13.name}`,
2410
- toggleTestId: `sc-global-toggle-${table_13.name}`,
2411
- children: /* @__PURE__ */ jsxDEV(ColumnChips, {
2412
- columns: globalColumns[table_13.name] ?? EMPTY_COLUMN_NAMES,
2413
- testId: `sc-global-columns-${table_13.name}`
2414
- }, void 0, false)
2415
- }, table_13.name, false))
2416
- }, void 0, false)]
2417
- }, void 0, true)]
2418
- }, void 0, true)]
2419
- }, void 0, true);
2420
- $[103] = columns;
2421
- $[104] = error;
2422
- $[105] = expanded;
2423
- $[106] = filteredGlobalTables;
2424
- $[107] = filteredTables;
2425
- $[108] = globalColumns;
2426
- $[109] = globalError;
2427
- $[110] = globalExpanded;
2428
- $[111] = globalTables;
2429
- $[112] = indexes;
2430
- $[113] = shardKey;
2431
- $[114] = t;
2432
- $[115] = tables;
2433
- $[116] = toggle;
2434
- $[117] = toggleGlobal;
2435
- $[118] = view;
2436
- $[119] = t42;
2437
- } else {
2438
- t42 = $[119];
2439
- }
2440
- let t43;
2441
- if ($[120] !== t38 || $[121] !== t39 || $[122] !== t40 || $[123] !== t41 || $[124] !== t42) {
2442
- t43 = /* @__PURE__ */ jsxDEV("div", {
2443
- className: "flex flex-col gap-4",
2444
- "data-testid": "lunora-schema",
2445
- children: [t38, t39, t40, t41, t42]
2446
- }, void 0, true);
2447
- $[120] = t38;
2448
- $[121] = t39;
2449
- $[122] = t40;
2450
- $[123] = t41;
2451
- $[124] = t42;
2452
- $[125] = t43;
2453
- } else {
2454
- t43 = $[125];
2455
- }
2456
- return t43;
2457
- };
2458
- function _temp(column) {
2459
- return /* @__PURE__ */ jsxDEV("li", {
2460
- className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[11px] text-muted-foreground",
2461
- children: column
2462
- }, column, false);
2463
- }
2464
- function _temp2(index) {
2465
- return /* @__PURE__ */ jsxDEV("li", {
2466
- className: "flex flex-wrap items-center gap-1.5 text-xs",
2467
- children: [/* @__PURE__ */ jsxDEV("span", {
2468
- className: "font-mono",
2469
- children: index.name
2470
- }, void 0, false), /* @__PURE__ */ jsxDEV(Badge, {
2471
- variant: "outline",
2472
- children: index.type
2473
- }, void 0, false), index.unique === true && /* @__PURE__ */ jsxDEV(Badge, {
2474
- variant: "secondary",
2475
- children: "unique"
2476
- }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
2477
- className: "text-muted-foreground",
2478
- children: index.fields.join(", ")
2479
- }, void 0, false)]
2480
- }, `${index.type}:${index.name}`, true);
2481
- }
2482
- function _temp3(t0) {
2483
- const {
2484
- columns: columnNames,
2485
- refs,
2486
- table: table_3
2487
- } = t0;
2488
- return [table_3, columnNames.map((name) => {
2489
- const ref = refs[name];
2490
- return ref === void 0 ? {
2491
- name,
2492
- optional: false,
2493
- type: ""
2494
- } : {
2495
- name,
2496
- optional: false,
2497
- ref,
2498
- type: "id"
2499
- };
2500
- })];
2501
- }
2502
- function _temp4(table_5) {
2503
- return table_5.name;
2504
- }
2505
- function _temp5(table_6) {
2506
- return table_6.name;
2507
- }
2508
- function _temp6(table_11) {
2509
- return table_11.name;
2510
- }
2511
-
2512
- export { SchemaViewer };