feat: cloudflare d1 fdw (#35055)

* feat: slack fdw

* fix slack options

* feat: cloudflare d1 fdw

* up minimum version and feedback

* revert bigint change

* fix styling
This commit is contained in:
Alaister Young authored and GitHub committed 2025-04-16 18:47:25 +08:00
1 parent fe87cf1f74
commit 40aceb7e68
4 files changed
+164 -8

No files matched your search

@@ -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 (
<>
<TableRow>
<TableCell className="space-y-3 align-top !py-3 min-w-80">
<TableCell className="gap-2 align-top !py-3 min-w-80">
{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"
>
<span className="text-foreground-lighter">{metadata.label}:</span>
<span>{serverOptions[metadata.name]}</span>
<span className="text-foreground-lighter text-nowrap">{metadata.label}:</span>
<span className="truncate max-w-72" title={serverOptions[metadata.name]}>
{serverOptions[metadata.name]}
</span>
</div>
))}
</TableCell>
@@ -99,7 +101,7 @@ const WrapperRow = ({ wrapper }: WrapperRowProps) => {
</div>
))}
</TableCell>
<TableCell className="space-x-2">
<TableCell className="space-x-2 flex-nowrap">
<ButtonTooltip
disabled={!canManageWrappers}
type="default"
@@ -132,17 +134,17 @@ const WrapperRow = ({ wrapper }: WrapperRowProps) => {
/>
</TableCell>
</TableRow>
<Sheet open={editWrapperShown} onOpenChange={() => setisClosingEditWrapper(true)}>
<Sheet open={editWrapperShown} onOpenChange={() => setIsClosingEditWrapper(true)}>
<SheetContent size="lg" tabIndex={undefined}>
<EditWrapperSheet
wrapper={wrapper}
wrapperMeta={integration.meta}
onClose={() => {
setEditWrapperShown(false)
setisClosingEditWrapper(false)
setIsClosingEditWrapper(false)
}}
isClosing={isClosingEditWrapper}
setIsClosing={setisClosingEditWrapper}
setIsClosing={setIsClosingEditWrapper}
/>
</SheetContent>
</Sheet>
@@ -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/<account_id>/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',
},
],
},
],
},
]
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg xmlns="http://www.w3.org/2000/svg"
aria-label="Cloudflare" role="img"
viewBox="0 0 512 512"><rect
width="512" height="512"
rx="15%"
fill="#ffffff"/><path fill="#f38020" d="M331 326c11-26-4-38-19-38l-148-2c-4 0-4-6 1-7l150-2c17-1 37-15 43-33 0 0 10-21 9-24a97 97 0 0 0-187-11c-38-25-78 9-69 46-48 3-65 46-60 72 0 1 1 2 3 2h274c1 0 3-1 3-3z"/><path fill="#faae40" d="M381 224c-4 0-6-1-7 1l-5 21c-5 16 3 30 20 31l32 2c4 0 4 6-1 7l-33 1c-36 4-46 39-46 39 0 2 0 3 2 3h113l3-2a81 81 0 0 0-78-103"/></svg>

After

Width:  |  Height:  |  Size: 622 B

@@ -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).