Uh oh!
There was an error while loading. Please reload this page.
fix: resolve env-only functions through module re-export chains - #6599
Conversation
📝 WalkthroughWalkthroughRemoves the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
View your CI Pipeline Execution ↗ for commit 16283f8
☁️ Nx Cloud last updated this comment at |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/start-plugin-core/tests/compiler.test.ts`:
- Around line 502-520: The declaration for the StartCompiler instance uses "let
compiler" but is never reassigned; change it to "const compiler" in the test to
satisfy prefer-const. Update both occurrences where the StartCompiler is created
(the first assignment using new StartCompiler and the later similar block around
lines ~594-612) so the variable is declared with const while keeping the same
object construction and options (references: the compiler variable and
StartCompiler constructor).
Uh oh!
There was an error while loading. Please reload this page.
1ab4313 to
16283f8CompareUh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/start-plugin-core/src/start-compiler-plugin/compiler.ts`:
- Around line 1166-1174: The direct-call handling treating any Identifier with a
resolved calleeKind as a factory call is misclassifying identifiers that are the
result of a factory invocation; update the Identifier branch (where you check
t.isIdentifier(expr.callee), this.validLookupKinds, and calleeKind) to guard
against bindings whose initializer is a CallExpression: look up the Identifier's
binding (via the current scope/binding APIs used by resolveBindingKind), and if
binding.path.node.init is a CallExpression (meaning the identifier was created
by calling a factory), do NOT accept calleeKind as a factory call; only accept
the calleeKind when the Identifier traces back to an import/alias (not an
initialized CallExpression). Ensure this guard is applied before returning
calleeKind so we don’t rewrite invocations of already-created env-only
functions.
| // For direct calls (callee is Identifier like createServerOnlyFn()), | ||
| // trust calleeKind if it resolved to a valid LookupKind. This means | ||
| // resolveBindingKind successfully traced the import back to | ||
| // @tanstack/start-fn-stubs (via fast path or slow path through re-exports). | ||
| // This handles both direct imports from @tanstack/react-start and imports | ||
| // from intermediate packages that re-export from @tanstack/start-client-core. | ||
| if (t.isIdentifier(expr.callee)) { | ||
| const isFactoryImport = await this.isKnownFactoryImport( | ||
| expr.callee.name, | ||
| fileId, | ||
| ) | ||
| if ( | ||
| isFactoryImport && | ||
| this.validLookupKinds.has(calleeKind as LookupKind) | ||
| ) { | ||
| if (this.validLookupKinds.has(calleeKind as LookupKind)) { | ||
| return calleeKind |
There was a problem hiding this comment.
Guard direct-call rewrites against identifiers bound to factory results.
With the new Identifier path (Line 1166), any Identifier that resolves to a LookupKind is treated as a factory call. This can misclassify a top-level invocation of an already-created env-only function, e.g.:const init = createClientOnlyFn(...); const result = init();init() now resolves to ClientOnlyFn and may be rewritten as if it were a factory call, which is incorrect and can drop/alter arguments.
Consider only accepting Identifier direct calls that trace back to an import/alias, not a binding whose init is itself a CallExpression.
🛠️ Suggested guard to avoid factory-result calls
if (t.isIdentifier(expr.callee)) {
if (this.validLookupKinds.has(calleeKind as LookupKind)) {
+ const info = await this.getModuleInfo(fileId)+ const binding = info.bindings.get(expr.callee.name)+ if (binding?.type === 'var' && t.isCallExpression(binding.init)) {+ return 'None'+ }
return calleeKind
}
}🤖 Prompt for AI Agents
In `@packages/start-plugin-core/src/start-compiler-plugin/compiler.ts` around
lines 1166 - 1174, The direct-call handling treating any Identifier with a
resolved calleeKind as a factory call is misclassifying identifiers that are the
result of a factory invocation; update the Identifier branch (where you check
t.isIdentifier(expr.callee), this.validLookupKinds, and calleeKind) to guard
against bindings whose initializer is a CallExpression: look up the Identifier's
binding (via the current scope/binding APIs used by resolveBindingKind), and if
binding.path.node.init is a CallExpression (meaning the identifier was created
by calling a factory), do NOT accept calleeKind as a factory call; only accept
the calleeKind when the Identifier traces back to an import/alias (not an
initialized CallExpression). Ensure this guard is applied before returning
calleeKind so we don’t rewrite invocations of already-created env-only
functions.
fixes#6583
Summary by CodeRabbit
Bug Fixes
Tests