Skip to content

[workers-utils] Move shared binding helpers into workers-utils#12948

Open
penalosa wants to merge 2 commits intomainfrom
penalosa/shared-binding-helpers
Open

[workers-utils] Move shared binding helpers into workers-utils#12948
penalosa wants to merge 2 commits intomainfrom
penalosa/shared-binding-helpers

Conversation

@penalosa
Copy link
Contributor

@penalosa penalosa commented Mar 18, 2026

Move shared helpers into @cloudflare/workers-utils so they can be reused across packages.

  • getAccessToken / domainUsesAccess: moved from wrangler/src/user/access.ts with an optional logger parameter. Wrangler's access.ts becomes a thin wrapper that passes its logger.
  • toWorkerMetadataBindings: new shared function that converts Record<string, Binding> to WorkerMetadataBinding[] for the Worker upload API. Wrangler's createWorkerUploadForm now delegates to it instead of inline conversion.

This is PR 1 of 2 — PR 2 adds @cloudflare/remote-bindings which reuses these shared helpers.


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because: pure refactor, existing wrangler tests cover these code paths
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: internal shared helpers, no user-facing changes

Open with Devin

@penalosa penalosa requested a review from a team as a code owner March 18, 2026 02:34
@changeset-bot
Copy link

changeset-bot bot commented Mar 18, 2026

🦋 Changeset detected

Latest commit: 019587c

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@workers-devprod
Copy link
Contributor

workers-devprod commented Mar 18, 2026

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • packages/workers-utils/package.json: [@cloudflare/wrangler]
  • packages/workers-utils/src/access.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/binding-helpers.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/capnp.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/create-worker-upload-form.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/access.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/api/startDevWorker/RemoteRuntimeController.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/create-worker-upload-form/bindings.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/create-worker-upload-form/commonjs.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/create-worker-upload-form/metadata.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/create-worker-upload-form/mime-types.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/pages/create-worker-bundle-contents.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/startDevWorker/RemoteRuntimeController.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/check/commands.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/deploy/deploy.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/dev/create-worker-preview.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/secret/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/user/auth-variables.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/user/user.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/versions/secrets/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/versions/upload.ts: [@cloudflare/wrangler]
  • pnpm-lock.yaml: [@cloudflare/wrangler]

@github-actions
Copy link
Contributor

github-actions bot commented Mar 18, 2026

✅ All changesets look good

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 18, 2026

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@12948

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@12948

miniflare

npm i https://pkg.pr.new/miniflare@12948

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@12948

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@12948

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@12948

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@12948

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@12948

wrangler

npm i https://pkg.pr.new/wrangler@12948

commit: 019587c

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

@penalosa penalosa marked this pull request as draft March 18, 2026 02:49
Pure file moves with no content changes. These will be adapted in the next commit.
@penalosa penalosa force-pushed the penalosa/shared-binding-helpers branch 2 times, most recently from 1bfe7f8 to 048c516 Compare March 18, 2026 03:15
- Update all wrangler import sites to import directly from @cloudflare/workers-utils (no re-export shims)
- access.ts: add optional AccessLogger parameter, replace wrangler logger import
- create-worker-upload-form.ts: fix self-referencing imports to use local paths
- capnp.ts: fix self-referencing import
- binding-helpers.ts: new file with extractBindingsOfType, isUnsafeBindingType, FlatBinding
- Delete old wrangler files (access.ts, create-worker-upload-form.ts, capnp.ts)
@penalosa penalosa force-pushed the penalosa/shared-binding-helpers branch from 048c516 to 019587c Compare March 18, 2026 03:20
@penalosa
Copy link
Contributor Author

/bonk I don't think the PR description here is correct anymore. Can you update it?

Copy link
Contributor

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

The refactoring is structurally sound — the file moves, import updates, and type adjustments are all correct. A few observations:

Issues

1. Changeset description is inaccurate

The changeset says:

Wrangler re-exports them at the original paths for backward compatibility.

This is not true. packages/wrangler/src/user/access.ts and packages/wrangler/src/deployment-bundle/create-worker-upload-form.ts were completely deleted — there are no re-export shims. This is fine since the package is private and all internal consumers were updated, but the changeset text is misleading.

2. extractBindingsOfType / isUnsafeBindingType are duplicated, not moved

The changeset claims these "now live in @cloudflare/workers-utils", but the original implementations in packages/wrangler/src/api/startDevWorker/utils.ts were left in place. Multiple wrangler files still import from the old location (./utils). Only the new create-worker-upload-form.ts in workers-utils uses the workers-utils copy.

This might be intentional (incremental migration for PR 2), but worth noting that there are now two independent copies of these functions.

3. undici is external but only in devDependencies

undici is listed in tsup.config.ts's external array (line 18), meaning it won't be bundled — it remains as a bare import "undici" in the built output. However, it's only in devDependencies. Since the package is "private": true and only consumed within the monorepo (where undici is hoisted by pnpm), this works in practice. But it's technically incorrect: an external dep that's needed at runtime should be in dependencies, or it should be removed from the external array so tsup bundles it.

command-exists is handled correctly — it's NOT in the external array, so it gets bundled, and being in devDependencies is consistent with the monorepo convention.

Looks good

  • The AccessLogger interface abstraction is clean — it decouples access.ts from wrangler's logger singleton while keeping the API simple with a noop default.
  • The type change from StartDevWorkerInput["bindings"] to Record<string, Binding> | undefined is type-identical (verified the source types), and correctly decouples the function from wrangler-specific types.
  • The usesAccessCache Map type annotation (Map<string, boolean>) and the matches[1] !== undefined check are nice improvements over the original.
  • All internal import paths in wrangler were properly updated — no stale references to removed files.

@penalosa penalosa marked this pull request as ready for review March 18, 2026 03:28
@penalosa penalosa requested a review from a team as a code owner March 18, 2026 03:28
@ask-bonk
Copy link
Contributor

ask-bonk bot commented Mar 18, 2026

Review posted on PR #12948. Here's a summary of the findings:

Three issues identified:

  1. Inaccurate changeset description — Claims "Wrangler re-exports them at the original paths for backward compatibility" but the files were fully deleted with no re-export shims.

  2. extractBindingsOfType / isUnsafeBindingType duplication — These functions now exist in both workers-utils/src/binding-helpers.ts AND wrangler/src/api/startDevWorker/utils.ts. The wrangler copy was left in place with multiple files still importing from it. May be intentional for incremental migration in PR 2.

  3. undici external but only in devDependencies — Since undici is in tsup's external array, it won't be bundled, but it's only listed as a dev dependency. Works in practice within the monorepo but is technically incorrect.

The core refactoring is correct — the AccessLogger abstraction, type equivalence verification, import path updates, and file moves are all sound.

github run

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Stale vi.mock path causes test mock to not intercept getAccessToken

The test imports getAccessToken from @cloudflare/workers-utils (line 2) and RemoteRuntimeController.ts also now imports it from @cloudflare/workers-utils (line 1 of that file). However, the vi.mock on line 38 still targets the old, deleted path "../../../user/access". This mock has no effect because no production code imports from that path anymore. As a result, vi.mocked(getAccessToken).mockResolvedValue(undefined) on line 167 will throw at runtime because getAccessToken is the real (non-mock) function from @cloudflare/workers-utils, not a vi.fn(). This will cause all tests in this file that depend on the mocked getAccessToken to fail.

(Refers to lines 38-41)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/bonk can you fix this?

@@ -1,4 +1,5 @@
/* eslint-disable workers-sdk/no-vitest-import-expect -- expect used in vi.waitFor callbacks */
import { getAccessToken } from "@cloudflare/workers-utils";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/bonk is this mock working?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

2 participants