Skip to content

fix: use node resolver to prevent escaped traversal errors#506

Merged
Brentlok merged 1 commit intomainfrom
fix/metro-resolver
Apr 22, 2026
Merged

fix: use node resolver to prevent escaped traversal errors#506
Brentlok merged 1 commit intomainfrom
fix/metro-resolver

Conversation

@Brentlok
Copy link
Copy Markdown
Contributor

@Brentlok Brentlok commented Apr 22, 2026

fixes #505

Summary by CodeRabbit

  • Chores
    • Optimized internal module resolution mechanism for improved reliability.
    • Updated internal linting configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

Updated a lint suppression comment in the config builder and refactored the computation of the internal base path in Metro resolvers by replacing context-dependent resolver calls with Node's require.resolve, adding error handling, and removing unused imports.

Changes

Cohort / File(s) Summary
Lint Suppression Update
packages/uniwind/src/core/config/config.common.ts
Changed lint suppression comment on updateInsets(insets: Insets) parameter from typescript/no-redundant-type-constituents to typescript/no-unused-vars to reflect intentional parameter non-usage.
Metro Base Path Resolution
packages/uniwind/src/metro/resolvers.ts
Replaced Metro resolver-based computation of cachedInternalBasePath with context-independent require.resolve('uniwind/package.json') wrapped in try/catch fallback. Removed unused join import and added clarifying blank line in webResolver initialization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested reviewers

  • jpudysz

Poem

🐰 A Metro path that once did roam,
Now finds its uniwind home,
No more traversal escapes the call,
require.resolve fixes it all!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: use node resolver to prevent escaped traversal errors' accurately reflects the main change: replacing Metro's resolver with Node's resolver to fix the traversal error issue described in #505.
Linked Issues check ✅ Passed The PR fully implements the coding requirements from issue #505: replaces Metro resolver with Node's require.resolve for both nativeResolver and webResolver paths with appropriate try/catch fallbacks.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the Metro traversal error. The lint suppression update and blank line addition in config.common.ts are supporting changes that align with the core fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/metro-resolver

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
packages/uniwind/src/metro/resolvers.ts (1)

47-53: Consider extracting the duplicated base-path resolution.

The identical try/catch block is duplicated in both nativeResolver (lines 47-53) and webResolver (lines 95-101). A small helper would keep both paths in sync if the strategy evolves again.

♻️ Proposed refactor
 let cachedInternalBasePath: string | null = null
+
+const getInternalBasePath = () => {
+    if (cachedInternalBasePath === null) {
+        try {
+            cachedInternalBasePath = dirname(require.resolve('uniwind/package.json'))
+        } catch {
+            cachedInternalBasePath = ''
+        }
+    }
+    return cachedInternalBasePath
+}

Then replace both inline blocks with const basePath = getInternalBasePath() and use basePath in the subsequent checks.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/uniwind/src/metro/resolvers.ts` around lines 47 - 53, Extract the
duplicated try/catch resolution into a small helper (e.g., getInternalBasePath)
that returns the dirname of require.resolve('uniwind/package.json') or '' on
failure and uses a module-scoped cache similar to cachedInternalBasePath; then
replace the inline blocks inside nativeResolver and webResolver with const
basePath = getInternalBasePath() (or use the cached value returned) and update
subsequent checks to reference basePath so both resolvers share the same
resolution logic.
packages/uniwind/src/core/config/config.common.ts (1)

104-107: Lint suppression correction is appropriate; underscore prefix would align with existing conventions.

The change to typescript/no-unused-vars correctly addresses the unused parameter. However, this file already uses underscore prefixes for intentionally unused parameters (line 109: _: GenerateStyleSheetsCallback), while updateInsets and updateCSSVariables use lint suppression comments. For consistency:

Optional refactor for consistency
-    // oxlint-disable-next-line typescript/no-unused-vars
-    updateInsets(insets: Insets) {
+    updateInsets(_insets: Insets) {
         // noop
     }

This matches the pattern at line 109 and eliminates the suppression comment entirely.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/uniwind/src/core/config/config.common.ts` around lines 104 - 107,
Replace the inline lint suppression for unused parameters with the
underscore-prefixed parameter naming used elsewhere: change the signatures of
updateInsets(insets: Insets) and updateCSSVariables(cssVars: CSSVariables) to
use _insets and _cssVars respectively (matching the existing pattern used for _:
GenerateStyleSheetsCallback) so the compiler understands the parameters are
intentionally unused and the types remain declared without needing the
typescript/no-unused-vars disable comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/uniwind/src/core/config/config.common.ts`:
- Around line 104-107: Replace the inline lint suppression for unused parameters
with the underscore-prefixed parameter naming used elsewhere: change the
signatures of updateInsets(insets: Insets) and updateCSSVariables(cssVars:
CSSVariables) to use _insets and _cssVars respectively (matching the existing
pattern used for _: GenerateStyleSheetsCallback) so the compiler understands the
parameters are intentionally unused and the types remain declared without
needing the typescript/no-unused-vars disable comment.

In `@packages/uniwind/src/metro/resolvers.ts`:
- Around line 47-53: Extract the duplicated try/catch resolution into a small
helper (e.g., getInternalBasePath) that returns the dirname of
require.resolve('uniwind/package.json') or '' on failure and uses a
module-scoped cache similar to cachedInternalBasePath; then replace the inline
blocks inside nativeResolver and webResolver with const basePath =
getInternalBasePath() (or use the cached value returned) and update subsequent
checks to reference basePath so both resolvers share the same resolution logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 822e3733-db72-4ec8-9494-0126e361004a

📥 Commits

Reviewing files that changed from the base of the PR and between 00df11b and d04279b.

📒 Files selected for processing (2)
  • packages/uniwind/src/core/config/config.common.ts
  • packages/uniwind/src/metro/resolvers.ts

@Brentlok Brentlok merged commit 8e0f8cc into main Apr 22, 2026
2 checks passed
@Brentlok Brentlok deleted the fix/metro-resolver branch April 22, 2026 06:27
@github-actions
Copy link
Copy Markdown
Contributor

🚀 This pull request is included in v1.6.3. See Release v1.6.3 for release notes.

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.

Metro Unexpectedly escaped traversal invariant in nativeResolver during Expo eager bundle

1 participant