Remove pre-monorepo node-renderer devDep baggage; consolidate test multipart builders - #4435
Conversation
WalkthroughAdds a local ChangesLocal formAutoContent Helper and Dependency Cleanup
Estimated code review effort: 2 (Simple) | ~15 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR removes four dead or redundant devDependencies (
Confidence Score: 5/5Safe to merge — all changes are confined to devDependencies and test helpers; no runtime code or published artifact is touched. The dep removals are each individually verified as dead or redundant (PR description documents grep results and lockfile evidence), the new formAutoContent shim faithfully reproduces the original package's behavior for all test call-sites, and 68/68 inject-transport tests pass. The only notable nuance is the || in getValue which matches the original source and does not affect any current test case. tests/formAutoContent.ts — the getValue || idiom is the one spot worth a second look if callers ever pass falsy-valued { value, options } entries. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["Test calls formAutoContent(json)"]
B["Build FormData\n(unfold arrays, append fields)"]
C{"Any field is a\nStream or Buffer?"}
D["Return multipart\n{ payload: FormData, headers: form.getHeaders() }"]
E["Return urlencoded\n{ payload: Readable.from(stringify(json)), headers: content-type:urlencoded }"]
F["fastify.inject()\n.payload(form.payload)\n.headers(form.headers)"]
A --> B
B --> C
C -- yes --> D
C -- no --> E
D --> F
E --> F
style D fill:#d4edda
style E fill:#d4edda
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A["Test calls formAutoContent(json)"]
B["Build FormData\n(unfold arrays, append fields)"]
C{"Any field is a\nStream or Buffer?"}
D["Return multipart\n{ payload: FormData, headers: form.getHeaders() }"]
E["Return urlencoded\n{ payload: Readable.from(stringify(json)), headers: content-type:urlencoded }"]
F["fastify.inject()\n.payload(form.payload)\n.headers(form.headers)"]
A --> B
B --> C
C -- yes --> D
C -- no --> E
D --> F
E --> F
style D fill:#d4edda
style E fill:#d4edda
Reviews (1): Last reviewed commit: "Remove pre-monorepo node-renderer devDep..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/react-on-rails-pro-node-renderer/tests/formAutoContent.ts (1)
79-79: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueType-unsafe
as nevercasts onform.append.Bypasses type checking entirely for the call arguments. Acceptable for a test helper mimicking a loosely-typed library, but worth a narrower type (e.g.
string | Blob | Buffer | NodeJS.ReadableStream) if this helper grows.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/react-on-rails-pro-node-renderer/tests/formAutoContent.ts` at line 79, The form helper’s append call is using broad `as never` casts, which bypass type safety in `formAutoContent` and should be narrowed instead. Update the helper around `form.append` to use a more specific union type for the value/options arguments, or encapsulate the library’s loose typing in a typed helper so the call remains safe without casting everything to never.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/react-on-rails-pro-node-renderer/tests/formAutoContent.ts`:
- Around line 50-52: The getValue helper is treating valid falsy extracted
values as missing because it uses a fallback on getField(o, 'value') || o.
Update getValue so it returns the extracted value whenever the value field
exists, even if it is 0, empty string, or false, and only falls back to the
wrapper object when the field is actually absent. Use the getValue and getField
helpers in formAutoContent.ts to locate and adjust this logic.
- Around line 91-102: The urlencoded fallback in formAutoContent does not unwrap
`{ value, options }` entries, so fields are serialized incorrectly when no file
is present. Update the fallback path to normalize the same way as the multipart
branch by extracting each field’s actual value via the existing `getValue()` /
`getOptions()` logic before calling `stringify`, and keep the behavior
consistent in `formAutoContent` for both payload types.
---
Nitpick comments:
In `@packages/react-on-rails-pro-node-renderer/tests/formAutoContent.ts`:
- Line 79: The form helper’s append call is using broad `as never` casts, which
bypass type safety in `formAutoContent` and should be narrowed instead. Update
the helper around `form.append` to use a more specific union type for the
value/options arguments, or encapsulate the library’s loose typing in a typed
helper so the call remains safe without casting everything to never.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8a8e0b5c-591b-44bb-86a9-92f365beea9f
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (5)
packages/react-on-rails-pro-node-renderer/package.jsonpackages/react-on-rails-pro-node-renderer/tests/formAutoContent.tspackages/react-on-rails-pro-node-renderer/tests/healthEndpoints.test.tspackages/react-on-rails-pro-node-renderer/tests/uploadRaceCondition.test.tspackages/react-on-rails-pro-node-renderer/tests/worker.test.ts
💤 Files with no reviewable changes (1)
- packages/react-on-rails-pro-node-renderer/package.json
…ltipart builders The react-on-rails-pro-node-renderer package.json carried devDependencies and a script that arrived verbatim with the pre-monorepo package import (#2069) and are dead in the workspace today. This removes them and consolidates the test suite's two overlapping multipart form builders down to one. Changes (all dev-only; no runtime/published-artifact impact): - Remove unused jsdom devDep (^16.5.0). Nothing in src/ or tests/ imports jsdom; Jest runs with testEnvironment "node". Root jsdom (^22.1.0, used by root Jest's jsdom testEnvironment) and the pro dummy's jsdom (^16.4.0) are untouched. - Remove the broken "developing": "nps node-renderer.debug" script and the nps devDep that only served it. The package has no package-scripts.yml and the root one has no node-renderer namespace, so the alias could never resolve. nps stays where it is genuinely used (root, react_on_rails_pro, pro dummy). - Remove redundant @babel/eslint-parser devDep. Linting runs from the repo-root flat config, which already declares @babel/eslint-parser at root. - Consolidate multipart builders onto form-data (the streaming-capable library) and remove the form-auto-content devDep. form-auto-content was itself a thin wrapper around form-data and only worked for the fastify.inject() transport; form-data is the only builder that also supports the raw-http2 streaming transport (form.pipe()/getBoundary()) used by the streaming regression tests. A small local tests/formAutoContent.ts helper reproduces form-auto-content's exact { payload, headers } transform on top of form-data, so the ~18 formAutoContent({...}) call sites in healthEndpoints/uploadRaceCondition/worker tests stay byte-identical apart from the import. pnpm-lock.yaml regenerated (pnpm install --lockfile-only): the node-renderer importer stanza drops jsdom, nps, @babel/eslint-parser, and form-auto-content; the form-auto-content package snapshot (whose only extra transitive dep was form-data, which we keep) is fully removed. jsdom@16 and nps snapshots remain in the graph because other importers still require them. Validation: build, type-check, lint, prettier --check, and knip all green; the three consolidation-affected suites pass 68/68. (The four SSR-bundle-fixture suites that need react_on_rails_pro/spec/dummy/ssr-generated fail only for the missing prebuilt bundle in a fresh worktree; none import the changed code.) Fixes #4407 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ReviewThis PR removes four dead/redundant devDependencies from One finding, left as an inline comment on
Everything else — the dependency removals, the lockfile diff, the import path swaps in the three test files — looks correct and low-risk. |
Addresses bot review feedback on the new tests/formAutoContent.ts shim. Both
changes intentionally diverge from the original form-auto-content footguns; the
shim is now the authoritative builder for these tests and is more correct. No
existing test relied on the old behavior.
- getValue: detect a `{ value, options? }` wrapper by presence of the `value`
key instead of truthiness (`getField(o, 'value') || o`). The old form returned
the whole wrapper object for a falsy value (`0`, `false`, `''`); now the falsy
value round-trips correctly. (coderabbit MAJOR / greptile P2)
- urlencoded fallback: unwrap `{ value, options }` fields via getValue in the
no-file path too, mirroring the multipart path. Previously a wrapper field with
no file serialized as "[object Object]". Field extraction is now computed once
and shared by both paths for consistency. (coderabbit MINOR)
Adds tests/formAutoContent.test.ts (8 cases) asserting falsy `{ value: 0 }` /
`{ value: false }` / `{ value: '' }` round-trip in both the urlencoded and
multipart paths, and that a `{ value, options }` field unwraps in the urlencoded
fallback (no "[object Object]").
Validation: node-renderer consolidation suites (healthEndpoints,
uploadRaceCondition, worker) stay 68/68; the new shim suite passes 8/8 (76 total);
build, type-check, lint, prettier --check, and knip all green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6641579 to
3ac0008
Compare
size-limit report 📦
|
…nsport * origin/main: Remove pre-monorepo node-renderer devDep baggage; consolidate test multipart builders (#4435)
* origin/main: Remove pre-monorepo node-renderer devDep baggage; consolidate test multipart builders (#4435)
* origin/main: Remove pre-monorepo node-renderer devDep baggage; consolidate test multipart builders (#4435)
…derer-shutdown-restart * origin/main: Remove pre-monorepo node-renderer devDep baggage; consolidate test multipart builders (#4435)
…370' into codex/batch-e-loadable-stats-retry-4371 * origin/codex/batch-e-rsc-parser-flush-4370: Add cached static RSC helper and diagnostics (#4386) Fix Pro tag revalidation retry after delete failures (#4375) Fix node renderer graceful shutdown restarts (#4400) Improve release-finish dry-run fetch handling (#4441) Flush RSC payloads before incomplete HTML tails (#4379) Handle sync RSC route failures as fetch errors (#4393) Delete never-wired RenderRequest/JsCodeBuilder/RenderingStrategy layer (#4414) (#4437) Delegate deprecated base/ shims to capabilities/ instead of cloning (#4413) (#4436) Remove pre-monorepo node-renderer devDep baggage; consolidate test multipart builders (#4435) Preserve streaming LoadError during dependency failures (#4388) Wire eslint-rules RuleTester suite into a runner, CI, and knip (#4409) (#4433) Handle fire-and-forget RSCRoute retry failures (#4378)
…w-boundary * origin/main: (26 commits) [Pro] Extract async props settled chunk writer (#4448) Fix incorrect defer_generated_component_packs = false migration guidance (#4451) Fix Pro renderer transport memory and reuse (#4394) Fix Pro RSC loadable stats retry visibility (#4447) Unify Pro component cache fetch behavior (#4384) Replace chalk with picocolors in create-react-on-rails-app (#4411) (#4444) Fix Pro RSC stylesheet stats retry after read failures (#4401) [Pro] Reduce tag-index cache work during streaming (#4443) Warn on truncated Pro RSC parser streams (#4392) Report response-start send rejections (#4389) Add cached static RSC helper and diagnostics (#4386) Fix Pro tag revalidation retry after delete failures (#4375) Fix node renderer graceful shutdown restarts (#4400) Improve release-finish dry-run fetch handling (#4441) Flush RSC payloads before incomplete HTML tails (#4379) Handle sync RSC route failures as fetch errors (#4393) Delete never-wired RenderRequest/JsCodeBuilder/RenderingStrategy layer (#4414) (#4437) Delegate deprecated base/ shims to capabilities/ instead of cloning (#4413) (#4436) Remove pre-monorepo node-renderer devDep baggage; consolidate test multipart builders (#4435) Preserve streaming LoadError during dependency failures (#4388) ... # Conflicts: # CHANGELOG.md # packages/react-on-rails-pro/src/RSCProvider.tsx # packages/react-on-rails-pro/src/RSCRoute.tsx # packages/react-on-rails-pro/tests/boundedCacheProvider.client.test.tsx # packages/react-on-rails-pro/tests/getReactServerComponent.client.test.ts
Why
packages/react-on-rails-pro-node-renderer/package.jsonstill carried devDependencies and a script that arrived verbatim with the pre-monorepo package import (#2069) and are dead in the workspace today. This removes them and consolidates the test suite's two overlapping multipart form builders down to one. All changes are dev-only — no runtime code paths change and published-artifact contents are unaffected.Fixes #4407
What changed
jsdomdevDep (^16.5.0). Nothing insrc/ortests/imports jsdom (the only string matches are inside checked-in webpack fixture bundles undertests/fixtures/**, not imports). Jest runs withtestEnvironment: "node", so jsdom is never loaded. Rootjsdom(^22.1.0, used by root Jest'sjsdomtestEnvironment —jest.config.base.js) and the pro dummy'sjsdom(^16.4.0) are untouched."developing": "nps node-renderer.debug"script and thenpsdevDep that only served it. The package has nopackage-scripts.yml/.jsand the root one has nonode-renderernamespace, sonps node-renderer.debugcould never resolve.npsstays where it is genuinely used (root,react_on_rails_pro, pro dummy — all have realstart/npsscripts).@babel/eslint-parserdevDep. Linting runs from the repo-root flat config (eslint.config.ts), and the rootpackage.jsonalready declares@babel/eslint-parser. The package's ownbabel.config.jsuses presets only.form-data; removed theform-auto-contentdevDep.Consolidation direction (note: this differs from the issue's suggestion)
The issue proposed consolidating onto
form-auto-content. That is not viable: the node-renderer tests use two different transports, and onlyform-datasupports both.form-auto-contentreturns a static{ payload, headers }object for thefastify.inject()transport (in-process). Used byhealthEndpoints,uploadRaceCondition,workertests.form-datais used over rawhttp2requests and relies on its streaming API —form.getBoundary(),form.pipe(request),form.on('end'), and lazyfs.createReadStreamfile parts — inhttpRequestUtils.ts(shared helper forhtmlStreaming,incrementalHtmlStreaming,concurrentHtmlStreaming), and directly instreamClientDisconnectAbortandstreamErrorHang(the React 19.2cacheSignal: settle RSC cache cleanup on render complete/abort (child of #3865) #3885 abort / stream-error-hang regression tests).form-auto-contenthas no.pipe()/.getBoundary(), so it cannot serve the streaming tests. Crucially,form-auto-contentis itself a ~40-line wrapper aroundform-data(its only extra transitive dep isform-data). Soform-datais the correct single builder to standardize on, and the issue's own plan explicitly says "pick whichever the tests already lean on."To keep the change behavior-preserving and small, this PR adds a tiny local
tests/formAutoContent.tshelper that reproducesform-auto-content's exact public transform (array-value unfolding,{ value, options }pass-through, multipart-vs-urlencoded branch,form.getHeaders()) on top ofform-data. The ~18formAutoContent({...})call sites across the three inject-transport suites stay byte-identical apart from the import.Per-removal verification
jsdomgrep -rn jsdom src tests→ only fixture bundles;testEnvironment: nodenps+developingscriptpackage-scripts.yml; root has nonode-renderernamespace@babel/eslint-parserpackage.json+knip.tsalready own itform-auto-contentform-data; replaced by localform-data-backed shimform-data(kept)Validation (real results)
pnpm install --prefer-offlinepnpm --filter react-on-rails-pro-node-renderer run buildpnpm --filter react-on-rails-pro-node-renderer run type-checkpnpm run lintpnpm start format.listDifferent(prettier --check)pnpm run knippnpm exec knip --productionprop-typesfinding inreact_on_rails/spec/dummy(identical on main; not my change)jest healthEndpoints uploadRaceCondition worker formAutoContenttestThe 4 failing full-suite tests are a pre-existing fixture prerequisite, not this change
incrementalHtmlStreaming,concurrentHtmlStreaming,htmlStreaming, andserverRenderRSCReactComponentfail withENOENTonreact_on_rails_pro/spec/dummy/ssr-generated/server-bundle.js/rsc-bundle.js. That directory does not exist in a fresh worktree — it is produced bypnpm run build:test(a Rails/webpack precompile) that CI runs before this package's tests. This set is exactly the 4 SSR-bundle-fixture-dependent suites, and none of them import the changed code (three usehttpRequestUtils.ts→form-data, untouched; one has no multipart import). Every suite that actually exercises the consolidation passes.Codex Decision Log
codex review --base origin/main.tests/formAutoContent.tswas untracked, so a clean checkout would fail to resolve./formAutoContentafter removingform-auto-content. Resolution: staged and committed the helper (it is part of this PR). This was a "not-yet-committed" artifact of reviewing the tracked diff, not a design defect.no-npsin the package.bin(nps binary correctly gone). Behavior-preserving.Round 2 — bot review on the shim (commit
3ac0008e0)Bot reviewers flagged two footguns in
tests/formAutoContent.tsthat this PR intentionally fixes (the shim is now the authoritative builder for these tests and is more correct than the originalform-auto-content; no existing test relied on the old behavior):getValuefalsy wrappers → fixed.getField(o, 'value') || oreturned the whole{ value, options }wrapper when the value was falsy (0,false,''). Now detects the wrapper by presence of thevalueown-key (hasOwn(o, 'value') ? o.value : o), so falsy values round-trip. This matches the fix theclaudereviewer independently recommended (explicithasOwnProperty, not||/??).{ value, options }field with no file serialized as[object Object]. Field extraction is now computed once and shared, so the urlencoded path unwraps wrappers just like the multipart path.tests/formAutoContent.test.ts(8 cases) asserts falsy{ value: 0 | false | '' }round-trips in both the urlencoded and multipart paths, and that a{ value, options }field unwraps in the urlencoded fallback.6641579e3. All three review threads resolved; 0 unresolved threads on current head.Lockfile evidence
pnpm install --lockfile-only. Net change:pnpm-lock.yaml, 21 deletions, 0 insertions.jsdom@^16.5.0,nps@^5.9.12,@babel/eslint-parser@^7.27.0,form-auto-content@^3.2.1.form-auto-content@3.2.1(both the resolution entry and its dependency block) — nothing else in the monorepo used it. Its only extra transitive dependency wasform-data@4.0.6, which we keep, so no capability is lost.fast-querystringwas pulled only by form-auto-content but remains in the graph via other importers.jsdom@16.7.0(still required byreact_on_rails_pro/spec/dummy^16.4.0),nps@5.10.0(root +react_on_rails_pro+ pro dummy^5.9.3),@babel/eslint-parser(root). Removing the node-renderer's redundant pins left no orphans.jsdom@16, and its snapshot was not dropped (still needed by the pro dummy), so no source-build / platform-precompiled transitive set changed as a result of this PR.form-auto-contentis pure JS with no native deps.react_on_rails_pro, pro dummy) — each removal was confirmed redundant only for the node-renderer, never for the packages that genuinely consume it..github/dependabot.yml(npm ecosystem). This PR reduces its devDep surface by four entries; no version bumps, only removals.Labels: ready-for-hosted-ci — dep + lockfile change trips the generator gate, which requires hosted CI to validate the regenerated
pnpm-lock.yaml.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Chores