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,344 @@
1
+ #!/usr/bin/env node
2
+ import chalk from 'chalk';
3
+ import open from 'open';
4
+ import { fileURLToPath } from 'url';
5
+ import { dirname, join } from 'path';
6
+ import { createHash } from 'crypto';
7
+ import { homedir } from 'os';
8
+ import os from 'os';
9
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
10
+ import express from 'express';
11
+ import { createServer } from 'http';
12
+ import next from 'next';
13
+ import { findWranglerConfig } from '../src/lib/find-wrangler-config.js';
14
+
15
+ // Compute the absolute path of this file and its directory.
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+
19
+ // console.log(chalk.blue('Resolved __filename:'), __filename);
20
+ // console.log(chalk.blue('Resolved __dirname:'), __dirname);
21
+
22
+ // License validation utilities
23
+ class LicenseError extends Error {
24
+ constructor(message, type = 'VALIDATION_ERROR') {
25
+ super(message);
26
+ this.name = 'LicenseError';
27
+ this.type = type;
28
+ }
29
+ }
30
+
31
+ async function generateHardwareId() {
32
+ const osInfo = {
33
+ platform: process.platform,
34
+ arch: process.arch,
35
+ cpus: os.cpus().length,
36
+ hostname: os.hostname(),
37
+ username: os.userInfo().username,
38
+ };
39
+ const systemString = JSON.stringify(osInfo);
40
+ return createHash('sha256').update(systemString).digest('hex');
41
+ }
42
+
43
+ async function validateLicenseRemote(licenseKey, email, hardwareId) {
44
+ const baseUrl =
45
+ process.env.NODE_ENV === 'development'
46
+ ? 'http://localhost:4000'
47
+ : 'https://d1-studio.com';
48
+
49
+ try {
50
+ const response = await fetch(`${baseUrl}/api/validate-license`, {
51
+ method: 'POST',
52
+ headers: {
53
+ 'Content-Type': 'application/json',
54
+ },
55
+ body: JSON.stringify({
56
+ licenseKey,
57
+ email,
58
+ hardwareId,
59
+ }),
60
+ });
61
+
62
+ const result = await response.json();
63
+
64
+ if (!response.ok) {
65
+ throw new LicenseError(
66
+ result.message || 'License validation failed',
67
+ result.type || 'VALIDATION_ERROR'
68
+ );
69
+ }
70
+
71
+ return result;
72
+ } catch (error) {
73
+ if (error instanceof LicenseError) {
74
+ throw error;
75
+ }
76
+
77
+ if (error.name === 'TypeError' && error.message.includes('fetch')) {
78
+ throw new LicenseError(
79
+ process.env.NODE_ENV === 'development'
80
+ ? 'Unable to connect to local license validation service. Make sure the development server is running.'
81
+ : 'Unable to connect to license server. Please check your internet connection.',
82
+ 'CONNECTION_ERROR'
83
+ );
84
+ }
85
+
86
+ throw new LicenseError(
87
+ 'An unexpected error occurred during license validation',
88
+ 'VALIDATION_ERROR'
89
+ );
90
+ }
91
+ }
92
+
93
+ async function checkLicenseFile() {
94
+ const licenseDir = join(homedir(), '.d1studio');
95
+ const licensePath = join(licenseDir, 'license.json');
96
+
97
+ try {
98
+ const licenseData = JSON.parse(await readFile(licensePath, 'utf8'));
99
+ const hardwareId = await generateHardwareId();
100
+
101
+ if (licenseData.hardwareId !== hardwareId) {
102
+ return null;
103
+ }
104
+
105
+ return licenseData;
106
+ } catch (error) {
107
+ return null;
108
+ }
109
+ }
110
+
111
+ async function saveLicenseFile(licenseData) {
112
+ const licenseDir = join(homedir(), '.d1studio');
113
+ const licensePath = join(licenseDir, 'license.json');
114
+
115
+ try {
116
+ await mkdir(licenseDir, { recursive: true });
117
+ await writeFile(licensePath, JSON.stringify(licenseData, null, 2));
118
+ } catch (error) {
119
+ throw new LicenseError('Failed to save license information', 'SAVE_ERROR');
120
+ }
121
+ }
122
+
123
+ async function startServer(port, projectDirectory) {
124
+ return new Promise((resolvePromise, rejectPromise) => {
125
+ const dev = process.env.NODE_ENV === 'development';
126
+ // Point to the parent directory that contains both app and .next
127
+ const dir = join(__dirname, '..');
128
+ const app = next({
129
+ dev,
130
+ dir,
131
+ conf: {
132
+ distDir: '.next',
133
+ // Ensure app directory is correctly set for routing
134
+ experimental: {
135
+ appDir: true
136
+ }
137
+ }
138
+ });
139
+ const handle = app.getRequestHandler();
140
+
141
+ app.prepare()
142
+ .then(() => {
143
+ const server = express();
144
+
145
+ // Set environment variables
146
+ process.env.PORT = port.toString();
147
+ process.env.D1_PROJECT_DIR = projectDirectory;
148
+
149
+ // Create HTTP server
150
+ const httpServer = createServer((req, res) => {
151
+ handle(req, res);
152
+ });
153
+
154
+ // Handle all requests through Next.js
155
+ server.all('*', (req, res) => {
156
+ return handle(req, res);
157
+ });
158
+
159
+ // Start listening
160
+ httpServer.listen(port, (err) => {
161
+ if (err) {
162
+ console.error(chalk.red('Failed to start server:'), err);
163
+ rejectPromise(err);
164
+ return;
165
+ }
166
+
167
+ console.log(chalk.green(`Server started on port ${port}`));
168
+ resolvePromise(httpServer);
169
+ });
170
+
171
+ // Handle server errors
172
+ httpServer.on('error', (err) => {
173
+ console.error(chalk.red('Server error:'), err);
174
+ rejectPromise(err);
175
+ });
176
+ })
177
+ .catch((err) => {
178
+ console.error(chalk.red('Failed to prepare Next.js app:'), err);
179
+ rejectPromise(err);
180
+ });
181
+ });
182
+ }
183
+
184
+ async function startStudio() {
185
+ try {
186
+ console.log(chalk.green('Initializing D1 Studio...'));
187
+
188
+ // Validate license
189
+ let licenseData = await checkLicenseFile();
190
+ console.log(chalk.blue('License data found:'), licenseData);
191
+
192
+ if (!licenseData) {
193
+ const { default: inquirer } = await import('inquirer');
194
+ console.log(chalk.blue('\nPlease enter your D1 Studio license information:'));
195
+
196
+ const answers = await inquirer.prompt([
197
+ {
198
+ type: 'input',
199
+ name: 'licenseKey',
200
+ message: 'License Key:',
201
+ validate: (input) => input.length > 0 || 'License key is required',
202
+ },
203
+ {
204
+ type: 'input',
205
+ name: 'email',
206
+ message: 'Email:',
207
+ validate: (input) => {
208
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
209
+ return emailRegex.test(input) || 'Please enter a valid email';
210
+ },
211
+ },
212
+ ]);
213
+
214
+ console.log(chalk.blue('Entered license information:'), answers);
215
+
216
+ const hardwareId = await generateHardwareId();
217
+ // console.log(chalk.blue('Generated hardware ID:'), hardwareId);
218
+
219
+ try {
220
+ const validation = await validateLicenseRemote(
221
+ answers.licenseKey,
222
+ answers.email,
223
+ hardwareId
224
+ );
225
+
226
+ licenseData = {
227
+ licenseKey: answers.licenseKey,
228
+ email: answers.email,
229
+ hardwareId,
230
+ licenseType: validation.licenseType,
231
+ activatedAt: new Date().toISOString(),
232
+ };
233
+
234
+ await saveLicenseFile(licenseData);
235
+ console.log(chalk.green('\nLicense activated successfully!'));
236
+ } catch (error) {
237
+ console.error(chalk.red('\nLicense validation failed:'), error.message);
238
+ process.exit(1);
239
+ }
240
+ }
241
+
242
+ // Get wrangler configuration
243
+ try {
244
+ const userProjectPath = process.cwd();
245
+ // console.log(chalk.blue('Current working directory:'), userProjectPath);
246
+
247
+ if (!userProjectPath) {
248
+ console.error(chalk.red('Error: Could not determine project directory'));
249
+ process.exit(1);
250
+ }
251
+
252
+ const wranglerResult = await findWranglerConfig(userProjectPath);
253
+ // console.log(chalk.blue('Wrangler config result:'), wranglerResult);
254
+
255
+ if (!wranglerResult || !wranglerResult.config) {
256
+ console.error(chalk.red('\nError: No wrangler.toml found in current directory'));
257
+ console.log(chalk.yellow('Make sure you are in a Cloudflare Workers project directory'));
258
+ console.log(chalk.yellow('with a valid wrangler.toml file.'));
259
+ process.exit(1);
260
+ }
261
+
262
+ const { config, projectPath } = wranglerResult;
263
+ // console.log(chalk.blue('Resolved wrangler.toml project path:'), projectPath);
264
+
265
+ if (!config.d1_databases?.length) {
266
+ console.error(chalk.red('\nError: No D1 databases configured in wrangler.toml'));
267
+ console.log(chalk.yellow('\nAdd D1 configuration to your wrangler.toml:'));
268
+ console.log(chalk.gray(`
269
+ [[d1_databases]]
270
+ binding = "DB"
271
+ database_name = "my-database"
272
+ database_id = "<your-database-id>"
273
+ `));
274
+ process.exit(1);
275
+ }
276
+
277
+ // Display found databases
278
+ console.log(chalk.green('\nFound D1 databases:'));
279
+ config.d1_databases.forEach((db) => {
280
+ console.log(chalk.blue(` - ${db.database_name} (${db.binding})`));
281
+ });
282
+
283
+ const port = 4000;
284
+ const url = `http://localhost:${port}`;
285
+
286
+ await startServer(port, projectPath);
287
+
288
+ console.log(chalk.green(`
289
+ ┌─────────────────────────────────────────┐
290
+ │ │
291
+ │ D1 Studio is running on port ${port} │
292
+ │ │
293
+ │ Local: ${url} │
294
+ │ │
295
+ └─────────────────────────────────────────┘
296
+ `));
297
+
298
+ // Add delay before opening browser
299
+ await new Promise(resolve => setTimeout(resolve, 2000));
300
+
301
+ try {
302
+ await open(url, {
303
+ wait: false,
304
+ url: true,
305
+ app: {
306
+ name: open.apps.chrome
307
+ }
308
+ }).catch(() => {
309
+ return open(url, {
310
+ wait: false,
311
+ url: true
312
+ });
313
+ });
314
+ } catch (browserError) {
315
+ console.log(chalk.yellow('\nCould not automatically open browser.'));
316
+ console.log(chalk.blue('Please open your browser and navigate to:'), url);
317
+ }
318
+
319
+ } catch (configError) {
320
+ console.error(chalk.red('\nConfiguration error:'), configError.message);
321
+ process.exit(1);
322
+ }
323
+
324
+ } catch (error) {
325
+ console.error(chalk.red('\nFailed to start D1 Studio:'), error);
326
+ process.exit(1);
327
+ }
328
+ }
329
+
330
+ // Handle termination
331
+ process.on('SIGINT', () => {
332
+ console.log(chalk.yellow('\nShutting down D1 Studio...'));
333
+ process.exit(0);
334
+ });
335
+
336
+ process.on('SIGTERM', () => {
337
+ console.log(chalk.yellow('\nShutting down D1 Studio...'));
338
+ process.exit(0);
339
+ });
340
+
341
+ startStudio().catch((error) => {
342
+ console.error(chalk.red('\nFailed to start D1 Studio:'), error);
343
+ process.exit(1);
344
+ });
@@ -0,0 +1,168 @@
1
+ // scripts/test.js
2
+ import { findWranglerConfig } from '../src/lib/find-wrangler-config.js';
3
+ import { fileURLToPath } from 'url';
4
+ import { dirname, join } from 'path';
5
+ import chalk from 'chalk';
6
+ import fs from 'fs/promises';
7
+ import os from 'os';
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+
12
+ async function testWranglerConfig() {
13
+ console.log('\nTesting Wrangler configuration...');
14
+
15
+ // Test with valid wrangler.toml
16
+ const validConfig = `
17
+ [[d1_databases]]
18
+ binding = "DB"
19
+ database_name = "test_db"
20
+ database_id = "test-id"
21
+ `;
22
+
23
+ const tempDir = await fs.mkdtemp(join(os.tmpdir(), 'd1-studio-test-'));
24
+ await fs.writeFile(join(tempDir, 'wrangler.toml'), validConfig);
25
+
26
+ try {
27
+ const config = await findWranglerConfig(tempDir);
28
+ if (!config || !config.config.d1_databases) {
29
+ console.warn(chalk.yellow('⚠ Valid wrangler.toml test: Config parsing incomplete'));
30
+ } else {
31
+ console.log(chalk.green('✓ Valid wrangler.toml test passed'));
32
+ }
33
+ } catch (error) {
34
+ console.warn(chalk.yellow('⚠ Valid wrangler.toml test issues:'), error.message);
35
+ }
36
+
37
+ // Test with invalid wrangler.toml
38
+ try {
39
+ await fs.writeFile(join(tempDir, 'wrangler.toml'), 'invalid: config: {');
40
+ await findWranglerConfig(tempDir);
41
+ console.warn(chalk.yellow('⚠ Invalid wrangler.toml test: Did not catch invalid config'));
42
+ } catch (error) {
43
+ console.log(chalk.green('✓ Invalid wrangler.toml handling test passed'));
44
+ }
45
+
46
+ // Cleanup
47
+ await fs.rm(tempDir, { recursive: true }).catch(() => {});
48
+ }
49
+
50
+ async function testProjectStructure() {
51
+ console.log('\nTesting project structure...');
52
+
53
+ // Check required directories exist
54
+ const requiredDirs = ['src', 'scripts', 'dist'];
55
+ for (const dir of requiredDirs) {
56
+ try {
57
+ await fs.access(join(__dirname, '..', dir));
58
+ console.log(chalk.green(`✓ ${dir} directory exists`));
59
+ } catch {
60
+ console.warn(chalk.yellow(`⚠ ${dir} directory missing`));
61
+ }
62
+ }
63
+
64
+ // Check required files exist
65
+ const requiredFiles = [
66
+ 'package.json',
67
+ 'next.config.js',
68
+ 'tailwind.config.js',
69
+ 'scripts/studio.js'
70
+ ];
71
+
72
+ for (const file of requiredFiles) {
73
+ try {
74
+ await fs.access(join(__dirname, '..', file));
75
+ console.log(chalk.green(`✓ ${file} exists`));
76
+ } catch {
77
+ console.warn(chalk.yellow(`⚠ ${file} missing`));
78
+ }
79
+ }
80
+ }
81
+
82
+ async function testStudioScript() {
83
+ console.log('\nTesting studio.js script...');
84
+
85
+ try {
86
+ const studioPath = join(__dirname, 'studio.js');
87
+ const stats = await fs.stat(studioPath);
88
+
89
+ // Check file permissions (should be executable)
90
+ const isExecutable = (stats.mode & 0o111) !== 0;
91
+ if (!isExecutable) {
92
+ console.warn(chalk.yellow('⚠ studio.js is not executable'));
93
+ } else {
94
+ console.log(chalk.green('✓ studio.js has correct permissions'));
95
+ }
96
+
97
+ // Check file content
98
+ const content = await fs.readFile(studioPath, 'utf8');
99
+ const requiredImports = ['chalk', 'open', 'findWranglerConfig'];
100
+
101
+ let missingImports = [];
102
+ for (const imp of requiredImports) {
103
+ if (!content.includes(imp)) {
104
+ missingImports.push(imp);
105
+ }
106
+ }
107
+
108
+ if (missingImports.length > 0) {
109
+ console.warn(chalk.yellow(`⚠ studio.js missing imports: ${missingImports.join(', ')}`));
110
+ } else {
111
+ console.log(chalk.green('✓ studio.js contains required imports'));
112
+ }
113
+
114
+ } catch (error) {
115
+ console.warn(chalk.yellow('⚠ studio.js test issues:'), error.message);
116
+ }
117
+ }
118
+
119
+ async function testUserConfig() {
120
+ console.log('\nTesting user configuration...');
121
+
122
+ const homeDir = os.homedir();
123
+ const d1StudioDir = join(homeDir, '.d1studio');
124
+
125
+ try {
126
+ await fs.access(d1StudioDir);
127
+ console.log(chalk.green('✓ D1 Studio config directory exists'));
128
+
129
+ const licenseFile = join(d1StudioDir, 'license.json');
130
+ try {
131
+ await fs.access(licenseFile);
132
+ console.log(chalk.green('✓ License file exists'));
133
+
134
+ // Validate license file structure
135
+ const license = JSON.parse(await fs.readFile(licenseFile, 'utf8'));
136
+ const requiredFields = ['licenseKey', 'email', 'hardwareId'];
137
+
138
+ const missingFields = requiredFields.filter(field => !license[field]);
139
+ if (missingFields.length > 0) {
140
+ console.warn(chalk.yellow(`⚠ License file missing fields: ${missingFields.join(', ')}`));
141
+ }
142
+ } catch {
143
+ console.warn(chalk.yellow('⚠ License file not found or invalid'));
144
+ }
145
+ } catch {
146
+ console.warn(chalk.yellow('⚠ D1 Studio config directory not found'));
147
+ }
148
+ }
149
+
150
+ async function runTests() {
151
+ console.log(chalk.blue('Running D1 Studio tests...'));
152
+
153
+ try {
154
+ await testProjectStructure();
155
+ await testWranglerConfig();
156
+ await testStudioScript();
157
+ await testUserConfig();
158
+
159
+ console.log(chalk.green('\nTests completed! 🎉'));
160
+ console.log(chalk.blue('Check warnings above for any issues that need attention.'));
161
+ } catch (error) {
162
+ console.warn(chalk.yellow('\nSome tests encountered issues:'), error.message);
163
+ }
164
+ }
165
+
166
+ runTests().catch(error => {
167
+ console.warn(chalk.yellow('Test suite encountered issues:'), error.message);
168
+ });
@@ -0,0 +1,146 @@
1
+ // api/cloudflare/route.js
2
+
3
+ import { NextResponse } from 'next/server';
4
+ import { findWranglerConfig } from '@/lib/find-wrangler-config.js';
5
+
6
+ /**
7
+ * Validates the provided Cloudflare credentials by fetching databases.
8
+ * @param {string} accountId - Cloudflare account ID.
9
+ * @param {string} apiToken - Cloudflare API token.
10
+ */
11
+ async function validateCredentials(accountId, apiToken) {
12
+ const response = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/d1/database`, {
13
+ headers: {
14
+ 'Authorization': `Bearer ${apiToken}`,
15
+ 'Content-Type': 'application/json',
16
+ },
17
+ });
18
+
19
+ if (!response.ok) {
20
+ throw new Error('Invalid Cloudflare credentials');
21
+ }
22
+
23
+ return response.json();
24
+ }
25
+
26
+ /**
27
+ * Fetches the list of databases from Cloudflare and returns the one that matches the given name.
28
+ * @param {string} accountId - Cloudflare account ID.
29
+ * @param {string} apiToken - Cloudflare API token.
30
+ * @param {string} databaseName - The name of the database to find.
31
+ */
32
+ async function findDatabase(accountId, apiToken, databaseName) {
33
+ const response = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/d1/database`, {
34
+ headers: {
35
+ 'Authorization': `Bearer ${apiToken}`,
36
+ 'Content-Type': 'application/json',
37
+ },
38
+ });
39
+
40
+ if (!response.ok) {
41
+ throw new Error('Failed to fetch databases');
42
+ }
43
+
44
+ const { result } = await response.json();
45
+ return result.find(db => db.name === databaseName);
46
+ }
47
+
48
+ /**
49
+ * Creates a new database on Cloudflare.
50
+ * @param {string} accountId - Cloudflare account ID.
51
+ * @param {string} apiToken - Cloudflare API token.
52
+ * @param {string} databaseName - The name for the new database.
53
+ */
54
+ async function createDatabase(accountId, apiToken, databaseName) {
55
+ const response = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/d1/database`, {
56
+ method: 'POST',
57
+ headers: {
58
+ 'Authorization': `Bearer ${apiToken}`,
59
+ 'Content-Type': 'application/json',
60
+ },
61
+ body: JSON.stringify({
62
+ name: databaseName,
63
+ }),
64
+ });
65
+
66
+ if (!response.ok) {
67
+ throw new Error('Failed to create database');
68
+ }
69
+
70
+ return response.json();
71
+ }
72
+
73
+ /**
74
+ * API POST handler to validate credentials, read the Wrangler configuration, and ensure the D1 database exists.
75
+ */
76
+ export async function POST(req) {
77
+ try {
78
+ // Parse accountId and apiToken from the request body.
79
+ const { accountId, apiToken } = await req.json();
80
+ const projectDir = process.env.D1_PROJECT_DIR;
81
+
82
+ // Check if the project directory is set.
83
+ if (!projectDir) {
84
+ return NextResponse.json(
85
+ { error: 'Project directory not configured' },
86
+ { status: 500 }
87
+ );
88
+ }
89
+
90
+ // Validate Cloudflare credentials.
91
+ await validateCredentials(accountId, apiToken);
92
+
93
+ // Retrieve the Wrangler configuration using the centralized helper.
94
+ const wranglerResult = await findWranglerConfig(projectDir);
95
+ if (!wranglerResult || !wranglerResult.config) {
96
+ return NextResponse.json(
97
+ { error: 'No Wrangler configuration file found in project directory' },
98
+ { status: 404 }
99
+ );
100
+ }
101
+ const config = wranglerResult.config;
102
+
103
+ // Ensure that at least one D1 database is configured.
104
+ if (!config.d1_databases?.length) {
105
+ return NextResponse.json(
106
+ { error: 'No D1 databases configured in Wrangler configuration' },
107
+ { status: 400 }
108
+ );
109
+ }
110
+
111
+ // Use the first configured D1 database.
112
+ const localDb = config.d1_databases[0];
113
+
114
+ // Check if the database exists on Cloudflare.
115
+ let database = await findDatabase(accountId, apiToken, localDb.database_name);
116
+
117
+ // If not found, create the database.
118
+ if (!database) {
119
+ const result = await createDatabase(accountId, apiToken, localDb.database_name);
120
+ database = result.result;
121
+ }
122
+
123
+ // Return the database details in the response.
124
+ return NextResponse.json({
125
+ success: true,
126
+ database: {
127
+ id: database.uuid,
128
+ name: database.name,
129
+ }
130
+ });
131
+
132
+ } catch (error) {
133
+ console.error('Cloudflare API error:', error);
134
+ return NextResponse.json(
135
+ { error: error.message },
136
+ { status: error.message.includes('Invalid credentials') ? 401 : 500 }
137
+ );
138
+ }
139
+ }
140
+
141
+ /**
142
+ * OPTIONS handler for pre-flight requests.
143
+ */
144
+ export async function OPTIONS() {
145
+ return new NextResponse(null, { status: 204 });
146
+ }