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
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// api/migrations/list/route.js
|
|
2
|
+
// Returns the list of local migration files cross-referenced with the local d1_migrations table.
|
|
3
|
+
|
|
4
|
+
import { NextResponse } from 'next/server';
|
|
5
|
+
import { findWranglerConfig } from '@/lib/find-wrangler-config.js';
|
|
6
|
+
import { promisify } from 'util';
|
|
7
|
+
import { exec } from 'child_process';
|
|
8
|
+
import { readdir } from 'fs/promises';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import logger from '@/lib/logger';
|
|
11
|
+
import { ensureChecksumColumn } from '@/lib/migrations';
|
|
12
|
+
import { executeLocalSQL } from '@/lib/local-db.js';
|
|
13
|
+
|
|
14
|
+
const execAsync = promisify(exec);
|
|
15
|
+
|
|
16
|
+
async function getAppliedMigrations(projectDir, dbConfig) {
|
|
17
|
+
const databaseName = dbConfig.database_name;
|
|
18
|
+
|
|
19
|
+
// Fast path: use better-sqlite3 directly — no wrangler subprocess needed
|
|
20
|
+
// Handle missing checksum column gracefully (wrangler creates d1_migrations without it)
|
|
21
|
+
try {
|
|
22
|
+
let localOutput = executeLocalSQL(
|
|
23
|
+
projectDir, dbConfig,
|
|
24
|
+
'SELECT name, checksum, applied_at FROM d1_migrations ORDER BY applied_at ASC;'
|
|
25
|
+
);
|
|
26
|
+
if (localOutput !== null) {
|
|
27
|
+
const parsed = JSON.parse(localOutput);
|
|
28
|
+
return parsed[0]?.results || [];
|
|
29
|
+
}
|
|
30
|
+
} catch (err) {
|
|
31
|
+
const msg = err?.message || '';
|
|
32
|
+
if (msg.includes('no such column')) {
|
|
33
|
+
// Table exists but was created by wrangler without checksum column — query without it
|
|
34
|
+
try {
|
|
35
|
+
const localOutput = executeLocalSQL(
|
|
36
|
+
projectDir, dbConfig,
|
|
37
|
+
'SELECT name, applied_at FROM d1_migrations ORDER BY applied_at ASC;'
|
|
38
|
+
);
|
|
39
|
+
if (localOutput !== null) {
|
|
40
|
+
const parsed = JSON.parse(localOutput);
|
|
41
|
+
return (parsed[0]?.results || []).map(r => ({ ...r, checksum: null }));
|
|
42
|
+
}
|
|
43
|
+
} catch {
|
|
44
|
+
// fall through to wrangler CLI
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Any other error (e.g. no such table) — fall through to wrangler CLI
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Slow path: wrangler CLI fallback (used when better-sqlite3 can't find the SQLite file)
|
|
51
|
+
try {
|
|
52
|
+
await ensureChecksumColumn(projectDir, databaseName);
|
|
53
|
+
const { stdout } = await execAsync(
|
|
54
|
+
`wrangler d1 execute ${databaseName} --local --command="SELECT name, checksum, applied_at FROM d1_migrations ORDER BY applied_at ASC;" --json`,
|
|
55
|
+
{ cwd: projectDir, timeout: 15000 }
|
|
56
|
+
);
|
|
57
|
+
const result = JSON.parse(stdout);
|
|
58
|
+
return result[0]?.results || [];
|
|
59
|
+
} catch {
|
|
60
|
+
// d1_migrations table may not exist yet
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function GET(request) {
|
|
66
|
+
try {
|
|
67
|
+
const { searchParams } = new URL(request.url);
|
|
68
|
+
const dbParam = searchParams.get('db');
|
|
69
|
+
|
|
70
|
+
const projectDir = process.env.D1_PROJECT_DIR;
|
|
71
|
+
if (!projectDir) throw new Error('Project directory not configured');
|
|
72
|
+
|
|
73
|
+
const wranglerResult = await findWranglerConfig(projectDir);
|
|
74
|
+
if (!wranglerResult?.config) throw new Error('No Wrangler configuration found');
|
|
75
|
+
const config = wranglerResult.config;
|
|
76
|
+
if (!config.d1_databases?.length) throw new Error('No D1 databases configured');
|
|
77
|
+
|
|
78
|
+
const dbConfig = dbParam
|
|
79
|
+
? config.d1_databases.find(d => d.database_name === dbParam)
|
|
80
|
+
: config.d1_databases[0];
|
|
81
|
+
if (!dbConfig) throw new Error(`Database not found: ${dbParam}`);
|
|
82
|
+
const databaseName = dbConfig.database_name;
|
|
83
|
+
|
|
84
|
+
// Read migration files from disk (respect per-database migrations_dir if configured)
|
|
85
|
+
const migrationsDir = dbConfig.migrations_dir
|
|
86
|
+
? path.join(projectDir, dbConfig.migrations_dir)
|
|
87
|
+
: path.join(projectDir, 'migrations');
|
|
88
|
+
let files = [];
|
|
89
|
+
try {
|
|
90
|
+
const entries = await readdir(migrationsDir);
|
|
91
|
+
files = entries
|
|
92
|
+
.filter(f => f.endsWith('.sql'))
|
|
93
|
+
.sort(); // timestamp prefix ensures chronological order
|
|
94
|
+
} catch {
|
|
95
|
+
// migrations/ folder doesn't exist yet — that's fine
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Get applied migrations from local DB
|
|
99
|
+
const applied = await getAppliedMigrations(projectDir, dbConfig);
|
|
100
|
+
const appliedMap = new Map(applied.map(m => [m.name, m]));
|
|
101
|
+
|
|
102
|
+
const migrations = files.map(name => {
|
|
103
|
+
const record = appliedMap.get(name);
|
|
104
|
+
return {
|
|
105
|
+
name,
|
|
106
|
+
applied: !!record,
|
|
107
|
+
applied_at: record?.applied_at || null,
|
|
108
|
+
checksum: record?.checksum || null,
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Also include any DB records whose files are missing (orphaned)
|
|
113
|
+
applied.forEach(record => {
|
|
114
|
+
if (!files.includes(record.name)) {
|
|
115
|
+
migrations.push({
|
|
116
|
+
name: record.name,
|
|
117
|
+
applied: true,
|
|
118
|
+
applied_at: record.applied_at,
|
|
119
|
+
checksum: record.checksum,
|
|
120
|
+
orphaned: true,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return NextResponse.json({ success: true, migrations, migrationsDir });
|
|
126
|
+
} catch (error) {
|
|
127
|
+
logger.error('Migrations list error:', error);
|
|
128
|
+
return NextResponse.json(
|
|
129
|
+
{ success: false, error: error.message },
|
|
130
|
+
{ status: 500 }
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export async function OPTIONS() {
|
|
136
|
+
return new NextResponse(null, { status: 204 });
|
|
137
|
+
}
|
|
@@ -6,7 +6,7 @@ import { readFile, readdir } from 'fs/promises';
|
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { promisify } from 'util';
|
|
8
8
|
import { exec } from 'child_process';
|
|
9
|
-
import { createChecksum } from '@/lib/migrations';
|
|
9
|
+
import { createChecksum, ensureChecksumColumn } from '@/lib/migrations';
|
|
10
10
|
|
|
11
11
|
const execAsync = promisify(exec);
|
|
12
12
|
|
|
@@ -15,6 +15,7 @@ const execAsync = promisify(exec);
|
|
|
15
15
|
*/
|
|
16
16
|
async function getDatabaseMigrations(projectDir, databaseName) {
|
|
17
17
|
try {
|
|
18
|
+
await ensureChecksumColumn(projectDir, databaseName);
|
|
18
19
|
const { stdout } = await execAsync(
|
|
19
20
|
`wrangler d1 execute ${databaseName} --local --command="SELECT name, checksum FROM d1_migrations;" --json`,
|
|
20
21
|
{ cwd: projectDir }
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// api/pro/route.js
|
|
2
|
+
// Returns whether Pro features are enabled for the current session.
|
|
3
|
+
// D1_IS_PRO is set by scripts/studio.js at startup after license validation.
|
|
4
|
+
|
|
5
|
+
export async function GET() {
|
|
6
|
+
return Response.json({ isPro: process.env.D1_IS_PRO === 'true' });
|
|
7
|
+
}
|
|
@@ -1,54 +1,46 @@
|
|
|
1
1
|
// api/pull-remote/confirm/route.js
|
|
2
2
|
|
|
3
3
|
import { NextResponse } from 'next/server';
|
|
4
|
-
import { writeFile, mkdir, readdir, unlink } from 'fs/promises';
|
|
4
|
+
import { writeFile, readFile, mkdir, readdir, unlink } from 'fs/promises';
|
|
5
|
+
import crypto from 'crypto';
|
|
5
6
|
import path from 'path';
|
|
7
|
+
import { promisify } from 'util';
|
|
8
|
+
import { exec } from 'child_process';
|
|
6
9
|
import { findWranglerConfig } from '@/lib/find-wrangler-config.js';
|
|
7
|
-
import {
|
|
10
|
+
import {
|
|
8
11
|
executeSQL,
|
|
9
12
|
ErrorTypes,
|
|
10
|
-
formatSQLStatement,
|
|
11
|
-
getMigrationFileContent
|
|
12
13
|
} from '@/lib/sql-operations';
|
|
13
14
|
import { getCurrentSchema, analyzeDependencies } from '@/lib/schema-operations';
|
|
14
15
|
import { initMigrationsTable, recordMigration, getRemoteMigrations } from '@/lib/migrations.js';
|
|
16
|
+
import { getLocalDb, invalidateLocalDb, executeLocalSQL } from '@/lib/local-db.js';
|
|
15
17
|
import logger from '@/lib/logger';
|
|
16
18
|
|
|
19
|
+
const execAsync = promisify(exec);
|
|
20
|
+
|
|
17
21
|
/**
|
|
18
22
|
* Applies the pull migrations by:
|
|
19
23
|
* 1. Fetching remote migration metadata.
|
|
20
|
-
* 2.
|
|
21
|
-
* 3.
|
|
22
|
-
* 4.
|
|
23
|
-
* 5.
|
|
24
|
-
* 6.
|
|
25
|
-
* 7. Replacing the local migrations folder with the staged files.
|
|
26
|
-
*
|
|
27
|
-
* This completely replaces the local state with the remote state.
|
|
28
|
-
*
|
|
29
|
-
* @param {string} projectDir - The project directory.
|
|
30
|
-
* @param {string} accountId - Cloudflare account ID.
|
|
31
|
-
* @param {string} apiToken - Cloudflare API token.
|
|
32
|
-
* @param {string} databaseName - The target D1 database name.
|
|
33
|
-
* @returns {object} Details of applied migrations.
|
|
24
|
+
* 2. Reading each migration file from the local migrations folder.
|
|
25
|
+
* 3. Performing a destructive update on local objects via better-sqlite3 (FK-safe).
|
|
26
|
+
* 4. Resetting the local migrations table.
|
|
27
|
+
* 5. Applying staged migrations sequentially.
|
|
28
|
+
* 6. Replacing the local migrations folder with only the remote-matched files.
|
|
34
29
|
*/
|
|
35
|
-
async function applyPullMigrations(projectDir,
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
CLOUDFLARE_API_TOKEN: apiToken,
|
|
39
|
-
CLOUDFLARE_ACCOUNT_ID: accountId
|
|
40
|
-
};
|
|
30
|
+
async function applyPullMigrations(projectDir, dbConfig) {
|
|
31
|
+
const databaseName = dbConfig.database_name;
|
|
32
|
+
const env = process.env;
|
|
41
33
|
|
|
42
34
|
try {
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
const migrationsDir = dbConfig.migrations_dir
|
|
36
|
+
? path.join(projectDir, dbConfig.migrations_dir)
|
|
37
|
+
: path.join(projectDir, 'migrations');
|
|
45
38
|
const stagingDir = path.join(projectDir, 'migrations-temp');
|
|
46
39
|
|
|
47
|
-
// Ensure both directories exist.
|
|
48
40
|
await mkdir(migrationsDir, { recursive: true });
|
|
49
41
|
await mkdir(stagingDir, { recursive: true });
|
|
50
42
|
|
|
51
|
-
// Clear
|
|
43
|
+
// Clear staging folder
|
|
52
44
|
const stagedFilesList = await readdir(stagingDir).catch(() => []);
|
|
53
45
|
await Promise.all(stagedFilesList.map(file => unlink(path.join(stagingDir, file))));
|
|
54
46
|
|
|
@@ -57,123 +49,134 @@ async function applyPullMigrations(projectDir, accountId, apiToken, databaseName
|
|
|
57
49
|
const remoteMigrations = await getRemoteMigrations(projectDir, databaseName, env);
|
|
58
50
|
logger.debug('Remote migration metadata:', remoteMigrations);
|
|
59
51
|
|
|
60
|
-
// --- STEP 2:
|
|
61
|
-
logger.debug('
|
|
52
|
+
// --- STEP 2: Read migration content from local files ---
|
|
53
|
+
logger.debug('Reading migration files from local migrations folder...');
|
|
62
54
|
const stagedFiles = new Map();
|
|
63
55
|
for (const migration of remoteMigrations) {
|
|
56
|
+
const migrationFileName = migration.name;
|
|
57
|
+
const localFilePath = path.join(migrationsDir, migrationFileName);
|
|
64
58
|
try {
|
|
65
|
-
const
|
|
66
|
-
const content = await getMigrationFileContent(projectDir, databaseName, migrationFileName, env);
|
|
59
|
+
const content = await readFile(localFilePath, 'utf8');
|
|
67
60
|
stagedFiles.set(migrationFileName, content);
|
|
68
|
-
logger.debug(`Staged migration file: ${migrationFileName}`);
|
|
69
61
|
await writeFile(path.join(stagingDir, migrationFileName), content, 'utf8');
|
|
62
|
+
logger.debug(`Staged migration file: ${migrationFileName}`);
|
|
70
63
|
} catch (fileError) {
|
|
71
|
-
logger.error(`
|
|
72
|
-
throw new Error(`
|
|
64
|
+
logger.error(`Migration file not found locally: ${migrationFileName}`, fileError.message);
|
|
65
|
+
throw new Error(`Migration file not found locally: ${migrationFileName}`);
|
|
73
66
|
}
|
|
74
67
|
}
|
|
75
68
|
|
|
76
|
-
// --- STEP 3:
|
|
77
|
-
logger.debug('Fetching local schema
|
|
69
|
+
// --- STEP 3: Get local schema for drop order ---
|
|
70
|
+
logger.debug('Fetching local schema...');
|
|
78
71
|
const currentSchema = await getCurrentSchema(projectDir, databaseName, env, false);
|
|
79
72
|
const tableSchema = currentSchema.filter(obj =>
|
|
80
73
|
obj.type === 'table' && obj.name && obj.name.toLowerCase() !== 'if'
|
|
81
74
|
);
|
|
82
|
-
logger.debug('Local table schema:', tableSchema);
|
|
83
75
|
const dropOrder = tableSchema.length > 0
|
|
84
|
-
? analyzeDependencies(
|
|
85
|
-
tableSchema.map(obj => ({
|
|
86
|
-
tableName: obj.name,
|
|
87
|
-
sql: obj.sql,
|
|
88
|
-
type: obj.type
|
|
89
|
-
}))
|
|
90
|
-
)
|
|
76
|
+
? analyzeDependencies(tableSchema.map(obj => ({ tableName: obj.name, sql: obj.sql, type: obj.type })))
|
|
91
77
|
: [];
|
|
92
|
-
logger.debug('Computed drop order:', dropOrder);
|
|
93
78
|
|
|
94
|
-
// --- STEP 4: Destructive update
|
|
79
|
+
// --- STEP 4: Destructive update ---
|
|
80
|
+
// Filter out Cloudflare/SQLite system objects — these are created by the runtime,
|
|
81
|
+
// not by migrations, and wrangler blocks dropping them with SQLITE_AUTH.
|
|
82
|
+
const SYSTEM_OBJECT = /^(_cf_|sqlite_)/i;
|
|
83
|
+
const triggers = currentSchema.filter(obj => obj.type === 'trigger' && !SYSTEM_OBJECT.test(obj.name));
|
|
84
|
+
const indexes = currentSchema.filter(obj => obj.type === 'index' && !SYSTEM_OBJECT.test(obj.name));
|
|
85
|
+
const reversedDropOrder = [...dropOrder].filter(t => !SYSTEM_OBJECT.test(t)).reverse();
|
|
86
|
+
|
|
95
87
|
logger.debug('Beginning destructive update...');
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
await executeSQL(
|
|
117
|
-
projectDir,
|
|
118
|
-
databaseName,
|
|
119
|
-
formatSQLStatement(`DROP INDEX IF EXISTS ${index.name}`),
|
|
120
|
-
env,
|
|
121
|
-
false
|
|
122
|
-
);
|
|
88
|
+
const db = getLocalDb(projectDir, dbConfig);
|
|
89
|
+
|
|
90
|
+
if (db) {
|
|
91
|
+
// better-sqlite3: persistent connection so PRAGMA FK=OFF persists across all drops
|
|
92
|
+
try {
|
|
93
|
+
db.pragma('foreign_keys = OFF');
|
|
94
|
+
for (const trigger of triggers) {
|
|
95
|
+
logger.debug(`Dropping trigger: ${trigger.name}`);
|
|
96
|
+
db.prepare(`DROP TRIGGER IF EXISTS "${trigger.name}"`).run();
|
|
97
|
+
}
|
|
98
|
+
for (const index of indexes) {
|
|
99
|
+
logger.debug(`Dropping index: ${index.name}`);
|
|
100
|
+
db.prepare(`DROP INDEX IF EXISTS "${index.name}"`).run();
|
|
101
|
+
}
|
|
102
|
+
for (const tableName of reversedDropOrder) {
|
|
103
|
+
logger.debug(`Dropping table: ${tableName}`);
|
|
104
|
+
db.prepare(`DROP TABLE IF EXISTS "${tableName}"`).run();
|
|
105
|
+
}
|
|
106
|
+
} finally {
|
|
107
|
+
db.pragma('foreign_keys = ON');
|
|
123
108
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
109
|
+
} else {
|
|
110
|
+
// Wrangler CLI fallback: drop in correct order (child-first) so FK constraints
|
|
111
|
+
// are satisfied without needing PRAGMA — PRAGMA is blocked by SQLITE_AUTH anyway.
|
|
112
|
+
logger.debug('better-sqlite3 unavailable, falling back to wrangler CLI for destructive update');
|
|
113
|
+
const stmts = [
|
|
114
|
+
...triggers.map(t => `DROP TRIGGER IF EXISTS "${t.name}"`),
|
|
115
|
+
...indexes.map(i => `DROP INDEX IF EXISTS "${i.name}"`),
|
|
116
|
+
...reversedDropOrder.map(t => `DROP TABLE IF EXISTS "${t}"`),
|
|
117
|
+
];
|
|
118
|
+
if (stmts.length > 0) {
|
|
119
|
+
await executeSQL(projectDir, databaseName, stmts.join(';\n') + ';', env, false, dbConfig);
|
|
134
120
|
}
|
|
135
|
-
logger.debug('Re-enabling foreign keys...');
|
|
136
|
-
await executeSQL(projectDir, databaseName, 'PRAGMA foreign_keys=ON;', env, false);
|
|
137
|
-
} catch (dropError) {
|
|
138
|
-
throw new Error(`Error dropping existing objects: ${dropError.message}`);
|
|
139
121
|
}
|
|
140
122
|
|
|
141
123
|
// --- STEP 5: Reset the local migrations table ---
|
|
124
|
+
logger.debug('Resetting local migrations table...');
|
|
142
125
|
try {
|
|
143
|
-
logger.debug('Resetting local migrations table...');
|
|
144
126
|
await initMigrationsTable(projectDir, databaseName, 'local', true);
|
|
145
127
|
} catch (initError) {
|
|
146
128
|
throw new Error(`Error resetting migrations table: ${initError.message}`);
|
|
147
129
|
}
|
|
148
130
|
|
|
131
|
+
// Invalidate cached DB instance so next access reflects cleared schema
|
|
132
|
+
invalidateLocalDb(projectDir, databaseName);
|
|
133
|
+
|
|
149
134
|
// --- STEP 6: Apply staged migrations ---
|
|
150
|
-
// (
|
|
135
|
+
// Use better-sqlite3 directly (handles multi-statement SQL, no shell escaping issues).
|
|
136
|
+
// Fall back to `wrangler --file` if the SQLite file can't be located — never use
|
|
137
|
+
// `--command` for migration files because it collapses newlines and breaks SQL comments.
|
|
138
|
+
const isWindows = process.platform === 'win32';
|
|
139
|
+
const npxCommand = isWindows ? 'npx.cmd' : 'npx';
|
|
140
|
+
|
|
151
141
|
const appliedPreview = { preview: [] };
|
|
152
142
|
let currentFilename = '';
|
|
153
143
|
try {
|
|
154
144
|
for (const [filename, content] of stagedFiles.entries()) {
|
|
155
145
|
currentFilename = filename;
|
|
156
146
|
logger.debug(`Applying migration: ${filename}`);
|
|
157
|
-
// Write the migration file to the main migrations folder.
|
|
158
|
-
await writeFile(path.join(migrationsDir, filename), content, 'utf8');
|
|
159
147
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
.createHash('sha256')
|
|
163
|
-
.update(content)
|
|
164
|
-
.digest('hex');
|
|
148
|
+
const filePath = path.join(migrationsDir, filename);
|
|
149
|
+
await writeFile(filePath, content, 'utf8');
|
|
165
150
|
|
|
166
|
-
|
|
167
|
-
await recordMigration(
|
|
168
|
-
projectDir,
|
|
169
|
-
databaseName,
|
|
170
|
-
{ name: filename, checksum },
|
|
171
|
-
env,
|
|
172
|
-
false
|
|
173
|
-
);
|
|
151
|
+
const checksum = crypto.createHash('sha256').update(content).digest('hex');
|
|
152
|
+
await recordMigration(projectDir, databaseName, { name: filename, checksum }, env, false);
|
|
174
153
|
|
|
175
|
-
//
|
|
176
|
-
|
|
154
|
+
// Try better-sqlite3 first; it handles multi-statement SQL in a single transaction
|
|
155
|
+
let usedLocal = false;
|
|
156
|
+
try {
|
|
157
|
+
const localResult = executeLocalSQL(projectDir, dbConfig, content);
|
|
158
|
+
if (localResult !== null) usedLocal = true;
|
|
159
|
+
} catch (localErr) {
|
|
160
|
+
// SQL error (not "file not found") — propagate immediately
|
|
161
|
+
throw localErr;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (!usedLocal) {
|
|
165
|
+
// Wrangler CLI fallback: --file preserves SQL as-is (no whitespace collapse, no escaping)
|
|
166
|
+
logger.debug(`Applying ${filename} via wrangler --file`);
|
|
167
|
+
const { stdout } = await execAsync(
|
|
168
|
+
`${npxCommand} wrangler d1 execute ${databaseName} --local --file="${filePath}" --json`,
|
|
169
|
+
{ cwd: projectDir, env: { ...process.env, ...env }, maxBuffer: 1024 * 1024 * 10 }
|
|
170
|
+
);
|
|
171
|
+
// Success output is a JSON array: [{results, success, meta}]
|
|
172
|
+
// Error output is a JSON object: {"error": {"text": "..."}}
|
|
173
|
+
// Only parse when it's an object (error case) — array means success.
|
|
174
|
+
const trimmed = stdout?.trim();
|
|
175
|
+
if (trimmed?.startsWith('{')) {
|
|
176
|
+
const parsed = JSON.parse(trimmed);
|
|
177
|
+
if (parsed?.error) throw new Error(parsed.error.text || JSON.stringify(parsed.error));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
177
180
|
|
|
178
181
|
appliedPreview.preview.push({ migration: filename, action: 'applied' });
|
|
179
182
|
}
|
|
@@ -181,17 +184,13 @@ async function applyPullMigrations(projectDir, accountId, apiToken, databaseName
|
|
|
181
184
|
throw new Error(`Error applying migration ${currentFilename}: ${applyError.message}`);
|
|
182
185
|
}
|
|
183
186
|
|
|
184
|
-
// --- STEP 7: Replace
|
|
185
|
-
logger.debug('Replacing
|
|
187
|
+
// --- STEP 7: Replace migrations folder with only staged (remote) files ---
|
|
188
|
+
logger.debug('Replacing migrations folder with staged files...');
|
|
186
189
|
const mainFiles = await readdir(migrationsDir).catch(() => []);
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
logger.debug(`Deleting local migration file: ${file}`);
|
|
190
|
-
await unlink(path.join(migrationsDir, file));
|
|
191
|
-
}
|
|
190
|
+
for (const file of mainFiles) {
|
|
191
|
+
await unlink(path.join(migrationsDir, file));
|
|
192
192
|
}
|
|
193
193
|
for (const [filename, content] of stagedFiles.entries()) {
|
|
194
|
-
logger.debug(`Copying staged file ${filename} to main migrations folder`);
|
|
195
194
|
await writeFile(path.join(migrationsDir, filename), content, 'utf8');
|
|
196
195
|
}
|
|
197
196
|
|
|
@@ -206,46 +205,48 @@ async function applyPullMigrations(projectDir, accountId, apiToken, databaseName
|
|
|
206
205
|
}
|
|
207
206
|
}
|
|
208
207
|
|
|
209
|
-
/**
|
|
210
|
-
* POST handler for pull-remote confirm.
|
|
211
|
-
* Reads the Wrangler configuration (via findWranglerConfig) to obtain the D1 database name,
|
|
212
|
-
* then applies the pull migrations.
|
|
213
|
-
*/
|
|
214
208
|
export async function POST(req) {
|
|
209
|
+
if (process.env.D1_IS_PRO !== 'true') {
|
|
210
|
+
return NextResponse.json({ success: false, error: { type: 'PRO_REQUIRED', message: 'Pro license required. Run: d1s --license YOUR-KEY' } }, { status: 402 });
|
|
211
|
+
}
|
|
215
212
|
try {
|
|
216
|
-
const { accountId, apiToken } = await req.json();
|
|
217
213
|
const projectDir = process.env.D1_PROJECT_DIR;
|
|
218
214
|
if (!projectDir) {
|
|
219
215
|
return NextResponse.json({
|
|
220
216
|
success: false,
|
|
221
|
-
error: {
|
|
222
|
-
type: ErrorTypes.VALIDATION_ERROR,
|
|
223
|
-
message: 'Project directory not configured'
|
|
224
|
-
}
|
|
217
|
+
error: { type: ErrorTypes.VALIDATION_ERROR, message: 'Project directory not configured' }
|
|
225
218
|
}, { status: 500 });
|
|
226
219
|
}
|
|
220
|
+
|
|
227
221
|
const wranglerResult = await findWranglerConfig(projectDir);
|
|
228
|
-
if (!wranglerResult
|
|
222
|
+
if (!wranglerResult?.config) {
|
|
229
223
|
return NextResponse.json({
|
|
230
224
|
success: false,
|
|
231
|
-
error: {
|
|
232
|
-
type: ErrorTypes.VALIDATION_ERROR,
|
|
233
|
-
message: 'Could not find Wrangler configuration'
|
|
234
|
-
}
|
|
225
|
+
error: { type: ErrorTypes.VALIDATION_ERROR, message: 'Could not find Wrangler configuration' }
|
|
235
226
|
}, { status: 400 });
|
|
236
227
|
}
|
|
228
|
+
|
|
237
229
|
const config = wranglerResult.config;
|
|
238
230
|
if (!config.d1_databases?.length) {
|
|
239
231
|
return NextResponse.json({
|
|
240
232
|
success: false,
|
|
241
|
-
error: {
|
|
242
|
-
type: ErrorTypes.VALIDATION_ERROR,
|
|
243
|
-
message: 'No D1 databases configured'
|
|
244
|
-
}
|
|
233
|
+
error: { type: ErrorTypes.VALIDATION_ERROR, message: 'No D1 databases configured' }
|
|
245
234
|
}, { status: 400 });
|
|
246
235
|
}
|
|
247
|
-
|
|
248
|
-
const
|
|
236
|
+
|
|
237
|
+
const body = await req.json().catch(() => ({}));
|
|
238
|
+
const dbParam = body?.db;
|
|
239
|
+
const dbConfig = dbParam
|
|
240
|
+
? config.d1_databases.find(d => d.database_name === dbParam)
|
|
241
|
+
: config.d1_databases[0];
|
|
242
|
+
if (!dbConfig) {
|
|
243
|
+
return NextResponse.json({
|
|
244
|
+
success: false,
|
|
245
|
+
error: { type: ErrorTypes.VALIDATION_ERROR, message: `Database not found: ${dbParam}` }
|
|
246
|
+
}, { status: 400 });
|
|
247
|
+
}
|
|
248
|
+
const result = await applyPullMigrations(projectDir, dbConfig);
|
|
249
|
+
|
|
249
250
|
return NextResponse.json({
|
|
250
251
|
success: true,
|
|
251
252
|
message: 'Pull migrations applied successfully',
|
|
@@ -258,21 +259,12 @@ export async function POST(req) {
|
|
|
258
259
|
error: {
|
|
259
260
|
type: error.type || ErrorTypes.EXECUTION_ERROR,
|
|
260
261
|
message: error.message || 'Failed to apply pull migrations',
|
|
261
|
-
details: error.details || {
|
|
262
|
-
suggestions: [
|
|
263
|
-
'Check your Cloudflare credentials',
|
|
264
|
-
'Verify database permissions',
|
|
265
|
-
'Ensure all migration files are accessible'
|
|
266
|
-
]
|
|
267
|
-
}
|
|
262
|
+
details: error.details || {}
|
|
268
263
|
}
|
|
269
264
|
}, { status: 500 });
|
|
270
265
|
}
|
|
271
266
|
}
|
|
272
267
|
|
|
273
|
-
/**
|
|
274
|
-
* OPTIONS handler for pre-flight requests.
|
|
275
|
-
*/
|
|
276
268
|
export async function OPTIONS() {
|
|
277
269
|
return new NextResponse(null, { status: 204 });
|
|
278
270
|
}
|