fix: verify native prebuild fixtures - #426
Conversation
|
Sorry, this needs a rebase now 🙈 |
33ca234 to
2d4f74f
Compare
|
Rebased onto the latest Re-ran:
Everything passes locally. The GitHub Actions workflow is currently awaiting maintainer approval. |
|
I pushed a few follow-up refinements (moving the Partially generated by Claude Code |
- Replace the Babel-transform-time require.resolve() guard with a check inside isNodeApiModule itself, so the fix lives in the shared utility (also used by findNodeAddonForBindings) instead of duplicating Node's module resolution algorithm via a second, independent code path that could diverge from what Metro actually resolves at runtime. - Verify the Info.plist contents with a zod schema instead of ad hoc "in" checks on an untyped object, matching how the rest of the repo validates untrusted structured data. - Reuse the exported escapeBundleIdentifier instead of re-deriving the bundle-identifier escaping regex inline in the verify script, so the two can't silently drift apart. Closes callstackincubator#424 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q1k6UQJPPaqKEKmnsRUatt
a848741 to
7e212f5
Compare
kraenhansen
left a comment
There was a problem hiding this comment.
Verified this against next and I think it fully closes #424:
- Info.plist gap:
verifyFrameworkInfoPlistassertsCFBundleExecutable/CFBundleIdentifieragainst exactly whatwriteFrameworkInfoPlist(packages/host/src/node/prebuilds/apple.ts) writes, reusing the same exportedescapeBundleIdentifierhelper on both sides so the check can't silently drift from the writer. - Missing
.nodefixture gap: the newmy-addon.nodefixture inplugin.test.tsgenuinely exercises precedence, not just decorates the test. Before theisNodeApiModuleguard added inpath-utils.ts, adding that fixture alone (without the fix) would make the pre-existing shortcut check (fs.accessSync(modulePath + '.node')) returntruefirst and fail the "does not touch required JS files" assertion — so the fixture and the fix are load-bearing together, confirming the original issue's claim that the old test passed for the wrong reason.
CI is green (Lint + Unit tests on ubuntu/macos/windows all success; the native app/device jobs show skipped, which is expected for a fork PR without the runner secrets/labels), mergeable_state is clean, and it's already got a maintainer approval.
One minor, non-blocking note for a possible follow-up: COLLIDING_SOURCE_EXTENSIONS includes .cjs/.mjs alongside .js/.json, with a comment attributing the list to "extensions Node's own require() resolves before ever trying .node". Node's documented LOAD_AS_FILE algorithm for an extensionless require() only tries .js, .json, then .node — not .mjs/.cjs — and per docs/HOW-IT-WORKS.md the actual runtime resolution here is Metro's bundler anyway, whose default sourceExts likewise don't include mjs/cjs. So a sibling foo.cjs/foo.mjs wouldn't actually shadow foo.node the way the guard assumes. This only makes the plugin more conservative than necessary (it could skip transforming a real addon require()), not a regression of the bug #424 describes, so it doesn't block merging — just a slightly inaccurate rationale comment worth tightening sometime.
Generated by Claude Code
Summary
Info.plistand verify its executable and bundle identifier.nodefixture to the Babel plugin testTest plan
pnpm run buildpnpm --filter react-native-node-api test(61 tests passed)pnpm exec eslint packages/host/src/node/babel-plugin/plugin.ts packages/host/src/node/babel-plugin/plugin.test.ts packages/node-addon-examples/scripts/verify-prebuilds.mtspnpm run prettier:checkCloses #424