Skip to content

Implement Cloudflare cloud adapter#747

Merged
ralyodio merged 3 commits into
profullstack:masterfrom
caydyan:codex/implement-cloudflare-cloud-adapter
Jun 14, 2026
Merged

Implement Cloudflare cloud adapter#747
ralyodio merged 3 commits into
profullstack:masterfrom
caydyan:codex/implement-cloudflare-cloud-adapter

Conversation

@caydyan

@caydyan caydyan commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • replace the Cloudflare cloud stub with REST API support for R2 buckets, D1 databases, Queues, and Cloudflare Tunnels
  • add account discovery, dry-run behavior, quote metadata, status/list/destroy mappings, and Cloudflare envelope error handling
  • document the supported resource types and keep Worker script deployment delegated to the deploy-workers target

Validation

  • pnpm --filter @profullstack/sh1pt-core build
  • pnpm --filter @profullstack/sh1pt-cloud-cloudflare typecheck
  • pnpm --filter @profullstack/sh1pt-cloud-cloudflare build
  • pnpm vitest run packages/cloud/cloudflare/src/index.test.ts
  • git diff --check

@greptile-apps

greptile-apps Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Replaces the Cloudflare cloud stub with a full REST API adapter covering R2 buckets, D1 databases, Queues, and Cloudflare Tunnels. The adapter adds account discovery with pagination, dry-run support, Cloudflare envelope error handling, prefixed instance IDs, and tunnel_token passthrough via the new Instance.metadata field.

  • Provision / status / destroy / list are all implemented for all four resource types, with cfListAll handling multi-page responses and cfRequest normalising both JSON envelope errors and non-JSON error bodies.
  • Tunnel provisioning now requires a caller-supplied tunnelSecret (throws early otherwise) and returns Cloudflare's tunnel_token in metadata.cloudflareTunnelToken so callers can hand it to cloudflared.
  • kindForResource maps queue and tunnel to 'object-storage' — this is intentional per the test assertions and the adapter's declared supports list, but downstream code that routes by kind should be aware these two resource types share the object-storage bucket.

Confidence Score: 4/5

The adapter is substantially complete and the previous round of blocking issues (tunnel secret loss, missing pagination, R2 nested array mismatch) have all been addressed. The remaining concerns are non-blocking: the tunnelStatus catch-all can misreport an errored tunnel as provisioning, and cfListAll may silently truncate lists on any CF endpoint that omits total_pages from its result_info.

The tunnelStatus catch-all returning 'provisioning' for unknown statuses (including Cloudflare's real 'errored' status) and cfListAll's silent truncation when total_pages is absent are both present-but-non-critical defects that could affect operator experience in production but don't corrupt data or block the primary provisioning flow.

packages/cloud/cloudflare/src/index.ts — specifically tunnelStatus (line 479) and the cfListAll pagination termination condition (line 274).

Important Files Changed

Filename Overview
packages/cloud/cloudflare/src/index.ts Full Cloudflare REST adapter replacing the stub — R2, D1, Queues, and Tunnels are implemented with pagination, dry-run, envelope error handling, and prefixed instance IDs. Two concerns: tunnelStatus catch-all maps 'errored' to 'provisioning', and cfListAll's pagination relies solely on total_pages which some CF endpoints may omit.
packages/cloud/cloudflare/src/index.test.ts Comprehensive unit tests covering connect (with and without accountId), account pagination, all four provision paths, dry-run, list (including nested R2 bucket response), status, destroy, and error handling for both Cloudflare envelope errors and non-JSON responses.
packages/core/src/cloud.ts Minimal additive change: adds optional metadata field (Record<string, string
packages/cloud/cloudflare/README.md Updated to accurately describe REST API support, supported resource types, tunnelSecret requirement, and tunnel_token handoff; replaces vague stub documentation.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant Adapter as cloud-cloudflare
    participant CF as Cloudflare REST API

    Caller->>Adapter: "connect(ctx, { accountId? })"
    alt accountId provided
        Adapter->>CF: GET /accounts/:id
        CF-->>Adapter: "{ result: { id, name } }"
    else no accountId
        loop cfListAll pages
            Adapter->>CF: "GET /accounts?page=N&per_page=100"
            CF-->>Adapter: "{ result: [...], result_info: { total_pages } }"
        end
    end
    Adapter-->>Caller: "{ accountId }"

    Caller->>Adapter: provision(ctx, spec, config)
    Adapter->>Adapter: resourceTypeFor(spec, config)
    Adapter->>Adapter: quote(ctx, spec, config)
    alt dryRun
        Adapter-->>Caller: dryRunInstance
    else live
        Adapter->>CF: "POST /accounts/:id/{r2/buckets|d1/database|queues|cfd_tunnel}"
        CF-->>Adapter: "{ result: { ..., tunnel_token? } }"
        Adapter-->>Caller: Instance (metadata.cloudflareTunnelToken if tunnel)
    end

    Caller->>Adapter: list(ctx, config)
    par all resource types
        Adapter->>CF: "GET /accounts/:id/r2/buckets?page=N"
        and
        Adapter->>CF: "GET /accounts/:id/d1/database?page=N"
        and
        Adapter->>CF: "GET /accounts/:id/queues?page=N"
        and
        Adapter->>CF: "GET /accounts/:id/cfd_tunnel?page=N"
    end
    CF-->>Adapter: paginated results
    Adapter-->>Caller: Instance[]

    Caller->>Adapter: destroy(ctx, instanceId, config)
    Adapter->>Adapter: parseResourceId(instanceId)
    Adapter->>CF: "DELETE /accounts/:id/{resource}/:nativeId"
    CF-->>Adapter: 200 / 204
Loading

Reviews (3): Last reviewed commit: "Fix Cloudflare review follow-ups" | Re-trigger Greptile

Comment thread packages/cloud/cloudflare/src/index.ts
Comment thread packages/cloud/cloudflare/src/index.ts
Comment thread packages/cloud/cloudflare/src/index.ts
Comment thread packages/cloud/cloudflare/src/index.ts
@caydyan

caydyan commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the Greptile findings in 39fcff4d:

  • Tunnel provisioning now requires a caller-supplied config.tunnelSecret, so the adapter no longer generates and loses a connector secret. Added negative and positive tunnel provisioning tests.
  • Provision/status/list now share kindForResource() so returned kind is consistent for each Cloudflare resource type.
  • The R2 list test now exercises Cloudflare's nested { buckets: [...] } response shape instead of only direct arrays.

Validation passed locally with corepack pnpm --filter @profullstack/sh1pt-core build, corepack pnpm --filter @profullstack/sh1pt-cloud-cloudflare typecheck, corepack pnpm --filter @profullstack/sh1pt-cloud-cloudflare build, corepack pnpm vitest run packages/cloud/cloudflare/src/index.test.ts, and git diff --check. GitHub test/security/Socket checks are passing on the updated head; Greptile is still pending.

@caydyan

caydyan commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the remaining Cloudflare adapter review threads in 78b68987:

  • Return Cloudflare's tunnel_token in provisioned tunnel instance metadata when the API provides it, while still requiring caller-owned tunnelSecret.
  • Reuse the paginated Cloudflare list helper for account auto-discovery instead of reading only page 1.
  • Make nested R2 bucket response coverage explicit in the resource-listing test.

Validation on the pushed head:

  • corepack pnpm --filter @profullstack/sh1pt-core build
  • corepack pnpm --filter @profullstack/sh1pt-cloud-cloudflare typecheck
  • corepack pnpm --filter @profullstack/sh1pt-cloud-cloudflare build
  • corepack pnpm vitest run packages/cloud/cloudflare/src/index.test.ts (17 tests)
  • git diff --check

GitHub test, vu1nz security scan, and both Socket checks are passing on 78b68987; Greptile is still pending at the time of this comment.

@github-actions

Copy link
Copy Markdown

🤖 Auto-rebase: The branch was rebased successfully locally but could not be pushed to the fork. Please enable 'Allow edits from maintainers' in the PR settings, or rebase manually: git fetch upstream master && git rebase upstream/master.

@ralyodio ralyodio merged commit f1b74ea into profullstack:master Jun 14, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants