d1s 0.2.10 → 0.2.12
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/dist/.next/.next/BUILD_ID +1 -1
- package/dist/.next/.next/app-build-manifest.json +33 -33
- package/dist/.next/.next/app-path-routes-manifest.json +1 -1
- package/dist/.next/.next/build-manifest.json +3 -3
- 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/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-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/required-server-files.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 +4 -4
- package/dist/.next/.next/server/app/api/cloudflare/route.js +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_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/migrations/sync/route.js +5 -5
- 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 +3 -3
- 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 -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 +2 -2
- 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_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/push-remote/confirm/route.js +5 -5
- 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 +4 -4
- 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 +3 -3
- 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 +5 -5
- 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_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/update/route.js +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 +3 -3
- package/dist/.next/.next/server/app/index.rsc +5 -5
- package/dist/.next/.next/server/app/page.js +11 -13
- 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 +3 -3
- package/dist/.next/.next/server/chunks/226.js +12 -12
- package/dist/.next/.next/server/chunks/391.js +5 -5
- package/dist/.next/.next/server/chunks/452.js +1 -1
- package/dist/.next/.next/server/chunks/572.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/middleware-build-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/_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/chunks/576-18a2209e1ed26aad.js +1 -0
- package/dist/.next/.next/static/chunks/{92-c4466e0f1ca8a3a8.js → 92-5f7522943fcb72a8.js} +1 -1
- package/dist/.next/.next/static/chunks/app/{layout-be6ee67cf0c92654.js → layout-40ec07d04681ba81.js} +1 -1
- package/dist/.next/.next/static/chunks/app/page-f05cd0fc436bf9bc.js +1 -0
- package/dist/.next/.next/static/chunks/{main-app-fa35024de9bd9284.js → main-app-4506e88db72db4b7.js} +1 -1
- package/dist/.next/.next/static/css/7c16f57d325d0d7d.css +3 -0
- package/dist/.next/.next/static/gABGrAoO8IPArDo_Ns_7g/_buildManifest.js +1 -0
- package/dist/.next/.next/static/gABGrAoO8IPArDo_Ns_7g/_ssgManifest.js +1 -0
- package/dist/.next/.next/static/gh-QfIUVo4FTTduYCVKT6/_buildManifest.js +1 -0
- package/dist/.next/.next/static/gh-QfIUVo4FTTduYCVKT6/_ssgManifest.js +1 -0
- package/dist/.next/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/.next/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/.next/.next/static/ybCx6L6gHqtODbKmlhU-d/_buildManifest.js +1 -0
- package/dist/.next/.next/static/ybCx6L6gHqtODbKmlhU-d/_ssgManifest.js +1 -0
- package/dist/.next/.next/trace +3 -3
- package/dist/.next/.next/types/app/api/cloudflare/route.ts +1 -1
- package/dist/.next/.next/types/app/api/databases/route.ts +1 -1
- package/dist/.next/.next/types/app/api/migrations/sync/route.ts +1 -1
- package/dist/.next/.next/types/app/api/migrations/sync-files/route.ts +1 -1
- package/dist/.next/.next/types/app/api/pull-data/confirm/route.ts +1 -1
- package/dist/.next/.next/types/app/api/pull-remote/confirm/route.ts +1 -1
- package/dist/.next/.next/types/app/api/pull-remote/preview/route.ts +1 -1
- package/dist/.next/.next/types/app/api/push-remote/confirm/route.ts +1 -1
- package/dist/.next/.next/types/app/api/push-remote/preview/route.ts +1 -1
- package/dist/.next/.next/types/app/api/query/route.ts +1 -1
- package/dist/.next/.next/types/app/api/tables/[name]/route.ts +1 -1
- package/dist/.next/.next/types/app/api/tables/route.ts +1 -1
- package/dist/.next/.next/types/app/api/update/route.ts +1 -1
- package/dist/.next/.next/types/app/page.ts +1 -1
- package/dist/.next/BUILD_ID +1 -1
- package/dist/.next/app-build-manifest.json +32 -32
- package/dist/.next/app-path-routes-manifest.json +1 -1
- package/dist/.next/build-manifest.json +3 -3
- 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/1.pack +0 -0
- package/dist/.next/cache/webpack/client-production/2.pack +0 -0
- package/dist/.next/cache/webpack/client-production/index.pack +0 -0
- package/dist/.next/cache/webpack/client-production/index.pack.old +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/required-server-files.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 +4 -4
- package/dist/.next/server/app/api/cloudflare/route.js +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_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/migrations/sync/route.js +5 -5
- 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 +3 -3
- 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 -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 +2 -2
- 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_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/push-remote/confirm/route.js +5 -5
- 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 +4 -4
- 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 +3 -3
- package/dist/.next/server/app/api/query/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/tables/[name]/route.js +5 -5
- 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_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/update/route.js +1 -1
- package/dist/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- 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 +11 -13
- 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 +2 -2
- package/dist/.next/server/chunks/226.js +12 -12
- package/dist/.next/server/chunks/391.js +5 -5
- package/dist/.next/server/chunks/452.js +1 -1
- package/dist/.next/server/chunks/572.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/middleware-build-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/_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/IX-QLbm7scYnyqWeeimal/_buildManifest.js +1 -0
- package/dist/.next/static/IX-QLbm7scYnyqWeeimal/_ssgManifest.js +1 -0
- package/dist/.next/static/chunks/576-18a2209e1ed26aad.js +1 -0
- package/dist/.next/static/chunks/{92-c4466e0f1ca8a3a8.js → 92-5f7522943fcb72a8.js} +1 -1
- package/dist/.next/static/chunks/app/{layout-be6ee67cf0c92654.js → layout-40ec07d04681ba81.js} +1 -1
- package/dist/.next/static/chunks/app/page-f05cd0fc436bf9bc.js +1 -0
- package/dist/.next/static/chunks/{main-app-fa35024de9bd9284.js → main-app-4506e88db72db4b7.js} +1 -1
- package/dist/.next/static/css/7c16f57d325d0d7d.css +3 -0
- package/dist/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/.next/trace +3 -16
- package/dist/.next/types/app/api/cloudflare/route.ts +1 -1
- package/dist/.next/types/app/api/databases/route.ts +1 -1
- package/dist/.next/types/app/api/migrations/sync/route.ts +1 -1
- package/dist/.next/types/app/api/migrations/sync-files/route.ts +1 -1
- package/dist/.next/types/app/api/pull-data/confirm/route.ts +1 -1
- package/dist/.next/types/app/api/pull-remote/confirm/route.ts +1 -1
- package/dist/.next/types/app/api/pull-remote/preview/route.ts +1 -1
- package/dist/.next/types/app/api/push-remote/confirm/route.ts +1 -1
- package/dist/.next/types/app/api/push-remote/preview/route.ts +1 -1
- package/dist/.next/types/app/api/query/route.ts +1 -1
- package/dist/.next/types/app/api/tables/[name]/route.ts +1 -1
- package/dist/.next/types/app/api/tables/route.ts +1 -1
- package/dist/.next/types/app/api/update/route.ts +1 -1
- package/dist/.next/types/app/page.ts +1 -1
- package/dist/app/api/tables/[name]/route.js +22 -10
- package/dist/app/globals.css +39 -0
- package/dist/app/page.jsx +13 -23
- package/dist/d1-studio.js +34 -4
- package/dist/lib/data-type-handlers.js +426 -0
- package/dist/lib/sql-operations.js +32 -8
- package/dist/lib/sql-sanitizer.js +233 -0
- package/package.json +3 -9
- package/dist/.next/.next/cache/webpack/server-production/2.pack +0 -0
- package/dist/.next/.next/server/chunks/90.js +0 -1
- package/dist/.next/.next/static/chunks/700-dc8f9f08b166c5e6.js +0 -1
- package/dist/.next/.next/static/chunks/app/page-16ec561fc8bebb5d.js +0 -1
- package/dist/.next/.next/static/css/0c512cea5f3d317a.css +0 -3
- package/dist/.next/server/chunks/90.js +0 -1
- package/dist/.next/static/chunks/700-dc8f9f08b166c5e6.js +0 -1
- package/dist/.next/static/chunks/app/page-16ec561fc8bebb5d.js +0 -1
- package/dist/.next/static/css/0c512cea5f3d317a.css +0 -3
- package/dist/app/app/api/cloudflare/route.js +0 -150
- package/dist/app/app/api/databases/route.js +0 -71
- package/dist/app/app/api/migrations/sync/route.js +0 -174
- package/dist/app/app/api/migrations/sync-files/route.js +0 -172
- package/dist/app/app/api/pull-data/confirm/route.js +0 -230
- package/dist/app/app/api/pull-remote/confirm/route.js +0 -278
- package/dist/app/app/api/pull-remote/preview/route.js +0 -144
- package/dist/app/app/api/push-remote/confirm/route.js +0 -196
- package/dist/app/app/api/push-remote/preview/route.js +0 -179
- package/dist/app/app/api/query/route.js +0 -168
- package/dist/app/app/api/tables/[name]/route.js +0 -174
- package/dist/app/app/api/tables/route.js +0 -178
- package/dist/app/app/api/update/route.js +0 -45
- package/dist/app/app/globals.css +0 -93
- package/dist/app/app/layout.jsx +0 -35
- package/dist/app/app/page.jsx +0 -44
- package/next.config.mjs +0 -18
- package/postcss.config.mjs +0 -8
- package/scripts/studio.js +0 -169
- package/scripts/test.js +0 -366
- package/src/app/api/cloudflare/route.js +0 -150
- package/src/app/api/databases/route.js +0 -71
- package/src/app/api/migrations/sync/route.js +0 -174
- package/src/app/api/migrations/sync-files/route.js +0 -172
- package/src/app/api/pull-data/confirm/route.js +0 -230
- package/src/app/api/pull-remote/confirm/route.js +0 -278
- package/src/app/api/pull-remote/preview/route.js +0 -144
- package/src/app/api/push-remote/confirm/route.js +0 -196
- package/src/app/api/push-remote/preview/route.js +0 -179
- package/src/app/api/query/route.js +0 -168
- package/src/app/api/tables/[name]/route.js +0 -174
- package/src/app/api/tables/route.js +0 -178
- package/src/app/api/update/route.js +0 -45
- package/src/app/globals.css +0 -93
- package/src/app/layout.jsx +0 -35
- package/src/app/page.jsx +0 -44
- package/src/components/cloudflare-credentials-modal.jsx +0 -94
- package/src/components/column-selector.jsx +0 -133
- package/src/components/column-sorting.jsx +0 -65
- package/src/components/delete-records-dialog.jsx +0 -64
- package/src/components/download-button.jsx +0 -205
- package/src/components/edit-error-alert.jsx +0 -30
- package/src/components/editable-cell.jsx +0 -163
- package/src/components/editable-row.jsx +0 -169
- package/src/components/environment-handler.jsx +0 -332
- package/src/components/environment-select.jsx +0 -62
- package/src/components/pull-preview-toast.jsx +0 -215
- package/src/components/push-error-alert.jsx +0 -72
- package/src/components/push-preview-toast.jsx +0 -183
- package/src/components/query-results.jsx +0 -112
- package/src/components/refresh-button.jsx +0 -61
- package/src/components/resize-columns.jsx +0 -101
- package/src/components/sidebar.jsx +0 -254
- package/src/components/sql-editor.jsx +0 -411
- package/src/components/sql-error-display.jsx +0 -167
- package/src/components/sync-migrations-button.jsx +0 -87
- package/src/components/table-error-dialog.jsx +0 -65
- package/src/components/table-toolbar.jsx +0 -285
- package/src/components/table-view.jsx +0 -843
- package/src/components/ui/alert.jsx +0 -47
- package/src/components/ui/button.jsx +0 -48
- package/src/components/ui/card.jsx +0 -50
- package/src/components/ui/checkbox.jsx +0 -24
- package/src/components/ui/collapsible.jsx +0 -11
- package/src/components/ui/dialog.jsx +0 -96
- package/src/components/ui/dropdown-menu.jsx +0 -158
- package/src/components/ui/input.jsx +0 -19
- package/src/components/ui/scroll-area.jsx +0 -40
- package/src/components/ui/select.jsx +0 -121
- package/src/components/ui/separator.jsx +0 -25
- package/src/components/ui/sheet.jsx +0 -109
- package/src/components/ui/sidebar.jsx +0 -620
- package/src/components/ui/skeleton.jsx +0 -14
- package/src/components/ui/table.jsx +0 -86
- package/src/components/ui/tabs.jsx +0 -43
- package/src/components/ui/toast.jsx +0 -86
- package/src/components/ui/toaster.jsx +0 -35
- package/src/components/ui/tooltip.jsx +0 -28
- package/src/components/update-banner.jsx +0 -93
- package/src/context/database-context.js +0 -510
- package/src/hooks/use-mobile.jsx +0 -19
- package/src/hooks/use-sql-error.ts +0 -23
- package/src/hooks/use-toast.js +0 -155
- package/src/lib/database-queue.js +0 -37
- package/src/lib/error.js +0 -20
- package/src/lib/find-wrangler-config.js +0 -74
- package/src/lib/license.js +0 -99
- package/src/lib/logger.js +0 -58
- package/src/lib/migrations.js +0 -415
- package/src/lib/parse-sql-error.js +0 -200
- package/src/lib/request-deduplication.js +0 -24
- package/src/lib/schema-operations.js +0 -106
- package/src/lib/sql-error-types.js +0 -14
- package/src/lib/sql-operations.js +0 -647
- package/src/lib/utils.js +0 -6
- package/src/lib/version-utils.js +0 -34
- /package/dist/.next/.next/static/{5dBGGUmK5q7of4h5Rahrg → Y9mYu4WBghepP5oT_3OdR}/_buildManifest.js +0 -0
- /package/dist/.next/.next/static/{5dBGGUmK5q7of4h5Rahrg → Y9mYu4WBghepP5oT_3OdR}/_ssgManifest.js +0 -0
- /package/dist/.next/.next/static/{PflNFnmFsNegSqhzjI6lA → ae3gNmoSGm-R5LJC4UagI}/_buildManifest.js +0 -0
- /package/dist/.next/.next/static/{PflNFnmFsNegSqhzjI6lA → ae3gNmoSGm-R5LJC4UagI}/_ssgManifest.js +0 -0
- /package/dist/.next/.next/static/{p8875OZM4iDNsPzmoyLe7 → bKfUJeuvAQlBmR3TjrfkH}/_buildManifest.js +0 -0
- /package/dist/.next/.next/static/{p8875OZM4iDNsPzmoyLe7 → bKfUJeuvAQlBmR3TjrfkH}/_ssgManifest.js +0 -0
- /package/dist/.next/{static 2/5dBGGUmK5q7of4h5Rahrg → .next/static/ejYPqJ2kVicVp5EFWOZIC}/_buildManifest.js +0 -0
- /package/dist/.next/{static 2/5dBGGUmK5q7of4h5Rahrg → .next/static/ejYPqJ2kVicVp5EFWOZIC}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL Sanitization and Security Utilities
|
|
3
|
+
* Prevents SQL injection attacks by properly escaping and validating identifiers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Validates and sanitizes table names to prevent SQL injection
|
|
8
|
+
* @param {string} tableName - The table name to sanitize
|
|
9
|
+
* @returns {string} - Sanitized table name wrapped in quotes
|
|
10
|
+
* @throws {Error} - If table name is invalid
|
|
11
|
+
*/
|
|
12
|
+
export function sanitizeTableName(tableName) {
|
|
13
|
+
if (!tableName || typeof tableName !== 'string') {
|
|
14
|
+
throw new Error('Table name must be a non-empty string');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// SQLite identifier rules: must start with letter or underscore, contain only letters, digits, underscores
|
|
18
|
+
const validIdentifierRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
19
|
+
|
|
20
|
+
if (!validIdentifierRegex.test(tableName)) {
|
|
21
|
+
throw new Error(`Invalid table name: ${tableName}. Must start with letter or underscore and contain only letters, digits, and underscores.`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// SQLite reserved words that should not be used as table names
|
|
25
|
+
const reservedWords = [
|
|
26
|
+
'SELECT', 'FROM', 'WHERE', 'INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP',
|
|
27
|
+
'ALTER', 'TABLE', 'INDEX', 'VIEW', 'TRIGGER', 'PRAGMA', 'VACUUM', 'REINDEX',
|
|
28
|
+
'EXPLAIN', 'QUERY', 'PLAN', 'TRANSACTION', 'BEGIN', 'COMMIT', 'ROLLBACK'
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
if (reservedWords.includes(tableName.toUpperCase())) {
|
|
32
|
+
throw new Error(`Table name cannot be a reserved word: ${tableName}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Return properly quoted identifier
|
|
36
|
+
return `"${tableName}"`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Validates and sanitizes column names to prevent SQL injection
|
|
41
|
+
* @param {string} columnName - The column name to sanitize
|
|
42
|
+
* @returns {string} - Sanitized column name wrapped in quotes
|
|
43
|
+
* @throws {Error} - If column name is invalid
|
|
44
|
+
*/
|
|
45
|
+
export function sanitizeColumnName(columnName) {
|
|
46
|
+
if (!columnName || typeof columnName !== 'string') {
|
|
47
|
+
throw new Error('Column name must be a non-empty string');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const validIdentifierRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
51
|
+
|
|
52
|
+
if (!validIdentifierRegex.test(columnName)) {
|
|
53
|
+
throw new Error(`Invalid column name: ${columnName}. Must start with letter or underscore and contain only letters, digits, and underscores.`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return `"${columnName}"`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Creates a parameterized query with proper escaping
|
|
61
|
+
* @param {string} query - The SQL query template with ? placeholders
|
|
62
|
+
* @param {Array} params - Array of parameter values
|
|
63
|
+
* @returns {Object} - Object with query and params
|
|
64
|
+
*/
|
|
65
|
+
export function createParameterizedQuery(query, params = []) {
|
|
66
|
+
if (!query || typeof query !== 'string') {
|
|
67
|
+
throw new Error('Query must be a non-empty string');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!Array.isArray(params)) {
|
|
71
|
+
throw new Error('Parameters must be an array');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Count placeholders in query
|
|
75
|
+
const placeholderCount = (query.match(/\?/g) || []).length;
|
|
76
|
+
|
|
77
|
+
if (placeholderCount !== params.length) {
|
|
78
|
+
throw new Error(`Parameter count mismatch: expected ${placeholderCount}, got ${params.length}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
query: query.trim(),
|
|
83
|
+
params: params
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Builds a safe WHERE clause with proper parameterization
|
|
89
|
+
* @param {Object} conditions - Object with column:value pairs
|
|
90
|
+
* @returns {Object} - Object with whereClause and params
|
|
91
|
+
*/
|
|
92
|
+
export function buildWhereClause(conditions) {
|
|
93
|
+
if (!conditions || typeof conditions !== 'object') {
|
|
94
|
+
throw new Error('Conditions must be an object');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const entries = Object.entries(conditions);
|
|
98
|
+
if (entries.length === 0) {
|
|
99
|
+
return { whereClause: '', params: [] };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const clauses = [];
|
|
103
|
+
const params = [];
|
|
104
|
+
|
|
105
|
+
for (const [column, value] of entries) {
|
|
106
|
+
const sanitizedColumn = sanitizeColumnName(column);
|
|
107
|
+
clauses.push(`${sanitizedColumn} = ?`);
|
|
108
|
+
params.push(value);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
whereClause: clauses.join(' AND '),
|
|
113
|
+
params: params
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Builds a safe UPDATE query with proper parameterization
|
|
119
|
+
* @param {string} tableName - The table name
|
|
120
|
+
* @param {Object} updates - Object with column:value pairs to update
|
|
121
|
+
* @param {Object} conditions - Object with column:value pairs for WHERE clause
|
|
122
|
+
* @returns {Object} - Object with query and params
|
|
123
|
+
*/
|
|
124
|
+
export function buildUpdateQuery(tableName, updates, conditions) {
|
|
125
|
+
const sanitizedTableName = sanitizeTableName(tableName);
|
|
126
|
+
|
|
127
|
+
if (!updates || typeof updates !== 'object' || Object.keys(updates).length === 0) {
|
|
128
|
+
throw new Error('Updates must be a non-empty object');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const updateEntries = Object.entries(updates);
|
|
132
|
+
const setClause = updateEntries.map(([column]) =>
|
|
133
|
+
`${sanitizeColumnName(column)} = ?`
|
|
134
|
+
).join(', ');
|
|
135
|
+
|
|
136
|
+
const { whereClause, params: whereParams } = buildWhereClause(conditions);
|
|
137
|
+
|
|
138
|
+
if (!whereClause) {
|
|
139
|
+
throw new Error('WHERE clause is required for UPDATE queries');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const updateParams = updateEntries.map(([, value]) => value);
|
|
143
|
+
|
|
144
|
+
return createParameterizedQuery(
|
|
145
|
+
`UPDATE ${sanitizedTableName} SET ${setClause} WHERE ${whereClause}`,
|
|
146
|
+
[...updateParams, ...whereParams]
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Builds a safe DELETE query with proper parameterization
|
|
152
|
+
* @param {string} tableName - The table name
|
|
153
|
+
* @param {Object} conditions - Object with column:value pairs for WHERE clause
|
|
154
|
+
* @returns {Object} - Object with query and params
|
|
155
|
+
*/
|
|
156
|
+
export function buildDeleteQuery(tableName, conditions) {
|
|
157
|
+
const sanitizedTableName = sanitizeTableName(tableName);
|
|
158
|
+
|
|
159
|
+
const { whereClause, params } = buildWhereClause(conditions);
|
|
160
|
+
|
|
161
|
+
if (!whereClause) {
|
|
162
|
+
throw new Error('WHERE clause is required for DELETE queries');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return createParameterizedQuery(
|
|
166
|
+
`DELETE FROM ${sanitizedTableName} WHERE ${whereClause}`,
|
|
167
|
+
params
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Builds a safe INSERT query with proper parameterization
|
|
173
|
+
* @param {string} tableName - The table name
|
|
174
|
+
* @param {Object} data - Object with column:value pairs to insert
|
|
175
|
+
* @returns {Object} - Object with query and params
|
|
176
|
+
*/
|
|
177
|
+
export function buildInsertQuery(tableName, data) {
|
|
178
|
+
const sanitizedTableName = sanitizeTableName(tableName);
|
|
179
|
+
|
|
180
|
+
if (!data || typeof data !== 'object' || Object.keys(data).length === 0) {
|
|
181
|
+
throw new Error('Data must be a non-empty object');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const entries = Object.entries(data);
|
|
185
|
+
const columns = entries.map(([column]) => sanitizeColumnName(column)).join(', ');
|
|
186
|
+
const placeholders = entries.map(() => '?').join(', ');
|
|
187
|
+
const values = entries.map(([, value]) => value);
|
|
188
|
+
|
|
189
|
+
return createParameterizedQuery(
|
|
190
|
+
`INSERT INTO ${sanitizedTableName} (${columns}) VALUES (${placeholders})`,
|
|
191
|
+
values
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Validates that a value is safe for use in SQL queries
|
|
197
|
+
* @param {any} value - The value to validate
|
|
198
|
+
* @returns {boolean} - True if value is safe
|
|
199
|
+
*/
|
|
200
|
+
export function isSafeValue(value) {
|
|
201
|
+
// Allow null, undefined, numbers, booleans, and strings
|
|
202
|
+
const safeTypes = ['string', 'number', 'boolean', 'undefined'];
|
|
203
|
+
return value === null || safeTypes.includes(typeof value);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Sanitizes a value for safe SQL usage
|
|
208
|
+
* @param {any} value - The value to sanitize
|
|
209
|
+
* @returns {any} - Sanitized value
|
|
210
|
+
*/
|
|
211
|
+
export function sanitizeValue(value) {
|
|
212
|
+
if (!isSafeValue(value)) {
|
|
213
|
+
throw new Error(`Unsafe value type: ${typeof value}`);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return value;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Escapes special characters in LIKE patterns
|
|
221
|
+
* @param {string} pattern - The LIKE pattern to escape
|
|
222
|
+
* @returns {string} - Escaped pattern
|
|
223
|
+
*/
|
|
224
|
+
export function escapeLikePattern(pattern) {
|
|
225
|
+
if (typeof pattern !== 'string') {
|
|
226
|
+
throw new Error('LIKE pattern must be a string');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return pattern
|
|
230
|
+
.replace(/\\/g, '\\\\') // Escape backslashes
|
|
231
|
+
.replace(/%/g, '\\%') // Escape percent signs
|
|
232
|
+
.replace(/_/g, '\\_'); // Escape underscores
|
|
233
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "d1s",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Manage your Cloudflare D1 database locally, lightning fast.",
|
|
6
6
|
"main": "./dist/d1-studio.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"d1studio": "dist/d1-studio.js"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"dev": "next dev",
|
|
12
12
|
"build": "next build",
|
|
13
|
-
"build:cli": "mkdir -p dist/lib && cp -r src/lib/* dist/lib/ && cp -r src/app dist/app && cp scripts/studio.js dist/d1-studio.js && cp -r .next dist/.next && chmod +x dist/d1-studio.js",
|
|
13
|
+
"build:cli": "npm run build && mkdir -p dist/lib && mkdir -p dist/app && cp -r src/lib/* dist/lib/ && cp -r src/app/* dist/app/ && cp scripts/studio.js dist/d1-studio.js && cp -r .next dist/.next && chmod +x dist/d1-studio.js",
|
|
14
14
|
"start": "next start",
|
|
15
15
|
"prepare": "npm run build:cli",
|
|
16
16
|
"link": "npm link",
|
|
@@ -22,12 +22,6 @@
|
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
"dist",
|
|
25
|
-
"public",
|
|
26
|
-
"src",
|
|
27
|
-
"scripts",
|
|
28
|
-
"next.config.mjs",
|
|
29
|
-
"tailwind.config.jms",
|
|
30
|
-
"postcss.config.mjs",
|
|
31
25
|
"README.md"
|
|
32
26
|
],
|
|
33
27
|
"keywords": [
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
exports.id=90,exports.ids=[90],exports.modules={1241:(e,t,r)=>{Promise.resolve().then(r.t.bind(r,13219,23)),Promise.resolve().then(r.t.bind(r,34863,23)),Promise.resolve().then(r.t.bind(r,25155,23)),Promise.resolve().then(r.t.bind(r,40802,23)),Promise.resolve().then(r.t.bind(r,9350,23)),Promise.resolve().then(r.t.bind(r,48530,23)),Promise.resolve().then(r.t.bind(r,88921,23))},54041:(e,t,r)=>{Promise.resolve().then(r.t.bind(r,66959,23)),Promise.resolve().then(r.t.bind(r,33875,23)),Promise.resolve().then(r.t.bind(r,88903,23)),Promise.resolve().then(r.t.bind(r,57174,23)),Promise.resolve().then(r.t.bind(r,84178,23)),Promise.resolve().then(r.t.bind(r,87190,23)),Promise.resolve().then(r.t.bind(r,61365,23))},34400:(e,t,r)=>{Promise.resolve().then(r.bind(r,13164)),Promise.resolve().then(r.bind(r,91831))},97952:(e,t,r)=>{Promise.resolve().then(r.bind(r,52652)),Promise.resolve().then(r.bind(r,2899))},52652:(e,t,r)=>{"use strict";r.d(t,{Toaster:()=>v});var a=r(45512),s=r(46888),o=r(58009),i=r(68952),n=r(21643),c=r(51255),l=r(3603);let d=i.Kq,u=o.forwardRef(({className:e,...t},r)=>(0,a.jsx)(i.LM,{ref:r,className:(0,l.cn)("fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",e),...t}));u.displayName=i.LM.displayName;let h=(0,n.F)("group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",{variants:{variant:{default:"border bg-background text-foreground",destructive:"destructive group border-destructive bg-destructive text-destructive-foreground"}},defaultVariants:{variant:"default"}}),p=o.forwardRef(({className:e,variant:t,...r},s)=>(0,a.jsx)(i.bL,{ref:s,className:(0,l.cn)(h({variant:t}),e),...r}));p.displayName=i.bL.displayName,o.forwardRef(({className:e,...t},r)=>(0,a.jsx)(i.rc,{ref:r,className:(0,l.cn)("inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",e),...t})).displayName=i.rc.displayName;let m=o.forwardRef(({className:e,...t},r)=>(0,a.jsx)(i.bm,{ref:r,className:(0,l.cn)("absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",e),"toast-close":"",...t,children:(0,a.jsx)(c.A,{className:"h-4 w-4"})}));m.displayName=i.bm.displayName;let f=o.forwardRef(({className:e,...t},r)=>(0,a.jsx)(i.hE,{ref:r,className:(0,l.cn)("text-sm font-semibold [&+div]:text-xs",e),...t}));f.displayName=i.hE.displayName;let b=o.forwardRef(({className:e,...t},r)=>(0,a.jsx)(i.VY,{ref:r,className:(0,l.cn)("text-sm opacity-90",e),...t}));function v(){let{toasts:e}=(0,s.dj)();return(0,a.jsxs)(d,{children:[e.map(function({id:e,title:t,description:r,action:s,...o}){return(0,a.jsxs)(p,{...o,children:[(0,a.jsxs)("div",{className:"grid gap-1",children:[t&&(0,a.jsx)(f,{children:t}),r&&(0,a.jsx)(b,{children:r})]}),s,(0,a.jsx)(m,{})]},e)}),(0,a.jsx)(u,{})]})}b.displayName=i.VY.displayName},98180:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>u,metadata:()=>d});var a=r(62740),s=r(27944),o=r.n(s),i=r(95510),n=r.n(i);r(61135);var c=r(91831),l=r(13164);let d={title:"d1-studio",description:"Native D1 database studio."};function u({children:e}){return(0,a.jsx)("html",{lang:"en",children:(0,a.jsx)("body",{className:`${o().variable} ${n().variable} antialiased`,children:(0,a.jsxs)(c.DatabaseProvider,{children:[e,(0,a.jsx)(l.Toaster,{})," "]})})})}},13164:(e,t,r)=>{"use strict";r.d(t,{Toaster:()=>a});let a=(0,r(46760).registerClientReference)(function(){throw Error("Attempted to call Toaster() from the server but Toaster is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/Users/kona/Desktop/d1studio/src/components/ui/toaster.jsx","Toaster")},61135:()=>{},2899:(e,t,r)=>{"use strict";r.d(t,{DatabaseProvider:()=>u,t:()=>h});var a=r(45512),s=r(58009),o=r(46888);let i=new Map;function n(e,t,r=2e3){let a=i.get(e);if(a&&Date.now()-a.timestamp<r)return a.promise;let s=t();return i.set(e,{promise:s,timestamp:Date.now()}),s.finally(()=>{setTimeout(()=>{i.delete(e)},r)}),s}let c=(0,s.createContext)(void 0);class l{constructor(){this.cache=new Map}get(e){return this.cache.get(e)||null}set(e,t,r,a){this.cache.set(e,{data:t,schema:r,meta:a,timestamp:Date.now()})}update(e,t,r,a){let s=this.cache.get(e);s&&this.cache.set(e,{data:t||s.data,schema:r||s.schema,meta:a||s.meta,timestamp:Date.now()})}invalidate(e){this.cache.delete(e)}clear(){this.cache.clear()}}class d{constructor(){this.queue=[],this.processing=!1}async add(e){return new Promise((t,r)=>{this.queue.push({operation:e,resolve:t,reject:r}),this.process()})}async process(){if(this.processing||0===this.queue.length)return;this.processing=!0;let{operation:e,resolve:t,reject:r}=this.queue.shift();try{let r=await e();t(r)}catch(e){r(e)}finally{this.processing=!1,this.process()}}}function u({children:e}){let{toast:t}=(0,o.dj)(),[r,i]=(0,s.useState)([]),[u,h]=(0,s.useState)(!0),[p,m]=(0,s.useState)(null),[f,b]=(0,s.useState)(null);(0,s.useRef)(new d);let[v,y]=(0,s.useState)(null),g=(0,s.useRef)(new l).current,w=(0,s.useCallback)((e,t=1,r=50)=>{let a=`table-${e}-${t}-${r}`;return g.get(a)},[]),x=(0,s.useCallback)(e=>{g.cache.forEach((t,r)=>{r.startsWith(`table-${e}-`)&&g.invalidate(r)})},[]),T=(0,s.useCallback)((e,t,r,a,s=1,o=50)=>{let i=`table-${e}-${s}-${o}`;g.update(i,t,r,a)},[]),S=(0,s.useCallback)(async e=>n(`query-${e}`,async()=>{try{let t=await fetch("/api/query",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:e})});if(!t.ok){let e="Failed to execute query";try{let r=await t.json();e=r?.error?.message||e}catch(e){}throw Error(e)}let r=await t.json();if(!r.success)throw Error(r.error||"Query execution failed");return r}catch(e){throw e||Error("An unknown error occurred")}},1e3),[]),j=(0,s.useCallback)(async e=>{try{let t=await fetch(`/api/tables/${e}`),r=await t.json();if(!t.ok||!r.success)throw Error(r.error||"Failed to fetch table schema");return r.schema||[]}catch(e){throw console.error("Schema fetch error:",e),t({variant:"destructive",title:"Schema Fetch Failed",description:e.message}),e}},[t]),E=(0,s.useCallback)(async(e,r={})=>{let{forceFetch:a=!1,page:s=1,limit:o=50}=r,i=`table-${e}-${s}-${o}`;if(!a){let e=g.get(i);if(e)return e}return n(`table-${e}-${s}-${o}`,async()=>{try{let t=await fetch(`/api/tables/${e}?page=${s}&limit=${o}`,{headers:{"Cache-Control":"no-cache",Pragma:"no-cache"}});if(!t.ok)throw Error("Failed to fetch table data");let r=await t.json();if(!r.success)throw Error(r.error||"Failed to fetch table data");return g.set(i,r.data,r.schema,r.meta),r}catch(e){throw console.error("Error fetching table data:",e),t({variant:"destructive",title:"Data Fetch Failed",description:e.message}),e}},1e3)},[t]),C=(0,s.useCallback)(async e=>{try{return g.invalidate(e),await E(e,{forceFetch:!0})}catch(e){throw console.error("Error updating table data:",e),t({variant:"destructive",title:"Update Failed",description:e.message}),e}},[E,t]),P=(0,s.useCallback)(async(e,t={})=>(y(e),await E(e,t)),[E]),k=(0,s.useCallback)(async()=>n("refresh-tables",async()=>{h(!0),m(null);try{let e=await fetch("/api/tables");if(!e.ok)throw Error("Failed to fetch tables");let t=await e.json();if(t.error)throw Error(t.error);return i(t.tables||[]),t.tables||[]}catch(e){throw m(e.message),t({variant:"destructive",title:"Refresh Failed",description:e.message}),e}finally{h(!1)}},2e3),[t]),D=(0,s.useCallback)(async e=>{try{await S(e),g.clear(),await k(),t({title:"Success",description:"Table created successfully"})}catch(e){throw t({variant:"destructive",title:"Create Table Failed",description:e.message}),Error(`Failed to create table: ${e.message}`)}},[S,k,t]),N=(0,s.useCallback)(async e=>{try{await S(`DROP TABLE ${e};`),g.invalidate(e),await k(),t({title:"Success",description:"Table dropped successfully"})}catch(e){throw t({variant:"destructive",title:"Drop Table Failed",description:e.message}),Error(`Failed to drop table: ${e.message}`)}},[S,k,t]),$=(0,s.useCallback)(async e=>{try{let r=await fetch("/api/migrations/sync",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){let e=await r.json();throw Error(e.error?.message||"Failed to sync migrations")}let a=await r.json();return t({title:"Success",description:"Migrations synced successfully"}),a}catch(e){throw console.error("Error syncing migrations:",e),t({variant:"destructive",title:"Sync Failed",description:e.message}),e}},[t]),F=(0,s.useCallback)(async()=>{try{let e=localStorage.getItem("cf_credentials");if(!e)throw Error("No Cloudflare credentials found. Please connect to Cloudflare first.");let t=JSON.parse(e);if(!t.accountId||!t.apiToken)throw Error("Invalid credentials stored. Please reconnect to Cloudflare.");let r=await fetch("/api/pull-remote/confirm",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:t.accountId,apiToken:t.apiToken})}),a=await r.json();if(!r.ok||!a.success)throw Error(a.error?.message||"Failed to pull from remote");return g.clear(),await k(),a}catch(e){throw console.error("Error pulling from remote:",e),t({variant:"destructive",title:"Pull Failed",description:e.message}),e}},[k,t]),O=(0,s.useCallback)(async e=>{try{let t=await fetch("/api/push-remote",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}),r=await t.json();if(!t.ok)throw Error(r.error?.message||"Failed to push to remote");return r}catch(e){throw console.error("Error pushing to remote:",e),e}},[t]),A=(0,s.useMemo)(()=>({tables:r,currentDatabase:f,isLoading:u,error:p,activeTable:v,refreshTables:k,executeQuery:S,fetchTableSchema:j,fetchTableData:E,updateTableData:C,createTable:D,dropTable:N,syncMigrations:$,pullFromRemote:F,pushToRemote:O,getCachedTable:w,updateTableCache:T,invalidateTable:x,switchTable:P}),[r,f,u,p,v,k,S,j,E,C,D,N,$,F,O,w,T,x,P]);return(0,a.jsx)(c.Provider,{value:A,children:e})}function h(){let e=(0,s.useContext)(c);if(!e)throw Error("useDatabase must be used within a DatabaseProvider");return e}},46888:(e,t,r)=>{"use strict";r.d(t,{dj:()=>h});var a=r(58009);let s=0,o=new Map,i=e=>{if(o.has(e))return;let t=setTimeout(()=>{o.delete(e),d({type:"REMOVE_TOAST",toastId:e})},1e6);o.set(e,t)},n=(e,t)=>{switch(t.type){case"ADD_TOAST":return{...e,toasts:[t.toast,...e.toasts].slice(0,1)};case"UPDATE_TOAST":return{...e,toasts:e.toasts.map(e=>e.id===t.toast.id?{...e,...t.toast}:e)};case"DISMISS_TOAST":{let{toastId:r}=t;return r?i(r):e.toasts.forEach(e=>{i(e.id)}),{...e,toasts:e.toasts.map(e=>e.id===r||void 0===r?{...e,open:!1}:e)}}case"REMOVE_TOAST":if(void 0===t.toastId)return{...e,toasts:[]};return{...e,toasts:e.toasts.filter(e=>e.id!==t.toastId)}}},c=[],l={toasts:[]};function d(e){l=n(l,e),c.forEach(e=>{e(l)})}function u({...e}){let t=(s=(s+1)%Number.MAX_SAFE_INTEGER).toString(),r=()=>d({type:"DISMISS_TOAST",toastId:t});return d({type:"ADD_TOAST",toast:{...e,id:t,open:!0,onOpenChange:e=>{e||r()}}}),{id:t,dismiss:r,update:e=>d({type:"UPDATE_TOAST",toast:{...e,id:t}})}}function h(){let[e,t]=a.useState(l);return a.useEffect(()=>(c.push(t),()=>{let e=c.indexOf(t);e>-1&&c.splice(e,1)}),[e]),{...e,toast:u,dismiss:e=>d({type:"DISMISS_TOAST",toastId:e})}}},3603:(e,t,r)=>{"use strict";r.d(t,{cn:()=>o});var a=r(82281),s=r(94805);function o(...e){return(0,s.QP)((0,a.$)(e))}},91831:(e,t,r)=>{"use strict";r.d(t,{DatabaseProvider:()=>s});var a=r(46760);let s=(0,a.registerClientReference)(function(){throw Error("Attempted to call DatabaseProvider() from the server but DatabaseProvider is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/Users/kona/Desktop/d1studio/src/context/database-context.js","DatabaseProvider");(0,a.registerClientReference)(function(){throw Error("Attempted to call useDatabase() from the server but useDatabase is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/Users/kona/Desktop/d1studio/src/context/database-context.js","useDatabase")}};
|