d1s 0.2.6 → 0.2.9
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 +3 -1
- package/dist/.next/.next/BUILD_ID +1 -1
- package/dist/.next/.next/app-build-manifest.json +38 -24
- package/dist/.next/.next/app-path-routes-manifest.json +1 -1
- package/dist/.next/.next/build-manifest.json +2 -2
- package/dist/.next/.next/cache/.rscinfo +1 -1
- package/dist/.next/.next/cache/.tsbuildinfo +1 -1
- 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/2.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-production/0.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/index.pack +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/server/app/_not-found/page.js +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 +4 -4
- 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/sync/route.js +28 -3
- 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 +26 -1
- 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/pull-data/confirm/route.js +1 -0
- package/dist/.next/.next/server/app/api/pull-data/confirm/route.js.nft.json +1 -0
- package/dist/.next/.next/server/app/api/pull-data/confirm/route_client-reference-manifest.js +1 -0
- package/dist/.next/.next/server/app/api/pull-remote/confirm/route.js +26 -1
- 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 +26 -1
- 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 +28 -3
- 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 +28 -3
- 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 +27 -2
- 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/tables/[name]/route.js +4 -4
- 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/update/route.js +5 -0
- package/dist/.next/.next/server/app/api/update/route.js.nft.json +1 -0
- package/dist/.next/.next/server/app/api/update/route_client-reference-manifest.js +1 -0
- package/dist/.next/.next/server/app/index.html +3 -3
- package/dist/.next/.next/server/app/index.rsc +5 -5
- package/dist/.next/.next/server/app/page.js +13 -11
- package/dist/.next/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app-paths-manifest.json +5 -3
- package/dist/.next/.next/server/chunks/226.js +30 -0
- package/dist/.next/.next/server/chunks/336.js +1 -1
- package/dist/.next/.next/server/chunks/391.js +23 -0
- package/dist/.next/.next/server/chunks/452.js +1 -0
- package/dist/.next/.next/server/chunks/627.js +3 -3
- package/dist/.next/.next/server/chunks/638.js +3 -3
- package/dist/.next/.next/server/chunks/992.js +3 -3
- 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/_app.js +1 -1
- package/dist/.next/.next/server/pages/_document.js +1 -1
- package/dist/.next/.next/server/pages/_error.js +1 -1
- package/dist/.next/.next/server/server-reference-manifest.json +1 -1
- package/dist/.next/.next/static/7XBqETNmhSxMXhw8iUpEa/_buildManifest.js +1 -0
- package/dist/.next/.next/static/chunks/176-9146975ef8699719.js +1 -0
- package/dist/.next/.next/static/chunks/{735-c9144179c6bd7d06.js → 735-b885dfec6353171d.js} +1 -1
- package/dist/.next/.next/static/chunks/app/api/cloudflare/route-b77846f372b01f38.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/databases/route-407794f8145d9a0b.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/migrations/sync/route-9f480f5590369a8f.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/migrations/sync-files/route-92010db279b4dd8e.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/pull-data/confirm/route-a02fe6d3cdd0a535.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/pull-remote/confirm/route-f401a03507d1da50.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/pull-remote/preview/route-3c53814b5cb8b6b0.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/push-remote/confirm/route-8f359249e907c63b.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/push-remote/preview/route-b51bf94f39c17a9d.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/query/route-87bae2d4aebaf859.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/tables/[name]/route-d20ca163b9c03e7c.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/tables/route-0f46f911562abcdf.js +1 -0
- package/dist/.next/.next/static/chunks/app/api/update/route-14edc1917760bce0.js +1 -0
- package/dist/.next/.next/static/chunks/app/page-5990cb23b8bd27c4.js +1 -0
- package/dist/.next/.next/static/css/674bee6608c638e4.css +3 -0
- package/dist/.next/.next/trace +3 -3
- package/dist/.next/.next/types/app/api/pull-data/confirm/route.ts +347 -0
- package/dist/.next/.next/types/app/api/update/route.ts +347 -0
- package/dist/.next/BUILD_ID +1 -1
- package/dist/.next/app-build-manifest.json +36 -22
- package/dist/.next/app-path-routes-manifest.json +1 -1
- package/dist/.next/build-manifest.json +2 -2
- 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/server/app/_not-found/page.js +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 +4 -4
- 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/sync/route.js +28 -3
- 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 +26 -1
- 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/pull-data/confirm/route.js +1 -0
- package/dist/.next/server/app/api/pull-data/confirm/route.js.nft.json +1 -0
- package/dist/.next/server/app/api/pull-data/confirm/route_client-reference-manifest.js +1 -0
- package/dist/.next/server/app/api/pull-remote/confirm/route.js +26 -1
- 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 +26 -1
- 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 +28 -3
- 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 +28 -3
- 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 +27 -2
- 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/tables/[name]/route.js +4 -4
- 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/update/route.js +5 -0
- package/dist/.next/server/app/api/update/route.js.nft.json +1 -0
- package/dist/.next/server/app/api/update/route_client-reference-manifest.js +1 -0
- package/dist/.next/server/app/index.html +3 -3
- package/dist/.next/server/app/index.rsc +5 -5
- package/dist/.next/server/app/page.js +13 -11
- package/dist/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app-paths-manifest.json +8 -6
- package/dist/.next/server/chunks/226.js +30 -0
- package/dist/.next/server/chunks/336.js +1 -1
- package/dist/.next/server/chunks/391.js +23 -0
- package/dist/.next/server/chunks/452.js +1 -0
- package/dist/.next/server/chunks/627.js +3 -3
- package/dist/.next/server/chunks/638.js +3 -3
- package/dist/.next/server/chunks/992.js +3 -3
- package/dist/.next/server/pages/404.html +1 -1
- package/dist/.next/server/pages/500.html +1 -1
- package/dist/.next/server/pages/_app.js +1 -1
- package/dist/.next/server/pages/_document.js +1 -1
- package/dist/.next/server/pages/_error.js +1 -1
- package/dist/.next/server/server-reference-manifest.json +1 -1
- package/dist/.next/static/MoZBULXFiTFzrY1JVK_Df/_buildManifest.js +1 -0
- package/dist/.next/static/chunks/176-9146975ef8699719.js +1 -0
- package/dist/.next/static/chunks/{735-c9144179c6bd7d06.js → 735-b885dfec6353171d.js} +1 -1
- package/dist/.next/static/chunks/app/api/cloudflare/route-b77846f372b01f38.js +1 -0
- package/dist/.next/static/chunks/app/api/databases/route-407794f8145d9a0b.js +1 -0
- package/dist/.next/static/chunks/app/api/migrations/sync/route-9f480f5590369a8f.js +1 -0
- package/dist/.next/static/chunks/app/api/migrations/sync-files/route-92010db279b4dd8e.js +1 -0
- package/dist/.next/static/chunks/app/api/pull-data/confirm/route-a02fe6d3cdd0a535.js +1 -0
- package/dist/.next/static/chunks/app/api/pull-remote/confirm/route-f401a03507d1da50.js +1 -0
- package/dist/.next/static/chunks/app/api/pull-remote/preview/route-3c53814b5cb8b6b0.js +1 -0
- package/dist/.next/static/chunks/app/api/push-remote/confirm/route-8f359249e907c63b.js +1 -0
- package/dist/.next/static/chunks/app/api/push-remote/preview/route-b51bf94f39c17a9d.js +1 -0
- package/dist/.next/static/chunks/app/api/query/route-87bae2d4aebaf859.js +1 -0
- package/dist/.next/static/chunks/app/api/tables/[name]/route-d20ca163b9c03e7c.js +1 -0
- package/dist/.next/static/chunks/app/api/tables/route-0f46f911562abcdf.js +1 -0
- package/dist/.next/static/chunks/app/api/update/route-14edc1917760bce0.js +1 -0
- package/dist/.next/static/chunks/app/page-5990cb23b8bd27c4.js +1 -0
- package/dist/.next/static/css/674bee6608c638e4.css +3 -0
- package/dist/.next/trace +17 -14
- package/dist/.next/types/app/api/pull-data/confirm/route.ts +347 -0
- package/dist/.next/types/app/api/update/route.ts +347 -0
- package/dist/app/api/cloudflare/route.js +5 -1
- package/dist/app/api/databases/route.js +3 -4
- package/dist/app/api/migrations/sync/route.js +5 -3
- package/dist/app/api/pull-data/confirm/route.js +230 -0
- package/dist/app/api/pull-remote/confirm/route.js +24 -23
- package/dist/app/api/pull-remote/preview/route.js +4 -3
- package/dist/app/api/push-remote/preview/route.js +3 -2
- package/dist/app/api/query/route.js +11 -3
- package/dist/app/api/tables/[name]/route.js +3 -2
- package/dist/app/api/tables/route.js +6 -2
- package/dist/app/api/update/route.js +36 -0
- package/dist/app/app/api/cloudflare/route.js +5 -1
- package/dist/app/app/api/databases/route.js +3 -4
- package/dist/app/app/api/migrations/sync/route.js +5 -3
- package/dist/app/app/api/pull-data/confirm/route.js +230 -0
- package/dist/app/app/api/pull-remote/confirm/route.js +24 -23
- package/dist/app/app/api/pull-remote/preview/route.js +4 -3
- package/dist/app/app/api/push-remote/preview/route.js +3 -2
- package/dist/app/app/api/query/route.js +11 -3
- package/dist/app/app/api/tables/[name]/route.js +3 -2
- package/dist/app/app/api/tables/route.js +6 -2
- package/dist/app/app/api/update/route.js +36 -0
- package/dist/app/app/page.jsx +24 -14
- package/dist/app/page.jsx +24 -14
- package/dist/d1-studio.js +101 -58
- package/dist/lib/database-queue.js +34 -30
- package/dist/lib/find-wrangler-config.js +14 -8
- package/dist/lib/logger.js +44 -5
- package/dist/lib/migrations.js +4 -4
- package/dist/lib/schema-operations.js +4 -1
- package/dist/lib/sql-operations.js +85 -1
- package/package.json +3 -1
- package/scripts/studio.js +101 -58
- package/scripts/test.js +280 -82
- package/src/app/api/cloudflare/route.js +5 -1
- package/src/app/api/databases/route.js +3 -4
- package/src/app/api/migrations/sync/route.js +5 -3
- package/src/app/api/pull-data/confirm/route.js +230 -0
- package/src/app/api/pull-remote/confirm/route.js +24 -23
- package/src/app/api/pull-remote/preview/route.js +4 -3
- package/src/app/api/push-remote/preview/route.js +3 -2
- package/src/app/api/query/route.js +11 -3
- package/src/app/api/tables/[name]/route.js +3 -2
- package/src/app/api/tables/route.js +6 -2
- package/src/app/api/update/route.js +36 -0
- package/src/app/page.jsx +24 -14
- package/src/components/environment-handler.jsx +70 -16
- package/src/components/environment-select.jsx +6 -3
- package/src/components/pull-preview-toast.jsx +90 -63
- package/src/components/sidebar.jsx +25 -24
- package/src/components/update-banner.jsx +62 -0
- package/src/context/database-context.js +4 -4
- package/src/lib/database-queue.js +34 -30
- package/src/lib/find-wrangler-config.js +14 -8
- package/src/lib/logger.js +44 -5
- package/src/lib/migrations.js +4 -4
- package/src/lib/schema-operations.js +4 -1
- package/src/lib/sql-operations.js +85 -1
- package/dist/.next/.next/cache/webpack/client-production/3.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/1.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/2.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/dist/.next/.next/server/chunks/603.js +0 -55
- package/dist/.next/.next/server/chunks/686.js +0 -23
- package/dist/.next/.next/static/HsZ8OanS5v86DqC9rErO-/_buildManifest.js +0 -1
- package/dist/.next/.next/static/chunks/422-6fa3c14fc64ad67b.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/cloudflare/route-3458d78022185d7f.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/databases/route-64255424877a9f72.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/migrations/sync/route-03766b3afcf043ba.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/migrations/sync-files/route-02fa291c8000dadf.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/pull-remote/confirm/route-7e05bb8920127abe.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/pull-remote/preview/route-0fa15f783e8a306c.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/push-remote/confirm/route-96691f1880e4ed14.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/push-remote/preview/route-a798679c67374552.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/query/route-e90d0030a5083e20.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/tables/[name]/route-1efe63e73b480e58.js +0 -1
- package/dist/.next/.next/static/chunks/app/api/tables/route-3772b4f480c4b4a4.js +0 -1
- package/dist/.next/.next/static/chunks/app/page-79049bfa6cc07e11.js +0 -1
- package/dist/.next/.next/static/css/cf41da7a0d47f779.css +0 -3
- package/dist/.next/.next/static/q6WmQmyONe88bMN0_jrC2/_buildManifest.js +0 -1
- package/dist/.next/server/chunks/603.js +0 -55
- package/dist/.next/server/chunks/686.js +0 -23
- package/dist/.next/static/Tk1fnz_CXLavm23ZEeChG/_buildManifest.js +0 -1
- package/dist/.next/static/Tk1fnz_CXLavm23ZEeChG/_ssgManifest.js +0 -1
- package/dist/.next/static/chunks/422-6fa3c14fc64ad67b.js +0 -1
- package/dist/.next/static/chunks/app/api/cloudflare/route-3458d78022185d7f.js +0 -1
- package/dist/.next/static/chunks/app/api/databases/route-64255424877a9f72.js +0 -1
- package/dist/.next/static/chunks/app/api/migrations/sync/route-03766b3afcf043ba.js +0 -1
- package/dist/.next/static/chunks/app/api/migrations/sync-files/route-02fa291c8000dadf.js +0 -1
- package/dist/.next/static/chunks/app/api/pull-remote/confirm/route-7e05bb8920127abe.js +0 -1
- package/dist/.next/static/chunks/app/api/pull-remote/preview/route-0fa15f783e8a306c.js +0 -1
- package/dist/.next/static/chunks/app/api/push-remote/confirm/route-96691f1880e4ed14.js +0 -1
- package/dist/.next/static/chunks/app/api/push-remote/preview/route-a798679c67374552.js +0 -1
- package/dist/.next/static/chunks/app/api/query/route-e90d0030a5083e20.js +0 -1
- package/dist/.next/static/chunks/app/api/tables/[name]/route-1efe63e73b480e58.js +0 -1
- package/dist/.next/static/chunks/app/api/tables/route-3772b4f480c4b4a4.js +0 -1
- package/dist/.next/static/chunks/app/page-79049bfa6cc07e11.js +0 -1
- package/dist/.next/static/css/cf41da7a0d47f779.css +0 -3
- /package/dist/.next/.next/static/{HsZ8OanS5v86DqC9rErO- → 7XBqETNmhSxMXhw8iUpEa}/_ssgManifest.js +0 -0
- /package/dist/.next/{.next/static/q6WmQmyONe88bMN0_jrC2 → static/MoZBULXFiTFzrY1JVK_Df}/_ssgManifest.js +0 -0
package/dist/lib/migrations.js
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
tableExists
|
|
17
17
|
} from './sql-operations.js';
|
|
18
18
|
import { analyzeDependencies } from '@/lib/schema-operations';
|
|
19
|
+
import logger from './logger.js';
|
|
19
20
|
|
|
20
21
|
const execAsync = promisify(exec);
|
|
21
22
|
|
|
@@ -67,7 +68,7 @@ export async function initMigrationsTable(projectDir, databaseName, environment
|
|
|
67
68
|
);
|
|
68
69
|
}
|
|
69
70
|
} catch (error) {
|
|
70
|
-
|
|
71
|
+
logger.error(`Failed to initialize migrations table in ${environment}:`, error);
|
|
71
72
|
throw error;
|
|
72
73
|
}
|
|
73
74
|
}
|
|
@@ -173,7 +174,6 @@ export async function getRemoteMigrations(projectDir, databaseName, env) {
|
|
|
173
174
|
* @param {Object} migrationData { name, checksum }
|
|
174
175
|
* @param {('local'|'remote')} environment
|
|
175
176
|
*/
|
|
176
|
-
// Update tracking function to handle both cases
|
|
177
177
|
export async function trackMigration(projectDir, databaseName, { name, checksum }, environment = 'local') {
|
|
178
178
|
const flag = environment === 'remote' ? '--remote' : '--local';
|
|
179
179
|
|
|
@@ -215,7 +215,7 @@ export async function trackMigration(projectDir, databaseName, { name, checksum
|
|
|
215
215
|
{ cwd: projectDir }
|
|
216
216
|
);
|
|
217
217
|
} catch (error) {
|
|
218
|
-
|
|
218
|
+
logger.error('Failed to track migration:', error);
|
|
219
219
|
throw error;
|
|
220
220
|
}
|
|
221
221
|
}
|
|
@@ -273,7 +273,7 @@ export async function compareMigrations(projectDir, databaseName) {
|
|
|
273
273
|
count: migrationMap.size
|
|
274
274
|
};
|
|
275
275
|
} catch (error) {
|
|
276
|
-
|
|
276
|
+
logger.error('Failed to compare migrations:', error);
|
|
277
277
|
throw error;
|
|
278
278
|
}
|
|
279
279
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// schema-operations.js
|
|
2
|
+
|
|
2
3
|
import { executeSQL, ErrorTypes } from './sql-operations.js';
|
|
4
|
+
import logger from './logger.js';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Retrieves the current database schema (tables, indexes, triggers),
|
|
@@ -24,6 +26,7 @@ export async function getCurrentSchema(projectDir, databaseName, env = {}, remot
|
|
|
24
26
|
const parsed = JSON.parse(result);
|
|
25
27
|
return parsed[0]?.results || [];
|
|
26
28
|
} catch (error) {
|
|
29
|
+
logger.error('Failed to get current schema:', error);
|
|
27
30
|
throw {
|
|
28
31
|
type: ErrorTypes.EXECUTION_ERROR,
|
|
29
32
|
message: 'Failed to get current schema',
|
|
@@ -100,4 +103,4 @@ export function orderTables(dependencies) {
|
|
|
100
103
|
}
|
|
101
104
|
}
|
|
102
105
|
return ordered;
|
|
103
|
-
}
|
|
106
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { promisify } from 'util';
|
|
4
4
|
import { exec } from 'child_process';
|
|
5
|
+
import logger from '@/lib/logger';
|
|
5
6
|
|
|
6
7
|
const execAsync = promisify(exec);
|
|
7
8
|
|
|
@@ -293,13 +294,19 @@ export async function executeSQL(projectDir, databaseName, sql, env = {}, remote
|
|
|
293
294
|
const npxCommand = isWindows ? 'npx.cmd' : 'npx';
|
|
294
295
|
const executionFlag = remote ? '--remote' : '--local';
|
|
295
296
|
const command = `${npxCommand} wrangler d1 execute ${databaseName} ${executionFlag} --command="${cleanSQL.replace(/"/g, '\\"')}"`;
|
|
297
|
+
|
|
298
|
+
// Only log in development
|
|
299
|
+
if (logger.shouldLog('debug')) {
|
|
300
|
+
logger.debug('Executing command:', command);
|
|
301
|
+
}
|
|
302
|
+
|
|
296
303
|
const execOptions = {
|
|
297
304
|
cwd: projectDir,
|
|
298
305
|
env: { ...process.env, ...env },
|
|
299
306
|
maxBuffer: 1024 * 1024 * 10,
|
|
300
307
|
shell: true
|
|
301
308
|
};
|
|
302
|
-
console.log('Executing command:', command);
|
|
309
|
+
// console.log('Executing command:', command);
|
|
303
310
|
const { stdout, stderr } = await execAsync(command, execOptions);
|
|
304
311
|
if (stderr && !stderr.includes('🌀')) {
|
|
305
312
|
throw new Error(stderr);
|
|
@@ -335,6 +342,83 @@ export async function executeSQL(projectDir, databaseName, sql, env = {}, remote
|
|
|
335
342
|
}
|
|
336
343
|
}
|
|
337
344
|
|
|
345
|
+
/**
|
|
346
|
+
* Fetches the latest `limit` records for a given table from the remote database.
|
|
347
|
+
*
|
|
348
|
+
* This implementation uses the executeSQL function with the remote flag enabled.
|
|
349
|
+
* It orders the results based on the provided ordering column. If no ordering column is provided,
|
|
350
|
+
* it falls back to the default "id" column.
|
|
351
|
+
*
|
|
352
|
+
* @param {string} projectDir - The project directory.
|
|
353
|
+
* @param {string} databaseName - The D1 database name.
|
|
354
|
+
* @param {string} tableName - The table to fetch records for.
|
|
355
|
+
* @param {object} env - Environment variables (including credentials).
|
|
356
|
+
* @param {number} limit - The number of records to fetch.
|
|
357
|
+
* @param {string} [orderingColumn="id"] - The column to order by.
|
|
358
|
+
* @returns {Promise<Array<object>>} Array of row objects.
|
|
359
|
+
*/
|
|
360
|
+
export async function fetchRemoteTableData(
|
|
361
|
+
projectDir,
|
|
362
|
+
databaseName,
|
|
363
|
+
tableName,
|
|
364
|
+
env,
|
|
365
|
+
limit,
|
|
366
|
+
orderingColumn = "id"
|
|
367
|
+
) {
|
|
368
|
+
// Use the provided ordering column; if not provided, default to "id".
|
|
369
|
+
const query = `SELECT * FROM "${tableName}" ORDER BY "${orderingColumn}" DESC LIMIT ${limit};`;
|
|
370
|
+
try {
|
|
371
|
+
// Execute the SQL command on the remote database.
|
|
372
|
+
const result = await executeSQL(projectDir, databaseName, query, env, true);
|
|
373
|
+
|
|
374
|
+
// ExecuteSQL returns stdout that should contain a JSON array starting from a '['.
|
|
375
|
+
const jsonStart = result.indexOf('[');
|
|
376
|
+
if (jsonStart === -1) {
|
|
377
|
+
throw new Error(`Unexpected result format: ${result}`);
|
|
378
|
+
}
|
|
379
|
+
const jsonStr = result.substring(jsonStart);
|
|
380
|
+
const parsed = JSON.parse(jsonStr);
|
|
381
|
+
// Assuming the structure: parsed[0].results contains the rows.
|
|
382
|
+
const rows = parsed[0]?.results || [];
|
|
383
|
+
return rows;
|
|
384
|
+
} catch (error) {
|
|
385
|
+
logger.error(`Error fetching remote data for table ${tableName}:`, error);
|
|
386
|
+
throw error;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Generates a bulk insert SQL statement for the specified table and rows.
|
|
392
|
+
*
|
|
393
|
+
* This function constructs a single INSERT statement that inserts multiple rows.
|
|
394
|
+
* It escapes single quotes in string values. You may need to extend this for
|
|
395
|
+
* additional data types (e.g., numbers, dates, booleans) or more complex structures.
|
|
396
|
+
*
|
|
397
|
+
* @param {string} tableName - The table to insert into.
|
|
398
|
+
* @param {Array<object>} rows - An array of objects, each representing a row.
|
|
399
|
+
* @returns {string} The bulk insert SQL statement.
|
|
400
|
+
*/
|
|
401
|
+
export function generateBulkInsertSQL(tableName, rows) {
|
|
402
|
+
if (!rows || rows.length === 0) return '';
|
|
403
|
+
|
|
404
|
+
// Get the list of columns from the first row object.
|
|
405
|
+
const columns = Object.keys(rows[0]);
|
|
406
|
+
const columnList = columns.map(col => `"${col}"`).join(', ');
|
|
407
|
+
|
|
408
|
+
// Build the values list for each row.
|
|
409
|
+
const valuesList = rows.map(row => {
|
|
410
|
+
const values = columns.map(col => {
|
|
411
|
+
const value = row[col];
|
|
412
|
+
if (value === null || value === undefined) return 'NULL';
|
|
413
|
+
// For simplicity, treat the value as a string.
|
|
414
|
+
return `'${String(value).replace(/'/g, "''")}'`;
|
|
415
|
+
}).join(', ');
|
|
416
|
+
return `(${values})`;
|
|
417
|
+
}).join(', ');
|
|
418
|
+
|
|
419
|
+
return `INSERT INTO "${tableName}" (${columnList}) VALUES ${valuesList};`;
|
|
420
|
+
}
|
|
421
|
+
|
|
338
422
|
// ---------------------------------------------------------------------
|
|
339
423
|
// SQL Formatting and Helper Functions
|
|
340
424
|
// ---------------------------------------------------------------------
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "d1s",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "D1 Studio – a native studio for managing Cloudflare D1 databases.",
|
|
6
6
|
"main": "./dist/d1-studio.js",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"@radix-ui/react-tabs": "^1.1.2",
|
|
66
66
|
"@radix-ui/react-toast": "^1.2.5",
|
|
67
67
|
"@radix-ui/react-tooltip": "^1.1.7",
|
|
68
|
+
"axios": "^1.7.9",
|
|
68
69
|
"chalk": "^4.1.2",
|
|
69
70
|
"class-variance-authority": "^0.7.1",
|
|
70
71
|
"clsx": "^2.1.1",
|
|
@@ -82,6 +83,7 @@
|
|
|
82
83
|
"strip-json-comments": "^5.0.1",
|
|
83
84
|
"tailwind-merge": "^2.6.0",
|
|
84
85
|
"tailwindcss-animate": "^1.0.7",
|
|
86
|
+
"update-notifier": "^7.3.1",
|
|
85
87
|
"winston": "^3.17.0"
|
|
86
88
|
},
|
|
87
89
|
"devDependencies": {
|
package/scripts/studio.js
CHANGED
|
@@ -12,8 +12,20 @@ import { createServer } from 'http';
|
|
|
12
12
|
import next from 'next';
|
|
13
13
|
import { findWranglerConfig } from '../src/lib/find-wrangler-config.js';
|
|
14
14
|
import logger from '../src/lib/logger.js';
|
|
15
|
+
import updateNotifier from 'update-notifier';
|
|
16
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
17
|
+
|
|
18
|
+
// Check for debug flag
|
|
19
|
+
const hasDebugFlag = process.argv.includes('--debug');
|
|
20
|
+
if (hasDebugFlag) {
|
|
21
|
+
process.env.DEBUG = 'true';
|
|
22
|
+
logger.debug('Debug mode enabled');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const notifier = updateNotifier({ pkg, updateCheckInterval: 1000 * 60 * 60 * 24 });
|
|
26
|
+
notifier.notify({ defer: false });
|
|
15
27
|
|
|
16
|
-
// Compute the absolute path of this file and its directory
|
|
28
|
+
// Compute the absolute path of this file and its directory
|
|
17
29
|
const __filename = fileURLToPath(import.meta.url);
|
|
18
30
|
const __dirname = dirname(__filename);
|
|
19
31
|
|
|
@@ -26,6 +38,70 @@ class LicenseError extends Error {
|
|
|
26
38
|
}
|
|
27
39
|
}
|
|
28
40
|
|
|
41
|
+
class StudioLicenseManager {
|
|
42
|
+
constructor() {
|
|
43
|
+
this.licenseDir = join(homedir(), '.d1studio');
|
|
44
|
+
this.licensePath = join(this.licenseDir, 'license.json');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async checkLicenseFile() {
|
|
48
|
+
try {
|
|
49
|
+
const licenseData = JSON.parse(await readFile(this.licensePath, 'utf8'));
|
|
50
|
+
|
|
51
|
+
// If no end_date or subscription_status, the license is valid (perpetual license)
|
|
52
|
+
if (!licenseData.end_date || !licenseData.subscription_status) {
|
|
53
|
+
return {
|
|
54
|
+
licenseData,
|
|
55
|
+
isValid: true,
|
|
56
|
+
isExpiringSoon: false
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Check subscription status first
|
|
61
|
+
if (licenseData.subscription_status !== 'active') {
|
|
62
|
+
return {
|
|
63
|
+
licenseData,
|
|
64
|
+
isValid: false,
|
|
65
|
+
isExpiringSoon: false
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const endDate = new Date(licenseData.end_date);
|
|
70
|
+
const now = new Date();
|
|
71
|
+
|
|
72
|
+
// Check if subscription has ended
|
|
73
|
+
if (endDate < now) {
|
|
74
|
+
return {
|
|
75
|
+
licenseData,
|
|
76
|
+
isValid: false,
|
|
77
|
+
isExpiringSoon: false
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Check if subscription ends in next 7 days
|
|
82
|
+
const sevenDaysFromNow = new Date(now.getTime() + (7 * 24 * 60 * 60 * 1000));
|
|
83
|
+
const isExpiringSoon = endDate <= sevenDaysFromNow;
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
licenseData,
|
|
87
|
+
isValid: true,
|
|
88
|
+
isExpiringSoon
|
|
89
|
+
};
|
|
90
|
+
} catch (error) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async saveLicenseFile(licenseData) {
|
|
96
|
+
try {
|
|
97
|
+
await mkdir(this.licenseDir, { recursive: true });
|
|
98
|
+
await writeFile(this.licensePath, JSON.stringify(licenseData, null, 2));
|
|
99
|
+
} catch (error) {
|
|
100
|
+
throw new LicenseError('Failed to save license information', 'SAVE_ERROR');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
29
105
|
async function generateHardwareId() {
|
|
30
106
|
const osInfo = {
|
|
31
107
|
platform: process.platform,
|
|
@@ -60,13 +136,6 @@ async function validateLicenseRemote(licenseKey, email, hardwareId) {
|
|
|
60
136
|
);
|
|
61
137
|
}
|
|
62
138
|
|
|
63
|
-
if (result.end_date && new Date(result.end_date) < new Date()) {
|
|
64
|
-
throw new LicenseError(
|
|
65
|
-
'Your subscription has expired. Please renew your license to continue using D1 Studio.',
|
|
66
|
-
'SUBSCRIPTION_EXPIRED'
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
139
|
return result;
|
|
71
140
|
} catch (error) {
|
|
72
141
|
if (error instanceof LicenseError) {
|
|
@@ -87,35 +156,6 @@ async function validateLicenseRemote(licenseKey, email, hardwareId) {
|
|
|
87
156
|
}
|
|
88
157
|
}
|
|
89
158
|
|
|
90
|
-
async function checkLicenseFile() {
|
|
91
|
-
const licenseDir = join(homedir(), '.d1studio');
|
|
92
|
-
const licensePath = join(licenseDir, 'license.json');
|
|
93
|
-
|
|
94
|
-
try {
|
|
95
|
-
const licenseData = JSON.parse(await readFile(licensePath, 'utf8'));
|
|
96
|
-
const hardwareId = await generateHardwareId();
|
|
97
|
-
|
|
98
|
-
if (licenseData.hardwareId !== hardwareId) {
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
return licenseData;
|
|
102
|
-
} catch (error) {
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async function saveLicenseFile(licenseData) {
|
|
108
|
-
const licenseDir = join(homedir(), '.d1studio');
|
|
109
|
-
const licensePath = join(licenseDir, 'license.json');
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
await mkdir(licenseDir, { recursive: true });
|
|
113
|
-
await writeFile(licensePath, JSON.stringify(licenseData, null, 2));
|
|
114
|
-
} catch (error) {
|
|
115
|
-
throw new LicenseError('Failed to save license information', 'SAVE_ERROR');
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
159
|
async function startServer(port, projectDirectory) {
|
|
120
160
|
return new Promise((resolvePromise, rejectPromise) => {
|
|
121
161
|
// Determine Next.js app directory based on environment:
|
|
@@ -170,20 +210,14 @@ async function startStudio() {
|
|
|
170
210
|
try {
|
|
171
211
|
logger.info(chalk.green('Initializing D1 Studio...'));
|
|
172
212
|
|
|
173
|
-
|
|
174
|
-
let licenseData = await checkLicenseFile();
|
|
175
|
-
logger.debug(chalk.blue(`License data found: ${JSON.stringify(licenseData)}`));
|
|
176
|
-
|
|
177
|
-
const TWELVE_HOURS_MS = 43200000; // 12 hours
|
|
178
|
-
let shouldRevalidate = true;
|
|
179
|
-
if (licenseData) {
|
|
180
|
-
const lastCheck = new Date(licenseData.lastValidatedAt || licenseData.activatedAt);
|
|
181
|
-
if (Date.now() - lastCheck.getTime() < TWELVE_HOURS_MS) {
|
|
182
|
-
shouldRevalidate = false;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
213
|
+
const licenseManager = new StudioLicenseManager();
|
|
185
214
|
|
|
186
|
-
|
|
215
|
+
// Check existing license
|
|
216
|
+
const licenseCheck = await licenseManager.checkLicenseFile();
|
|
217
|
+
|
|
218
|
+
// Handle license validation
|
|
219
|
+
if (!licenseCheck || !licenseCheck.isValid) {
|
|
220
|
+
// Prompt for license information if needed
|
|
187
221
|
const { default: inquirer } = await import('inquirer');
|
|
188
222
|
logger.info(chalk.yellow('\nPlease enter your D1 Studio license information:'));
|
|
189
223
|
|
|
@@ -205,9 +239,8 @@ async function startStudio() {
|
|
|
205
239
|
},
|
|
206
240
|
]);
|
|
207
241
|
|
|
208
|
-
logger.debug(chalk.blue(`Entered license information: ${JSON.stringify(answers)}`));
|
|
209
|
-
|
|
210
242
|
const hardwareId = await generateHardwareId();
|
|
243
|
+
|
|
211
244
|
try {
|
|
212
245
|
const validation = await validateLicenseRemote(
|
|
213
246
|
answers.licenseKey,
|
|
@@ -215,19 +248,29 @@ async function startStudio() {
|
|
|
215
248
|
hardwareId
|
|
216
249
|
);
|
|
217
250
|
|
|
218
|
-
|
|
251
|
+
// Save the complete validation response
|
|
252
|
+
await licenseManager.saveLicenseFile({
|
|
219
253
|
licenseKey: answers.licenseKey,
|
|
220
254
|
email: answers.email,
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
255
|
+
hardwareId,
|
|
256
|
+
end_date: validation.end_date,
|
|
257
|
+
subscription_status: validation.subscription_status,
|
|
258
|
+
type: validation.licenseType,
|
|
259
|
+
activatedAt: new Date().toISOString()
|
|
260
|
+
});
|
|
224
261
|
|
|
225
|
-
await saveLicenseFile(licenseData);
|
|
226
262
|
logger.info(chalk.green('\nLicense activated successfully!'));
|
|
227
263
|
} catch (error) {
|
|
228
264
|
logger.error(chalk.red(`\nLicense validation failed: ${error.message}`));
|
|
229
265
|
process.exit(1);
|
|
230
266
|
}
|
|
267
|
+
} else if (licenseCheck.isExpiringSoon) {
|
|
268
|
+
// Show warning about expiring subscription
|
|
269
|
+
const endDate = new Date(licenseCheck.licenseData.end_date).toLocaleDateString();
|
|
270
|
+
logger.warn(chalk.yellow(`
|
|
271
|
+
⚠️ Your subscription will expire on ${endDate}
|
|
272
|
+
Please renew your subscription at https://d1-studio.com to continue using D1 Studio.
|
|
273
|
+
`));
|
|
231
274
|
}
|
|
232
275
|
|
|
233
276
|
// Get wrangler configuration
|
|
@@ -317,4 +360,4 @@ process.on('SIGTERM', () => {
|
|
|
317
360
|
startStudio().catch((error) => {
|
|
318
361
|
logger.error(chalk.red(`\nFailed to start D1 Studio: ${error}`));
|
|
319
362
|
process.exit(1);
|
|
320
|
-
});
|
|
363
|
+
});
|