d1s 0.2.10 → 0.2.12

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 (329) hide show
  1. package/dist/.next/.next/BUILD_ID +1 -1
  2. package/dist/.next/.next/app-build-manifest.json +33 -33
  3. package/dist/.next/.next/app-path-routes-manifest.json +1 -1
  4. package/dist/.next/.next/build-manifest.json +3 -3
  5. package/dist/.next/.next/cache/.rscinfo +1 -1
  6. package/dist/.next/.next/cache/.tsbuildinfo +1 -1
  7. package/dist/.next/.next/cache/webpack/client-production/0.pack +0 -0
  8. package/dist/.next/.next/cache/webpack/client-production/1.pack +0 -0
  9. package/dist/.next/.next/cache/webpack/client-production/10.pack +0 -0
  10. package/dist/.next/.next/cache/webpack/client-production/11.pack +0 -0
  11. package/dist/.next/.next/cache/webpack/client-production/12.pack +0 -0
  12. package/dist/.next/.next/cache/webpack/client-production/2.pack +0 -0
  13. package/dist/.next/.next/cache/webpack/client-production/3.pack +0 -0
  14. package/dist/.next/.next/cache/webpack/client-production/4.pack +0 -0
  15. package/dist/.next/.next/cache/webpack/client-production/5.pack +0 -0
  16. package/dist/.next/.next/cache/webpack/client-production/6.pack +0 -0
  17. package/dist/.next/.next/cache/webpack/client-production/7.pack +0 -0
  18. package/dist/.next/.next/cache/webpack/client-production/8.pack +0 -0
  19. package/dist/.next/.next/cache/webpack/client-production/9.pack +0 -0
  20. package/dist/.next/.next/cache/webpack/client-production/index.pack +0 -0
  21. package/dist/.next/.next/cache/webpack/client-production/index.pack.old +0 -0
  22. package/dist/.next/.next/cache/webpack/edge-server-production/index.pack +0 -0
  23. package/dist/.next/.next/cache/webpack/server-production/0.pack +0 -0
  24. package/dist/.next/.next/cache/webpack/server-production/1.pack +0 -0
  25. package/dist/.next/.next/cache/webpack/server-production/index.pack +0 -0
  26. package/dist/.next/.next/cache/webpack/server-production/index.pack.old +0 -0
  27. package/dist/.next/.next/next-minimal-server.js.nft.json +1 -1
  28. package/dist/.next/.next/next-server.js.nft.json +1 -1
  29. package/dist/.next/.next/prerender-manifest.json +1 -1
  30. package/dist/.next/.next/required-server-files.json +1 -1
  31. package/dist/.next/.next/server/app/_not-found/page.js +1 -1
  32. package/dist/.next/.next/server/app/_not-found/page.js.nft.json +1 -1
  33. package/dist/.next/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  34. package/dist/.next/.next/server/app/_not-found.html +1 -1
  35. package/dist/.next/.next/server/app/_not-found.rsc +4 -4
  36. package/dist/.next/.next/server/app/api/cloudflare/route.js +1 -1
  37. package/dist/.next/.next/server/app/api/cloudflare/route_client-reference-manifest.js +1 -1
  38. package/dist/.next/.next/server/app/api/databases/route.js +1 -1
  39. package/dist/.next/.next/server/app/api/databases/route_client-reference-manifest.js +1 -1
  40. package/dist/.next/.next/server/app/api/migrations/sync/route.js +5 -5
  41. package/dist/.next/.next/server/app/api/migrations/sync/route_client-reference-manifest.js +1 -1
  42. package/dist/.next/.next/server/app/api/migrations/sync-files/route.js +3 -3
  43. package/dist/.next/.next/server/app/api/migrations/sync-files/route_client-reference-manifest.js +1 -1
  44. package/dist/.next/.next/server/app/api/pull-data/confirm/route.js +1 -1
  45. package/dist/.next/.next/server/app/api/pull-data/confirm/route_client-reference-manifest.js +1 -1
  46. package/dist/.next/.next/server/app/api/pull-remote/confirm/route.js +2 -2
  47. package/dist/.next/.next/server/app/api/pull-remote/confirm/route_client-reference-manifest.js +1 -1
  48. package/dist/.next/.next/server/app/api/pull-remote/preview/route.js +4 -4
  49. package/dist/.next/.next/server/app/api/pull-remote/preview/route_client-reference-manifest.js +1 -1
  50. package/dist/.next/.next/server/app/api/push-remote/confirm/route.js +5 -5
  51. package/dist/.next/.next/server/app/api/push-remote/confirm/route_client-reference-manifest.js +1 -1
  52. package/dist/.next/.next/server/app/api/push-remote/preview/route.js +4 -4
  53. package/dist/.next/.next/server/app/api/push-remote/preview/route_client-reference-manifest.js +1 -1
  54. package/dist/.next/.next/server/app/api/query/route.js +3 -3
  55. package/dist/.next/.next/server/app/api/query/route_client-reference-manifest.js +1 -1
  56. package/dist/.next/.next/server/app/api/tables/[name]/route.js +5 -5
  57. package/dist/.next/.next/server/app/api/tables/[name]/route_client-reference-manifest.js +1 -1
  58. package/dist/.next/.next/server/app/api/tables/route.js +2 -2
  59. package/dist/.next/.next/server/app/api/tables/route_client-reference-manifest.js +1 -1
  60. package/dist/.next/.next/server/app/api/update/route.js +1 -1
  61. package/dist/.next/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  62. package/dist/.next/.next/server/app/index.html +3 -3
  63. package/dist/.next/.next/server/app/index.rsc +5 -5
  64. package/dist/.next/.next/server/app/page.js +11 -13
  65. package/dist/.next/.next/server/app/page.js.nft.json +1 -1
  66. package/dist/.next/.next/server/app/page_client-reference-manifest.js +1 -1
  67. package/dist/.next/.next/server/app-paths-manifest.json +3 -3
  68. package/dist/.next/.next/server/chunks/226.js +12 -12
  69. package/dist/.next/.next/server/chunks/391.js +5 -5
  70. package/dist/.next/.next/server/chunks/452.js +1 -1
  71. package/dist/.next/.next/server/chunks/572.js +1 -0
  72. package/dist/.next/.next/server/chunks/627.js +3 -3
  73. package/dist/.next/.next/server/chunks/638.js +3 -3
  74. package/dist/.next/.next/server/chunks/992.js +3 -3
  75. package/dist/.next/.next/server/middleware-build-manifest.js +1 -1
  76. package/dist/.next/.next/server/next-font-manifest.js +1 -1
  77. package/dist/.next/.next/server/next-font-manifest.json +1 -1
  78. package/dist/.next/.next/server/pages/404.html +1 -1
  79. package/dist/.next/.next/server/pages/500.html +1 -1
  80. package/dist/.next/.next/server/pages/_app.js +1 -1
  81. package/dist/.next/.next/server/pages/_document.js +1 -1
  82. package/dist/.next/.next/server/pages/_error.js +1 -1
  83. package/dist/.next/.next/server/server-reference-manifest.json +1 -1
  84. package/dist/.next/.next/static/chunks/576-18a2209e1ed26aad.js +1 -0
  85. package/dist/.next/.next/static/chunks/{92-c4466e0f1ca8a3a8.js → 92-5f7522943fcb72a8.js} +1 -1
  86. package/dist/.next/.next/static/chunks/app/{layout-be6ee67cf0c92654.js → layout-40ec07d04681ba81.js} +1 -1
  87. package/dist/.next/.next/static/chunks/app/page-f05cd0fc436bf9bc.js +1 -0
  88. package/dist/.next/.next/static/chunks/{main-app-fa35024de9bd9284.js → main-app-4506e88db72db4b7.js} +1 -1
  89. package/dist/.next/.next/static/css/7c16f57d325d0d7d.css +3 -0
  90. package/dist/.next/.next/static/gABGrAoO8IPArDo_Ns_7g/_buildManifest.js +1 -0
  91. package/dist/.next/.next/static/gABGrAoO8IPArDo_Ns_7g/_ssgManifest.js +1 -0
  92. package/dist/.next/.next/static/gh-QfIUVo4FTTduYCVKT6/_buildManifest.js +1 -0
  93. package/dist/.next/.next/static/gh-QfIUVo4FTTduYCVKT6/_ssgManifest.js +1 -0
  94. package/dist/.next/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  95. package/dist/.next/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  96. package/dist/.next/.next/static/ybCx6L6gHqtODbKmlhU-d/_buildManifest.js +1 -0
  97. package/dist/.next/.next/static/ybCx6L6gHqtODbKmlhU-d/_ssgManifest.js +1 -0
  98. package/dist/.next/.next/trace +3 -3
  99. package/dist/.next/.next/types/app/api/cloudflare/route.ts +1 -1
  100. package/dist/.next/.next/types/app/api/databases/route.ts +1 -1
  101. package/dist/.next/.next/types/app/api/migrations/sync/route.ts +1 -1
  102. package/dist/.next/.next/types/app/api/migrations/sync-files/route.ts +1 -1
  103. package/dist/.next/.next/types/app/api/pull-data/confirm/route.ts +1 -1
  104. package/dist/.next/.next/types/app/api/pull-remote/confirm/route.ts +1 -1
  105. package/dist/.next/.next/types/app/api/pull-remote/preview/route.ts +1 -1
  106. package/dist/.next/.next/types/app/api/push-remote/confirm/route.ts +1 -1
  107. package/dist/.next/.next/types/app/api/push-remote/preview/route.ts +1 -1
  108. package/dist/.next/.next/types/app/api/query/route.ts +1 -1
  109. package/dist/.next/.next/types/app/api/tables/[name]/route.ts +1 -1
  110. package/dist/.next/.next/types/app/api/tables/route.ts +1 -1
  111. package/dist/.next/.next/types/app/api/update/route.ts +1 -1
  112. package/dist/.next/.next/types/app/page.ts +1 -1
  113. package/dist/.next/BUILD_ID +1 -1
  114. package/dist/.next/app-build-manifest.json +32 -32
  115. package/dist/.next/app-path-routes-manifest.json +1 -1
  116. package/dist/.next/build-manifest.json +3 -3
  117. package/dist/.next/cache/.rscinfo +1 -1
  118. package/dist/.next/cache/.tsbuildinfo +1 -1
  119. package/dist/.next/cache/webpack/client-production/0.pack +0 -0
  120. package/dist/.next/cache/webpack/client-production/1.pack +0 -0
  121. package/dist/.next/cache/webpack/client-production/2.pack +0 -0
  122. package/dist/.next/cache/webpack/client-production/index.pack +0 -0
  123. package/dist/.next/cache/webpack/client-production/index.pack.old +0 -0
  124. package/dist/.next/cache/webpack/edge-server-production/index.pack +0 -0
  125. package/dist/.next/cache/webpack/server-production/0.pack +0 -0
  126. package/dist/.next/cache/webpack/server-production/index.pack +0 -0
  127. package/dist/.next/next-minimal-server.js.nft.json +1 -1
  128. package/dist/.next/next-server.js.nft.json +1 -1
  129. package/dist/.next/prerender-manifest.json +1 -1
  130. package/dist/.next/required-server-files.json +1 -1
  131. package/dist/.next/server/app/_not-found/page.js +1 -1
  132. package/dist/.next/server/app/_not-found/page.js.nft.json +1 -1
  133. package/dist/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  134. package/dist/.next/server/app/_not-found.html +1 -1
  135. package/dist/.next/server/app/_not-found.rsc +4 -4
  136. package/dist/.next/server/app/api/cloudflare/route.js +1 -1
  137. package/dist/.next/server/app/api/cloudflare/route_client-reference-manifest.js +1 -1
  138. package/dist/.next/server/app/api/databases/route.js +1 -1
  139. package/dist/.next/server/app/api/databases/route_client-reference-manifest.js +1 -1
  140. package/dist/.next/server/app/api/migrations/sync/route.js +5 -5
  141. package/dist/.next/server/app/api/migrations/sync/route_client-reference-manifest.js +1 -1
  142. package/dist/.next/server/app/api/migrations/sync-files/route.js +3 -3
  143. package/dist/.next/server/app/api/migrations/sync-files/route_client-reference-manifest.js +1 -1
  144. package/dist/.next/server/app/api/pull-data/confirm/route.js +1 -1
  145. package/dist/.next/server/app/api/pull-data/confirm/route_client-reference-manifest.js +1 -1
  146. package/dist/.next/server/app/api/pull-remote/confirm/route.js +2 -2
  147. package/dist/.next/server/app/api/pull-remote/confirm/route_client-reference-manifest.js +1 -1
  148. package/dist/.next/server/app/api/pull-remote/preview/route.js +4 -4
  149. package/dist/.next/server/app/api/pull-remote/preview/route_client-reference-manifest.js +1 -1
  150. package/dist/.next/server/app/api/push-remote/confirm/route.js +5 -5
  151. package/dist/.next/server/app/api/push-remote/confirm/route_client-reference-manifest.js +1 -1
  152. package/dist/.next/server/app/api/push-remote/preview/route.js +4 -4
  153. package/dist/.next/server/app/api/push-remote/preview/route_client-reference-manifest.js +1 -1
  154. package/dist/.next/server/app/api/query/route.js +3 -3
  155. package/dist/.next/server/app/api/query/route_client-reference-manifest.js +1 -1
  156. package/dist/.next/server/app/api/tables/[name]/route.js +5 -5
  157. package/dist/.next/server/app/api/tables/[name]/route_client-reference-manifest.js +1 -1
  158. package/dist/.next/server/app/api/tables/route.js +2 -2
  159. package/dist/.next/server/app/api/tables/route_client-reference-manifest.js +1 -1
  160. package/dist/.next/server/app/api/update/route.js +1 -1
  161. package/dist/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  162. package/dist/.next/server/app/index.html +3 -3
  163. package/dist/.next/server/app/index.rsc +5 -5
  164. package/dist/.next/server/app/page.js +11 -13
  165. package/dist/.next/server/app/page.js.nft.json +1 -1
  166. package/dist/.next/server/app/page_client-reference-manifest.js +1 -1
  167. package/dist/.next/server/app-paths-manifest.json +2 -2
  168. package/dist/.next/server/chunks/226.js +12 -12
  169. package/dist/.next/server/chunks/391.js +5 -5
  170. package/dist/.next/server/chunks/452.js +1 -1
  171. package/dist/.next/server/chunks/572.js +1 -0
  172. package/dist/.next/server/chunks/627.js +3 -3
  173. package/dist/.next/server/chunks/638.js +3 -3
  174. package/dist/.next/server/chunks/992.js +3 -3
  175. package/dist/.next/server/middleware-build-manifest.js +1 -1
  176. package/dist/.next/server/next-font-manifest.js +1 -1
  177. package/dist/.next/server/next-font-manifest.json +1 -1
  178. package/dist/.next/server/pages/404.html +1 -1
  179. package/dist/.next/server/pages/500.html +1 -1
  180. package/dist/.next/server/pages/_app.js +1 -1
  181. package/dist/.next/server/pages/_document.js +1 -1
  182. package/dist/.next/server/pages/_error.js +1 -1
  183. package/dist/.next/server/server-reference-manifest.json +1 -1
  184. package/dist/.next/static/IX-QLbm7scYnyqWeeimal/_buildManifest.js +1 -0
  185. package/dist/.next/static/IX-QLbm7scYnyqWeeimal/_ssgManifest.js +1 -0
  186. package/dist/.next/static/chunks/576-18a2209e1ed26aad.js +1 -0
  187. package/dist/.next/static/chunks/{92-c4466e0f1ca8a3a8.js → 92-5f7522943fcb72a8.js} +1 -1
  188. package/dist/.next/static/chunks/app/{layout-be6ee67cf0c92654.js → layout-40ec07d04681ba81.js} +1 -1
  189. package/dist/.next/static/chunks/app/page-f05cd0fc436bf9bc.js +1 -0
  190. package/dist/.next/static/chunks/{main-app-fa35024de9bd9284.js → main-app-4506e88db72db4b7.js} +1 -1
  191. package/dist/.next/static/css/7c16f57d325d0d7d.css +3 -0
  192. package/dist/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  193. package/dist/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  194. package/dist/.next/trace +3 -16
  195. package/dist/.next/types/app/api/cloudflare/route.ts +1 -1
  196. package/dist/.next/types/app/api/databases/route.ts +1 -1
  197. package/dist/.next/types/app/api/migrations/sync/route.ts +1 -1
  198. package/dist/.next/types/app/api/migrations/sync-files/route.ts +1 -1
  199. package/dist/.next/types/app/api/pull-data/confirm/route.ts +1 -1
  200. package/dist/.next/types/app/api/pull-remote/confirm/route.ts +1 -1
  201. package/dist/.next/types/app/api/pull-remote/preview/route.ts +1 -1
  202. package/dist/.next/types/app/api/push-remote/confirm/route.ts +1 -1
  203. package/dist/.next/types/app/api/push-remote/preview/route.ts +1 -1
  204. package/dist/.next/types/app/api/query/route.ts +1 -1
  205. package/dist/.next/types/app/api/tables/[name]/route.ts +1 -1
  206. package/dist/.next/types/app/api/tables/route.ts +1 -1
  207. package/dist/.next/types/app/api/update/route.ts +1 -1
  208. package/dist/.next/types/app/page.ts +1 -1
  209. package/dist/app/api/tables/[name]/route.js +22 -10
  210. package/dist/app/globals.css +39 -0
  211. package/dist/app/page.jsx +13 -23
  212. package/dist/d1-studio.js +34 -4
  213. package/dist/lib/data-type-handlers.js +426 -0
  214. package/dist/lib/sql-operations.js +32 -8
  215. package/dist/lib/sql-sanitizer.js +233 -0
  216. package/package.json +3 -9
  217. package/dist/.next/.next/cache/webpack/server-production/2.pack +0 -0
  218. package/dist/.next/.next/server/chunks/90.js +0 -1
  219. package/dist/.next/.next/static/chunks/700-dc8f9f08b166c5e6.js +0 -1
  220. package/dist/.next/.next/static/chunks/app/page-16ec561fc8bebb5d.js +0 -1
  221. package/dist/.next/.next/static/css/0c512cea5f3d317a.css +0 -3
  222. package/dist/.next/server/chunks/90.js +0 -1
  223. package/dist/.next/static/chunks/700-dc8f9f08b166c5e6.js +0 -1
  224. package/dist/.next/static/chunks/app/page-16ec561fc8bebb5d.js +0 -1
  225. package/dist/.next/static/css/0c512cea5f3d317a.css +0 -3
  226. package/dist/app/app/api/cloudflare/route.js +0 -150
  227. package/dist/app/app/api/databases/route.js +0 -71
  228. package/dist/app/app/api/migrations/sync/route.js +0 -174
  229. package/dist/app/app/api/migrations/sync-files/route.js +0 -172
  230. package/dist/app/app/api/pull-data/confirm/route.js +0 -230
  231. package/dist/app/app/api/pull-remote/confirm/route.js +0 -278
  232. package/dist/app/app/api/pull-remote/preview/route.js +0 -144
  233. package/dist/app/app/api/push-remote/confirm/route.js +0 -196
  234. package/dist/app/app/api/push-remote/preview/route.js +0 -179
  235. package/dist/app/app/api/query/route.js +0 -168
  236. package/dist/app/app/api/tables/[name]/route.js +0 -174
  237. package/dist/app/app/api/tables/route.js +0 -178
  238. package/dist/app/app/api/update/route.js +0 -45
  239. package/dist/app/app/globals.css +0 -93
  240. package/dist/app/app/layout.jsx +0 -35
  241. package/dist/app/app/page.jsx +0 -44
  242. package/next.config.mjs +0 -18
  243. package/postcss.config.mjs +0 -8
  244. package/scripts/studio.js +0 -169
  245. package/scripts/test.js +0 -366
  246. package/src/app/api/cloudflare/route.js +0 -150
  247. package/src/app/api/databases/route.js +0 -71
  248. package/src/app/api/migrations/sync/route.js +0 -174
  249. package/src/app/api/migrations/sync-files/route.js +0 -172
  250. package/src/app/api/pull-data/confirm/route.js +0 -230
  251. package/src/app/api/pull-remote/confirm/route.js +0 -278
  252. package/src/app/api/pull-remote/preview/route.js +0 -144
  253. package/src/app/api/push-remote/confirm/route.js +0 -196
  254. package/src/app/api/push-remote/preview/route.js +0 -179
  255. package/src/app/api/query/route.js +0 -168
  256. package/src/app/api/tables/[name]/route.js +0 -174
  257. package/src/app/api/tables/route.js +0 -178
  258. package/src/app/api/update/route.js +0 -45
  259. package/src/app/globals.css +0 -93
  260. package/src/app/layout.jsx +0 -35
  261. package/src/app/page.jsx +0 -44
  262. package/src/components/cloudflare-credentials-modal.jsx +0 -94
  263. package/src/components/column-selector.jsx +0 -133
  264. package/src/components/column-sorting.jsx +0 -65
  265. package/src/components/delete-records-dialog.jsx +0 -64
  266. package/src/components/download-button.jsx +0 -205
  267. package/src/components/edit-error-alert.jsx +0 -30
  268. package/src/components/editable-cell.jsx +0 -163
  269. package/src/components/editable-row.jsx +0 -169
  270. package/src/components/environment-handler.jsx +0 -332
  271. package/src/components/environment-select.jsx +0 -62
  272. package/src/components/pull-preview-toast.jsx +0 -215
  273. package/src/components/push-error-alert.jsx +0 -72
  274. package/src/components/push-preview-toast.jsx +0 -183
  275. package/src/components/query-results.jsx +0 -112
  276. package/src/components/refresh-button.jsx +0 -61
  277. package/src/components/resize-columns.jsx +0 -101
  278. package/src/components/sidebar.jsx +0 -254
  279. package/src/components/sql-editor.jsx +0 -411
  280. package/src/components/sql-error-display.jsx +0 -167
  281. package/src/components/sync-migrations-button.jsx +0 -87
  282. package/src/components/table-error-dialog.jsx +0 -65
  283. package/src/components/table-toolbar.jsx +0 -285
  284. package/src/components/table-view.jsx +0 -843
  285. package/src/components/ui/alert.jsx +0 -47
  286. package/src/components/ui/button.jsx +0 -48
  287. package/src/components/ui/card.jsx +0 -50
  288. package/src/components/ui/checkbox.jsx +0 -24
  289. package/src/components/ui/collapsible.jsx +0 -11
  290. package/src/components/ui/dialog.jsx +0 -96
  291. package/src/components/ui/dropdown-menu.jsx +0 -158
  292. package/src/components/ui/input.jsx +0 -19
  293. package/src/components/ui/scroll-area.jsx +0 -40
  294. package/src/components/ui/select.jsx +0 -121
  295. package/src/components/ui/separator.jsx +0 -25
  296. package/src/components/ui/sheet.jsx +0 -109
  297. package/src/components/ui/sidebar.jsx +0 -620
  298. package/src/components/ui/skeleton.jsx +0 -14
  299. package/src/components/ui/table.jsx +0 -86
  300. package/src/components/ui/tabs.jsx +0 -43
  301. package/src/components/ui/toast.jsx +0 -86
  302. package/src/components/ui/toaster.jsx +0 -35
  303. package/src/components/ui/tooltip.jsx +0 -28
  304. package/src/components/update-banner.jsx +0 -93
  305. package/src/context/database-context.js +0 -510
  306. package/src/hooks/use-mobile.jsx +0 -19
  307. package/src/hooks/use-sql-error.ts +0 -23
  308. package/src/hooks/use-toast.js +0 -155
  309. package/src/lib/database-queue.js +0 -37
  310. package/src/lib/error.js +0 -20
  311. package/src/lib/find-wrangler-config.js +0 -74
  312. package/src/lib/license.js +0 -99
  313. package/src/lib/logger.js +0 -58
  314. package/src/lib/migrations.js +0 -415
  315. package/src/lib/parse-sql-error.js +0 -200
  316. package/src/lib/request-deduplication.js +0 -24
  317. package/src/lib/schema-operations.js +0 -106
  318. package/src/lib/sql-error-types.js +0 -14
  319. package/src/lib/sql-operations.js +0 -647
  320. package/src/lib/utils.js +0 -6
  321. package/src/lib/version-utils.js +0 -34
  322. /package/dist/.next/.next/static/{5dBGGUmK5q7of4h5Rahrg → Y9mYu4WBghepP5oT_3OdR}/_buildManifest.js +0 -0
  323. /package/dist/.next/.next/static/{5dBGGUmK5q7of4h5Rahrg → Y9mYu4WBghepP5oT_3OdR}/_ssgManifest.js +0 -0
  324. /package/dist/.next/.next/static/{PflNFnmFsNegSqhzjI6lA → ae3gNmoSGm-R5LJC4UagI}/_buildManifest.js +0 -0
  325. /package/dist/.next/.next/static/{PflNFnmFsNegSqhzjI6lA → ae3gNmoSGm-R5LJC4UagI}/_ssgManifest.js +0 -0
  326. /package/dist/.next/.next/static/{p8875OZM4iDNsPzmoyLe7 → bKfUJeuvAQlBmR3TjrfkH}/_buildManifest.js +0 -0
  327. /package/dist/.next/.next/static/{p8875OZM4iDNsPzmoyLe7 → bKfUJeuvAQlBmR3TjrfkH}/_ssgManifest.js +0 -0
  328. /package/dist/.next/{static 2/5dBGGUmK5q7of4h5Rahrg → .next/static/ejYPqJ2kVicVp5EFWOZIC}/_buildManifest.js +0 -0
  329. /package/dist/.next/{static 2/5dBGGUmK5q7of4h5Rahrg → .next/static/ejYPqJ2kVicVp5EFWOZIC}/_ssgManifest.js +0 -0
@@ -1,254 +0,0 @@
1
- // components/sidebar.jsx
2
- 'use client';
3
-
4
- import React, { useEffect, useState, useMemo } from 'react';
5
- import {
6
- Table2,
7
- Search,
8
- Loader2,
9
- AlertCircle,
10
- TerminalSquare,
11
- } from 'lucide-react';
12
- import { Input } from '@/components/ui/input';
13
- import { Alert, AlertDescription } from '@/components/ui/alert';
14
- import { useDatabase } from '@/context/database-context';
15
- import { CloudflareCredentialsModal } from './cloudflare-credentials-modal';
16
- import { useEnvironmentController } from './environment-handler';
17
- import { EnvironmentSelect } from './environment-select';
18
-
19
- export function AppSidebar({
20
- className,
21
- currentView,
22
- onNavigate,
23
- onTableSelect,
24
- }) {
25
- const { tables, refreshTables, isLoading: isTablesLoading, error } = useDatabase();
26
- const [databases, setDatabases] = useState([]);
27
- const [searchTerm, setSearchTerm] = useState('');
28
- const [environment, setEnvironment] = useState('local');
29
- const [showCredentialsModal, setShowCredentialsModal] = useState(false);
30
- const [selectedTable, setSelectedTable] = useState(null);
31
- const [isTableLoading, setIsTableLoading] = useState(false);
32
-
33
- const {
34
- isConnecting,
35
- isPushing,
36
- showPreview,
37
- connectToCloudflare,
38
- pushToRemote,
39
- pullFromRemote,
40
- pullToRemotePreview,
41
- validateStoredCredentials,
42
- PreviewUI,
43
- } = useEnvironmentController();
44
-
45
- // Updated filtering logic with d1_migrations priority
46
- const filteredTables = useMemo(() => {
47
- const filtered = tables?.filter((table) =>
48
- table.toLowerCase().includes(searchTerm.toLowerCase())
49
- ) || [];
50
-
51
- // Sort all tables alphabetically first
52
- const sortedTables = [...filtered].sort((a, b) => a.localeCompare(b));
53
-
54
- // If d1_migrations exists in the filtered list, move it to the top
55
- const d1MigrationsIndex = sortedTables.indexOf('d1_migrations');
56
- if (d1MigrationsIndex !== -1) {
57
- sortedTables.splice(d1MigrationsIndex, 1);
58
- sortedTables.unshift('d1_migrations');
59
- }
60
-
61
- return sortedTables;
62
- }, [tables, searchTerm]);
63
-
64
- const handleTableClick = async (table) => {
65
- try {
66
- setIsTableLoading(true);
67
- setSelectedTable(table);
68
- onTableSelect(table);
69
- } catch (error) {
70
- console.error('Error selecting table:', error);
71
- } finally {
72
- setIsTableLoading(false);
73
- }
74
- };
75
-
76
- const handleEnvironmentChange = async (value) => {
77
- console.log('Environment change triggered:', value);
78
- // Immediately update the environment state so the UI reflects the correct label
79
- setEnvironment(value);
80
-
81
- if (value === 'production') {
82
- try {
83
- const credentials = await validateStoredCredentials();
84
- if (!credentials) {
85
- setShowCredentialsModal(true);
86
- return;
87
- }
88
- // Trigger push preview or push directly (as desired)
89
- await pushToRemote();
90
- } catch (error) {
91
- console.error('Environment change failed:', error);
92
- setEnvironment('local');
93
- }
94
- } else if (value === 'pull') {
95
- try {
96
- const credentials = await validateStoredCredentials();
97
- if (!credentials) {
98
- setShowCredentialsModal(true);
99
- return;
100
- }
101
- // Instead of immediately pulling, show the pull preview toast
102
- await pullToRemotePreview();
103
- // Optionally, you may keep the environment value as "pull" until confirmation,
104
- // then revert to "local" in the confirm pull flow.
105
- } catch (error) {
106
- console.error('Pull from remote failed:', error);
107
- setEnvironment('local');
108
- }
109
- } else {
110
- setEnvironment(value);
111
- }
112
- };
113
-
114
- useEffect(() => {
115
- const fetchDatabases = async () => {
116
- try {
117
- const response = await fetch('/api/databases');
118
- const data = await response.json();
119
-
120
- if (!response.ok) {
121
- throw new Error(data.error || 'Failed to fetch databases');
122
- }
123
-
124
- setDatabases(data.databases || []);
125
- } catch (error) {
126
- console.error('Error fetching databases:', error);
127
- }
128
- };
129
-
130
- fetchDatabases();
131
- refreshTables();
132
- }, [refreshTables]);
133
-
134
- return (
135
- <>
136
- {/* The sidebar now has top position adjusted for the banner */}
137
- <aside className={`${className} top-[var(--banner-height,0px)] left-0 h-[calc(100vh-var(--banner-height,0px))] bg-neutral-50 p-4`}>
138
- <div className="flex flex-col h-full font-sans">
139
- {/* Header */}
140
- <div className="flex items-center gap-2 mb-4">
141
- <Table2 className="h-5 w-5" />
142
- <span className="font-mono font-bold text-sm">d1-studio</span>
143
- </div>
144
-
145
- {/* Error Message */}
146
- {error && (
147
- <Alert variant="destructive" className="mb-4">
148
- <AlertCircle className="h-4 w-4" />
149
- <AlertDescription className="text-sm ml-2">{error}</AlertDescription>
150
- </Alert>
151
- )}
152
-
153
- {/* Database Section */}
154
- <div className="mb-2">
155
- <div className="text-xs text-muted-foreground mb-1">Database name</div>
156
- <div className="font-semibold text-sm">
157
- {databases[0]?.database_name || 'No database found'}
158
- </div>
159
- </div>
160
-
161
- {/* Environment Section - Full Width */}
162
- <div className="mb-6">
163
- <EnvironmentSelect className="w-full"
164
- value={environment}
165
- onValueChange={handleEnvironmentChange}
166
- isLoading={isPushing}
167
- disabled={isConnecting}
168
- showPreview={showPreview}
169
- />
170
- </div>
171
-
172
- {/* SQL Editor Section */}
173
- <div className="mb-3">
174
- <button
175
- className={`w-full flex items-center gap-x-1 border rounded-md text-sm font-medium transition-colors px-2 py-2
176
- ${currentView === 'sql-editor' ? 'bg-neutral-900 text-white' : 'bg-white hover:bg-neutral-100'}`}
177
- onClick={() => onNavigate('sql-editor')}
178
- disabled={isTableLoading}
179
- >
180
- <TerminalSquare className="h-[16px] w-[16px]" />
181
- SQL editor
182
- </button>
183
- </div>
184
-
185
- {/* Search Section */}
186
- <div className="relative mb-3 bg-white">
187
- <Search className="absolute left-2 top-2.5 h-4 w-4 text-neutral-500" />
188
- <Input
189
- placeholder="Search tables"
190
- value={searchTerm}
191
- onChange={(e) => setSearchTerm(e.target.value)}
192
- className="pl-7"
193
- />
194
- </div>
195
-
196
- {/* Scrollable Tables Section - Updated */}
197
- <div className="flex-1 min-h-0 flex flex-col">
198
- {/* Tables Header */}
199
- <div className="flex items-center justify-between mb-1 flex-none">
200
- <h3 className="text-sm font-medium text-muted-foreground">
201
- Tables {tables?.length ? `(${tables.length})` : ''}
202
- </h3>
203
- {isTablesLoading && <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />}
204
- </div>
205
-
206
- {/* Tables List - Scrollable - Updated with padding bottom */}
207
- <div className="overflow-y-auto flex-1">
208
- <div className="pr-2 pb-4"> {/* Added pb-4 for bottom padding */}
209
- {!isTablesLoading && filteredTables.length === 0 && (
210
- <div className="text-sm font-medium text-muted-foreground px-2 py-2">
211
- {searchTerm
212
- ? 'No matching tables found'
213
- : error
214
- ? 'Error loading tables'
215
- : 'No tables available'
216
- }
217
- </div>
218
- )}
219
-
220
- {filteredTables.map((table) => (
221
- <button
222
- key={table}
223
- className={`w-full text-left text-sm font-medium rounded-md transition-colors px-2 py-2
224
- ${currentView === 'table-view' && selectedTable === table
225
- ? 'bg-[#F0F0F0] text-neutral-900 font-semibold'
226
- : 'text-neutral-700 hover:bg-[#F2F2F2]'}
227
- ${isTableLoading && 'opacity-50 cursor-not-allowed'}`}
228
- onClick={() => handleTableClick(table)}
229
- disabled={isTableLoading}
230
- >
231
- {table}
232
- </button>
233
- ))}
234
- </div>
235
- </div>
236
- </div>
237
- </div>
238
-
239
- {/* Cloudflare Credentials Modal */}
240
- <CloudflareCredentialsModal
241
- open={showCredentialsModal}
242
- onClose={() => {
243
- setShowCredentialsModal(false);
244
- setEnvironment('local');
245
- }}
246
- onSubmit={connectToCloudflare}
247
- />
248
- </aside>
249
-
250
- {/* Preview UI */}
251
- {PreviewUI}
252
- </>
253
- );
254
- }
@@ -1,411 +0,0 @@
1
- 'use client';
2
-
3
- import React, { useState, useRef, useEffect, useCallback } from 'react';
4
- import Editor from '@monaco-editor/react';
5
- import { Loader2, Command, CornerDownLeft, GripHorizontal, ChevronDown } from 'lucide-react';
6
- import { Button } from "@/components/ui/button";
7
- import { useDatabase } from '@/context/database-context';
8
- import { SQLResultsView, SQLErrorDisplay } from './query-results';
9
- import {
10
- DropdownMenu,
11
- DropdownMenuContent,
12
- DropdownMenuItem,
13
- DropdownMenuTrigger,
14
- } from "@/components/ui/dropdown-menu";
15
- import { parseSQLError } from '@/lib/parse-sql-error';
16
-
17
- // Helpful predefined queries
18
- const HELPFUL_QUERIES = {
19
- // Table listing queries
20
- 'Show Tables': `SELECT name
21
- FROM sqlite_master
22
- WHERE type='table'
23
- AND name NOT LIKE 'sqlite_%';`,
24
-
25
- // Schema queries
26
- 'Table Schema': `-- Table Schema
27
- -- Replace table_name with your table name
28
- PRAGMA table_info(table_name);`,
29
-
30
- 'Table Indexes': `-- Table Indexes
31
- -- Replace table_name with your table name
32
- SELECT
33
- m.name as table_name,
34
- i.name as index_name,
35
- i.sql as index_definition
36
- FROM sqlite_master m
37
- JOIN sqlite_master i ON m.name = i.tbl_name
38
- WHERE m.type = 'table'
39
- AND i.type = 'index'
40
- AND m.name = 'table_name';`,
41
-
42
- 'Foreign Keys': `-- Foreign Key Information
43
- -- Replace table_name with your table name
44
- PRAGMA foreign_key_list(table_name);`,
45
-
46
- // Data queries
47
- 'Table Data': `-- Table Data
48
- -- Replace table_name with your table name
49
- SELECT * FROM table_name LIMIT 100;`,
50
-
51
- 'Row Count': `-- Row Count
52
- -- Replace table_name with your table name
53
- SELECT COUNT(*) as total_rows FROM table_name;`,
54
-
55
- 'Column Stats': `-- Column Statistics
56
- -- Replace table_name and column_name with your values
57
- SELECT
58
- COUNT(*) as total_rows,
59
- COUNT(column_name) as non_null_count,
60
- COUNT(DISTINCT column_name) as unique_values,
61
- MIN(column_name) as min_value,
62
- MAX(column_name) as max_value
63
- FROM table_name;`,
64
-
65
- // Schema modification
66
- 'Create Table': `CREATE TABLE IF NOT EXISTS new_table (
67
- id INTEGER PRIMARY KEY AUTOINCREMENT,
68
- name TEXT NOT NULL,
69
- email TEXT UNIQUE,
70
- status TEXT CHECK(status IN ('active', 'inactive')) DEFAULT 'active',
71
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP
72
- );
73
-
74
- -- Create indexes
75
- CREATE INDEX idx_new_table_name ON new_table(name);
76
- CREATE UNIQUE INDEX idx_new_table_email ON new_table(email);`,
77
-
78
- 'Create View': `-- Create a view
79
- CREATE VIEW view_name AS
80
- SELECT column1, column2
81
- FROM table_name
82
- WHERE condition;`
83
- };
84
-
85
- // Query categories for organization
86
- const QUERY_CATEGORIES = {
87
- 'Schema Information': ['Show Tables', 'Table Schema', 'Table Indexes', 'Foreign Keys'],
88
- 'Data Queries': ['Table Data', 'Row Count', 'Column Stats'],
89
- 'Schema Modification': ['Create Table', 'Create View']
90
- };
91
-
92
- function QueryTemplateMenu({ onSelectQuery }) {
93
- return (
94
- <DropdownMenu>
95
- <DropdownMenuTrigger asChild>
96
- <Button variant="outline" size="sm">
97
- Query Templates
98
- <ChevronDown className="ml-2 h-4 w-4" />
99
- </Button>
100
- </DropdownMenuTrigger>
101
- <DropdownMenuContent align="start" className="w-72">
102
- {Object.entries(QUERY_CATEGORIES).map(([category, queryNames]) => (
103
- <React.Fragment key={category}>
104
- <div className="px-2 py-1.5 text-sm font-semibold text-neutral-900 font-sans">
105
- {category}
106
- </div>
107
- {queryNames.map((queryName) => (
108
- <DropdownMenuItem
109
- key={queryName}
110
- onClick={() => onSelectQuery(queryName)}
111
- className="font-sans text-neutral-800"
112
- >
113
- {queryName}
114
- </DropdownMenuItem>
115
- ))}
116
- </React.Fragment>
117
- ))}
118
- </DropdownMenuContent>
119
- </DropdownMenu>
120
- );
121
- }
122
-
123
- export function SQLEditor() {
124
- const { executeQuery, refreshTables } = useDatabase();
125
- const [queryResult, setQueryResult] = useState(null);
126
- const [isExecuting, setIsExecuting] = useState(false);
127
- const [editorHeight, setEditorHeight] = useState(300);
128
- const [isResizing, setIsResizing] = useState(false);
129
- const editorRef = useRef(null);
130
- const panelRef = useRef(null);
131
-
132
- // Update the height of the panel on editorHeight change
133
- useEffect(() => {
134
- if (panelRef.current) {
135
- panelRef.current.style.height = `${editorHeight}px`;
136
- }
137
- }, [editorHeight]);
138
-
139
- // Resizing logic for editor
140
- const startResizing = useCallback((mouseDownEvent) => {
141
- mouseDownEvent.preventDefault();
142
-
143
- const startHeight = editorHeight;
144
- const startY = mouseDownEvent.pageY;
145
-
146
- const onMouseMove = (mouseMoveEvent) => {
147
- const currentY = mouseMoveEvent.pageY;
148
- const newHeight = startHeight + (currentY - startY);
149
- const minHeight = 100;
150
- const maxHeight = window.innerHeight * 0.8;
151
-
152
- setEditorHeight(Math.min(Math.max(newHeight, minHeight), maxHeight));
153
- };
154
-
155
- const onMouseUp = () => {
156
- document.removeEventListener("mousemove", onMouseMove);
157
- document.removeEventListener("mouseup", onMouseUp);
158
- };
159
-
160
- document.addEventListener("mousemove", onMouseMove);
161
- document.addEventListener("mouseup", onMouseUp);
162
- }, [editorHeight]);
163
-
164
- // Execute query and refresh tables
165
- const executeQueryAndRefresh = async () => {
166
- if (!editorRef.current) return;
167
-
168
- const query = editorRef.current.getValue().trim().replace(/;+$/, '');
169
- if (!query) {
170
- setQueryResult({
171
- success: false,
172
- error: { message: "Query cannot be empty." },
173
- });
174
- return;
175
- }
176
-
177
- try {
178
- setIsExecuting(true);
179
- setQueryResult(null);
180
-
181
- const data = await executeQuery(query);
182
- const isSchemaModifying = /^(CREATE|DROP|ALTER)\s+TABLE/i.test(query);
183
- if (isSchemaModifying) {
184
- await refreshTables();
185
- }
186
-
187
- let results = [];
188
-
189
- // --- Updated extraction logic ---
190
- if (data.results) {
191
- if (Array.isArray(data.results)) {
192
- // Check for the columns/values shape (typical for schema queries)
193
- if (
194
- data.results.length > 0 &&
195
- data.results[0]?.columns &&
196
- data.results[0]?.values
197
- ) {
198
- const resultSet = data.results[0];
199
- results = resultSet.values.map((row) =>
200
- resultSet.columns.reduce((acc, col, idx) => {
201
- acc[col] = row[idx];
202
- return acc;
203
- }, {})
204
- );
205
- } else {
206
- // If we have one element with a "results" property, unwrap it.
207
- if (
208
- data.results.length === 1 &&
209
- data.results[0].results &&
210
- Array.isArray(data.results[0].results)
211
- ) {
212
- results = data.results[0].results;
213
- } else {
214
- // Otherwise, assume data.results is already an array of row objects.
215
- results = data.results;
216
- }
217
- }
218
- } else if (data.results.columns && data.results.values) {
219
- const resultSet = data.results;
220
- results = resultSet.values.map((row) =>
221
- resultSet.columns.reduce((acc, col, idx) => {
222
- acc[col] = row[idx];
223
- return acc;
224
- }, {})
225
- );
226
- }
227
- } else if (data.result && data.result.results) {
228
- if (Array.isArray(data.result.results)) {
229
- if (
230
- data.result.results.length > 0 &&
231
- data.result.results[0]?.columns &&
232
- data.result.results[0]?.values
233
- ) {
234
- const resultSet = data.result.results[0];
235
- results = resultSet.values.map((row) =>
236
- resultSet.columns.reduce((acc, col, idx) => {
237
- acc[col] = row[idx];
238
- return acc;
239
- }, {})
240
- );
241
- } else {
242
- if (
243
- data.result.results.length === 1 &&
244
- data.result.results[0].results &&
245
- Array.isArray(data.result.results[0].results)
246
- ) {
247
- results = data.result.results[0].results;
248
- } else {
249
- results = data.result.results;
250
- }
251
- }
252
- } else if (data.result.results.columns && data.result.results.values) {
253
- const resultSet = data.result.results;
254
- results = resultSet.values.map((row) =>
255
- resultSet.columns.reduce((acc, col, idx) => {
256
- acc[col] = row[idx];
257
- return acc;
258
- }, {})
259
- );
260
- }
261
- }
262
- // --- End updated extraction logic ---
263
-
264
- setQueryResult({
265
- success: true,
266
- results,
267
- });
268
- } catch (error) {
269
- const parsedError = parseSQLError(error) || { message: 'An unknown error occurred', details: {} };
270
- setQueryResult({
271
- success: false,
272
- error: parsedError,
273
- });
274
- } finally {
275
- setIsExecuting(false);
276
- }
277
- };
278
-
279
- const renderQueryResult = () => {
280
- if (isExecuting) {
281
- return (
282
- <div className="flex items-center text-sm text-neutral-700">
283
- <Loader2 className="h-4 w-4 animate-spin mr-2 font-sans" />
284
- Running your query...
285
- </div>
286
- );
287
- }
288
-
289
- if (!queryResult) {
290
- return <div className="text-sm text-neutral-500 font-sans">Run the query to see the results.</div>;
291
- }
292
-
293
- if (!queryResult.success) {
294
- console.debug("SQLEditor - Rendering error:", queryResult.error);
295
- return <SQLErrorDisplay error={queryResult.error} />;
296
- }
297
-
298
- const results = queryResult.results;
299
- if (!results || results.length === 0) {
300
- return <div className="text-sm text-neutral-900 font-sans">Success. No results to display.</div>;
301
- }
302
-
303
- return (
304
- <SQLResultsView
305
- query={editorRef.current?.getValue() || ''}
306
- results={results}
307
- />
308
- );
309
- };
310
-
311
-
312
- return (
313
- <div className="h-full flex flex-col bg-white text-neutral-900 font-sans">
314
- {/* Toolbar */}
315
- <div className="px-4 py-2 bg-neutral-100 border-b flex items-center gap-4">
316
- <QueryTemplateMenu
317
- onSelectQuery={(queryType) => {
318
- if (editorRef.current) {
319
- // Normalize the queryType to match HELPFUL_QUERIES keys
320
- const formattedQueryType = Object.keys(HELPFUL_QUERIES).find(
321
- (key) => key.toLowerCase() === queryType.toLowerCase()
322
- );
323
-
324
- if (formattedQueryType) {
325
- const query = HELPFUL_QUERIES[formattedQueryType];
326
- editorRef.current.setValue(query);
327
- editorRef.current.focus();
328
- } else {
329
- console.warn(`Query template not found for: ${queryType}`);
330
- }
331
- }
332
- }}
333
- />
334
- </div>
335
-
336
- {/* Query Editor */}
337
- <div
338
- ref={panelRef}
339
- className="relative pt-2 overflow-hidden"
340
- style={{ height: `${editorHeight}px`, minHeight: '100px' }}
341
- >
342
- <Editor
343
- height="100%"
344
- language="sql"
345
- options={{
346
- minimap: { enabled: false },
347
- fontSize: 14,
348
- wordWrap: "on",
349
- automaticLayout: true,
350
- lineNumbers: "on",
351
- fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
352
- }}
353
- onMount={(editor) => {
354
- editorRef.current = editor;
355
- // Ensure that the "monaco" global is available.
356
- editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => {
357
- executeQueryAndRefresh();
358
- });
359
- }}
360
- />
361
- </div>
362
-
363
- {/* Resizer */}
364
- <div
365
- className={`relative h-0.5 cursor-row-resize bg-neutral-200 group ${
366
- isResizing ? "bg-neutral-300" : "hover:bg-neutral-300"
367
- }`}
368
- onMouseDown={(e) => {
369
- setIsResizing(true);
370
- startResizing(e);
371
- }}
372
- onMouseUp={() => setIsResizing(false)}
373
- >
374
- <div
375
- className={`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-neutral-900 rounded-sm px-0.5
376
- ${isResizing ? "visible" : "invisible group-hover:visible"}`}
377
- >
378
- <GripHorizontal className="h-3 w-3 text-white" />
379
- </div>
380
- </div>
381
-
382
- {/* Query Results */}
383
- <div className="px-4 py-3 bg-neutral-100 border-b font-sans">
384
- <div className="flex justify-between items-center">
385
- <h3 className="text-sm font-medium">Results</h3>
386
- <Button
387
- size="sm"
388
- onClick={executeQueryAndRefresh}
389
- disabled={isExecuting}
390
- className="flex items-center gap-1 text-sm font-medium"
391
- >
392
- Run
393
- {isExecuting ? (
394
- <Loader2 className="h-4 w-4 animate-spin" />
395
- ) : (
396
- <>
397
- <Command className="h-4 w-4" />
398
- <CornerDownLeft className="h-4 w-4" />
399
- </>
400
- )}
401
- </Button>
402
- </div>
403
- </div>
404
-
405
- {/* Render Query Results */}
406
- <div className="flex-1 overflow-auto p-4 bg-white">
407
- {renderQueryResult()}
408
- </div>
409
- </div>
410
- );
411
- }