d1s 0.2.13 → 0.3.0
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.
- package/README.md +14 -1
- package/dist/.next/.next/BUILD_ID +1 -1
- package/dist/.next/.next/app-build-manifest.json +121 -79
- package/dist/.next/.next/app-path-routes-manifest.json +1 -1
- package/dist/.next/.next/build-manifest.json +7 -7
- package/dist/.next/.next/cache/.rscinfo +1 -1
- package/dist/.next/.next/cache/.tsbuildinfo +1 -1
- package/dist/.next/.next/cache/webpack/client-development/0.pack.gz +0 -0
- package/dist/.next/.next/cache/webpack/client-development/1.pack.gz +0 -0
- package/dist/.next/.next/cache/webpack/client-development/index.pack.gz +0 -0
- package/dist/.next/.next/cache/webpack/client-development/index.pack.gz.old +0 -0
- package/dist/.next/.next/cache/webpack/client-production/0.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/1.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/10.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/11.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/12.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/2.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/3.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/4.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/5.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/6.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/7.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/8.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/9.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/index.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/dist/.next/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-development/0.pack.gz +0 -0
- package/dist/.next/.next/cache/webpack/server-development/1.pack.gz +0 -0
- package/dist/.next/.next/cache/webpack/server-development/index.pack.gz +0 -0
- package/dist/.next/.next/cache/webpack/server-production/0.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/1.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/index.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/dist/.next/.next/next-minimal-server.js.nft.json +1 -1
- package/dist/.next/.next/next-server.js.nft.json +1 -1
- package/dist/.next/.next/prerender-manifest.json +1 -1
- package/dist/.next/.next/react-loadable-manifest.json +11 -1
- package/dist/.next/.next/required-server-files.json +1 -1
- package/dist/.next/.next/routes-manifest.json +1 -1
- package/dist/.next/.next/server/app/_not-found/page.js +1 -1
- package/dist/.next/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/.next/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/_not-found.html +1 -1
- package/dist/.next/.next/server/app/_not-found.rsc +5 -5
- package/dist/.next/.next/server/app/api/cloudflare/route.js +1 -1
- package/dist/.next/.next/server/app/api/cloudflare/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/cloudflare/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/databases/route.js +1 -1
- package/dist/.next/.next/server/app/api/databases/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/databases/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/migrations/list/route.js +26 -0
- package/dist/.next/.next/server/app/api/migrations/list/route.js.nft.json +1 -0
- package/dist/.next/.next/server/app/api/migrations/list/route_client-reference-manifest.js +1 -0
- package/dist/.next/.next/server/app/api/migrations/sync/route.js +5 -5
- package/dist/.next/.next/server/app/api/migrations/sync/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/migrations/sync/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/migrations/sync-files/route.js +4 -4
- package/dist/.next/.next/server/app/api/migrations/sync-files/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/migrations/sync-files/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/pro/route.js +1 -0
- package/dist/.next/.next/server/app/api/pro/route.js.nft.json +1 -0
- package/dist/.next/.next/server/app/api/pro/route_client-reference-manifest.js +1 -0
- package/dist/.next/.next/server/app/api/pull-data/confirm/route.js +1 -1
- package/dist/.next/.next/server/app/api/pull-data/confirm/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/pull-data/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/pull-remote/confirm/route.js +4 -4
- package/dist/.next/.next/server/app/api/pull-remote/confirm/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/pull-remote/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/pull-remote/preview/route.js +4 -4
- package/dist/.next/.next/server/app/api/pull-remote/preview/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/pull-remote/preview/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/push-remote/confirm/route.js +6 -6
- package/dist/.next/.next/server/app/api/push-remote/confirm/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/push-remote/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/push-remote/preview/route.js +6 -6
- package/dist/.next/.next/server/app/api/push-remote/preview/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/push-remote/preview/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/query/route.js +9 -9
- package/dist/.next/.next/server/app/api/query/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/query/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/schema/route.js +1 -0
- package/dist/.next/.next/server/app/api/schema/route.js.nft.json +1 -0
- package/dist/.next/.next/server/app/api/schema/route_client-reference-manifest.js +1 -0
- package/dist/.next/.next/server/app/api/tables/[name]/import/route.js +1 -0
- package/dist/.next/.next/server/app/api/tables/[name]/import/route.js.nft.json +1 -0
- package/dist/.next/.next/server/app/api/tables/[name]/import/route_client-reference-manifest.js +1 -0
- package/dist/.next/.next/server/app/api/tables/[name]/route.js +5 -5
- package/dist/.next/.next/server/app/api/tables/[name]/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/tables/[name]/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/tables/route.js +2 -2
- package/dist/.next/.next/server/app/api/tables/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/tables/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/time-travel/preview/route.js +1 -0
- package/dist/.next/.next/server/app/api/time-travel/preview/route.js.nft.json +1 -0
- package/dist/.next/.next/server/app/api/time-travel/preview/route_client-reference-manifest.js +1 -0
- package/dist/.next/.next/server/app/api/time-travel/restore/route.js +1 -0
- package/dist/.next/.next/server/app/api/time-travel/restore/route.js.nft.json +1 -0
- package/dist/.next/.next/server/app/api/time-travel/restore/route_client-reference-manifest.js +1 -0
- package/dist/.next/.next/server/app/api/update/route.js +1 -1
- package/dist/.next/.next/server/app/api/update/route.js.nft.json +1 -1
- package/dist/.next/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/index.html +5 -3
- package/dist/.next/.next/server/app/index.rsc +6 -6
- package/dist/.next/.next/server/app/page.js +15 -15
- package/dist/.next/.next/server/app/page.js.nft.json +1 -1
- package/dist/.next/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app-paths-manifest.json +10 -4
- package/dist/.next/.next/server/chunks/226.js +12 -12
- package/dist/.next/.next/server/chunks/391.js +1 -1
- package/dist/.next/.next/server/chunks/452.js +1 -1
- package/dist/.next/.next/server/chunks/487.js +1 -0
- package/dist/.next/.next/server/chunks/572.js +1 -1
- package/dist/.next/.next/server/chunks/992.js +3 -3
- package/dist/.next/{server/chunks/638.js → .next/server/chunks/994.js} +3 -3
- package/dist/.next/.next/server/middleware-build-manifest.js +1 -1
- package/dist/.next/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/.next/.next/server/next-font-manifest.js +1 -1
- package/dist/.next/.next/server/next-font-manifest.json +1 -1
- package/dist/.next/.next/server/pages/404.html +1 -1
- package/dist/.next/.next/server/pages/500.html +1 -1
- package/dist/.next/.next/server/pages-manifest.json +1 -1
- package/dist/.next/.next/server/server-reference-manifest.json +1 -1
- package/dist/.next/.next/static/-OO4tE7EKr8o62Bne-ODo/_buildManifest.js +1 -0
- package/dist/.next/.next/static/3kAeIJC56X7aw1Fk5_OXO/_buildManifest.js +1 -0
- package/dist/.next/.next/static/J8r9W6xxmYYvuKehItNuW/_buildManifest.js +1 -0
- package/dist/.next/.next/static/arc9h7hbaQzL1Dl0iuVrT/_buildManifest.js +1 -0
- package/dist/.next/.next/static/chunks/1a258343.3b3e7ba5ba0bd0d2.js +1 -0
- package/dist/.next/.next/static/chunks/345.8fc37569d5708622.js +1 -0
- package/dist/.next/.next/static/chunks/480-85b6c8ae3f51b156.js +1 -0
- package/dist/.next/.next/static/chunks/52.2cdc9bdb75e1fc2e.js +1 -0
- package/dist/.next/.next/static/chunks/803-a2fcfbd00e6b3b38.js +1 -0
- package/dist/.next/.next/static/chunks/{92-5f7522943fcb72a8.js → 92-a84bdac2be7c8d7a.js} +1 -1
- package/dist/.next/.next/static/chunks/app/api/cloudflare/route-d0c1dc2a9e7dce36.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/databases/route-cd322321212797cf.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/migrations/list/route-cd710ff75b6bcd02.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/migrations/sync/route-ee522f232b9f0a9c.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/migrations/sync-files/route-79ee2c26f87d3bc7.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/pro/route-c90c1f901fc00d38.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/pull-data/confirm/route-118764086af798f8.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/pull-remote/confirm/route-2b0ade4ebfcea0bc.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/pull-remote/preview/route-342db7ea13e6f447.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/push-remote/confirm/route-b778c053bd515abd.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/push-remote/preview/route-ab090482f299f57f.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/query/route-4d21a8b1d34491f1.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/schema/route-cb17a387d6b557ad.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/tables/[name]/import/route-510472de7a5c29bd.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/tables/[name]/route-6a1fa95c303ce0de.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/tables/route-daa975df4ea8e8f8.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/time-travel/preview/route-5787d7e8f17bd539.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/time-travel/restore/route-84b64a27e831e21c.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/update/route-54ee900537982652.js +1 -0
- package/dist/.next/.next/static/chunks/app/{layout-40ec07d04681ba81.js → layout-f0ec4d636ee0f763.js} +1 -1
- package/dist/.next/.next/static/chunks/app/page-358bf2112802ff85.js +1 -0
- package/dist/.next/.next/static/chunks/webpack-024900a94af4f0a7.js +1 -0
- package/dist/.next/.next/static/css/2c165a0ede9b2442.css +3 -0
- package/dist/.next/.next/static/css/32df9a4d493f8b0f.css +31 -0
- package/dist/.next/.next/static/fiesjBWbrmSSyLf4biwrX/_buildManifest.js +1 -0
- package/dist/.next/.next/static/ft39e6W6vSgUL7peRo7pE/_buildManifest.js +1 -0
- package/dist/.next/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/.next/.next/static/u7ssdTycF4iQ-w-pQZhxg/_buildManifest.js +1 -0
- package/dist/.next/.next/trace +3 -3
- package/dist/.next/.next/types/app/api/migrations/list/route.ts +347 -0
- package/dist/.next/.next/types/app/api/pro/route.ts +347 -0
- package/dist/.next/.next/types/app/api/schema/route.ts +347 -0
- package/dist/.next/.next/types/app/api/tables/[name]/import/route.ts +347 -0
- package/dist/.next/.next/types/app/api/time-travel/preview/route.ts +347 -0
- package/dist/.next/.next/types/app/api/time-travel/restore/route.ts +347 -0
- package/dist/.next/BUILD_ID +1 -1
- package/dist/.next/app-build-manifest.json +122 -80
- package/dist/.next/app-path-routes-manifest.json +1 -1
- package/dist/.next/build-manifest.json +7 -7
- package/dist/.next/cache/.rscinfo +1 -1
- package/dist/.next/cache/.tsbuildinfo +1 -1
- package/dist/.next/cache/webpack/client-production/0.pack +0 -0
- package/dist/.next/cache/webpack/client-production/index.pack +0 -0
- package/dist/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/dist/.next/cache/webpack/server-production/0.pack +0 -0
- package/dist/.next/cache/webpack/server-production/index.pack +0 -0
- package/dist/.next/next-minimal-server.js.nft.json +1 -1
- package/dist/.next/next-server.js.nft.json +1 -1
- package/dist/.next/prerender-manifest.json +1 -1
- package/dist/.next/react-loadable-manifest.json +11 -1
- package/dist/.next/required-server-files.json +1 -1
- package/dist/.next/routes-manifest.json +1 -1
- package/dist/.next/server/app/_not-found/page.js +1 -1
- package/dist/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/_not-found.html +1 -1
- package/dist/.next/server/app/_not-found.rsc +5 -5
- package/dist/.next/server/app/api/cloudflare/route.js +1 -1
- package/dist/.next/server/app/api/cloudflare/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/cloudflare/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/databases/route.js +1 -1
- package/dist/.next/server/app/api/databases/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/databases/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/migrations/list/route.js +26 -0
- package/dist/.next/server/app/api/migrations/list/route.js.nft.json +1 -0
- package/dist/.next/server/app/api/migrations/list/route_client-reference-manifest.js +1 -0
- package/dist/.next/server/app/api/migrations/sync/route.js +5 -5
- package/dist/.next/server/app/api/migrations/sync/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/migrations/sync/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/migrations/sync-files/route.js +4 -4
- package/dist/.next/server/app/api/migrations/sync-files/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/migrations/sync-files/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/pro/route.js +1 -0
- package/dist/.next/server/app/api/pro/route.js.nft.json +1 -0
- package/dist/.next/server/app/api/pro/route_client-reference-manifest.js +1 -0
- package/dist/.next/server/app/api/pull-data/confirm/route.js +1 -1
- package/dist/.next/server/app/api/pull-data/confirm/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/pull-data/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/pull-remote/confirm/route.js +4 -4
- package/dist/.next/server/app/api/pull-remote/confirm/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/pull-remote/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/pull-remote/preview/route.js +4 -4
- package/dist/.next/server/app/api/pull-remote/preview/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/pull-remote/preview/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/push-remote/confirm/route.js +6 -6
- package/dist/.next/server/app/api/push-remote/confirm/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/push-remote/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/push-remote/preview/route.js +6 -6
- package/dist/.next/server/app/api/push-remote/preview/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/push-remote/preview/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/query/route.js +9 -9
- package/dist/.next/server/app/api/query/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/query/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/schema/route.js +1 -0
- package/dist/.next/server/app/api/schema/route.js.nft.json +1 -0
- package/dist/.next/server/app/api/schema/route_client-reference-manifest.js +1 -0
- package/dist/.next/server/app/api/tables/[name]/import/route.js +1 -0
- package/dist/.next/server/app/api/tables/[name]/import/route.js.nft.json +1 -0
- package/dist/.next/server/app/api/tables/[name]/import/route_client-reference-manifest.js +1 -0
- package/dist/.next/server/app/api/tables/[name]/route.js +5 -5
- package/dist/.next/server/app/api/tables/[name]/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/tables/[name]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/tables/route.js +2 -2
- package/dist/.next/server/app/api/tables/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/tables/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/time-travel/preview/route.js +1 -0
- package/dist/.next/server/app/api/time-travel/preview/route.js.nft.json +1 -0
- package/dist/.next/server/app/api/time-travel/preview/route_client-reference-manifest.js +1 -0
- package/dist/.next/server/app/api/time-travel/restore/route.js +1 -0
- package/dist/.next/server/app/api/time-travel/restore/route.js.nft.json +1 -0
- package/dist/.next/server/app/api/time-travel/restore/route_client-reference-manifest.js +1 -0
- package/dist/.next/server/app/api/update/route.js +1 -1
- package/dist/.next/server/app/api/update/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/index.html +5 -3
- package/dist/.next/server/app/index.rsc +6 -6
- package/dist/.next/server/app/page.js +15 -15
- package/dist/.next/server/app/page.js.nft.json +1 -1
- package/dist/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app-paths-manifest.json +11 -5
- package/dist/.next/server/chunks/226.js +12 -12
- package/dist/.next/server/chunks/391.js +1 -1
- package/dist/.next/server/chunks/452.js +1 -1
- package/dist/.next/server/chunks/487.js +1 -0
- package/dist/.next/server/chunks/572.js +1 -1
- package/dist/.next/server/chunks/992.js +3 -3
- package/dist/.next/{.next/server/chunks/638.js → server/chunks/994.js} +3 -3
- package/dist/.next/server/middleware-build-manifest.js +1 -1
- package/dist/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/.next/server/next-font-manifest.js +1 -1
- package/dist/.next/server/next-font-manifest.json +1 -1
- package/dist/.next/server/pages/404.html +1 -1
- package/dist/.next/server/pages/500.html +1 -1
- package/dist/.next/server/pages-manifest.json +1 -1
- package/dist/.next/server/server-reference-manifest.json +1 -1
- package/dist/.next/static/chunks/1a258343.3b3e7ba5ba0bd0d2.js +1 -0
- package/dist/.next/static/chunks/345.8fc37569d5708622.js +1 -0
- package/dist/.next/static/chunks/480-85b6c8ae3f51b156.js +1 -0
- package/dist/.next/static/chunks/52.2cdc9bdb75e1fc2e.js +1 -0
- package/dist/.next/static/chunks/803-a2fcfbd00e6b3b38.js +1 -0
- package/dist/.next/static/chunks/{92-5f7522943fcb72a8.js → 92-a84bdac2be7c8d7a.js} +1 -1
- package/dist/.next/static/chunks/app/api/cloudflare/route-d0c1dc2a9e7dce36.js +1 -0
- package/dist/.next/static/chunks/app/api/databases/route-cd322321212797cf.js +1 -0
- package/dist/.next/static/chunks/app/api/migrations/list/route-cd710ff75b6bcd02.js +1 -0
- package/dist/.next/static/chunks/app/api/migrations/sync/route-ee522f232b9f0a9c.js +1 -0
- package/dist/.next/static/chunks/app/api/migrations/sync-files/route-79ee2c26f87d3bc7.js +1 -0
- package/dist/.next/static/chunks/app/api/pro/route-c90c1f901fc00d38.js +1 -0
- package/dist/.next/static/chunks/app/api/pull-data/confirm/route-118764086af798f8.js +1 -0
- package/dist/.next/static/chunks/app/api/pull-remote/confirm/route-2b0ade4ebfcea0bc.js +1 -0
- package/dist/.next/static/chunks/app/api/pull-remote/preview/route-342db7ea13e6f447.js +1 -0
- package/dist/.next/static/chunks/app/api/push-remote/confirm/route-b778c053bd515abd.js +1 -0
- package/dist/.next/static/chunks/app/api/push-remote/preview/route-ab090482f299f57f.js +1 -0
- package/dist/.next/static/chunks/app/api/query/route-4d21a8b1d34491f1.js +1 -0
- package/dist/.next/static/chunks/app/api/schema/route-cb17a387d6b557ad.js +1 -0
- package/dist/.next/static/chunks/app/api/tables/[name]/import/route-510472de7a5c29bd.js +1 -0
- package/dist/.next/static/chunks/app/api/tables/[name]/route-6a1fa95c303ce0de.js +1 -0
- package/dist/.next/static/chunks/app/api/tables/route-daa975df4ea8e8f8.js +1 -0
- package/dist/.next/static/chunks/app/api/time-travel/preview/route-5787d7e8f17bd539.js +1 -0
- package/dist/.next/static/chunks/app/api/time-travel/restore/route-84b64a27e831e21c.js +1 -0
- package/dist/.next/static/chunks/app/api/update/route-54ee900537982652.js +1 -0
- package/dist/.next/static/chunks/app/{layout-40ec07d04681ba81.js → layout-f0ec4d636ee0f763.js} +1 -1
- package/dist/.next/static/chunks/app/page-358bf2112802ff85.js +1 -0
- package/dist/.next/static/chunks/webpack-024900a94af4f0a7.js +1 -0
- package/dist/.next/static/css/2c165a0ede9b2442.css +3 -0
- package/dist/.next/static/css/32df9a4d493f8b0f.css +31 -0
- package/dist/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/.next/static/zh4Fz2tbm8GRka4woRrGp/_buildManifest.js +1 -0
- package/dist/.next/trace +18 -3
- package/dist/.next/types/app/api/migrations/list/route.ts +347 -0
- package/dist/.next/types/app/api/pro/route.ts +347 -0
- package/dist/.next/types/app/api/schema/route.ts +347 -0
- package/dist/.next/types/app/api/tables/[name]/import/route.ts +347 -0
- package/dist/.next/types/app/api/time-travel/preview/route.ts +347 -0
- package/dist/.next/types/app/api/time-travel/restore/route.ts +347 -0
- package/dist/app/api/databases/route.js +2 -1
- package/dist/app/api/migrations/list/route.js +137 -0
- package/dist/app/api/migrations/sync-files/route.js +2 -1
- package/dist/app/api/pro/route.js +7 -0
- package/dist/app/api/pull-remote/confirm/route.js +138 -146
- package/dist/app/api/pull-remote/preview/route.js +49 -84
- package/dist/app/api/push-remote/confirm/route.js +31 -12
- package/dist/app/api/push-remote/preview/route.js +27 -12
- package/dist/app/api/query/route.js +24 -13
- package/dist/app/api/schema/route.js +63 -0
- package/dist/app/api/tables/[name]/import/route.js +112 -0
- package/dist/app/api/tables/[name]/route.js +38 -29
- package/dist/app/api/tables/route.js +29 -16
- package/dist/app/api/time-travel/preview/route.js +122 -0
- package/dist/app/api/time-travel/restore/route.js +106 -0
- package/dist/app/page.jsx +26 -8
- package/dist/d1-studio.js +129 -23
- package/dist/lib/license.js +99 -71
- package/dist/lib/local-db.js +223 -0
- package/dist/lib/migrations.js +40 -2
- package/dist/lib/parse-sql-error.js +99 -160
- package/dist/lib/sql-operations.js +28 -10
- package/dist/lib/telemetry.js +39 -0
- package/package.json +6 -2
- package/dist/.next/.next/cache/webpack/server-production/2.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/3.pack +0 -0
- package/dist/.next/.next/static/FEsQ9jwPUQv5A3fwg6Opl/_buildManifest.js +0 -1
- package/dist/.next/.next/static/Y9mYu4WBghepP5oT_3OdR/_buildManifest.js +0 -1
- package/dist/.next/.next/static/ae3gNmoSGm-R5LJC4UagI/_buildManifest.js +0 -1
- package/dist/.next/.next/static/bKfUJeuvAQlBmR3TjrfkH/_buildManifest.js +0 -1
- package/dist/.next/.next/static/chunks/576-18a2209e1ed26aad.js +0 -1
- package/dist/.next/.next/static/chunks/735-b885dfec6353171d.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/cloudflare/route-b77846f372b01f38.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/databases/route-407794f8145d9a0b.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/migrations/sync/route-9f480f5590369a8f.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/migrations/sync-files/route-92010db279b4dd8e.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/pull-data/confirm/route-a02fe6d3cdd0a535.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/pull-remote/confirm/route-f401a03507d1da50.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/pull-remote/preview/route-3c53814b5cb8b6b0.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/push-remote/confirm/route-8f359249e907c63b.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/push-remote/preview/route-b51bf94f39c17a9d.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/query/route-87bae2d4aebaf859.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/tables/[name]/route-d20ca163b9c03e7c.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/tables/route-0f46f911562abcdf.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/update/route-14edc1917760bce0.js +0 -1
- package/dist/.next/.next/static/chunks/app/page-f05cd0fc436bf9bc.js +0 -1
- package/dist/.next/.next/static/chunks/app/page-f2bc307c0d8acdaa.js +0 -1
- package/dist/.next/.next/static/chunks/webpack-c76ac1e586b2802a.js +0 -1
- package/dist/.next/.next/static/css/7c16f57d325d0d7d.css +0 -3
- package/dist/.next/.next/static/ejYPqJ2kVicVp5EFWOZIC/_buildManifest.js +0 -1
- package/dist/.next/.next/static/gABGrAoO8IPArDo_Ns_7g/_buildManifest.js +0 -1
- package/dist/.next/.next/static/gh-QfIUVo4FTTduYCVKT6/_buildManifest.js +0 -1
- package/dist/.next/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
- package/dist/.next/.next/static/thaCy2qVeNqYYhdayr13C/_buildManifest.js +0 -1
- package/dist/.next/.next/static/ybCx6L6gHqtODbKmlhU-d/_buildManifest.js +0 -1
- package/dist/.next/.next/static/ybCx6L6gHqtODbKmlhU-d/_ssgManifest.js +0 -1
- package/dist/.next/cache/webpack/client-production/1.pack +0 -0
- package/dist/.next/cache/webpack/client-production/2.pack +0 -0
- package/dist/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/dist/.next/static/IX-QLbm7scYnyqWeeimal/_buildManifest.js +0 -1
- package/dist/.next/static/IX-QLbm7scYnyqWeeimal/_ssgManifest.js +0 -1
- package/dist/.next/static/chunks/576-18a2209e1ed26aad.js +0 -1
- package/dist/.next/static/chunks/735-b885dfec6353171d.js +0 -1
- package/dist/.next/static/chunks/app/api/cloudflare/route-b77846f372b01f38.js +0 -1
- package/dist/.next/static/chunks/app/api/databases/route-407794f8145d9a0b.js +0 -1
- package/dist/.next/static/chunks/app/api/migrations/sync/route-9f480f5590369a8f.js +0 -1
- package/dist/.next/static/chunks/app/api/migrations/sync-files/route-92010db279b4dd8e.js +0 -1
- package/dist/.next/static/chunks/app/api/pull-data/confirm/route-a02fe6d3cdd0a535.js +0 -1
- package/dist/.next/static/chunks/app/api/pull-remote/confirm/route-f401a03507d1da50.js +0 -1
- package/dist/.next/static/chunks/app/api/pull-remote/preview/route-3c53814b5cb8b6b0.js +0 -1
- package/dist/.next/static/chunks/app/api/push-remote/confirm/route-8f359249e907c63b.js +0 -1
- package/dist/.next/static/chunks/app/api/push-remote/preview/route-b51bf94f39c17a9d.js +0 -1
- package/dist/.next/static/chunks/app/api/query/route-87bae2d4aebaf859.js +0 -1
- package/dist/.next/static/chunks/app/api/tables/[name]/route-d20ca163b9c03e7c.js +0 -1
- package/dist/.next/static/chunks/app/api/tables/route-0f46f911562abcdf.js +0 -1
- package/dist/.next/static/chunks/app/api/update/route-14edc1917760bce0.js +0 -1
- package/dist/.next/static/chunks/app/page-f05cd0fc436bf9bc.js +0 -1
- package/dist/.next/static/chunks/webpack-c76ac1e586b2802a.js +0 -1
- package/dist/.next/static/css/7c16f57d325d0d7d.css +0 -3
- package/dist/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
- /package/dist/.next/.next/static/{FEsQ9jwPUQv5A3fwg6Opl → -OO4tE7EKr8o62Bne-ODo}/_ssgManifest.js +0 -0
- /package/dist/.next/.next/static/{Y9mYu4WBghepP5oT_3OdR → 3kAeIJC56X7aw1Fk5_OXO}/_ssgManifest.js +0 -0
- /package/dist/.next/.next/static/{ae3gNmoSGm-R5LJC4UagI → J8r9W6xxmYYvuKehItNuW}/_ssgManifest.js +0 -0
- /package/dist/.next/.next/static/{bKfUJeuvAQlBmR3TjrfkH → arc9h7hbaQzL1Dl0iuVrT}/_ssgManifest.js +0 -0
- /package/dist/.next/.next/static/chunks/{4bd1b696-8c908eb707f85a27.js → 4bd1b696-124ea104c06f6cea.js} +0 -0
- /package/dist/.next/.next/static/chunks/{517-3b698a5d3da06ff7.js → 517-c876ce2f00030cd0.js} +0 -0
- /package/dist/.next/.next/static/chunks/{692-ede418e1d28a1394.js → 692-9e59d546afd11ec3.js} +0 -0
- /package/dist/.next/.next/static/chunks/app/_not-found/{page-b786c3dd79ad15a5.js → page-3e24b81707d98126.js} +0 -0
- /package/dist/.next/.next/static/{ejYPqJ2kVicVp5EFWOZIC → fiesjBWbrmSSyLf4biwrX}/_ssgManifest.js +0 -0
- /package/dist/.next/.next/static/{gABGrAoO8IPArDo_Ns_7g → ft39e6W6vSgUL7peRo7pE}/_ssgManifest.js +0 -0
- /package/dist/.next/.next/static/{gh-QfIUVo4FTTduYCVKT6 → u7ssdTycF4iQ-w-pQZhxg}/_ssgManifest.js +0 -0
- /package/dist/.next/static/chunks/{4bd1b696-8c908eb707f85a27.js → 4bd1b696-124ea104c06f6cea.js} +0 -0
- /package/dist/.next/static/chunks/{517-3b698a5d3da06ff7.js → 517-c876ce2f00030cd0.js} +0 -0
- /package/dist/.next/static/chunks/{692-ede418e1d28a1394.js → 692-9e59d546afd11ec3.js} +0 -0
- /package/dist/.next/static/chunks/app/_not-found/{page-b786c3dd79ad15a5.js → page-3e24b81707d98126.js} +0 -0
- /package/dist/.next/{.next/static/thaCy2qVeNqYYhdayr13C → static/zh4Fz2tbm8GRka4woRrGp}/_ssgManifest.js +0 -0
|
@@ -1,122 +1,90 @@
|
|
|
1
1
|
// api/pull-remote/preview/route.js
|
|
2
2
|
|
|
3
3
|
import { NextResponse } from 'next/server';
|
|
4
|
+
import { readdir } from 'fs/promises';
|
|
5
|
+
import path from 'path';
|
|
4
6
|
import { findWranglerConfig } from '@/lib/find-wrangler-config.js';
|
|
5
7
|
import { ErrorTypes } from '@/lib/sql-operations';
|
|
6
|
-
import { getCurrentSchema, analyzeDependencies } from '@/lib/schema-operations';
|
|
7
8
|
import { getRemoteMigrations } from '@/lib/migrations.js';
|
|
8
9
|
import logger from '@/lib/logger';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Generates a preview for pulling remote migrations.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* @param {string} projectDir - The project directory path.
|
|
16
|
-
* @param {string} accountId - Cloudflare account ID.
|
|
17
|
-
* @param {string} apiToken - Cloudflare API token.
|
|
18
|
-
* @param {string} databaseName - The target D1 database name.
|
|
19
|
-
* @returns {object} Preview object containing migration details.
|
|
13
|
+
* Compares remote migration records against local migration files and shows
|
|
14
|
+
* which migrations will be applied locally.
|
|
20
15
|
*/
|
|
21
|
-
async function generatePullPreview(projectDir,
|
|
22
|
-
const env =
|
|
23
|
-
...process.env,
|
|
24
|
-
CLOUDFLARE_API_TOKEN: apiToken,
|
|
25
|
-
CLOUDFLARE_ACCOUNT_ID: accountId
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
// Get the remote schema and migration metadata using provided helpers
|
|
30
|
-
const remoteSchema = await getCurrentSchema(projectDir, databaseName, env, true);
|
|
31
|
-
const remoteMigrations = await getRemoteMigrations(projectDir, databaseName, env);
|
|
32
|
-
|
|
33
|
-
// Analyze dependencies to order tables for creation
|
|
34
|
-
const orderedTables = analyzeDependencies(remoteSchema);
|
|
16
|
+
async function generatePullPreview(projectDir, databaseName, dbMigrationsDir) {
|
|
17
|
+
const env = process.env;
|
|
35
18
|
|
|
36
|
-
|
|
37
|
-
const preview = {
|
|
38
|
-
preview: [],
|
|
39
|
-
totalTables: remoteSchema.length,
|
|
40
|
-
totalMigrations: remoteMigrations.length
|
|
41
|
-
};
|
|
19
|
+
const remoteMigrations = await getRemoteMigrations(projectDir, databaseName, env);
|
|
42
20
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
});
|
|
21
|
+
// Read local migration files to flag any that are missing
|
|
22
|
+
const migrationsDir = dbMigrationsDir || path.join(projectDir, 'migrations');
|
|
23
|
+
let localFiles = new Set();
|
|
24
|
+
try {
|
|
25
|
+
const files = await readdir(migrationsDir);
|
|
26
|
+
localFiles = new Set(files.filter(f => f.endsWith('.sql')));
|
|
27
|
+
} catch {
|
|
28
|
+
// migrations dir may not exist yet
|
|
29
|
+
}
|
|
55
30
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
type: 'migration',
|
|
62
|
-
action: 'will be tracked'
|
|
63
|
-
});
|
|
64
|
-
});
|
|
31
|
+
const preview = remoteMigrations.map(migration => ({
|
|
32
|
+
name: migration.name,
|
|
33
|
+
type: 'migration',
|
|
34
|
+
action: localFiles.has(migration.name) ? 'will be applied' : 'file missing locally',
|
|
35
|
+
}));
|
|
65
36
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
37
|
+
return {
|
|
38
|
+
preview,
|
|
39
|
+
totalMigrations: remoteMigrations.length,
|
|
40
|
+
};
|
|
71
41
|
}
|
|
72
42
|
|
|
73
|
-
/**
|
|
74
|
-
* POST handler for pull-remote preview.
|
|
75
|
-
* Reads the Wrangler configuration (via findWranglerConfig) to get the D1 database name,
|
|
76
|
-
* then generates a preview of the migrations to be pulled.
|
|
77
|
-
*/
|
|
78
43
|
export async function POST(req) {
|
|
44
|
+
if (process.env.D1_IS_PRO !== 'true') {
|
|
45
|
+
return NextResponse.json({ success: false, error: { type: 'PRO_REQUIRED', message: 'Pro license required. Run: d1s --license YOUR-KEY' } }, { status: 402 });
|
|
46
|
+
}
|
|
79
47
|
try {
|
|
80
|
-
const { accountId, apiToken } = await req.json();
|
|
81
48
|
const projectDir = process.env.D1_PROJECT_DIR;
|
|
82
|
-
|
|
83
49
|
if (!projectDir) {
|
|
84
50
|
return NextResponse.json({
|
|
85
51
|
success: false,
|
|
86
|
-
error: {
|
|
87
|
-
type: ErrorTypes.VALIDATION_ERROR,
|
|
88
|
-
message: 'Project directory not configured'
|
|
89
|
-
}
|
|
52
|
+
error: { type: ErrorTypes.VALIDATION_ERROR, message: 'Project directory not configured' }
|
|
90
53
|
}, { status: 500 });
|
|
91
54
|
}
|
|
92
55
|
|
|
93
|
-
// Load Wrangler configuration.
|
|
94
56
|
const wranglerResult = await findWranglerConfig(projectDir);
|
|
95
|
-
if (!wranglerResult
|
|
57
|
+
if (!wranglerResult?.config) {
|
|
96
58
|
return NextResponse.json({
|
|
97
59
|
success: false,
|
|
98
|
-
error: {
|
|
99
|
-
type: ErrorTypes.VALIDATION_ERROR,
|
|
100
|
-
message: 'Could not find Wrangler configuration'
|
|
101
|
-
}
|
|
60
|
+
error: { type: ErrorTypes.VALIDATION_ERROR, message: 'Could not find Wrangler configuration' }
|
|
102
61
|
}, { status: 400 });
|
|
103
62
|
}
|
|
104
|
-
const config = wranglerResult.config;
|
|
105
63
|
|
|
106
|
-
|
|
64
|
+
const config = wranglerResult.config;
|
|
107
65
|
if (!config.d1_databases?.length) {
|
|
108
66
|
return NextResponse.json({
|
|
109
67
|
success: false,
|
|
110
|
-
error: {
|
|
111
|
-
type: ErrorTypes.VALIDATION_ERROR,
|
|
112
|
-
message: 'No D1 databases configured'
|
|
113
|
-
}
|
|
68
|
+
error: { type: ErrorTypes.VALIDATION_ERROR, message: 'No D1 databases configured' }
|
|
114
69
|
}, { status: 400 });
|
|
115
70
|
}
|
|
116
71
|
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
const
|
|
72
|
+
const body = await req.json().catch(() => ({}));
|
|
73
|
+
const dbParam = body?.db;
|
|
74
|
+
const dbConfig = dbParam
|
|
75
|
+
? config.d1_databases.find(d => d.database_name === dbParam)
|
|
76
|
+
: config.d1_databases[0];
|
|
77
|
+
if (!dbConfig) {
|
|
78
|
+
return NextResponse.json({
|
|
79
|
+
success: false,
|
|
80
|
+
error: { type: ErrorTypes.VALIDATION_ERROR, message: `Database not found: ${dbParam}` }
|
|
81
|
+
}, { status: 400 });
|
|
82
|
+
}
|
|
83
|
+
const databaseName = dbConfig.database_name;
|
|
84
|
+
const migrationsDir = dbConfig.migrations_dir
|
|
85
|
+
? path.join(projectDir, dbConfig.migrations_dir)
|
|
86
|
+
: path.join(projectDir, 'migrations');
|
|
87
|
+
const preview = await generatePullPreview(projectDir, databaseName, migrationsDir);
|
|
120
88
|
|
|
121
89
|
return NextResponse.json({
|
|
122
90
|
success: true,
|
|
@@ -136,9 +104,6 @@ export async function POST(req) {
|
|
|
136
104
|
}
|
|
137
105
|
}
|
|
138
106
|
|
|
139
|
-
/**
|
|
140
|
-
* OPTIONS handler for pre-flight requests.
|
|
141
|
-
*/
|
|
142
107
|
export async function OPTIONS() {
|
|
143
108
|
return new NextResponse(null, { status: 204 });
|
|
144
109
|
}
|
|
@@ -6,13 +6,10 @@ import path from 'path';
|
|
|
6
6
|
import { findWranglerConfig } from '@/lib/find-wrangler-config.js';
|
|
7
7
|
import { executeSQL, ErrorTypes, tableExists, parseStatement, removeSQLComments } from '@/lib/sql-operations';
|
|
8
8
|
import { validateMigrationFile } from '@/lib/migrations.js';
|
|
9
|
+
import logger from '@/lib/logger';
|
|
9
10
|
|
|
10
|
-
async function pushToRemote(projectDir,
|
|
11
|
-
const env =
|
|
12
|
-
...process.env,
|
|
13
|
-
CLOUDFLARE_ACCOUNT_ID: accountId,
|
|
14
|
-
CLOUDFLARE_API_TOKEN: apiToken,
|
|
15
|
-
};
|
|
11
|
+
async function pushToRemote(projectDir, databaseName, preview = false, dbMigrationsDir) {
|
|
12
|
+
const env = process.env;
|
|
16
13
|
|
|
17
14
|
try {
|
|
18
15
|
// Create local migrations table (with checksum) and remote migrations table (without checksum)
|
|
@@ -50,14 +47,17 @@ async function pushToRemote(projectDir, accountId, apiToken, databaseName, previ
|
|
|
50
47
|
return [];
|
|
51
48
|
}
|
|
52
49
|
};
|
|
50
|
+
const parsedRemoteRows = parseResults(remoteMigrations);
|
|
51
|
+
console.log(`[push-confirm] remote d1_migrations raw response: ${remoteMigrations}`);
|
|
52
|
+
console.log(`[push-confirm] remote d1_migrations parsed rows (${parsedRemoteRows.length}): ${JSON.stringify(parsedRemoteRows)}`);
|
|
53
53
|
const remoteMigrationsMap = new Map(
|
|
54
|
-
|
|
54
|
+
parsedRemoteRows.map(m => [m.name, m])
|
|
55
55
|
);
|
|
56
56
|
|
|
57
57
|
// Read migration files from disk.
|
|
58
|
-
const migrationsDir = path.join(projectDir, 'migrations');
|
|
58
|
+
const migrationsDir = dbMigrationsDir || path.join(projectDir, 'migrations');
|
|
59
59
|
const files = await readdir(migrationsDir);
|
|
60
|
-
const migrationFiles = files.filter(f => f.endsWith('.sql')).sort();
|
|
60
|
+
const migrationFiles = files.filter(f => f.endsWith('.sql') && !/seed/i.test(f)).sort();
|
|
61
61
|
|
|
62
62
|
const results = { applied: [], skipped: [], preview: [] };
|
|
63
63
|
|
|
@@ -75,6 +75,7 @@ for (const migrationFile of migrationFiles) {
|
|
|
75
75
|
}
|
|
76
76
|
// For remote, compare by migration file name.
|
|
77
77
|
if (remoteMigrationsMap.has(migrationFile)) {
|
|
78
|
+
console.log(`[push-confirm] SKIP ${migrationFile} — found in remote d1_migrations`);
|
|
78
79
|
previewRecord.action = 'skipped';
|
|
79
80
|
previewRecord.reason = 'Already applied';
|
|
80
81
|
results.preview.push(previewRecord);
|
|
@@ -92,7 +93,9 @@ for (const migrationFile of migrationFiles) {
|
|
|
92
93
|
// Only if the migration is a CREATE_TABLE do we check for existing table.
|
|
93
94
|
if (parsedStatement.type === 'CREATE_TABLE' && tableName) {
|
|
94
95
|
const exists = await tableExists(projectDir, databaseName, env, tableName, true);
|
|
96
|
+
console.log(`[push-confirm] tableExists(${tableName}, remote) = ${exists}`);
|
|
95
97
|
if (exists) {
|
|
98
|
+
console.log(`[push-confirm] SKIP ${migrationFile} — table "${tableName}" already exists on remote`);
|
|
96
99
|
previewRecord.action = 'skipped';
|
|
97
100
|
previewRecord.reason = `Table "${tableName}" already exists`;
|
|
98
101
|
results.skipped.push({ name: migrationFile, reason: previewRecord.reason });
|
|
@@ -145,8 +148,10 @@ for (const migrationFile of migrationFiles) {
|
|
|
145
148
|
}
|
|
146
149
|
|
|
147
150
|
export async function POST(req) {
|
|
151
|
+
if (process.env.D1_IS_PRO !== 'true') {
|
|
152
|
+
return NextResponse.json({ success: false, error: { type: 'PRO_REQUIRED', message: 'Pro license required. Run: d1s --license YOUR-KEY' } }, { status: 402 });
|
|
153
|
+
}
|
|
148
154
|
try {
|
|
149
|
-
const { accountId, apiToken } = await req.json();
|
|
150
155
|
const projectDir = process.env.D1_PROJECT_DIR;
|
|
151
156
|
if (!projectDir) {
|
|
152
157
|
return NextResponse.json({
|
|
@@ -168,9 +173,23 @@ export async function POST(req) {
|
|
|
168
173
|
error: { message: 'No D1 databases configured', type: ErrorTypes.VALIDATION_ERROR }
|
|
169
174
|
}, { status: 400 });
|
|
170
175
|
}
|
|
171
|
-
const
|
|
176
|
+
const body = await req.json().catch(() => ({}));
|
|
177
|
+
const dbParam = body?.db;
|
|
178
|
+
const dbConfig = dbParam
|
|
179
|
+
? config.d1_databases.find(d => d.database_name === dbParam)
|
|
180
|
+
: config.d1_databases[0];
|
|
181
|
+
if (!dbConfig) {
|
|
182
|
+
return NextResponse.json({
|
|
183
|
+
success: false,
|
|
184
|
+
error: { message: `Database not found: ${dbParam}`, type: ErrorTypes.VALIDATION_ERROR }
|
|
185
|
+
}, { status: 400 });
|
|
186
|
+
}
|
|
187
|
+
const databaseName = dbConfig.database_name;
|
|
188
|
+
const migrationsDir = dbConfig.migrations_dir
|
|
189
|
+
? path.join(projectDir, dbConfig.migrations_dir)
|
|
190
|
+
: path.join(projectDir, 'migrations');
|
|
172
191
|
// Force preview to be false for actual execution.
|
|
173
|
-
const result = await pushToRemote(projectDir,
|
|
192
|
+
const result = await pushToRemote(projectDir, databaseName, false, migrationsDir);
|
|
174
193
|
return NextResponse.json({
|
|
175
194
|
success: true,
|
|
176
195
|
message: 'Successfully pushed migrations to remote',
|
|
@@ -15,12 +15,8 @@ import logger from '@/lib/logger';
|
|
|
15
15
|
*
|
|
16
16
|
* Note: For remote, we no longer use the checksum.
|
|
17
17
|
*/
|
|
18
|
-
async function pushToRemote(projectDir,
|
|
19
|
-
const env =
|
|
20
|
-
...process.env,
|
|
21
|
-
CLOUDFLARE_ACCOUNT_ID: accountId,
|
|
22
|
-
CLOUDFLARE_API_TOKEN: apiToken,
|
|
23
|
-
};
|
|
18
|
+
async function pushToRemote(projectDir, databaseName, preview = true, dbMigrationsDir) {
|
|
19
|
+
const env = process.env;
|
|
24
20
|
|
|
25
21
|
try {
|
|
26
22
|
// Create local migrations table (with checksum)
|
|
@@ -60,14 +56,17 @@ async function pushToRemote(projectDir, accountId, apiToken, databaseName, previ
|
|
|
60
56
|
}
|
|
61
57
|
};
|
|
62
58
|
// Use migration file name as key
|
|
59
|
+
const parsedRemoteRows = parseResults(remoteMigrations);
|
|
60
|
+
console.log(`[push-preview] remote d1_migrations raw response: ${remoteMigrations}`);
|
|
61
|
+
console.log(`[push-preview] remote d1_migrations parsed rows (${parsedRemoteRows.length}): ${JSON.stringify(parsedRemoteRows)}`);
|
|
63
62
|
const remoteMigrationsMap = new Map(
|
|
64
|
-
|
|
63
|
+
parsedRemoteRows.map(m => [m.name, m])
|
|
65
64
|
);
|
|
66
65
|
|
|
67
66
|
// Read migration files from disk.
|
|
68
|
-
const migrationsDir = path.join(projectDir, 'migrations');
|
|
67
|
+
const migrationsDir = dbMigrationsDir || path.join(projectDir, 'migrations');
|
|
69
68
|
const files = await readdir(migrationsDir);
|
|
70
|
-
const migrationFiles = files.filter(f => f.endsWith('.sql')).sort();
|
|
69
|
+
const migrationFiles = files.filter(f => f.endsWith('.sql') && !/seed/i.test(f)).sort();
|
|
71
70
|
|
|
72
71
|
const results = { applied: [], skipped: [], preview: [] };
|
|
73
72
|
|
|
@@ -118,8 +117,10 @@ async function pushToRemote(projectDir, accountId, apiToken, databaseName, previ
|
|
|
118
117
|
* then calls pushToRemote in preview mode and returns a preview.
|
|
119
118
|
*/
|
|
120
119
|
export async function POST(req) {
|
|
120
|
+
if (process.env.D1_IS_PRO !== 'true') {
|
|
121
|
+
return NextResponse.json({ success: false, error: { type: 'PRO_REQUIRED', message: 'Pro license required. Run: d1s --license YOUR-KEY' } }, { status: 402 });
|
|
122
|
+
}
|
|
121
123
|
try {
|
|
122
|
-
const { accountId, apiToken } = await req.json();
|
|
123
124
|
const projectDir = process.env.D1_PROJECT_DIR;
|
|
124
125
|
if (!projectDir) {
|
|
125
126
|
return NextResponse.json({
|
|
@@ -150,8 +151,22 @@ export async function POST(req) {
|
|
|
150
151
|
}
|
|
151
152
|
}, { status: 400 });
|
|
152
153
|
}
|
|
153
|
-
const
|
|
154
|
-
const
|
|
154
|
+
const body = await req.json().catch(() => ({}));
|
|
155
|
+
const dbParam = body?.db;
|
|
156
|
+
const dbConfig = dbParam
|
|
157
|
+
? config.d1_databases.find(d => d.database_name === dbParam)
|
|
158
|
+
: config.d1_databases[0];
|
|
159
|
+
if (!dbConfig) {
|
|
160
|
+
return NextResponse.json({
|
|
161
|
+
success: false,
|
|
162
|
+
error: { type: ErrorTypes.VALIDATION_ERROR, message: `Database not found: ${dbParam}` }
|
|
163
|
+
}, { status: 400 });
|
|
164
|
+
}
|
|
165
|
+
const databaseName = dbConfig.database_name;
|
|
166
|
+
const migrationsDir = dbConfig.migrations_dir
|
|
167
|
+
? path.join(projectDir, dbConfig.migrations_dir)
|
|
168
|
+
: path.join(projectDir, 'migrations');
|
|
169
|
+
const result = await pushToRemote(projectDir, databaseName, true, migrationsDir);
|
|
155
170
|
return NextResponse.json({
|
|
156
171
|
success: true,
|
|
157
172
|
message: 'Preview generated for migrations to be pushed to remote',
|
|
@@ -31,7 +31,7 @@ export async function POST(req) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// Extract the SQL query from the request body.
|
|
34
|
-
const { query } = await req.json();
|
|
34
|
+
const { query, db } = await req.json();
|
|
35
35
|
|
|
36
36
|
if (logger.shouldLog('debug')) {
|
|
37
37
|
logger.debug('Received query:', query);
|
|
@@ -63,9 +63,17 @@ export async function POST(req) {
|
|
|
63
63
|
);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
//
|
|
67
|
-
const
|
|
68
|
-
|
|
66
|
+
// Resolve target database — use body.db if provided, else fall back to first
|
|
67
|
+
const dbConfig = db
|
|
68
|
+
? config.d1_databases.find(d => d.database_name === db)
|
|
69
|
+
: config.d1_databases[0];
|
|
70
|
+
if (!dbConfig) {
|
|
71
|
+
return NextResponse.json(
|
|
72
|
+
{ success: false, error: { message: `Database not found: ${db}` } },
|
|
73
|
+
{ status: 404 }
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
const databaseName = dbConfig.database_name;
|
|
69
77
|
|
|
70
78
|
// Parse the query into individual SQL statements.
|
|
71
79
|
let statements = parseQuery(query);
|
|
@@ -80,9 +88,9 @@ export async function POST(req) {
|
|
|
80
88
|
|
|
81
89
|
// Validate each parsed statement.
|
|
82
90
|
statements = statements.map(validateStatement);
|
|
83
|
-
// console.log('Validated statements:', statements);
|
|
84
91
|
|
|
85
|
-
// Initialize the migrations table
|
|
92
|
+
// Initialize the migrations table only for non-read-only queries.
|
|
93
|
+
// Skipping for SELECT/PRAGMA/EXPLAIN avoids an extra wrangler/miniflare process per read query.
|
|
86
94
|
const createMigrationsTable = `
|
|
87
95
|
CREATE TABLE IF NOT EXISTS d1_migrations (
|
|
88
96
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -91,11 +99,16 @@ export async function POST(req) {
|
|
|
91
99
|
applied_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
92
100
|
);
|
|
93
101
|
`;
|
|
94
|
-
|
|
102
|
+
const isReadOnly = statements.every(s => {
|
|
103
|
+
const u = s.sql.trim().toUpperCase();
|
|
104
|
+
return u.startsWith('SELECT') || u.startsWith('PRAGMA') || u.startsWith('EXPLAIN');
|
|
105
|
+
});
|
|
106
|
+
if (!isReadOnly) {
|
|
107
|
+
await executeSQL(projectDir, databaseName, createMigrationsTable, {}, false, dbConfig);
|
|
108
|
+
}
|
|
95
109
|
|
|
96
110
|
// Determine whether the query involves any schema changes.
|
|
97
111
|
const hasSchemaChanges = statements.some(isSchemaChange);
|
|
98
|
-
// console.log('Has schema changes:', hasSchemaChanges);
|
|
99
112
|
|
|
100
113
|
let result;
|
|
101
114
|
if (hasSchemaChanges) {
|
|
@@ -113,15 +126,13 @@ export async function POST(req) {
|
|
|
113
126
|
// For data modification queries, execute the statements.
|
|
114
127
|
const results = [];
|
|
115
128
|
for (const stmt of statements) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
129
|
+
const output = await executeSQL(projectDir, databaseName, stmt.sql, {}, false, dbConfig);
|
|
130
|
+
|
|
119
131
|
try {
|
|
120
132
|
const parsed = JSON.parse(output);
|
|
121
133
|
const queryResults = parsed[0]?.results || [];
|
|
122
134
|
results.push(...queryResults);
|
|
123
135
|
} catch (parseError) {
|
|
124
|
-
// console.log('Non-JSON output:', output);
|
|
125
136
|
continue;
|
|
126
137
|
}
|
|
127
138
|
}
|
|
@@ -135,8 +146,8 @@ export async function POST(req) {
|
|
|
135
146
|
return NextResponse.json(result);
|
|
136
147
|
|
|
137
148
|
} catch (error) {
|
|
138
|
-
logger.logError(error, 'query-route');
|
|
139
149
|
const parsedError = parseSQLError(error);
|
|
150
|
+
logger.error(`✗ ${parsedError.message}`);
|
|
140
151
|
|
|
141
152
|
const statusCode =
|
|
142
153
|
error.type === ErrorTypes.VALIDATION_ERROR ? 400 :
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// api/schema/route.js
|
|
2
|
+
// Returns all tables with column schemas and FK relationships.
|
|
3
|
+
|
|
4
|
+
import { NextResponse } from 'next/server';
|
|
5
|
+
import { exec } from 'child_process';
|
|
6
|
+
import { promisify } from 'util';
|
|
7
|
+
import { findWranglerConfig } from '@/lib/find-wrangler-config.js';
|
|
8
|
+
|
|
9
|
+
const execAsync = promisify(exec);
|
|
10
|
+
|
|
11
|
+
async function runPragma(databaseName, query, projectDir) {
|
|
12
|
+
const { stdout } = await execAsync(
|
|
13
|
+
`wrangler d1 execute ${databaseName} --local --command="${query.replace(/"/g, '\\"')}" --json`,
|
|
14
|
+
{ cwd: projectDir }
|
|
15
|
+
);
|
|
16
|
+
const result = JSON.parse(stdout);
|
|
17
|
+
return result[0]?.results || [];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function GET(request) {
|
|
21
|
+
try {
|
|
22
|
+
const { searchParams } = new URL(request.url);
|
|
23
|
+
const dbParam = searchParams.get('db');
|
|
24
|
+
|
|
25
|
+
const projectDir = process.env.D1_PROJECT_DIR;
|
|
26
|
+
if (!projectDir) throw new Error('Project directory not configured');
|
|
27
|
+
|
|
28
|
+
const wranglerResult = await findWranglerConfig(projectDir);
|
|
29
|
+
if (!wranglerResult?.config) throw new Error('No Wrangler configuration found');
|
|
30
|
+
const config = wranglerResult.config;
|
|
31
|
+
if (!config.d1_databases?.length) throw new Error('No D1 databases configured');
|
|
32
|
+
|
|
33
|
+
const dbConfig = dbParam
|
|
34
|
+
? config.d1_databases.find(d => d.database_name === dbParam)
|
|
35
|
+
: config.d1_databases[0];
|
|
36
|
+
if (!dbConfig) throw new Error(`Database not found: ${dbParam}`);
|
|
37
|
+
const databaseName = dbConfig.database_name;
|
|
38
|
+
|
|
39
|
+
// Get all user tables
|
|
40
|
+
const tableRows = await runPragma(
|
|
41
|
+
databaseName,
|
|
42
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_cf_%' ORDER BY name;`,
|
|
43
|
+
projectDir
|
|
44
|
+
);
|
|
45
|
+
const tableNames = tableRows.map(r => r.name);
|
|
46
|
+
|
|
47
|
+
// Run sequentially to avoid SQLITE_BUSY (database locked) errors
|
|
48
|
+
const tables = [];
|
|
49
|
+
for (const name of tableNames) {
|
|
50
|
+
const columns = await runPragma(databaseName, `PRAGMA table_info(${name});`, projectDir);
|
|
51
|
+
const foreignKeys = await runPragma(databaseName, `PRAGMA foreign_key_list(${name});`, projectDir);
|
|
52
|
+
tables.push({ name, columns, foreignKeys });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return NextResponse.json({ success: true, tables });
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export async function OPTIONS() {
|
|
62
|
+
return new NextResponse(null, { status: 204 });
|
|
63
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// api/tables/[name]/import/route.js
|
|
2
|
+
|
|
3
|
+
import { NextResponse } from 'next/server';
|
|
4
|
+
import { findWranglerConfig } from '@/lib/find-wrangler-config.js';
|
|
5
|
+
import { sanitizeTableName, sanitizeColumnName } from '@/lib/sql-sanitizer.js';
|
|
6
|
+
import { promisify } from 'util';
|
|
7
|
+
import { exec } from 'child_process';
|
|
8
|
+
import { executeLocalSQL } from '@/lib/local-db.js';
|
|
9
|
+
import logger from '@/lib/logger';
|
|
10
|
+
|
|
11
|
+
const execAsync = promisify(exec);
|
|
12
|
+
const BATCH_SIZE = 100;
|
|
13
|
+
|
|
14
|
+
async function executeD1Command(sql, projectDir, dbConfig) {
|
|
15
|
+
// Try direct SQLite access first (fast path)
|
|
16
|
+
const localOutput = executeLocalSQL(projectDir, dbConfig, sql);
|
|
17
|
+
if (localOutput !== null) return JSON.parse(localOutput);
|
|
18
|
+
|
|
19
|
+
// Fall back to wrangler CLI
|
|
20
|
+
const databaseName = dbConfig.database_name;
|
|
21
|
+
const { stdout } = await execAsync(
|
|
22
|
+
`wrangler d1 execute ${databaseName} --local --command="${sql.replace(/"/g, '\\"')}" --json`,
|
|
23
|
+
{ cwd: projectDir }
|
|
24
|
+
);
|
|
25
|
+
return JSON.parse(stdout);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function POST(req, context) {
|
|
29
|
+
try {
|
|
30
|
+
const params = await context.params;
|
|
31
|
+
const { name } = params;
|
|
32
|
+
|
|
33
|
+
const { rows, db } = await req.json();
|
|
34
|
+
|
|
35
|
+
if (!Array.isArray(rows) || rows.length === 0) {
|
|
36
|
+
return NextResponse.json(
|
|
37
|
+
{ success: false, error: 'No rows provided' },
|
|
38
|
+
{ status: 400 }
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const projectDir = process.env.D1_PROJECT_DIR;
|
|
43
|
+
if (!projectDir) throw new Error('Project directory not configured');
|
|
44
|
+
|
|
45
|
+
const wranglerResult = await findWranglerConfig(projectDir);
|
|
46
|
+
if (!wranglerResult?.config) throw new Error('No Wrangler configuration found');
|
|
47
|
+
const config = wranglerResult.config;
|
|
48
|
+
if (!config.d1_databases?.length) throw new Error('No D1 databases configured');
|
|
49
|
+
|
|
50
|
+
const dbConfig = db
|
|
51
|
+
? config.d1_databases.find(d => d.database_name === db)
|
|
52
|
+
: config.d1_databases[0];
|
|
53
|
+
if (!dbConfig) throw new Error(`Database not found: ${db}`);
|
|
54
|
+
const databaseName = dbConfig.database_name;
|
|
55
|
+
|
|
56
|
+
const sanitizedTableName = sanitizeTableName(name);
|
|
57
|
+
const columns = Object.keys(rows[0]).map(sanitizeColumnName);
|
|
58
|
+
|
|
59
|
+
let imported = 0;
|
|
60
|
+
const errors = [];
|
|
61
|
+
|
|
62
|
+
// Process in batches to avoid wrangler command size limits
|
|
63
|
+
for (let i = 0; i < rows.length; i += BATCH_SIZE) {
|
|
64
|
+
const batch = rows.slice(i, i + BATCH_SIZE);
|
|
65
|
+
const valuesList = batch.map(row => {
|
|
66
|
+
const vals = columns.map(col => {
|
|
67
|
+
const rawCol = Object.keys(rows[0])[columns.indexOf(col)];
|
|
68
|
+
const v = row[rawCol];
|
|
69
|
+
if (v === null || v === undefined || v === '') return 'NULL';
|
|
70
|
+
if (typeof v === 'number') return v;
|
|
71
|
+
return `'${String(v).replace(/'/g, "''")}'`;
|
|
72
|
+
});
|
|
73
|
+
return `(${vals.join(', ')})`;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const sql = `INSERT INTO ${sanitizedTableName} (${columns.join(', ')}) VALUES ${valuesList.join(', ')};`;
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
await executeD1Command(sql, projectDir, dbConfig);
|
|
80
|
+
imported += batch.length;
|
|
81
|
+
} catch (err) {
|
|
82
|
+
logger.error(`Import batch ${i}-${i + BATCH_SIZE} failed:`, err);
|
|
83
|
+
errors.push({ batch: i, error: err.message });
|
|
84
|
+
// Continue with remaining batches
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return NextResponse.json({
|
|
89
|
+
success: true,
|
|
90
|
+
imported,
|
|
91
|
+
failed: rows.length - imported,
|
|
92
|
+
errors,
|
|
93
|
+
});
|
|
94
|
+
} catch (error) {
|
|
95
|
+
logger.error('Import error:', error);
|
|
96
|
+
return NextResponse.json(
|
|
97
|
+
{ success: false, error: error.message },
|
|
98
|
+
{ status: 500 }
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export async function OPTIONS() {
|
|
104
|
+
return new NextResponse(null, {
|
|
105
|
+
status: 204,
|
|
106
|
+
headers: {
|
|
107
|
+
'Access-Control-Allow-Origin': '*',
|
|
108
|
+
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
|
109
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|