Skip to content

Commit 25cde38

Browse files
justin808claude
andauthored
fix: scan .mts and .cts in Pro migration base-package check (#3250) (#3334)
## Summary Follow-up to [PR #3232](#3232). The Pro migration base-package reference scan now covers TypeScript 4.7 `.mts` / `.cts` source files (and their `.d.mts` / `.d.cts` declaration counterparts), matching the existing `.mjs` / `.cjs` coverage. - Adds `mts` and `cts` to `ReactOnRails::ProMigration::JS_SOURCE_EXTENSIONS`. This shared constant drives both `react_on_rails:doctor`'s stale-reference scanner and the Pro generator's import rewriter, so the doctor warns on and the generator can rewrite the new extensions in one step. - `**/*.mts` / `**/*.cts` globs naturally cover `*.d.mts` / `*.d.cts` declaration files, same as `.ts` covers `.d.ts`. - Existing `react-on-rails-pro` false-positive guards (the `(?:/[^'"]*)?['"]` lookahead in every reference pattern) carry over unchanged. Fixes #3250. ## Test plan - [x] `bundle exec rspec spec/lib/react_on_rails/doctor_spec.rb -e "check_base_package_references"` — 34 examples, 0 failures (includes 2 new specs) - [x] `bundle exec rspec spec/react_on_rails/generators/pro_generator_spec.rb` — 122 examples, 0 failures - [x] `bundle exec rubocop lib/react_on_rails/pro_migration.rb spec/lib/react_on_rails/doctor_spec.rb` — no offenses - [x] New positive spec: stale `react-on-rails` references in `.mts`, `.cts`, `.d.mts`, and `.d.cts` files all surface as warnings - [x] New negative spec: `.mts`/`.cts`/`.d.mts` files referencing `react-on-rails-pro` are not flagged <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: expands file-extension globbing for Pro migration/doctor scans and adds regression tests; no runtime rendering or security-sensitive logic changes. > > **Overview** > Extends the Pro migration/`react_on_rails:doctor` base-package reference scan to include TypeScript 4.7 module extensions `*.mts`/`*.cts` (including `*.d.mts`/`*.d.cts` via globbing), matching existing `*.mjs`/`*.cjs` coverage. > > Adds RSpec coverage to ensure `.mts`/`.cts` files with stale `react-on-rails` references are flagged and that correct `react-on-rails-pro` references are not, and documents the fix in `CHANGELOG.md`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a1bc6f9. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Development tools now scan additional TypeScript module formats (.mts/.cts) and their declarations. * **Documentation** * Changelog updated to reflect expanded TypeScript module coverage. * **Tests** * Test coverage extended to validate scanning and warnings for the new TypeScript module formats. <!-- review_stack_entry_start --> [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/shakacode/react_on_rails/pull/3334?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c7a5193 commit 25cde38

3 files changed

Lines changed: 59 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ After a release, run `/update-changelog` in Claude Code to analyze commits, writ
4848

4949
- **[Pro]** **Allow patched ruby-jwt releases**: React on Rails Pro now requires `jwt >= 3.2.0`, removing the previous `~> 2.7` cap so applications can resolve the patched ruby-jwt release for the empty-key HMAC advisory. [PR 3322](https://github.com/shakacode/react_on_rails/pull/3322) by [ihabadham](https://github.com/ihabadham).
5050
- **[Pro]** **Pro migration generator rewrites all base-package references and preserves Gemfile pins**: `rails generate react_on_rails:pro` now rewrites Jest/Vitest mock helpers (`jest.mock`, `vi.mock`, `requireActual`/`importActual`, and the rest) and TypeScript `declare module 'react-on-rails'` blocks alongside its existing `import`/`require`/dynamic-import handling, and the Gemfile swap now preserves the user's existing version pin (and other gem options) instead of overwriting them with the running gem's version. `react_on_rails:doctor` is widened to match: it also flags stale side-effect imports (`import 'react-on-rails';`), Jest/Vitest mock helpers, and `declare module` blocks, and the new side-effect-import pattern keeps the doctor a superset of the rewriter so anything the rewriter doesn't reach gets surfaced. Closes [Issue 3104](https://github.com/shakacode/react_on_rails/issues/3104). [PR 3232](https://github.com/shakacode/react_on_rails/pull/3232) by [justin808](https://github.com/justin808).
51+
- **[Pro]** **Pro migration scans TypeScript 4.7 `.mts` and `.cts` modules**: `react_on_rails:doctor` and the Pro migration rewriter now include `.mts`/`.cts` source files (and their `.d.mts`/`.d.cts` declaration counterparts) when looking for stale `react-on-rails` references, matching the existing `.mjs`/`.cjs` coverage. Fixes [Issue 3250](https://github.com/shakacode/react_on_rails/issues/3250). [PR 3334](https://github.com/shakacode/react_on_rails/pull/3334) by [justin808](https://github.com/justin808).
5152
- **Doctor now honors nested JavaScript package roots**: `react_on_rails:doctor` now checks package-manager lockfiles, `package.json`, and installed React from the configured `node_modules_location`, reducing false diagnostics for legacy apps that keep dependencies under `client/`. The Vite migration guide now documents the supported thin-wrapper pattern for those layouts. Note: a missing `package.json` at the configured `node_modules_location` now emits a warning instead of being silently skipped, so apps misconfigured against a nonexistent path will see new diagnostics on upgrade. Fixes [Issue 3205](https://github.com/shakacode/react_on_rails/issues/3205). [PR 3220](https://github.com/shakacode/react_on_rails/pull/3220) by [justin808](https://github.com/justin808).
5253
- **Generated pack regeneration is now serialized**: `generate_packs_if_stale` now uses a Rails `tmp/` lock file, re-checks staleness after waiting, and avoids concurrent cleanup/regeneration races when multiple processes trigger auto-bundling at the same time. Fixes [Issue 1627](https://github.com/shakacode/react_on_rails/issues/1627). [PR 3231](https://github.com/shakacode/react_on_rails/pull/3231) by [justin808](https://github.com/justin808).
5354
- **Install generator validates the selected JavaScript package manager**: The install generator now checks the manager selected from `REACT_ON_RAILS_PACKAGE_MANAGER`, the `packageManager` field in `package.json`, or a lockfile on disk — instead of passing when any JavaScript package manager is installed. When the selected command is missing, the error names the selected manager, the source that selected it, and the available alternatives. The generator also warns when `REACT_ON_RAILS_PACKAGE_MANAGER` is set to a value outside the supported set (`npm`, `pnpm`, `yarn`, `bun`). Addresses package manager validation from [Issue 1958](https://github.com/shakacode/react_on_rails/issues/1958). [PR 3229](https://github.com/shakacode/react_on_rails/pull/3229) by [justin808](https://github.com/justin808).

react_on_rails/lib/react_on_rails/pro_migration.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module ReactOnRails
44
# Shared Pro migration facts and Gemfile parsing used by the generator and doctor.
55
module ProMigration
66
JS_SOURCE_ROOTS = %w[app/javascript app/frontend frontend javascript client].freeze
7-
JS_SOURCE_EXTENSIONS = %w[js jsx ts tsx mjs cjs vue svelte].freeze
7+
JS_SOURCE_EXTENSIONS = %w[js jsx ts tsx mjs cjs mts cts vue svelte].freeze
88

99
JEST_MODULE_SPECIFIER_METHOD_NAMES = %w[
1010
createMockFromModule

react_on_rails/spec/lib/react_on_rails/doctor_spec.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3841,6 +3841,63 @@ def self.upload(_hash, **_opts); end
38413841
end
38423842
end
38433843

3844+
context "when TypeScript module files use .mts or .cts extensions after a Pro migration" do
3845+
around do |example|
3846+
Dir.mktmpdir do |tmpdir|
3847+
Dir.chdir(tmpdir) do
3848+
FileUtils.mkdir_p("app/javascript/packs")
3849+
FileUtils.mkdir_p("app/javascript/types")
3850+
File.write("app/javascript/packs/esm-entry.mts",
3851+
"import ReactOnRails from 'react-on-rails';\n")
3852+
File.write("app/javascript/packs/cjs-entry.cts",
3853+
"const ReactOnRails = require('react-on-rails/client');\n")
3854+
File.write("app/javascript/types/react-on-rails.d.mts",
3855+
"declare module 'react-on-rails' {\n export function register(): void;\n}\n")
3856+
File.write("app/javascript/types/react-on-rails.d.cts",
3857+
"declare module 'react-on-rails/client' {\n export function register(): void;\n}\n")
3858+
example.run
3859+
end
3860+
end
3861+
end
3862+
3863+
it "reports warning for each TypeScript module and declaration file" do
3864+
doctor.send(:check_base_package_references)
3865+
warning_content = checker.messages.select { |m| m[:type] == :warning }.map { |m| m[:content] }.join("\n")
3866+
expect(warning_content).to include("esm-entry.mts")
3867+
expect(warning_content).to include("cjs-entry.cts")
3868+
expect(warning_content).to include("react-on-rails.d.mts")
3869+
expect(warning_content).to include("react-on-rails.d.cts")
3870+
end
3871+
end
3872+
3873+
context "when .mts or .cts files correctly reference 'react-on-rails-pro'" do
3874+
around do |example|
3875+
Dir.mktmpdir do |tmpdir|
3876+
Dir.chdir(tmpdir) do
3877+
FileUtils.mkdir_p("app/javascript/packs")
3878+
FileUtils.mkdir_p("app/javascript/types")
3879+
File.write("app/javascript/packs/esm-entry.mts",
3880+
"import ReactOnRails from 'react-on-rails-pro';\n")
3881+
File.write("app/javascript/packs/cjs-entry.cts",
3882+
"const ReactOnRails = require('react-on-rails-pro/client');\n")
3883+
File.write("app/javascript/types/react-on-rails-pro.d.mts",
3884+
"declare module 'react-on-rails-pro' {\n export function register(): void;\n}\n")
3885+
File.write("app/javascript/types/react-on-rails-pro.d.cts",
3886+
"declare module 'react-on-rails-pro/client' {\n export function register(): void;\n}\n")
3887+
example.run
3888+
end
3889+
end
3890+
end
3891+
3892+
it "reports success without flagging Pro references" do
3893+
doctor.send(:check_base_package_references)
3894+
warning_msgs = checker.messages.select { |m| m[:type] == :warning }
3895+
success_msgs = checker.messages.select { |m| m[:type] == :success }
3896+
expect(warning_msgs).to be_empty
3897+
expect(success_msgs.any? { |m| m[:content].include?("Pro package used correctly") }).to be true
3898+
end
3899+
end
3900+
38443901
context "when one scanned file has invalid UTF-8 content" do
38453902
around do |example|
38463903
Dir.mktmpdir do |tmpdir|

0 commit comments

Comments
 (0)