diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/WrapperRow.tsx b/apps/studio/components/interfaces/Integrations/Wrappers/WrapperRow.tsx
index 7e583499894..bfdd02cf96d 100644
--- a/apps/studio/components/interfaces/Integrations/Wrappers/WrapperRow.tsx
+++ b/apps/studio/components/interfaces/Integrations/Wrappers/WrapperRow.tsx
@@ -23,7 +23,7 @@ const WrapperRow = ({ wrapper }: WrapperRowProps) => {
const canManageWrappers = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'wrappers')
const [editWrapperShown, setEditWrapperShown] = useState(false)
- const [isClosingEditWrapper, setisClosingEditWrapper] = useState(false)
+ const [isClosingEditWrapper, setIsClosingEditWrapper] = useState(false)
const [deleteWrapperShown, setDeleteWrapperShown] = useState(false)
const integration = INTEGRATIONS.find((i) => i.id === id)
@@ -45,7 +45,7 @@ const WrapperRow = ({ wrapper }: WrapperRowProps) => {
return (
<>
-
+
{wrapper.name}
{visibleMetadata.map((metadata) => (
@@ -53,8 +53,10 @@ const WrapperRow = ({ wrapper }: WrapperRowProps) => {
key={metadata.name}
className="flex items-center space-x-2 text-sm text-foreground-light"
>
- {metadata.label}:
- {serverOptions[metadata.name]}
+ {metadata.label}:
+
+ {serverOptions[metadata.name]}
+
))}
@@ -99,7 +101,7 @@ const WrapperRow = ({ wrapper }: WrapperRowProps) => {
))}
-
+
{
/>
- setisClosingEditWrapper(true)}>
+ setIsClosingEditWrapper(true)}>
{
setEditWrapperShown(false)
- setisClosingEditWrapper(false)
+ setIsClosingEditWrapper(false)
}}
isClosing={isClosingEditWrapper}
- setIsClosing={setisClosingEditWrapper}
+ setIsClosing={setIsClosingEditWrapper}
/>
diff --git a/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.constants.ts b/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.constants.ts
index a6b2bb40718..bae71c82a7e 100644
--- a/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.constants.ts
+++ b/apps/studio/components/interfaces/Integrations/Wrappers/Wrappers.constants.ts
@@ -20,6 +20,7 @@ export const WRAPPER_HANDLERS = {
CLERK: 'wasm_fdw_handler',
NOTION: 'wasm_fdw_handler',
SLACK: 'wasm_fdw_handler',
+ CLOUDFLARE_D1: 'wasm_fdw_handler',
}
export const WRAPPERS: WrapperMeta[] = [
@@ -3316,4 +3317,140 @@ export const WRAPPERS: WrapperMeta[] = [
},
],
},
+ {
+ name: 'cfd1_wrapper',
+ description: 'Read and write data from Cloudflare D1 databases using the Wasm FDW.',
+ handlerName: WRAPPER_HANDLERS.CLOUDFLARE_D1,
+ validatorName: 'wasm_fdw_validator',
+ icon: `${BASE_PATH}/img/icons/cloudflare-icon.svg`,
+ extensionName: 'Cfd1Fdw',
+ label: 'Cloudflare D1',
+ docsUrl: 'https://fdw.dev/catalog/cfd1/',
+ minimumExtensionVersion: '0.4.0',
+ server: {
+ options: [
+ {
+ name: 'fdw_package_url',
+ label: 'FDW Package URL',
+ required: true,
+ encrypted: false,
+ secureEntry: false,
+ defaultValue:
+ 'https://github.com/supabase/wrappers/releases/download/wasm_cfd1_fdw_v0.1.0/cfd1_fdw.wasm',
+ hidden: true,
+ },
+ {
+ name: 'fdw_package_name',
+ label: 'FDW Package Name',
+ required: true,
+ encrypted: false,
+ secureEntry: false,
+ defaultValue: 'supabase:cfd1-fdw',
+ hidden: true,
+ },
+ {
+ name: 'fdw_package_version',
+ label: 'FDW Package Version',
+ required: true,
+ encrypted: false,
+ secureEntry: false,
+ defaultValue: '0.1.0',
+ hidden: true,
+ },
+ {
+ name: 'fdw_package_checksum',
+ label: 'FDW Package Checksum',
+ required: true,
+ encrypted: false,
+ secureEntry: false,
+ defaultValue: '783232834bb29dbd3ee6b09618c16f8a847286e63d05c54397d56c3e703fad31',
+ hidden: true,
+ },
+ {
+ name: 'api_url',
+ label: 'API URL',
+ required: false,
+ encrypted: false,
+ secureEntry: false,
+ defaultValue: 'https://api.cloudflare.com/client/v4/accounts//d1/database',
+ },
+ {
+ name: 'account_id',
+ label: 'Account ID',
+ required: true,
+ encrypted: false,
+ secureEntry: false,
+ },
+ {
+ name: 'database_id',
+ label: 'Database ID',
+ required: true,
+ encrypted: false,
+ secureEntry: false,
+ },
+ {
+ name: 'api_token_id',
+ label: 'Cloudflare D1 API Token',
+ required: true,
+ encrypted: true,
+ secureEntry: true,
+ urlHelper: 'https://dash.cloudflare.com/profile/api-tokens',
+ },
+ ],
+ },
+ tables: [
+ {
+ label: 'D1 Databases',
+ description: 'D1 databases in your Cloudflare account',
+ availableColumns: [
+ { name: 'uuid', type: 'text' },
+ { name: 'name', type: 'text' },
+ { name: 'version', type: 'text' },
+ { name: 'num_tables', type: 'bigint' },
+ { name: 'file_size', type: 'bigint' },
+ { name: 'created_at', type: 'text' },
+ { name: '_attrs', type: 'jsonb' },
+ ],
+ options: [
+ {
+ name: 'table',
+ defaultValue: '_meta_databases',
+ editable: false,
+ required: true,
+ type: 'text',
+ },
+ ],
+ },
+ {
+ label: 'D1 Table',
+ description: 'A table in your D1 database (define columns to match your D1 schema)',
+ availableColumns: [
+ { name: 'id', type: 'bigint' },
+ { name: 'name', type: 'text' },
+ { name: 'amount', type: 'double precision' },
+ { name: 'metadata', type: 'text' },
+ { name: '_attrs', type: 'jsonb' },
+ ],
+ options: [
+ {
+ label: 'Table',
+ name: 'table',
+ placeholder: 'mytable',
+ editable: true,
+ required: true,
+ type: 'text',
+ },
+ {
+ label: 'Row ID Column',
+ name: 'rowid_column',
+ placeholder: 'id',
+ defaultValue: 'id',
+ editable: true,
+ required: false,
+ type: 'text',
+ },
+ ],
+ },
+ ],
+ },
]
diff --git a/apps/studio/public/img/icons/cloudflare-icon.svg b/apps/studio/public/img/icons/cloudflare-icon.svg
new file mode 100644
index 00000000000..739274a993c
--- /dev/null
+++ b/apps/studio/public/img/icons/cloudflare-icon.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/apps/studio/static-data/integrations/cfd1_wrapper/overview.md b/apps/studio/static-data/integrations/cfd1_wrapper/overview.md
new file mode 100644
index 00000000000..424a5977bba
--- /dev/null
+++ b/apps/studio/static-data/integrations/cfd1_wrapper/overview.md
@@ -0,0 +1,10 @@
+Cloudflare D1 is Cloudflare's managed, serverless database with SQLite's SQL semantics, built-in disaster recovery, and Worker and HTTP API access.
+
+The Cloudflare D1 Wrapper is a WebAssembly (Wasm) foreign data wrapper that allows you to read and write data from Cloudflare D1 databases within your Postgres database.
+
+**Features**
+
+- Query D1 databases directly from Postgres using SQL.
+- Read and write support for D1 tables.
+- Secure credential storage via Supabase Vault.
+- Supports query pushdown (where, order by, limit).