d1s 0.2.1

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 (408) hide show
  1. package/README.md +7 -0
  2. package/dist/.next/.next/BUILD_ID +1 -0
  3. package/dist/.next/.next/app-build-manifest.json +109 -0
  4. package/dist/.next/.next/app-path-routes-manifest.json +1 -0
  5. package/dist/.next/.next/build-manifest.json +33 -0
  6. package/dist/.next/.next/cache/.rscinfo +1 -0
  7. package/dist/.next/.next/cache/.tsbuildinfo +1 -0
  8. package/dist/.next/.next/cache/webpack/client-production/0.pack +0 -0
  9. package/dist/.next/.next/cache/webpack/client-production/1.pack +0 -0
  10. package/dist/.next/.next/cache/webpack/client-production/2.pack +0 -0
  11. package/dist/.next/.next/cache/webpack/client-production/index.pack +0 -0
  12. package/dist/.next/.next/cache/webpack/client-production/index.pack.old +0 -0
  13. package/dist/.next/.next/cache/webpack/edge-server-production/0.pack +0 -0
  14. package/dist/.next/.next/cache/webpack/edge-server-production/index.pack +0 -0
  15. package/dist/.next/.next/cache/webpack/server-production/0.pack +0 -0
  16. package/dist/.next/.next/cache/webpack/server-production/1.pack +0 -0
  17. package/dist/.next/.next/cache/webpack/server-production/index.pack +0 -0
  18. package/dist/.next/.next/cache/webpack/server-production/index.pack.old +0 -0
  19. package/dist/.next/.next/diagnostics/build-diagnostics.json +6 -0
  20. package/dist/.next/.next/diagnostics/framework.json +1 -0
  21. package/dist/.next/.next/export-marker.json +1 -0
  22. package/dist/.next/.next/images-manifest.json +1 -0
  23. package/dist/.next/.next/next-minimal-server.js.nft.json +1 -0
  24. package/dist/.next/.next/next-server.js.nft.json +1 -0
  25. package/dist/.next/.next/package.json +1 -0
  26. package/dist/.next/.next/prerender-manifest.json +1 -0
  27. package/dist/.next/.next/react-loadable-manifest.json +1 -0
  28. package/dist/.next/.next/required-server-files.json +1 -0
  29. package/dist/.next/.next/routes-manifest.json +1 -0
  30. package/dist/.next/.next/server/app/_not-found/page.js +1 -0
  31. package/dist/.next/.next/server/app/_not-found/page.js.nft.json +1 -0
  32. package/dist/.next/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  33. package/dist/.next/.next/server/app/_not-found.html +1 -0
  34. package/dist/.next/.next/server/app/_not-found.meta +8 -0
  35. package/dist/.next/.next/server/app/_not-found.rsc +16 -0
  36. package/dist/.next/.next/server/app/api/cloudflare/route.js +1 -0
  37. package/dist/.next/.next/server/app/api/cloudflare/route.js.nft.json +1 -0
  38. package/dist/.next/.next/server/app/api/cloudflare/route_client-reference-manifest.js +1 -0
  39. package/dist/.next/.next/server/app/api/databases/route.js +1 -0
  40. package/dist/.next/.next/server/app/api/databases/route.js.nft.json +1 -0
  41. package/dist/.next/.next/server/app/api/databases/route_client-reference-manifest.js +1 -0
  42. package/dist/.next/.next/server/app/api/migrations/sync/route.js +12 -0
  43. package/dist/.next/.next/server/app/api/migrations/sync/route.js.nft.json +1 -0
  44. package/dist/.next/.next/server/app/api/migrations/sync/route_client-reference-manifest.js +1 -0
  45. package/dist/.next/.next/server/app/api/migrations/sync-files/route.js +1 -0
  46. package/dist/.next/.next/server/app/api/migrations/sync-files/route.js.nft.json +1 -0
  47. package/dist/.next/.next/server/app/api/migrations/sync-files/route_client-reference-manifest.js +1 -0
  48. package/dist/.next/.next/server/app/api/pull-remote/confirm/route.js +1 -0
  49. package/dist/.next/.next/server/app/api/pull-remote/confirm/route.js.nft.json +1 -0
  50. package/dist/.next/.next/server/app/api/pull-remote/confirm/route_client-reference-manifest.js +1 -0
  51. package/dist/.next/.next/server/app/api/pull-remote/preview/route.js +1 -0
  52. package/dist/.next/.next/server/app/api/pull-remote/preview/route.js.nft.json +1 -0
  53. package/dist/.next/.next/server/app/api/pull-remote/preview/route_client-reference-manifest.js +1 -0
  54. package/dist/.next/.next/server/app/api/push-remote/confirm/route.js +14 -0
  55. package/dist/.next/.next/server/app/api/push-remote/confirm/route.js.nft.json +1 -0
  56. package/dist/.next/.next/server/app/api/push-remote/confirm/route_client-reference-manifest.js +1 -0
  57. package/dist/.next/.next/server/app/api/push-remote/preview/route.js +14 -0
  58. package/dist/.next/.next/server/app/api/push-remote/preview/route.js.nft.json +1 -0
  59. package/dist/.next/.next/server/app/api/push-remote/preview/route_client-reference-manifest.js +1 -0
  60. package/dist/.next/.next/server/app/api/query/route.js +8 -0
  61. package/dist/.next/.next/server/app/api/query/route.js.nft.json +1 -0
  62. package/dist/.next/.next/server/app/api/query/route_client-reference-manifest.js +1 -0
  63. package/dist/.next/.next/server/app/api/tables/[name]/route.js +5 -0
  64. package/dist/.next/.next/server/app/api/tables/[name]/route.js.nft.json +1 -0
  65. package/dist/.next/.next/server/app/api/tables/[name]/route_client-reference-manifest.js +1 -0
  66. package/dist/.next/.next/server/app/api/tables/route.js +7 -0
  67. package/dist/.next/.next/server/app/api/tables/route.js.nft.json +1 -0
  68. package/dist/.next/.next/server/app/api/tables/route_client-reference-manifest.js +1 -0
  69. package/dist/.next/.next/server/app/index.html +3 -0
  70. package/dist/.next/.next/server/app/index.meta +7 -0
  71. package/dist/.next/.next/server/app/index.rsc +20 -0
  72. package/dist/.next/.next/server/app/page.js +58 -0
  73. package/dist/.next/.next/server/app/page.js.nft.json +1 -0
  74. package/dist/.next/.next/server/app/page_client-reference-manifest.js +1 -0
  75. package/dist/.next/.next/server/app-paths-manifest.json +15 -0
  76. package/dist/.next/.next/server/chunks/336.js +1 -0
  77. package/dist/.next/.next/server/chunks/627.js +6 -0
  78. package/dist/.next/.next/server/chunks/638.js +13 -0
  79. package/dist/.next/.next/server/chunks/801.js +55 -0
  80. package/dist/.next/.next/server/chunks/973.js +2 -0
  81. package/dist/.next/.next/server/chunks/992.js +3 -0
  82. package/dist/.next/.next/server/functions-config-manifest.json +1 -0
  83. package/dist/.next/.next/server/interception-route-rewrite-manifest.js +1 -0
  84. package/dist/.next/.next/server/middleware-build-manifest.js +1 -0
  85. package/dist/.next/.next/server/middleware-manifest.json +6 -0
  86. package/dist/.next/.next/server/middleware-react-loadable-manifest.js +1 -0
  87. package/dist/.next/.next/server/next-font-manifest.js +1 -0
  88. package/dist/.next/.next/server/next-font-manifest.json +1 -0
  89. package/dist/.next/.next/server/pages/404.html +1 -0
  90. package/dist/.next/.next/server/pages/500.html +1 -0
  91. package/dist/.next/.next/server/pages/_app.js +1 -0
  92. package/dist/.next/.next/server/pages/_app.js.nft.json +1 -0
  93. package/dist/.next/.next/server/pages/_document.js +1 -0
  94. package/dist/.next/.next/server/pages/_document.js.nft.json +1 -0
  95. package/dist/.next/.next/server/pages/_error.js +1 -0
  96. package/dist/.next/.next/server/pages/_error.js.nft.json +1 -0
  97. package/dist/.next/.next/server/pages-manifest.json +1 -0
  98. package/dist/.next/.next/server/server-reference-manifest.js +1 -0
  99. package/dist/.next/.next/server/server-reference-manifest.json +1 -0
  100. package/dist/.next/.next/server/webpack-runtime.js +1 -0
  101. package/dist/.next/.next/static/ODMSSwVqLoDcBgbFHUjr8/_buildManifest.js +1 -0
  102. package/dist/.next/.next/static/ODMSSwVqLoDcBgbFHUjr8/_ssgManifest.js +1 -0
  103. package/dist/.next/.next/static/chunks/422-6fa3c14fc64ad67b.js +1 -0
  104. package/dist/.next/.next/static/chunks/4bd1b696-8c908eb707f85a27.js +1 -0
  105. package/dist/.next/.next/static/chunks/517-3b698a5d3da06ff7.js +2 -0
  106. package/dist/.next/.next/static/chunks/692-ede418e1d28a1394.js +1 -0
  107. package/dist/.next/.next/static/chunks/735-c9144179c6bd7d06.js +1 -0
  108. package/dist/.next/.next/static/chunks/92-c4466e0f1ca8a3a8.js +1 -0
  109. package/dist/.next/.next/static/chunks/app/_not-found/page-b786c3dd79ad15a5.js +1 -0
  110. package/dist/.next/.next/static/chunks/app/api/cloudflare/route-3458d78022185d7f.js +1 -0
  111. package/dist/.next/.next/static/chunks/app/api/databases/route-64255424877a9f72.js +1 -0
  112. package/dist/.next/.next/static/chunks/app/api/migrations/sync/route-03766b3afcf043ba.js +1 -0
  113. package/dist/.next/.next/static/chunks/app/api/migrations/sync-files/route-02fa291c8000dadf.js +1 -0
  114. package/dist/.next/.next/static/chunks/app/api/pull-remote/confirm/route-7e05bb8920127abe.js +1 -0
  115. package/dist/.next/.next/static/chunks/app/api/pull-remote/preview/route-0fa15f783e8a306c.js +1 -0
  116. package/dist/.next/.next/static/chunks/app/api/push-remote/confirm/route-96691f1880e4ed14.js +1 -0
  117. package/dist/.next/.next/static/chunks/app/api/push-remote/preview/route-a798679c67374552.js +1 -0
  118. package/dist/.next/.next/static/chunks/app/api/query/route-e90d0030a5083e20.js +1 -0
  119. package/dist/.next/.next/static/chunks/app/api/tables/[name]/route-1efe63e73b480e58.js +1 -0
  120. package/dist/.next/.next/static/chunks/app/api/tables/route-3772b4f480c4b4a4.js +1 -0
  121. package/dist/.next/.next/static/chunks/app/layout-8360fab69b848283.js +1 -0
  122. package/dist/.next/.next/static/chunks/app/page-75081ac7a88cb706.js +1 -0
  123. package/dist/.next/.next/static/chunks/framework-d29117d969504448.js +1 -0
  124. package/dist/.next/.next/static/chunks/main-8d0ab17774ffa031.js +1 -0
  125. package/dist/.next/.next/static/chunks/main-app-d36cdfb402b40f13.js +1 -0
  126. package/dist/.next/.next/static/chunks/pages/_app-d23763e3e6c904ff.js +1 -0
  127. package/dist/.next/.next/static/chunks/pages/_error-9b7125ad1a1e68fa.js +1 -0
  128. package/dist/.next/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  129. package/dist/.next/.next/static/chunks/webpack-c76ac1e586b2802a.js +1 -0
  130. package/dist/.next/.next/static/css/c51a7ef325e30c16.css +3 -0
  131. package/dist/.next/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
  132. package/dist/.next/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  133. package/dist/.next/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  134. package/dist/.next/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  135. package/dist/.next/.next/trace +3 -0
  136. package/dist/.next/.next/types/app/api/cloudflare/route.ts +347 -0
  137. package/dist/.next/.next/types/app/api/databases/route.ts +347 -0
  138. package/dist/.next/.next/types/app/api/migrations/sync/route.ts +347 -0
  139. package/dist/.next/.next/types/app/api/migrations/sync-files/route.ts +347 -0
  140. package/dist/.next/.next/types/app/api/pull-remote/confirm/route.ts +347 -0
  141. package/dist/.next/.next/types/app/api/pull-remote/preview/route.ts +347 -0
  142. package/dist/.next/.next/types/app/api/push-remote/confirm/route.ts +347 -0
  143. package/dist/.next/.next/types/app/api/push-remote/preview/route.ts +347 -0
  144. package/dist/.next/.next/types/app/api/query/route.ts +347 -0
  145. package/dist/.next/.next/types/app/api/tables/[name]/route.ts +347 -0
  146. package/dist/.next/.next/types/app/api/tables/route.ts +347 -0
  147. package/dist/.next/.next/types/app/page.ts +84 -0
  148. package/dist/.next/.next/types/cache-life.d.ts +141 -0
  149. package/dist/.next/.next/types/package.json +1 -0
  150. package/dist/.next/BUILD_ID +1 -0
  151. package/dist/.next/app-build-manifest.json +109 -0
  152. package/dist/.next/app-path-routes-manifest.json +1 -0
  153. package/dist/.next/build-manifest.json +33 -0
  154. package/dist/.next/cache/.rscinfo +1 -0
  155. package/dist/.next/cache/.tsbuildinfo +1 -0
  156. package/dist/.next/cache/webpack/client-production/0.pack +0 -0
  157. package/dist/.next/cache/webpack/client-production/index.pack +0 -0
  158. package/dist/.next/cache/webpack/edge-server-production/0.pack +0 -0
  159. package/dist/.next/cache/webpack/edge-server-production/index.pack +0 -0
  160. package/dist/.next/cache/webpack/server-production/0.pack +0 -0
  161. package/dist/.next/cache/webpack/server-production/index.pack +0 -0
  162. package/dist/.next/diagnostics/build-diagnostics.json +6 -0
  163. package/dist/.next/diagnostics/framework.json +1 -0
  164. package/dist/.next/export-marker.json +1 -0
  165. package/dist/.next/images-manifest.json +1 -0
  166. package/dist/.next/next-minimal-server.js.nft.json +1 -0
  167. package/dist/.next/next-server.js.nft.json +1 -0
  168. package/dist/.next/package.json +1 -0
  169. package/dist/.next/prerender-manifest.json +1 -0
  170. package/dist/.next/react-loadable-manifest.json +1 -0
  171. package/dist/.next/required-server-files.json +1 -0
  172. package/dist/.next/routes-manifest.json +1 -0
  173. package/dist/.next/server/app/_not-found/page.js +1 -0
  174. package/dist/.next/server/app/_not-found/page.js.nft.json +1 -0
  175. package/dist/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  176. package/dist/.next/server/app/_not-found.html +1 -0
  177. package/dist/.next/server/app/_not-found.meta +8 -0
  178. package/dist/.next/server/app/_not-found.rsc +16 -0
  179. package/dist/.next/server/app/api/cloudflare/route.js +1 -0
  180. package/dist/.next/server/app/api/cloudflare/route.js.nft.json +1 -0
  181. package/dist/.next/server/app/api/cloudflare/route_client-reference-manifest.js +1 -0
  182. package/dist/.next/server/app/api/databases/route.js +1 -0
  183. package/dist/.next/server/app/api/databases/route.js.nft.json +1 -0
  184. package/dist/.next/server/app/api/databases/route_client-reference-manifest.js +1 -0
  185. package/dist/.next/server/app/api/migrations/sync/route.js +12 -0
  186. package/dist/.next/server/app/api/migrations/sync/route.js.nft.json +1 -0
  187. package/dist/.next/server/app/api/migrations/sync/route_client-reference-manifest.js +1 -0
  188. package/dist/.next/server/app/api/migrations/sync-files/route.js +1 -0
  189. package/dist/.next/server/app/api/migrations/sync-files/route.js.nft.json +1 -0
  190. package/dist/.next/server/app/api/migrations/sync-files/route_client-reference-manifest.js +1 -0
  191. package/dist/.next/server/app/api/pull-remote/confirm/route.js +1 -0
  192. package/dist/.next/server/app/api/pull-remote/confirm/route.js.nft.json +1 -0
  193. package/dist/.next/server/app/api/pull-remote/confirm/route_client-reference-manifest.js +1 -0
  194. package/dist/.next/server/app/api/pull-remote/preview/route.js +1 -0
  195. package/dist/.next/server/app/api/pull-remote/preview/route.js.nft.json +1 -0
  196. package/dist/.next/server/app/api/pull-remote/preview/route_client-reference-manifest.js +1 -0
  197. package/dist/.next/server/app/api/push-remote/confirm/route.js +14 -0
  198. package/dist/.next/server/app/api/push-remote/confirm/route.js.nft.json +1 -0
  199. package/dist/.next/server/app/api/push-remote/confirm/route_client-reference-manifest.js +1 -0
  200. package/dist/.next/server/app/api/push-remote/preview/route.js +14 -0
  201. package/dist/.next/server/app/api/push-remote/preview/route.js.nft.json +1 -0
  202. package/dist/.next/server/app/api/push-remote/preview/route_client-reference-manifest.js +1 -0
  203. package/dist/.next/server/app/api/query/route.js +8 -0
  204. package/dist/.next/server/app/api/query/route.js.nft.json +1 -0
  205. package/dist/.next/server/app/api/query/route_client-reference-manifest.js +1 -0
  206. package/dist/.next/server/app/api/tables/[name]/route.js +5 -0
  207. package/dist/.next/server/app/api/tables/[name]/route.js.nft.json +1 -0
  208. package/dist/.next/server/app/api/tables/[name]/route_client-reference-manifest.js +1 -0
  209. package/dist/.next/server/app/api/tables/route.js +7 -0
  210. package/dist/.next/server/app/api/tables/route.js.nft.json +1 -0
  211. package/dist/.next/server/app/api/tables/route_client-reference-manifest.js +1 -0
  212. package/dist/.next/server/app/index.html +3 -0
  213. package/dist/.next/server/app/index.meta +7 -0
  214. package/dist/.next/server/app/index.rsc +20 -0
  215. package/dist/.next/server/app/page.js +58 -0
  216. package/dist/.next/server/app/page.js.nft.json +1 -0
  217. package/dist/.next/server/app/page_client-reference-manifest.js +1 -0
  218. package/dist/.next/server/app-paths-manifest.json +15 -0
  219. package/dist/.next/server/chunks/336.js +1 -0
  220. package/dist/.next/server/chunks/627.js +6 -0
  221. package/dist/.next/server/chunks/638.js +13 -0
  222. package/dist/.next/server/chunks/801.js +55 -0
  223. package/dist/.next/server/chunks/973.js +2 -0
  224. package/dist/.next/server/chunks/992.js +3 -0
  225. package/dist/.next/server/functions-config-manifest.json +1 -0
  226. package/dist/.next/server/interception-route-rewrite-manifest.js +1 -0
  227. package/dist/.next/server/middleware-build-manifest.js +1 -0
  228. package/dist/.next/server/middleware-manifest.json +6 -0
  229. package/dist/.next/server/middleware-react-loadable-manifest.js +1 -0
  230. package/dist/.next/server/next-font-manifest.js +1 -0
  231. package/dist/.next/server/next-font-manifest.json +1 -0
  232. package/dist/.next/server/pages/404.html +1 -0
  233. package/dist/.next/server/pages/500.html +1 -0
  234. package/dist/.next/server/pages/_app.js +1 -0
  235. package/dist/.next/server/pages/_app.js.nft.json +1 -0
  236. package/dist/.next/server/pages/_document.js +1 -0
  237. package/dist/.next/server/pages/_document.js.nft.json +1 -0
  238. package/dist/.next/server/pages/_error.js +1 -0
  239. package/dist/.next/server/pages/_error.js.nft.json +1 -0
  240. package/dist/.next/server/pages-manifest.json +1 -0
  241. package/dist/.next/server/server-reference-manifest.js +1 -0
  242. package/dist/.next/server/server-reference-manifest.json +1 -0
  243. package/dist/.next/server/webpack-runtime.js +1 -0
  244. package/dist/.next/static/OmPVuV0d1lrcjSBQzxkdH/_buildManifest.js +1 -0
  245. package/dist/.next/static/OmPVuV0d1lrcjSBQzxkdH/_ssgManifest.js +1 -0
  246. package/dist/.next/static/chunks/422-6fa3c14fc64ad67b.js +1 -0
  247. package/dist/.next/static/chunks/4bd1b696-8c908eb707f85a27.js +1 -0
  248. package/dist/.next/static/chunks/517-3b698a5d3da06ff7.js +2 -0
  249. package/dist/.next/static/chunks/692-ede418e1d28a1394.js +1 -0
  250. package/dist/.next/static/chunks/735-c9144179c6bd7d06.js +1 -0
  251. package/dist/.next/static/chunks/92-c4466e0f1ca8a3a8.js +1 -0
  252. package/dist/.next/static/chunks/app/_not-found/page-b786c3dd79ad15a5.js +1 -0
  253. package/dist/.next/static/chunks/app/api/cloudflare/route-3458d78022185d7f.js +1 -0
  254. package/dist/.next/static/chunks/app/api/databases/route-64255424877a9f72.js +1 -0
  255. package/dist/.next/static/chunks/app/api/migrations/sync/route-03766b3afcf043ba.js +1 -0
  256. package/dist/.next/static/chunks/app/api/migrations/sync-files/route-02fa291c8000dadf.js +1 -0
  257. package/dist/.next/static/chunks/app/api/pull-remote/confirm/route-7e05bb8920127abe.js +1 -0
  258. package/dist/.next/static/chunks/app/api/pull-remote/preview/route-0fa15f783e8a306c.js +1 -0
  259. package/dist/.next/static/chunks/app/api/push-remote/confirm/route-96691f1880e4ed14.js +1 -0
  260. package/dist/.next/static/chunks/app/api/push-remote/preview/route-a798679c67374552.js +1 -0
  261. package/dist/.next/static/chunks/app/api/query/route-e90d0030a5083e20.js +1 -0
  262. package/dist/.next/static/chunks/app/api/tables/[name]/route-1efe63e73b480e58.js +1 -0
  263. package/dist/.next/static/chunks/app/api/tables/route-3772b4f480c4b4a4.js +1 -0
  264. package/dist/.next/static/chunks/app/layout-8360fab69b848283.js +1 -0
  265. package/dist/.next/static/chunks/app/page-75081ac7a88cb706.js +1 -0
  266. package/dist/.next/static/chunks/framework-d29117d969504448.js +1 -0
  267. package/dist/.next/static/chunks/main-8d0ab17774ffa031.js +1 -0
  268. package/dist/.next/static/chunks/main-app-d36cdfb402b40f13.js +1 -0
  269. package/dist/.next/static/chunks/pages/_app-d23763e3e6c904ff.js +1 -0
  270. package/dist/.next/static/chunks/pages/_error-9b7125ad1a1e68fa.js +1 -0
  271. package/dist/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  272. package/dist/.next/static/chunks/webpack-c76ac1e586b2802a.js +1 -0
  273. package/dist/.next/static/css/c51a7ef325e30c16.css +3 -0
  274. package/dist/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
  275. package/dist/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  276. package/dist/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  277. package/dist/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  278. package/dist/.next/trace +13 -0
  279. package/dist/.next/types/app/api/cloudflare/route.ts +347 -0
  280. package/dist/.next/types/app/api/databases/route.ts +347 -0
  281. package/dist/.next/types/app/api/migrations/sync/route.ts +347 -0
  282. package/dist/.next/types/app/api/migrations/sync-files/route.ts +347 -0
  283. package/dist/.next/types/app/api/pull-remote/confirm/route.ts +347 -0
  284. package/dist/.next/types/app/api/pull-remote/preview/route.ts +347 -0
  285. package/dist/.next/types/app/api/push-remote/confirm/route.ts +347 -0
  286. package/dist/.next/types/app/api/push-remote/preview/route.ts +347 -0
  287. package/dist/.next/types/app/api/query/route.ts +347 -0
  288. package/dist/.next/types/app/api/tables/[name]/route.ts +347 -0
  289. package/dist/.next/types/app/api/tables/route.ts +347 -0
  290. package/dist/.next/types/app/page.ts +84 -0
  291. package/dist/.next/types/cache-life.d.ts +141 -0
  292. package/dist/.next/types/package.json +1 -0
  293. package/dist/app/api/cloudflare/route.js +146 -0
  294. package/dist/app/api/databases/route.js +72 -0
  295. package/dist/app/api/migrations/sync/route.js +172 -0
  296. package/dist/app/api/migrations/sync-files/route.js +172 -0
  297. package/dist/app/api/pull-remote/confirm/route.js +277 -0
  298. package/dist/app/api/pull-remote/preview/route.js +143 -0
  299. package/dist/app/api/push-remote/confirm/route.js +196 -0
  300. package/dist/app/api/push-remote/preview/route.js +178 -0
  301. package/dist/app/api/query/route.js +160 -0
  302. package/dist/app/api/tables/[name]/route.js +173 -0
  303. package/dist/app/api/tables/route.js +174 -0
  304. package/dist/app/app/api/cloudflare/route.js +146 -0
  305. package/dist/app/app/api/databases/route.js +72 -0
  306. package/dist/app/app/api/migrations/sync/route.js +172 -0
  307. package/dist/app/app/api/migrations/sync-files/route.js +172 -0
  308. package/dist/app/app/api/pull-remote/confirm/route.js +277 -0
  309. package/dist/app/app/api/pull-remote/preview/route.js +143 -0
  310. package/dist/app/app/api/push-remote/confirm/route.js +196 -0
  311. package/dist/app/app/api/push-remote/preview/route.js +178 -0
  312. package/dist/app/app/api/query/route.js +160 -0
  313. package/dist/app/app/api/tables/[name]/route.js +173 -0
  314. package/dist/app/app/api/tables/route.js +174 -0
  315. package/dist/app/app/globals.css +93 -0
  316. package/dist/app/app/layout.jsx +35 -0
  317. package/dist/app/app/page.jsx +37 -0
  318. package/dist/app/globals.css +93 -0
  319. package/dist/app/layout.jsx +35 -0
  320. package/dist/app/page.jsx +37 -0
  321. package/dist/d1-studio.js +344 -0
  322. package/dist/lib/database-queue.js +33 -0
  323. package/dist/lib/error.js +20 -0
  324. package/dist/lib/find-wrangler-config.js +67 -0
  325. package/dist/lib/license.js +99 -0
  326. package/dist/lib/migrations.js +415 -0
  327. package/dist/lib/parse-sql-error.js +200 -0
  328. package/dist/lib/request-deduplication.js +24 -0
  329. package/dist/lib/schema-operations.js +103 -0
  330. package/dist/lib/sql-error-types.js +14 -0
  331. package/dist/lib/sql-operations.js +557 -0
  332. package/dist/lib/utils.js +6 -0
  333. package/next.config.mjs +18 -0
  334. package/package.json +97 -0
  335. package/postcss.config.mjs +8 -0
  336. package/scripts/studio.js +344 -0
  337. package/scripts/test.js +168 -0
  338. package/src/app/api/cloudflare/route.js +146 -0
  339. package/src/app/api/databases/route.js +72 -0
  340. package/src/app/api/migrations/sync/route.js +172 -0
  341. package/src/app/api/migrations/sync-files/route.js +172 -0
  342. package/src/app/api/pull-remote/confirm/route.js +277 -0
  343. package/src/app/api/pull-remote/preview/route.js +143 -0
  344. package/src/app/api/push-remote/confirm/route.js +196 -0
  345. package/src/app/api/push-remote/preview/route.js +178 -0
  346. package/src/app/api/query/route.js +160 -0
  347. package/src/app/api/tables/[name]/route.js +173 -0
  348. package/src/app/api/tables/route.js +174 -0
  349. package/src/app/globals.css +93 -0
  350. package/src/app/layout.jsx +35 -0
  351. package/src/app/page.jsx +37 -0
  352. package/src/components/cloudflare-credentials-modal.jsx +94 -0
  353. package/src/components/column-selector.jsx +133 -0
  354. package/src/components/column-sorting.jsx +65 -0
  355. package/src/components/delete-records-dialog.jsx +64 -0
  356. package/src/components/download-button.jsx +205 -0
  357. package/src/components/edit-error-alert.jsx +30 -0
  358. package/src/components/editable-cell.jsx +163 -0
  359. package/src/components/editable-row.jsx +169 -0
  360. package/src/components/environment-handler.jsx +278 -0
  361. package/src/components/environment-select.jsx +59 -0
  362. package/src/components/pull-preview-toast.jsx +188 -0
  363. package/src/components/push-error-alert.jsx +72 -0
  364. package/src/components/push-preview-toast.jsx +183 -0
  365. package/src/components/query-results.jsx +112 -0
  366. package/src/components/refresh-button.jsx +61 -0
  367. package/src/components/resize-columns.jsx +101 -0
  368. package/src/components/sidebar.jsx +236 -0
  369. package/src/components/sql-editor.jsx +411 -0
  370. package/src/components/sql-error-display.jsx +167 -0
  371. package/src/components/sync-migrations-button.jsx +87 -0
  372. package/src/components/table-error-dialog.jsx +65 -0
  373. package/src/components/table-toolbar.jsx +285 -0
  374. package/src/components/table-view.jsx +843 -0
  375. package/src/components/ui/alert.jsx +47 -0
  376. package/src/components/ui/button.jsx +48 -0
  377. package/src/components/ui/card.jsx +50 -0
  378. package/src/components/ui/checkbox.jsx +24 -0
  379. package/src/components/ui/collapsible.jsx +11 -0
  380. package/src/components/ui/dialog.jsx +96 -0
  381. package/src/components/ui/dropdown-menu.jsx +158 -0
  382. package/src/components/ui/input.jsx +19 -0
  383. package/src/components/ui/scroll-area.jsx +40 -0
  384. package/src/components/ui/select.jsx +121 -0
  385. package/src/components/ui/separator.jsx +25 -0
  386. package/src/components/ui/sheet.jsx +109 -0
  387. package/src/components/ui/sidebar.jsx +620 -0
  388. package/src/components/ui/skeleton.jsx +14 -0
  389. package/src/components/ui/table.jsx +86 -0
  390. package/src/components/ui/tabs.jsx +43 -0
  391. package/src/components/ui/toast.jsx +86 -0
  392. package/src/components/ui/toaster.jsx +35 -0
  393. package/src/components/ui/tooltip.jsx +28 -0
  394. package/src/context/database-context.js +510 -0
  395. package/src/hooks/use-mobile.jsx +19 -0
  396. package/src/hooks/use-sql-error.ts +23 -0
  397. package/src/hooks/use-toast.js +155 -0
  398. package/src/lib/database-queue.js +33 -0
  399. package/src/lib/error.js +20 -0
  400. package/src/lib/find-wrangler-config.js +67 -0
  401. package/src/lib/license.js +99 -0
  402. package/src/lib/migrations.js +415 -0
  403. package/src/lib/parse-sql-error.js +200 -0
  404. package/src/lib/request-deduplication.js +24 -0
  405. package/src/lib/schema-operations.js +103 -0
  406. package/src/lib/sql-error-types.js +14 -0
  407. package/src/lib/sql-operations.js +557 -0
  408. package/src/lib/utils.js +6 -0
@@ -0,0 +1,236 @@
1
+ // components/sidebar.jsx
2
+ 'use client';
3
+
4
+ import React, { useEffect, useState } 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
+ // Filter tables based on search term
46
+ const filteredTables =
47
+ tables?.filter((table) =>
48
+ table.toLowerCase().includes(searchTerm.toLowerCase())
49
+ ) || [];
50
+
51
+ const handleTableClick = async (table) => {
52
+ try {
53
+ setIsTableLoading(true);
54
+ setSelectedTable(table);
55
+ onTableSelect(table);
56
+ } catch (error) {
57
+ console.error('Error selecting table:', error);
58
+ } finally {
59
+ setIsTableLoading(false);
60
+ }
61
+ };
62
+
63
+ const handleEnvironmentChange = async (value) => {
64
+ console.log('Environment change triggered:', value);
65
+ // Immediately update the environment state so the UI reflects the correct label
66
+ setEnvironment(value);
67
+
68
+ if (value === 'production') {
69
+ try {
70
+ const credentials = await validateStoredCredentials();
71
+ if (!credentials) {
72
+ setShowCredentialsModal(true);
73
+ return;
74
+ }
75
+ // Trigger push preview or push directly (as desired)
76
+ await pushToRemote();
77
+ } catch (error) {
78
+ console.error('Environment change failed:', error);
79
+ setEnvironment('local');
80
+ }
81
+ } else if (value === 'pull') {
82
+ try {
83
+ const credentials = await validateStoredCredentials();
84
+ if (!credentials) {
85
+ setShowCredentialsModal(true);
86
+ return;
87
+ }
88
+ // Instead of immediately pulling, show the pull preview toast
89
+ await pullToRemotePreview();
90
+ // Optionally, you may keep the environment value as "pull" until confirmation,
91
+ // then revert to "local" in the confirm pull flow.
92
+ } catch (error) {
93
+ console.error('Pull from remote failed:', error);
94
+ setEnvironment('local');
95
+ }
96
+ } else {
97
+ setEnvironment(value);
98
+ }
99
+ };
100
+
101
+ useEffect(() => {
102
+ const fetchDatabases = async () => {
103
+ try {
104
+ const response = await fetch('/api/databases');
105
+ const data = await response.json();
106
+
107
+ if (!response.ok) {
108
+ throw new Error(data.error || 'Failed to fetch databases');
109
+ }
110
+
111
+ setDatabases(data.databases || []);
112
+ } catch (error) {
113
+ console.error('Error fetching databases:', error);
114
+ }
115
+ };
116
+
117
+ fetchDatabases();
118
+ refreshTables();
119
+ }, [refreshTables]);
120
+
121
+ return (
122
+ <>
123
+ <aside className={`${className} bg-neutral-50 p-4`}>
124
+ <div className="font-sans">
125
+ {/* Header */}
126
+ <div className="flex items-center gap-2 mb-6">
127
+ <Table2 className="h-5 w-5" />
128
+ <span className="font-mono font-bold text-sm">d1-studio</span>
129
+ </div>
130
+
131
+ {/* Error Message */}
132
+ {error && (
133
+ <Alert variant="destructive" className="mb-4">
134
+ <AlertCircle className="h-4 w-4" />
135
+ <AlertDescription className="text-sm ml-2">{error}</AlertDescription>
136
+ </Alert>
137
+ )}
138
+
139
+ {/* Database Section */}
140
+ <div className="flex items-center justify-between mb-6">
141
+ <div>
142
+ <div className="text-xs text-muted-foreground mb-1">Database name</div>
143
+ <div className="font-semibold text-sm">
144
+ {databases[0]?.database_name || 'No database found'}
145
+ </div>
146
+ </div>
147
+
148
+ <EnvironmentSelect
149
+ value={environment}
150
+ onValueChange={handleEnvironmentChange}
151
+ isLoading={isPushing}
152
+ disabled={isConnecting}
153
+ showPreview={showPreview}
154
+ />
155
+ </div>
156
+
157
+ {/* SQL Editor Section */}
158
+ <div className="mb-6">
159
+ <button
160
+ className={`w-full flex items-center gap-x-1 border rounded-md text-sm font-medium transition-colors px-2 py-2
161
+ ${currentView === 'sql-editor' ? 'bg-neutral-900 text-white' : 'bg-white hover:bg-neutral-100'}`}
162
+ onClick={() => onNavigate('sql-editor')}
163
+ disabled={isTableLoading}
164
+ >
165
+ <TerminalSquare className="h-[16px] w-[16px]" />
166
+ SQL editor
167
+ </button>
168
+ </div>
169
+
170
+ {/* Search Section */}
171
+ <div className="relative mb-6 bg-white">
172
+ <Search className="absolute left-2 top-2.5 h-4 w-4 text-neutral-500" />
173
+ <Input
174
+ placeholder="Search tables"
175
+ value={searchTerm}
176
+ onChange={(e) => setSearchTerm(e.target.value)}
177
+ className="pl-7"
178
+ />
179
+ </div>
180
+
181
+ {/* Tables Section */}
182
+ <div>
183
+ <div className="flex items-center justify-between mb-1">
184
+ <h3 className="text-sm font-medium text-muted-foreground">
185
+ Tables {tables?.length ? `(${tables.length})` : ''}
186
+ </h3>
187
+ {isTablesLoading && <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />}
188
+ </div>
189
+
190
+ {/* Tables List */}
191
+ <div className="space-y-1 font-sans">
192
+ {!isTablesLoading && filteredTables.length === 0 && (
193
+ <div className="text-sm font-medium text-muted-foreground px-2 py-2">
194
+ {searchTerm
195
+ ? 'No matching tables found'
196
+ : error
197
+ ? 'Error loading tables'
198
+ : 'No tables available'
199
+ }
200
+ </div>
201
+ )}
202
+
203
+ {filteredTables.map((table) => (
204
+ <button
205
+ key={table}
206
+ className={`w-full text-left text-sm font-medium rounded-md transition-colors px-2 py-2
207
+ ${currentView === 'table-view' && selectedTable === table
208
+ ? 'bg-[#F0F0F0] text-neutral-900 font-semibold'
209
+ : 'text-neutral-700 hover:bg-[#F2F2F2]'}
210
+ ${isTableLoading && 'opacity-50 cursor-not-allowed'}`}
211
+ onClick={() => handleTableClick(table)}
212
+ disabled={isTableLoading}
213
+ >
214
+ {table}
215
+ </button>
216
+ ))}
217
+ </div>
218
+ </div>
219
+ </div>
220
+
221
+ {/* Cloudflare Credentials Modal */}
222
+ <CloudflareCredentialsModal
223
+ open={showCredentialsModal}
224
+ onClose={() => {
225
+ setShowCredentialsModal(false);
226
+ setEnvironment('local');
227
+ }}
228
+ onSubmit={connectToCloudflare}
229
+ />
230
+ </aside>
231
+
232
+ {/* Preview UI */}
233
+ {PreviewUI}
234
+ </>
235
+ );
236
+ }
@@ -0,0 +1,411 @@
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
+ }