Skip to content

feat(nx-cloudflare): add binding generator for KV/R2/D1/DO/Queue/Workflow/Service#185

Open
NachoVazquez wants to merge 1 commit into
mainfrom
feat/nx-cloudflare-binding-generator
Open

feat(nx-cloudflare): add binding generator for KV/R2/D1/DO/Queue/Workflow/Service#185
NachoVazquez wants to merge 1 commit into
mainfrom
feat/nx-cloudflare-binding-generator

Conversation

@NachoVazquez

Copy link
Copy Markdown
Contributor

TL;DR

Wiring a binding's config block + Env field (+ class & migrations for DO/Workflow) by hand is the core daily friction in a Cloudflare Worker workspace — exactly where an Nx generator shines. This PR adds nx g @naxodev/nx-cloudflare:binding --type=kv|r2|d1|do|queue|workflow|service, which edits wrangler.jsonc, stubs the required code (DO/Workflow classes, queue consumer, [[migrations]]), emits a matching test, and refreshes wrangler types.

Files to review (13, +1640 / -10):

File Why
packages/nx-cloudflare/src/generators/binding/generator.ts (start here) The generator — orchestration for all 7 binding types.
packages/nx-cloudflare/src/utils/wrangler-config.ts JSONC-aware reader/editor (jsonc-parser). The core new capability — updateJson strips comments.
packages/nx-cloudflare/src/generators/binding/schema.json CLI options + x-prompt interactivity.
packages/nx-cloudflare/src/utils/provision.ts --create command builders + exec wrapper for KV/R2/D1/Queue provisioning.
packages/nx-cloudflare/src/utils/run-wrangler-types.ts execFileSync wrapper for auto-running wrangler types post-flush.
packages/nx-cloudflare/src/generators/binding/generator.spec.ts 24 unit tests covering all types, validation, idempotency, callbacks.
packages/nx-cloudflare-e2e/src/binding.spec.ts 3 e2e tests (KV, DO, Queue) against the published tarball.

Why

Adding a KV namespace or Durable Object to a Worker today means: hand-edit wrangler.jsonc (careful not to break the comments), look up the wrangler config schema for the right key shape, write the DO class + migration, add a queue() handler if it's a queue, re-run wrangler types to refresh Env, and write a test. That's 5–6 manual steps per binding, repeated for every binding on every Worker.

Before After
KV/R2/D1 binding Hand-edit JSONC + look up schema nx g binding --type=kv --binding=MY_KV --id=...
Durable Object Hand-edit config + write class + add migration + re-export nx g binding --type=do --binding=MY_DO --name=MyDurableObject
Queue Hand-edit producers + consumers + write handler nx g binding --type=queue --binding=MY_QUEUE --name=my-queue
Env types Manual wrangler types rerun Auto-runs in the generator callback
Provisioning Separate wrangler kv namespace create + copy ID --create provisions and fills the ID automatically

How

  1. JSONC editing. wrangler-config.ts wraps jsonc-parser's modify/applyEdits to append entries to nested arrays (kv_namespaces[], durable_objects.bindings[], queues.producers[], etc.) while preserving comments and formatting. The existing retargetWranglerSchema used regex string-replace for the $schema line — that approach doesn't scale to structured array appends.

  2. Type-aware stubs. DO and Workflow classes land in src/<kebab-name>.ts and are re-exported from src/index.ts (Wrangler requires export from the main entrypoint). Queue consumers get a queue(batch, env) method injected into the existing export default { ... } object via bracket-matching. KV/R2/D1/Service are config-only — Env typing comes from wrangler types.

  3. DO migrations. The generator counts existing migrations[] entries and writes tag: "v{N+1}" with new_sqlite_classes: [ClassName].

  4. --create provisioning. The generator writes a __PENDING_CREATE__ sentinel into the config. The GeneratorCallback (post-flush) shells out to wrangler kv namespace create / r2 bucket create / d1 create / queues create, captures the real ID, and replaces the sentinel on the real filesystem. On failure: warns and leaves the placeholder for manual fill-in.

  5. Typegen. The callback auto-runs wrangler types via execFileSync so Env picks up the new binding. --skipTypegen opts out.

Reviewer notes

  • jsonc-parser is a new direct dependency. It was already transitively present (via jsonc-eslint-parser). Added as a direct dependency with a loose ^3.3.0 range since it's runtime code in the published package. updateJson from @nx/devkit is strict-JSON and strips comments — not viable for JSONC.

  • TOML is rejected, not supported. The inference plugin accepts .toml, but TOML array-of-tables editing needs a separate parser. The generator errors with a pointer to convert to .jsonc first. Covering .toml would double the editor surface for v1.

  • --create only for KV/R2/D1/Queue. DO/Workflow are code classes (no remote resource), Service is a reference to another Worker. Passing --create with those types errors explicitly.

  • Queue handler injection uses bracket-counting, not ts-morph. The existing src/index.ts from C3 ships export default { async fetch(...) {} }. The generator finds the matching closing brace and inserts before it. If no default export object exists, it warns and prints the template for manual insertion.

  • Duplicate binding names error, never overwrite. The generator scans the target array for an existing binding/name match before appending.

  • No executors. All wrangler CLI calls go through the existing inferred nx:run-commands targets. The generator's GeneratorCallback calls wrangler types directly (not nx typegen) to avoid Nx daemon overhead in a post-flush callback.

Tests

24 unit tests in generator.spec.ts (mock run-wrangler-types + provisionResource): all 7 binding types, JSONC comment preservation, DO migration tag increment, queue handler injection + fetch handler preservation, duplicate detection, validation errors (missing --name, --create on non-provisionable, missing --bucketName/--databaseName, wrong project, TOML rejection), callback behavior (typegen auto-run, --skipTypegen, --create provisioning).

3 e2e tests in binding.spec.ts (real C3 scaffold + published tarball): KV with existing ID, DO with migration + class stub + re-export, Queue with producer + consumer + handler injection.

Run: bunx nx test nx-cloudflare (unit) / bunx nx e2e nx-cloudflare-e2e (e2e).

Follow-up

  • Hyperdrive, Vectorize, AI, Browser Rendering bindings (the issue names these as "expand later")
  • TOML config support (if demand materializes)
  • --remove flag or a remove-binding generator

Links

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 21, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
gonx-docs b6809ca Commit Preview URL

Branch Preview URL
Jun 22 2026, 10:56 AM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 21, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
nx-cloudflare b6809ca Jun 22 2026, 10:56 AM

@nx-cloud

nx-cloud Bot commented Jun 21, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit b6809ca

Command Status Duration Result
nx affected -t e2e --parallel=1 ❌ Failed 3m 48s View ↗
nx affected -t build --yes ✅ Succeeded 3s View ↗
nx affected -t lint test ✅ Succeeded 33s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 1s View ↗

💡 Dealing with memory or CPU issues? See memory and CPU details with the resource usage add-on ↗.


☁️ Nx Cloud last updated this comment at 2026-06-22 11:01:25 UTC

@nx-cloud

nx-cloud Bot commented Jun 21, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit 23452ba

Command Status Duration Result
nx-cloud record -- nx format:check ❌ Failed 1s View ↗

💡 Dealing with memory or CPU issues? See memory and CPU details with the resource usage add-on ↗.


☁️ Nx Cloud last updated this comment at 2026-06-21 18:53:43 UTC

@nx-cloud

nx-cloud Bot commented Jun 21, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit 23452ba

Command Status Duration Result
nx-cloud record -- nx format:check ❌ Failed 1s View ↗

💡 Dealing with memory or CPU issues? See memory and CPU details with the resource usage add-on ↗.


☁️ Nx Cloud last updated this comment at 2026-06-21 18:53:44 UTC

@NachoVazquez NachoVazquez force-pushed the feat/nx-cloudflare-binding-generator branch 2 times, most recently from 0124bca to ca0bfc0 Compare June 21, 2026 20:10
@NachoVazquez NachoVazquez force-pushed the feat/nx-cloudflare-binding-generator branch from ca0bfc0 to b6809ca Compare June 22, 2026 10:56
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.

1 participant