Skip to content

chore: sync main with upstream/main#1

Merged
NathanDrake2406 merged 8 commits intomainfrom
sync/upstream-main-20260308-90771f7
Mar 7, 2026
Merged

chore: sync main with upstream/main#1
NathanDrake2406 merged 8 commits intomainfrom
sync/upstream-main-20260308-90771f7

Conversation

@NathanDrake2406
Copy link
Copy Markdown
Owner

Summary\n- fast-forward fork history to upstream/main at 90771f7\n- bring origin/main in sync with cloudflare/vinext main\n\n## Verification\n- fetched both remotes and compared origin/main, main, and upstream/main\n- fast-forwarded local main with git merge --ff-only upstream/main\n

tomasgferreira and others added 8 commits March 7, 2026 01:27
Co-authored-by: tomoconstrutor <tomoconstrutor@gmail.com>
…oudflare#289)

* fix(instrumentation): defer ssrLoadModule call to post-middleware hook

Vite 7's SSRCompatModuleRunner requires the SSR environment's transport
channel to be initialized before ssrLoadModule() can be called. During
configureServer(), the channel is not yet ready, causing a TypeError
when instrumentation.ts exists.

Move the runInstrumentation() call from the configureServer body into
the returned post-middleware function, where environments are fully
initialized.

Fixes cloudflare#167

* fix(instrumentation): address review comments on deferred ssrLoadModule

- Remove unreachable .catch() on runInstrumentation() since internal
  try/catch already handles errors and the function never rejects
- Mock console.error in transport error test to suppress noisy output
  and assert the expected error message
- Rename misleading test to accurately describe what it verifies

* test: address instrumentation review feedback
…oudflare#122)

* fix(deploy): monorepo-aware lock file and node_modules resolution

vinext deploy failed in monorepos in two ways:

1. Wrong package manager detected — detectPackageManager only checked for
   bun.lockb (legacy binary format), missing bun.lock (text format, Bun
   v1.0+). It also only searched the immediate project directory, so any
   monorepo where the lock file lives at the workspace root fell through to
   npm, causing a confusing "npm error Invalid Version:" failure.

2. Dependency detection and wrangler binary path hard-coded to the app
   directory — hasCloudflarePlugin, hasRscPlugin, hasWrangler, hasMdxRollup
   all checked {root}/node_modules only, producing false negatives for
   hoisted packages. runWranglerDeploy then crashed with ENOENT because
   the wrangler binary was at the workspace root, not the app root.

Changes:
- Add walkUpUntil<T>(start, check) to utils/project.ts — a shared primitive
  that walks ancestor directories until check() returns non-null. Both the
  lock-file and node_modules walkers are built on top of this.
- Rewrite detectPackageManager / detectPackageManagerName using walkUpUntil;
  add bun.lock (text) check alongside existing bun.lockb (binary).
- Add findInNodeModules(start, subPath) using walkUpUntil — walks up to find
  node_modules/{subPath}, returning the absolute path or null.
- Use findInNodeModules in detectProject (hasCloudflarePlugin, hasRscPlugin,
  hasWrangler), getMissingDeps (hasMdxRollup), and runWranglerDeploy.

Tests (12 new):
- detectPackageManager: pnpm, yarn, bun.lock, bun.lockb, npm fallback,
  monorepo root traversal, closest-wins precedence
- findInNodeModules: package lookup, binary lookup, null fallback,
  monorepo root traversal, closest-wins precedence

* fix(test): clear npm_config_user_agent in npm fallback test

On CI, pnpm sets process.env.npm_config_user_agent which causes
detectPackageManagerName to return 'pnpm' instead of falling through
to the npm default. Save and restore the env var around the assertion.

---------

Co-authored-by: Steve Faulkner <sfaulkner@cloudflare.com>
* feat: add react plugin for client components

* fix: improve react plugin JSDoc and update stale HMR comment

---------

Co-authored-by: Steve Faulkner <sfaulkner@cloudflare.com>
…loudflare#305)

* refactor: extract applyMiddlewareRequestHeaders into config-matchers

Move the x-middleware-request-* unpacking + postMwReqCtx rebuild logic
out of prod-server.ts and deploy.ts and into a shared
applyMiddlewareRequestHeaders() in config-matchers.ts, eliminating ~30
lines of duplicated code from each callsite.

* fix(test): update deploy test to reflect applyMiddlewareRequestHeaders refactor
…flare#306)

* fix: stub node:async_hooks in client builds via virtual module

Several shims (headers, cache, navigation-state, etc.) import
AsyncLocalStorage from node:async_hooks. Since resolve.alias applies
globally, these shims resolve in every environment including client.
Vite externalizes node:async_hooks to __vite-browser-external in browser
builds — an empty stub with no named exports — causing Rollup errors.

Add a vinext:async-hooks-stub plugin that intercepts node:async_hooks
in the client environment and provides a no-op AsyncLocalStorage via a
virtual module. This is semantically correct: shims already guard with
`_als.getStore() ?? fallback` patterns, so undefined store returns
produce correct client-side behavior.

Unlike the external file approach in cloudflare#293, this uses a virtual module
inline in the plugin — no additional files, no build artifacts.

Closes cloudflare#293

* fix: address async-hooks-stub code review feedback

- Convert load hook to object form with handler() for consistency
- Match bare `async_hooks` specifier in addition to `node:async_hooks`
- Add intentionally-minimal comment explaining stub scope
- Add regression tests for resolveId and load hook behavior

* refactor: extract async-hooks-stub plugin to plugins/ and test against real implementation

Move the vinext:async-hooks-stub plugin object from an inline definition in
index.ts to packages/vinext/src/plugins/async-hooks-stub.ts, exporting it as
asyncHooksStubPlugin. Import and use it directly in index.ts.

Update the regression test to import the real plugin via _asyncHooksStubPlugin
and invoke its resolveId/load handlers with a mock context, eliminating the
duplicated logic that the test previously used as a workaround for the plugin
being unexported and inline.

* fix: add filter to load hook, evaluate stub at runtime in test

- Add filter to load hook object form for consistency with resolveId
  and to opt into Vite/Rolldown hook optimization path
- Replace overlapping string-assertion test with one that evaluates
  the generated source via new Function, testing actual runtime
  behavior (getStore returns undefined, run/exit pass through return values)

* fix: remove control-char regex from load filter to fix lint

* fix: suppress no-control-regex for load filter via eslint-disable comment

* refactor: derive load filter regex from ASYNC_HOOKS_STUB_ID constant

* Update build-optimization.test.ts

Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>

* Update index.ts

Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>

* fix: widen run() type signature to accept rest args and typed callback

---------

Co-authored-by: James <james@eli.cx>
Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
…loudflare#314)

* refactor(ci): extract composite actions and improve workflow hygiene

- Add composite actions: setup-node-pnpm, build-vinext, deploy-example, comment-preview-urls
- Cache Playwright browsers in CI to avoid ~150MB download per E2E run
- Add concurrency group to deploy-examples.yml to prevent deploy pileup
- Replace inline CJS node script in create-next-app job with portable bash
- Convert ecosystem-run.yml inline Node scripts from CJS require() to ESM
- Apply composite actions across all workflows to eliminate repeated boilerplate

* refactor(ci): revert to inline steps, keep only setup-node-pnpm composite action

Remove the build-vinext, deploy-example, and comment-preview-urls composite
actions and inline their steps back into each workflow. Keep setup-node-pnpm
as the one reusable action (pnpm install + node setup). Retain all other
improvements from the previous commit: concurrency groups, Playwright browser
cache, bash-based dev-server check, ESM node scripts in ecosystem-run.

* refactor(ci): use setup-node-pnpm composite action consistently

Every workflow that does pnpm/node setup + install now uses the
setup-node-pnpm composite action instead of the inline 3-step triplet.
Added optional registry-url input to support publish.yml's npm auth.

Exceptions (intentionally kept inline):
- bonk.yml / bigbonk.yml: issue_comment trigger, GHAS constraint
- tip.yml notify-on-failure: node-only, no pnpm install needed
@NathanDrake2406 NathanDrake2406 merged commit 90771f7 into main Mar 7, 2026
13 of 20 checks passed
james-elicx added a commit that referenced this pull request Mar 12, 2026
- Bug cloudflare#2: hybrid build skipped Pages Router pre-rendering when App Router entry
  also present — fix: only bail out on pure App Router builds (no pages entry)
- Bug #1: getOutputPath traversal guard bypassed on Windows by backslash urlPath
  — fix: reject urlPath containing backslashes before posix normalize
- Bug cloudflare#4: double-counting in result.skipped when AbortController fires and
  res.text() throws — fix: replace await res.text() with res.body?.cancel()
- Bug cloudflare#6: dynamic routes without getStaticPaths/generateStaticParams classified
  as 'ssr' — fix: use 'unknown' (skipped for unenumerable params, not SSR APIs)
- Bug cloudflare#3: routes that throw in ssrLoadModule silently omitted from
  routeClassifications — fix: wrap in try/catch, add 'unknown' classification
- Bug cloudflare#5: buildReportRows ignored knownRoutes for API routes — fix: check
  known?.get(route.pattern) first, fall back to 'api'
- Bug cloudflare#7: dead !Array.isArray guard after try/catch in expandDynamicAppRoute
  — remove unreachable branch
- Bug cloudflare#8: middlewareHeaders spread onto 200 pre-rendered response could include
  Location header — fix: filter out 'location' before spreading
- Bug cloudflare#9: configOverride typed as Partial<NextConfig> allows unsafe non-scalar
  fields — narrow to Pick<NextConfig, 'output' | 'trailingSlash'>
@NathanDrake2406 NathanDrake2406 deleted the sync/upstream-main-20260308-90771f7 branch March 18, 2026 09:51
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.

6 participants