-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
refactor: consolidate start compiler #6210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📝 WalkthroughWalkthroughConsolidates server-function and directive-function plugins into a new start-compiler-plugin, removes two standalone plugin packages, renames virtual module manifest → resolver, adds batch-processed compiler handlers and utilities, updates tests and snapshots to use RPC wrappers and the StartCompiler, and adds a type augmentation for react-start SSR router types. Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer Code (source files / compiler)
participant Vite as Vite Plugin System
participant Compiler as StartCompiler
participant Resolver as ServerFn Resolver (virtual module)
participant Client as App (client/runtime)
rect rgb(240,248,255)
Dev->>Vite: install startCompilerPlugin
Vite->>Compiler: initialize per-env compiler (envName, providerEnvName)
end
rect rgb(245,255,240)
Note over Compiler,Dev: Static analysis phase (build/dev)
Compiler->>Compiler: collect RewriteCandidates from AST
Compiler->>Compiler: group by LookupKind and dispatch to KindHandlers
KindHandlers-->>Compiler: produce replacements (RPC stubs, extracted fns)
end
rect rgb(255,250,240)
Compiler->>Resolver: register/discover server handlers (onServerFnsById)
Resolver->>Client: expose getServerFnById / SSR RPC endpoints (virtual module)
Client->>Resolver: createClientRpc / createSsrRpc call → resolve handler id
Resolver->>Client: return handler invocation (dynamic import or HTTP)
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx affected --targets=test:eslint,test:unit,tes... |
❌ Failed | 8m 55s | View ↗ |
nx run-many --target=build --exclude=examples/*... |
✅ Succeeded | 20s | View ↗ |
☁️ Nx Cloud last updated this comment at 2025-12-24 22:38:06 UTC
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (11)
e2e/react-start/basic/src/routeTree.gen.ts (1)
1021-1022: Remove the unusedcreateStartimport or verify it's intentionally generated.The import at line 1022 resolves correctly to
@tanstack/react-start, butcreateStartis never used in the module augmentation block or elsewhere in this file. SincerouteTree.gen.tsis auto-generated, this unused import likely originates from the route generator—either remove it from the generator's output or confirm it's needed for future use.packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts (4)
208-208: Unsafe type assertion may cause runtime issues.The type assertion
as [string]assumescontext.id.split('?')always returns at least one element. Whilespliton a non-empty string always returns at least one element, the assertion hides this assumption. Consider using a safer approach:🔎 Suggested improvement
- const [baseFilename] = context.id.split('?') as [string] + const baseFilename = context.id.split('?')[0]!The non-null assertion (
!) is more idiomatic for this case sincesplitalways returns at least one element, and it's clearer about the assumption being made.
219-221: Consider usingcodeFrameErrorfor consistent error reporting.Other validation errors in this function use
codeFrameErrorto provide source location context, but this error uses a plainError. For consistency and better developer experience, consider usingcodeFrameErrorhere as well.🔎 Suggested improvement
// Check if the call is assigned to a variable if (!candidatePath.parentPath.isVariableDeclarator()) { - throw new Error('createServerFn must be assigned to a variable!') + throw codeFrameError( + context.code, + candidatePath.node.loc!, + 'createServerFn must be assigned to a variable!', + ) }
444-451: Edge case:makeIdentifierSafemay return empty string.If the input consists entirely of unsafe characters followed by underscores, the function could return an empty string after all the replacements and trimming, which would be an invalid identifier.
🔎 Suggested defensive handling
function makeIdentifierSafe(identifier: string): string { - return identifier + const safe = identifier .replace(/[^a-zA-Z0-9_$]/g, '_') // Replace unsafe chars with underscore .replace(/^[0-9]/, '_$&') // Prefix leading number with underscore .replace(/^\$/, '_$') // Prefix leading $ with underscore .replace(/_{2,}/g, '_') // Collapse multiple underscores .replace(/^_|_$/g, '') // Trim leading/trailing underscores + return safe || '_anonymous' }
489-492: Consider handlingundefineddeclaration in addition tonull.The check
node.declaration === nullmay not catch all cases. In TypeScript's Babel types,declarationcan benull | undefinedfor named exports likeexport { foo }. Consider using a falsy check for robustness.🔎 Suggested fix
- } else if (node.declaration === null) { + } else if (!node.declaration) { // remove e.g. `export { RouteComponent as component }` return [] }packages/start-plugin-core/tests/clientOnlyJSX/clientOnlyJSX.test.ts (1)
10-20: Consider extractinggetDefaultTestOptionsto a shared test utility.This helper is duplicated identically across multiple test files (
clientOnlyJSX.test.ts,createIsomorphicFn.test.ts,envOnly.test.ts, etc.). Extract it to a shared module liketests/test-utils.tsto reduce duplication and centralize test configuration.🔎 Example shared utility
// tests/test-utils.ts export function getDefaultTestOptions(env: 'client' | 'server') { const envName = env === 'client' ? 'client' : 'ssr' return { envName, root: '/test', directiveSplitParam: 'tsr-directive-use-server', framework: 'react' as const, providerEnvName: 'ssr', } }packages/start-plugin-core/src/start-compiler-plugin/handleCreateIsomorphicFn.ts (1)
27-32: Consider using a structured logger instead ofconsole.warn.Using
console.warndirectly may make it difficult to control log output in production or testing environments. If there's a logging utility available in the codebase, consider using it for consistency.packages/start-plugin-core/src/start-compiler-plugin/handleEnvOnly.ts (1)
5-8: Consider using a standard utility forcapitalize.This simple helper could be replaced with a well-known utility if available in the project's dependencies (e.g., lodash's
capitalize). However, given the minimal scope, this inline implementation is acceptable.packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts (1)
30-37: Consider extracting effectiveId logic into a named helper for clarity.The nested ternary logic for computing
effectiveIdis correct but dense. Consider extracting to a small helper function to improve readability:🔎 Optional refactor for clarity
+function computeEffectiveId(id: string, isProviderFile: boolean): string { + if (isProviderFile) { + return id.includes(TSS_SERVERFN_SPLIT_PARAM) + ? id + : `${id.split('?')[0]}?${TSS_SERVERFN_SPLIT_PARAM}` + } + return id.includes(TSS_SERVERFN_SPLIT_PARAM) + ? id.split('?')[0]! + : id +} async function compile(opts: { env: 'client' | 'server' code: string id: string isProviderFile: boolean }) { - // If isProviderFile is true, ensure the id contains the split param - const effectiveId = opts.isProviderFile - ? opts.id.includes(TSS_SERVERFN_SPLIT_PARAM) - ? opts.id - : `${opts.id.split('?')[0]}?${TSS_SERVERFN_SPLIT_PARAM}` - : opts.id.includes(TSS_SERVERFN_SPLIT_PARAM) - ? opts.id.split('?')[0]! // Remove split param if not provider - : opts.id + const effectiveId = computeEffectiveId(opts.id, opts.isProviderFile)packages/start-plugin-core/src/start-compiler-plugin/plugin.ts (1)
110-168: Consider escapingfunctionNamein generated code.The
functionNameis directly interpolated into the generated JavaScript string on lines 117 and 155. While these values are internally generated and should be safe identifiers, defensive escaping would prevent potential issues if naming patterns change.🔎 Suggested improvement
const manifestEntries = Object.entries(directiveFnsById) .map(([id, fn]) => { - const baseEntry = `'${id}': { - functionName: '${fn.functionName}', + const baseEntry = `'${id}': { + functionName: ${JSON.stringify(fn.functionName)}, importer: () => import(${JSON.stringify(fn.extractedFilename)})${Similarly on line 155:
- const action = fnModule[serverFnInfo.functionName] + const action = fnModule[serverFnInfo.functionName](Line 155 is fine since
functionNameis already in the manifest object)packages/start-plugin-core/src/start-compiler-plugin/types.ts (1)
57-65: Consider using optional properties instead of null forMethodChainPaths.The current design uses
| nullfor each property. Consider using optional properties (?:) which is more idiomatic for TypeScript when fields may be absent:🔎 Alternative pattern
export interface MethodChainPaths { middleware?: MethodCallInfo inputValidator?: MethodCallInfo handler?: MethodCallInfo server?: MethodCallInfo client?: MethodCallInfo }This would change access patterns from checking
!== nullto using optional chaining, which is more idiomatic. However, explicitnullis also valid if the intent is to distinguish "not present" from "not yet checked."
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
-
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (63)
e2e/react-start/basic/src/routeTree.gen.tslabeler-config.ymlpackage.jsonpackages/directive-functions-plugin/README.mdpackages/directive-functions-plugin/eslint.config.jspackages/directive-functions-plugin/package.jsonpackages/directive-functions-plugin/src/compilers.tspackages/directive-functions-plugin/src/index.tspackages/directive-functions-plugin/tests/compiler.test.tspackages/directive-functions-plugin/tsconfig.jsonpackages/directive-functions-plugin/vite.config.tspackages/react-router/package.jsonpackages/server-functions-plugin/README.mdpackages/server-functions-plugin/eslint.config.jspackages/server-functions-plugin/package.jsonpackages/server-functions-plugin/src/index.tspackages/server-functions-plugin/tests/index.test.tspackages/server-functions-plugin/tsconfig.jsonpackages/server-functions-plugin/vite.config.tspackages/start-plugin-core/package.jsonpackages/start-plugin-core/src/create-server-fn-plugin/handleCreateIsomorphicFn.tspackages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.tspackages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.tspackages/start-plugin-core/src/create-server-fn-plugin/handleEnvOnly.tspackages/start-plugin-core/src/create-server-fn-plugin/plugin.tspackages/start-plugin-core/src/create-server-fn-plugin/types.tspackages/start-plugin-core/src/create-server-fn-plugin/utils.tspackages/start-plugin-core/src/plugin.tspackages/start-plugin-core/src/start-compiler-plugin/compiler.tspackages/start-plugin-core/src/start-compiler-plugin/handleClientOnlyJSX.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateIsomorphicFn.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateMiddleware.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.tspackages/start-plugin-core/src/start-compiler-plugin/handleEnvOnly.tspackages/start-plugin-core/src/start-compiler-plugin/plugin.tspackages/start-plugin-core/src/start-compiler-plugin/types.tspackages/start-plugin-core/src/start-compiler-plugin/utils.tspackages/start-plugin-core/tests/clientOnlyJSX/clientOnlyJSX.test.tspackages/start-plugin-core/tests/compiler.test.tspackages/start-plugin-core/tests/createIsomorphicFn/createIsomorphicFn.test.tspackages/start-plugin-core/tests/createMiddleware/createMiddleware.test.tspackages/start-plugin-core/tests/createServerFn/createServerFn.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/factory.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnValidator.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/factory.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/isomorphic-fns.tsxpackages/start-plugin-core/tests/envOnly/envOnly.test.tspackages/start-server-core/package.jsonpackages/start-server-core/src/createSsrRpc.tspackages/start-server-core/src/fake-start-server-fn-resolver.tspackages/start-server-core/src/getServerFnById.tspackages/start-server-core/src/tanstack-start.d.tspackages/start-server-core/src/virtual-modules.tspackages/start-server-core/vite.config.tsscripts/publish.js
💤 Files with no reviewable changes (26)
- packages/server-functions-plugin/tests/index.test.ts
- packages/server-functions-plugin/tsconfig.json
- packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts
- packages/server-functions-plugin/package.json
- packages/directive-functions-plugin/vite.config.ts
- packages/start-plugin-core/src/create-server-fn-plugin/handleEnvOnly.ts
- packages/start-plugin-core/src/create-server-fn-plugin/types.ts
- packages/start-plugin-core/src/create-server-fn-plugin/utils.ts
- packages/server-functions-plugin/eslint.config.js
- labeler-config.yml
- packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts
- package.json
- scripts/publish.js
- packages/directive-functions-plugin/src/compilers.ts
- packages/server-functions-plugin/src/index.ts
- packages/directive-functions-plugin/package.json
- packages/directive-functions-plugin/README.md
- packages/directive-functions-plugin/tests/compiler.test.ts
- packages/start-plugin-core/src/create-server-fn-plugin/plugin.ts
- packages/start-plugin-core/src/create-server-fn-plugin/handleCreateIsomorphicFn.ts
- packages/directive-functions-plugin/eslint.config.js
- packages/start-plugin-core/package.json
- packages/server-functions-plugin/vite.config.ts
- packages/directive-functions-plugin/tsconfig.json
- packages/server-functions-plugin/README.md
- packages/directive-functions-plugin/src/index.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
packages/start-server-core/vite.config.tspackages/start-plugin-core/src/start-compiler-plugin/handleEnvOnly.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateIsomorphicFn.tspackages/start-server-core/src/createSsrRpc.tse2e/react-start/basic/src/routeTree.gen.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateMiddleware.tspackages/start-plugin-core/tests/createIsomorphicFn/createIsomorphicFn.test.tspackages/start-server-core/src/virtual-modules.tspackages/start-plugin-core/src/start-compiler-plugin/utils.tspackages/start-server-core/src/tanstack-start.d.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.tspackages/start-plugin-core/tests/createServerFn/createServerFn.test.tspackages/start-plugin-core/src/start-compiler-plugin/types.tspackages/start-server-core/src/getServerFnById.tspackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/isomorphic-fns.tsxpackages/start-plugin-core/src/start-compiler-plugin/compiler.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/factory.tsxpackages/start-plugin-core/src/start-compiler-plugin/plugin.tspackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnValidator.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructured.tsxpackages/start-plugin-core/src/plugin.tspackages/start-plugin-core/tests/clientOnlyJSX/clientOnlyJSX.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsxpackages/start-plugin-core/tests/envOnly/envOnly.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createMiddleware/createMiddleware.test.tspackages/start-plugin-core/tests/compiler.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/factory.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
packages/start-server-core/vite.config.tspackages/start-plugin-core/src/start-compiler-plugin/handleEnvOnly.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateIsomorphicFn.tspackages/start-server-core/src/createSsrRpc.tse2e/react-start/basic/src/routeTree.gen.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateMiddleware.tspackages/start-plugin-core/tests/createIsomorphicFn/createIsomorphicFn.test.tspackages/start-server-core/src/virtual-modules.tspackages/start-plugin-core/src/start-compiler-plugin/utils.tspackages/start-server-core/src/tanstack-start.d.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.tspackages/start-plugin-core/tests/createServerFn/createServerFn.test.tspackages/start-plugin-core/src/start-compiler-plugin/types.tspackages/start-server-core/src/getServerFnById.tspackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/isomorphic-fns.tsxpackages/start-plugin-core/src/start-compiler-plugin/compiler.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/factory.tsxpackages/start-plugin-core/src/start-compiler-plugin/plugin.tspackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnValidator.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructured.tsxpackages/start-plugin-core/src/plugin.tspackages/start-plugin-core/tests/clientOnlyJSX/clientOnlyJSX.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsxpackages/start-plugin-core/tests/envOnly/envOnly.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createMiddleware/createMiddleware.test.tspackages/start-plugin-core/tests/compiler.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/factory.tsx
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Use workspace protocol
workspace:*for internal dependencies in package.json files
Files:
packages/start-server-core/package.jsonpackages/react-router/package.json
🧠 Learnings (6)
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
packages/start-server-core/vite.config.tspackages/start-server-core/src/createSsrRpc.tse2e/react-start/basic/src/routeTree.gen.tspackages/start-server-core/package.jsonpackages/start-server-core/src/tanstack-start.d.tspackages/start-server-core/src/getServerFnById.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/isomorphic-fns.tsxpackages/start-plugin-core/tests/clientOnlyJSX/clientOnlyJSX.test.tspackages/start-plugin-core/tests/envOnly/envOnly.test.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
e2e/react-start/basic/src/routeTree.gen.ts
📚 Learning: 2025-12-17T02:17:55.086Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.
Applied to files:
e2e/react-start/basic/src/routeTree.gen.ts
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
e2e/react-start/basic/src/routeTree.gen.tspackages/start-plugin-core/tests/createServerFn/createServerFn.test.tspackages/start-plugin-core/tests/compiler.test.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Always run `pnpm test:eslint`, `pnpm test:types`, and `pnpm test:unit` before committing code
Applied to files:
packages/react-router/package.json
📚 Learning: 2025-12-16T02:59:11.506Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6104
File: packages/start-plugin-core/tests/split-exports-plugin/snapshots/exports/functionExports.ts:1-1
Timestamp: 2025-12-16T02:59:11.506Z
Learning: In transformation test snapshots (e.g., split-exports plugin), comments at the top of snapshot files often describe the original input scenario being tested (e.g., "Multiple function exports") rather than the transformed output in the snapshot itself. This helps document what transformation is being validated.
Applied to files:
packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructured.tsx
🧬 Code graph analysis (16)
packages/start-server-core/vite.config.ts (1)
packages/start-server-core/src/virtual-modules.ts (1)
VIRTUAL_MODULES(1-5)
packages/start-plugin-core/src/start-compiler-plugin/handleEnvOnly.ts (3)
packages/start-plugin-core/src/start-compiler-plugin/types.ts (2)
RewriteCandidate(70-73)CompilationContext(9-31)packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (1)
LookupKind(43-49)packages/router-core/src/route.ts (1)
path(1553-1555)
packages/start-plugin-core/src/start-compiler-plugin/handleCreateIsomorphicFn.ts (1)
packages/start-plugin-core/src/start-compiler-plugin/types.ts (2)
RewriteCandidate(70-73)CompilationContext(9-31)
packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts (1)
packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (2)
compile(656-993)ServerFnCompiler(315-1316)
packages/start-plugin-core/src/start-compiler-plugin/types.ts (1)
packages/start-plugin-core/src/types.ts (1)
CompileStartFrameworkOptions(3-3)
packages/start-plugin-core/tests/createServerFn/snapshots/server/isomorphic-fns.tsx (1)
packages/start-plugin-core/tests/createServerFn/snapshots/client/isomorphic-fns.tsx (1)
Route(9-16)
packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (4)
packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts (1)
handleCreateServerFn(190-439)packages/start-plugin-core/src/start-compiler-plugin/handleCreateMiddleware.ts (1)
handleCreateMiddleware(10-39)packages/start-plugin-core/src/start-compiler-plugin/handleCreateIsomorphicFn.ts (1)
handleCreateIsomorphicFn(10-54)packages/start-plugin-core/src/start-compiler-plugin/handleEnvOnly.ts (1)
handleEnvOnlyFn(17-56)
packages/start-plugin-core/tests/createServerFn/snapshots/client/factory.tsx (1)
packages/start-client-core/src/client-rpc/createClientRpc.ts (1)
createClientRpc(4-16)
packages/start-plugin-core/src/start-compiler-plugin/plugin.ts (6)
packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (7)
LookupKindsPerEnv(99-114)KindDetectionPatterns(89-96)LookupKind(43-49)LookupConfig(192-196)ServerFnCompiler(315-1316)mode(433-435)detectKindsInCode(146-162)packages/start-plugin-core/src/types.ts (1)
CompileStartFrameworkOptions(3-3)packages/start-plugin-core/src/start-compiler-plugin/types.ts (2)
DirectiveFn(79-93)GenerateFunctionIdFnOptional(107-109)packages/start-server-core/src/virtual-modules.ts (1)
VIRTUAL_MODULES(1-5)packages/start-plugin-core/src/constants.ts (2)
VITE_ENVIRONMENT_NAMES(1-6)TRANSFORM_ID_REGEX(26-26)packages/start-plugin-core/src/start-compiler-plugin/utils.ts (1)
cleanId(28-35)
packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnValidator.tsx (6)
packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructured.tsx (1)
withUseServer_createServerFn_handler(58-58)packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructuredRename.tsx (1)
withUseServer_createServerFn_handler(42-42)packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnStarImport.tsx (1)
withUseServer_createServerFn_handler(44-44)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsx (1)
withUseServer(3-5)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsx (1)
withUseServer(3-5)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsx (1)
withUseServer(3-5)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsx (3)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsx (4)
withUseServer(3-5)withoutUseServer(12-14)withVariable(15-17)withZodValidator(18-20)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsx (4)
withUseServer(3-5)withoutUseServer(6-8)withVariable(9-11)withZodValidator(12-14)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsx (1)
withUseServer(3-5)
packages/start-plugin-core/tests/createServerFn/snapshots/client/isomorphic-fns.tsx (1)
packages/start-client-core/src/client-rpc/createClientRpc.ts (1)
createClientRpc(4-16)
packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructured.tsx (3)
packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructuredRename.tsx (4)
withUseServer_createServerFn_handler(42-42)withoutUseServer_createServerFn_handler(42-42)withVariable_createServerFn_handler(42-42)withZodValidator_createServerFn_handler(42-42)packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnStarImport.tsx (4)
withUseServer_createServerFn_handler(44-44)withoutUseServer_createServerFn_handler(44-44)withVariable_createServerFn_handler(44-44)withZodValidator_createServerFn_handler(44-44)packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnValidator.tsx (1)
withUseServer_createServerFn_handler(10-10)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsx (4)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsx (1)
withUseServer(3-5)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsx (1)
withUseServer(3-5)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsx (1)
withUseServer(3-5)packages/start-client-core/src/client-rpc/createClientRpc.ts (1)
createClientRpc(4-16)
packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructuredRename.tsx (4)
packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructured.tsx (4)
withUseServer_createServerFn_handler(58-58)withoutUseServer_createServerFn_handler(58-58)withVariable_createServerFn_handler(58-58)withZodValidator_createServerFn_handler(58-58)packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnStarImport.tsx (4)
withUseServer_createServerFn_handler(44-44)withoutUseServer_createServerFn_handler(44-44)withVariable_createServerFn_handler(44-44)withZodValidator_createServerFn_handler(44-44)packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnValidator.tsx (1)
withUseServer_createServerFn_handler(10-10)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsx (4)
withUseServer(3-5)withoutUseServer(12-14)withVariable(15-17)withZodValidator(18-20)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsx (3)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsx (4)
withUseServer(3-5)withoutUseServer(6-8)withVariable(9-11)withZodValidator(12-14)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsx (4)
withUseServer(3-5)withoutUseServer(6-8)withVariable(9-11)withZodValidator(12-14)packages/start-client-core/src/client-rpc/createClientRpc.ts (1)
createClientRpc(4-16)
🪛 ast-grep (0.40.3)
packages/start-plugin-core/src/start-compiler-plugin/plugin.ts
[warning] 235-235: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${SERVER_FN_LOOKUP}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 342-342: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${SERVER_FN_LOOKUP}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 379-379: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(VIRTUAL_MODULES.serverFnResolver)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 385-385: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(resolvedResolverVirtualImportId)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test
- GitHub Check: Preview
🔇 Additional comments (61)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsx (2)
1-1: LGTM - Import added correctly for RPC-based handlers.The
createClientRpcimport is necessary for the refactored client-side server function handlers and correctly references the client-rpc module.
5-23: LGTM - Handler transformations align with RPC-based compilation approach.All server function handlers have been correctly transformed to use
createClientRpcwith base64-encoded payloads. The encoded payloads contain the correct file path and export identifiers for each function (withUseServer, withArrowFunction, withArrowFunctionAndFunction, withoutUseServer, withVariable, withZodValidator, withValidatorFn), replacing the previous inline__executeServerapproach.This snapshot accurately represents the expected compiler output for the consolidated start-compiler-plugin.
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsx (2)
1-1: LGTM - Import added correctly for RPC-based handlers.The
createClientRpcimport is necessary for the refactored client-side server function handlers and correctly references the client-rpc module.
5-14: LGTM - Handler transformations correctly use renamed import alias.All server function handlers have been correctly transformed to use
createClientRpcwith properly encoded payloads. The snapshot correctly demonstrates that the compiler transformation works with renamed imports (createServerFn as serverFn), with each encoded payload containing the correct file path (createServerFnDestructuredRename.tsx) and export identifiers.This snapshot accurately represents the expected compiler output for the renamed import variant.
e2e/react-start/basic/src/routeTree.gen.ts (1)
1023-1028: Module augmentation for SSR integration looks correct.The module augmentation properly extends the
Registerinterface for@tanstack/react-startwith SSR-aware router typing. The use ofAwaited<ReturnType<typeof getRouter>>correctly handles the potentially async return type.packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsx (1)
3-5: LGTM! Pattern is consistent with other snapshot files.The handler correctly uses
createClientRpcwith an encoded functionId that matches the expected pattern. The encoded string properly identifies this file and export, consistent with the compiler transformation applied across other snapshot files.packages/start-server-core/package.json (1)
65-66: LGTM! Consistent import alias rename.The import alias and target file have been correctly renamed from manifest to resolver, aligning with the broader shift to resolver-based server function resolution.
packages/start-server-core/src/tanstack-start.d.ts (1)
13-14: LGTM! Module renamed and type exported.The module declaration has been correctly renamed to match the resolver-based approach, and the
ServerFntype is now exported to support imports in consuming code (e.g.,createSsrRpc.ts).packages/start-server-core/src/createSsrRpc.ts (1)
3-3: LGTM! Import source updated consistently.The import has been correctly updated to use the resolver module, aligning with the renamed module declaration in
tanstack-start.d.ts.packages/start-server-core/vite.config.ts (2)
31-31: LGTM! External dependency reference updated consistently.The external dependency has been correctly updated to reference the resolver module.
25-25: Resolver file exists and is correctly referenced.The
fake-start-server-fn-resolver.tsfile has been created and is properly configured in the entry array at line 25 of vite.config.ts.packages/start-server-core/src/getServerFnById.ts (1)
1-1: LGTM! Re-export source updated consistently.The re-export source has been correctly updated to use the resolver module while maintaining the same public API.
packages/start-server-core/src/virtual-modules.ts (1)
4-4: Rename ofserverFnManifesttoserverFnResolveris complete across the codebase.Verification confirms that there are no remaining references to the old
serverFnManifestkey. The newserverFnResolverkey is properly used in two locations:
packages/start-plugin-core/src/start-compiler-plugin/plugin.ts:200for resolving the virtual import IDpackages/start-plugin-core/src/start-compiler-plugin/plugin.ts:380for the plugin'sresolveIdfilterAll references have been updated accordingly.
packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnStarImport.tsx (1)
4-13: No changes needed — this is snapshot/expected compiler output.This file in the
snapshotsdirectory contains expected transformation output, not source code requiring review. The forward reference pattern where handlers reference server functions before declaration is the intended compiler transformation. This pattern is systematically applied across all snapshot files and works correctly due to JavaScript closure timing—the handler function won't execute until after the server function is fully declared. No action required.packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsx (2)
3-14: RPC handler payloads are valid. All four encoded payloads decode correctly to valid JSON structures with proper file paths and export references. The consistent pattern across all server functions is correct.
1-1: No action required. ThecreateClientRpcimport is properly exported from@tanstack/react-start/client-rpcwith correct TypeScript typing (functionId: stringparameter). The snapshot correctly shows the compiler-transformed output using this function with base64-encoded payload strings, which align with the function's expected string parameter type.packages/start-plugin-core/tests/createServerFn/snapshots/server/factory.tsx (3)
1-1: LGTM: New import supports RPC handler pattern.The import of
createServerRpcis correctly added to support the new RPC-wrapped handler pattern introduced in this refactor.
45-45: Confirm the new public API surface.The RPC handlers are now exported instead of the original server functions. This represents a significant change in the public API, where consumers import RPC-wrapped handlers rather than direct server function references.
Please verify this aligns with the intended architecture and that the security model properly restricts access through the
createServerRpcwrapper.
27-28: No issues found. The forward-reference pattern is safe and intentional compiler-generated code. The__executeServermethod is guaranteed to exist on instances created by.handler(), and the callback is lazily evaluated—only invoked after the server function is fully initialized. This pattern is explicitly documented in the compilation logic athandleCreateServerFn.ts:310-324.packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts (5)
87-118: LGTM!The environment configuration logic is clear and handles the three cases (provider, client, SSR caller) correctly with proper type safety.
138-166: LGTM!The caller RPC stub generation logic correctly handles the different environments and reference scenarios with clear comments explaining the branching conditions.
381-386: Verify that removing the bound function doesn't affect other usages.Calling
binding.path.remove()will remove the function declaration/expression entirely from the AST. If the handler function is referenced elsewhere in the file (e.g., called directly or passed to another function), this could break the code.Consider checking if the binding has other references before removal:
if (t.isIdentifier(handlerFn)) { const binding = handlerFnPath.scope.getBinding(handlerFn.name) - if (binding) { + if (binding && binding.references === 1) { binding.path.remove() } }
467-495:ExportAllDeclarationis not handled and will pass through unchanged.The function handles
ExportNamedDeclarationandExportDefaultDeclaration, butExportAllDeclaration(e.g.,export * from './module') is not addressed. If provider files could contain such exports, they would not be removed.Is this intentional? If
export * fromstatements should also be removed in provider files, consider adding:if ( t.isExportNamedDeclaration(node) || - t.isExportDefaultDeclaration(node) + t.isExportDefaultDeclaration(node) || + t.isExportAllDeclaration(node) ) { + if (t.isExportAllDeclaration(node)) { + return [] // Remove export * statements + }
41-44: TheCompileStartFrameworkOptionstype is a string literal union ('react' | 'solid' | 'vue'), not a complex object. Using it as a Map key is valid and correct—string values have proper value equality semantics in JavaScript, so the cache will function as intended regardless of how instances are passed.packages/start-plugin-core/tests/createServerFn/snapshots/client/factory.tsx (3)
2-26: LGTM: Middleware composition and test fixtures are correct.The middleware chain is properly preserved through the factory pattern (
createAuthServerFn→createAdminServerFn), and the test fixtures serve their purpose in the snapshot file.Also applies to: 29-38
27-28: Confirm base64-encoded RPC identifiers are correctly generated and reference existing server exports.The base64 strings decode to valid JSON identifiers that correctly reference the server-side handler exports:
myAuthedFn→ encodesmyAuthedFn_createServerFn_handlerdeleteUserFn→ encodesdeleteUserFn_createServerFn_handlerBoth exports are properly defined in the server snapshot file and the client snapshot correctly transforms the inline handlers into RPC calls using
createClientRpc.
1-1: The import path is correctly exported. The./client-rpcsubpath export is properly defined inpackages/react-start/package.jsonand resolves to./dist/esm/client-rpc.js.packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnValidator.tsx (1)
1-10: LGTM! Snapshot correctly demonstrates the new RPC handler wiring pattern.The generated code properly separates the RPC handler creation from the server function definition, with the handler exported for use in client-side code splitting. The forward reference to
withUseServer.__executeServerat line 4 is valid since the callback is not immediately invoked.packages/start-plugin-core/tests/createServerFn/snapshots/client/isomorphic-fns.tsx (1)
1-8: LGTM! Client snapshot correctly shows RPC stub generation.The client-side handlers now use
createClientRpcwith encoded payloads containing the module path and export name, enabling proper routing to the server-side handlers.packages/start-plugin-core/tests/createServerFn/snapshots/server/isomorphic-fns.tsx (2)
72-72: LGTM! Handler exports correctly expose server RPC endpoints.The explicit export of handler constants enables proper client/server code splitting by allowing the client build to reference these handlers by name.
13-20: No action required. TheRouteconstant in the server snapshot is correctly defined as a local (non-exported) constant. This is the expected behavior for server-client code splitting: the client snapshot exportsRoutefor routing purposes, while the server snapshot keeps it local since the route is used internally only via the loader function.packages/start-plugin-core/tests/clientOnlyJSX/clientOnlyJSX.test.ts (1)
5-8: LGTM! Import path updated to consolidated compiler location.The import correctly references the new
start-compiler-plugin/compilerpath.packages/start-plugin-core/tests/createIsomorphicFn/createIsomorphicFn.test.ts (1)
5-26: LGTM! Test configuration updated correctly.The import path and helper integration follow the same pattern as other test files in this PR. The
getDefaultTestOptionshelper duplication was noted in the clientOnlyJSX.test.ts review.packages/start-plugin-core/src/start-compiler-plugin/handleCreateIsomorphicFn.ts (1)
10-53: LGTM! Handler correctly transforms isomorphic functions based on environment.The implementation properly handles all cases:
- No implementations provided → warn and replace with no-op
- Missing implementation for current environment → silent no-op replacement
- Valid implementation → extract and replace with inner function
packages/start-plugin-core/src/start-compiler-plugin/handleEnvOnly.ts (1)
17-55: LGTM! Handler correctly enforces environment-only function restrictions.The implementation properly:
- Extracts the inner function when called in the correct environment
- Replaces with a throwing function when called in the wrong environment, providing clear runtime error messages
packages/start-plugin-core/tests/envOnly/envOnly.test.ts (2)
5-26: LGTM! Test configuration updated consistently.The import path and helper integration follow the established pattern. The
getDefaultTestOptionsduplication was addressed in the clientOnlyJSX.test.ts review.
83-103: LGTM! Error cases properly test validation.The tests verify that
createClientOnlyFn()andcreateServerOnlyFn()throw errors when called without a function argument, ensuring the validation inhandleEnvOnlyFnis exercised.packages/start-plugin-core/src/start-compiler-plugin/handleCreateMiddleware.ts (1)
10-38: LGTM - Well-structured middleware handler with appropriate guards.The function correctly:
- Guards against server-side execution
- Validates
inputValidatorhas an argument before stripping- Strips both
inputValidatorandservermethod calls from the chainpackages/start-plugin-core/tests/createMiddleware/createMiddleware.test.ts (1)
6-16: LGTM - Centralized test options helper improves maintainability.The
getDefaultTestOptionshelper provides consistent configuration across tests with appropriate environment-specificenvNamemapping.packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructuredRename.tsx (1)
1-42: Snapshot correctly reflects the new RPC-based server function wiring.The output shows the expected pattern where:
createServerRpcgenerates handler constants with encoded function IDs- These handlers are passed to
.handler()along with the implementation- Handler constants are exported for RPC access
Based on learnings, this snapshot file is a test fixture and correctly captures the expected compiler output.
packages/start-plugin-core/src/start-compiler-plugin/utils.ts (2)
46-52: LGTM - Well-documented utility with appropriate guard.The
stripMethodCallfunction correctly guards against non-MemberExpression callees before attempting replacement. The JSDoc clearly explains the transformation pattern.
28-35: LGTM - cleanId handles virtual module edge cases correctly.The function properly handles:
- Vite/Rollup null byte prefix for virtual modules
- Query string stripping for module IDs
packages/start-plugin-core/tests/compiler.test.ts (2)
11-21: Consistent test helper pattern across test files.The
getDefaultTestOptionshelper follows the same pattern as other test files, ensuring consistent compiler configuration for tests.
229-235: Expectations correctly updated for new RPC-based output.The test now expects
createClientRpcin the compiled output, matching the new server function wiring approach.packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (3)
116-140: Clean registry-based handler dispatch pattern.The
KindHandlersregistry provides a maintainable and extensible pattern for processing different function kinds. The comment about ClientOnlyJSX being handled separately via JSX traversal is helpful.
377-431: Well-implemented function ID generation with proper collision handling.The
generateFunctionIdmethod correctly handles:
- Dev mode: Base64url encoding for human-readable debugging
- Build mode: SHA256 hashing with custom generator support
- Deduplication: Iterative suffix appending to avoid collisions
One minor observation: the deduplication loop could theoretically run indefinitely if
functionIdsis extremely large, but this is practically impossible in real-world scenarios.
926-960: Batch processing correctly groups candidates by kind.The implementation:
- Creates a proper
CompilationContextwith all required fields- Groups candidates by kind using a Map
- Dispatches to registered handlers via
KindHandlers[kind]This is a clean separation of concerns that makes adding new kinds straightforward.
packages/start-plugin-core/src/plugin.ts (1)
356-368: Clean plugin wiring with clear documentation.The comment block effectively documents what
startCompilerPluginnow handles:
- Server function identification and extraction
- RPC stub generation
- Manifest generation
- Multiple function types (isomorphic, server-only, client-only, middleware)
The
providerEnvNameoption correctly replaces the previous directive-based configuration.packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts (1)
123-146: RPC wrapper implementations are properly exported and match test expectations.All three RPC wrappers are correctly implemented and exported:
createClientRpctakes a functionId and returns a function for client-side calls viaserverFnFetchercreateSsrRpctakes a functionId and optional importer, using direct execution in SSR environments or falling back to manifest lookupcreateServerRpctakes a functionId and the actual implementation function to wrapThe test snapshots at lines 123-146 accurately reflect the expected behavior: client uses a single argument, while SSR and server variants accept the implementation details as a second argument.
packages/start-plugin-core/src/start-compiler-plugin/plugin.ts (6)
16-27: LGTM!Clean helper function that derives regex patterns from the single source of truth (
KindDetectionPatterns). The iteration and filtering logic is correct.
29-82: LGTM!The environment-based configuration is well-structured with clear separation of common and environment-specific configs. The dynamic
libNameconstruction using the framework parameter is appropriate.
91-101: LGTM!The query parsing logic is clean and handles both cases (with/without query string) correctly.
233-237: Static analysis false positive - constant values used in RegExp.The static analysis flagged ReDoS concerns for
new RegExp(\${SERVER_FN_LOOKUP}$ `). This is a false positive sinceSERVER_FN_LOOKUPis a hardcoded constant ('server-fn-module-lookup'`), not user input.However, for defense-in-depth, consider escaping special regex characters if these patterns might ever include characters like
.or?in the future.
243-299: LGTM! Well-structured transform handler with proper mode detection.The compiler initialization is correctly deferred and cached per environment. The distinction between build mode (
ctx.load()) and dev mode (fetchModule) is appropriate given Vite's behavior differences. The graceful handling of modules with no runtime code (line 269) prevents errors with type-only files.
396-408: Dev mode resolver uses clever validation via virtual module import.The pattern of validating function IDs via a virtual module import before dynamic loading is a good security measure. The
/@id/__x00__prefix correctly handles Vite's virtual module resolution.packages/start-plugin-core/src/start-compiler-plugin/types.ts (4)
9-31: Well-documented CompilationContext interface.The separation of
readonlyfields for input data and mutable callback fields is a good practice. The JSDoc comments clearly explain the purpose of each field.
75-93: LGTM!The
DirectiveFninterface is well-documented and correctly uses optionalisClientReferencedfor the conditional client-reference tracking.
95-109: LGTM!The two-tier function ID generation types are well-designed. The optional variant appropriately omits
extractedFilename(which may not be known at call time) and allowsundefinedreturn for default fallback.
111-133: LGTM!The
ReplacerFntype is comprehensive with excellent documentation for each parameter. The distinction betweenisSourceFnandisClientReferencedis clearly explained.packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructured.tsx (2)
1-11: Snapshot demonstrates the new server function compilation pattern.The test snapshot correctly shows the expected output format with:
createServerRpcimport from@tanstack/react-start/server-rpc- Handler constants created with base64-encoded function IDs
- Callbacks using
.__executeServer(opts, signal)patternThis validates that the compiler correctly transforms server functions to the RPC-backed architecture.
50-58: LGTM! Snapshot correctly demonstratesinputValidatorchain handling.The
withValidatorFnexample shows that the compiler correctly handles the.inputValidator()chain before.handler(). The export statement properly includes all seven handler constants, ensuring they're accessible for the manifest.
packages/react-router/package.json
Outdated
| "test:perf:dev": "pnpm run test:perf --watch --hideSkippedTests", | ||
| "test:build": "publint --strict && attw --ignore-rules no-resolution --pack .", | ||
| "build": "pnpm run build:lib && pnpm run build:llm", | ||
| "build": "pnpm run build:lib", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, let's examine the current state of the package.json file
echo "=== Current state of packages/react-router/package.json ==="
cat -n packages/react-router/package.json | sed -n '30,100p'Repository: TanStack/router
Length of output: 2978
🏁 Script executed:
#!/bin/bash
# Search for references to build:llm and llms in the workspace
echo "=== References to build:llm in workspace ==="
rg "build:llm" --type json -g '!node_modules'
echo -e "\n=== References to 'llm' in package.json files ==="
rg "llm" packages/ --type json -B 2 -A 2
echo -e "\n=== Check for GitHub workflows related to llm ==="
fd -e yml -e yaml . .github 2>/dev/null | head -20Repository: TanStack/router
Length of output: 1376
🏁 Script executed:
#!/bin/bash
# Check if there are build configuration files that might generate llm artifacts
echo "=== Looking for build configuration files ==="
fd -e "ts" -e "js" . . -path "*/build*" -o -path "*/scripts*" 2>/dev/null | grep -E "(build|script)" | head -20
echo -e "\n=== Check turbo.json or other build orchestration ==="
cat turbo.json 2>/dev/null || echo "No turbo.json found"Repository: TanStack/router
Length of output: 179
🏁 Script executed:
#!/bin/bash
# Get the full context of the build scripts and exports from package.json
echo "=== Full build scripts section ==="
rg -A 5 '"scripts"' packages/react-router/package.json
echo -e "\n=== Full exports section ==="
rg -A 20 '"exports"' packages/react-router/package.jsonRepository: TanStack/router
Length of output: 1000
🏁 Script executed:
#!/bin/bash
# Check the llms-generate script
echo "=== Checking llms-generate.mjs script ==="
cat ../../scripts/llms-generate.mjs 2>/dev/null | head -50
echo -e "\n=== Check if llms directory exists in react-router ==="
ls -la packages/react-router/llms/ 2>/dev/null || echo "No llms directory found"
echo -e "\n=== Check for llms references in dist ==="
ls -la packages/react-router/dist/llms/ 2>/dev/null || echo "No dist/llms directory found"
echo -e "\n=== Check if there are any CI workflow files that call build:llm ==="
grep -r "build:llm" .github/ 2>/dev/null || echo "No build:llm found in workflows"Repository: TanStack/router
Length of output: 354
🏁 Script executed:
#!/bin/bash
# Check if the scripts directory exists and what scripts are there
echo "=== Content of scripts directory ==="
ls -la scripts/ 2>/dev/null | head -20
echo -e "\n=== Check if llms-generate.mjs exists ==="
test -f scripts/llms-generate.mjs && echo "File exists: scripts/llms-generate.mjs" || echo "File not found"
echo -e "\n=== Search for any build orchestration in root package.json ==="
cat package.json 2>/dev/null | grep -A 50 '"scripts"' | head -60Repository: TanStack/router
Length of output: 3049
🏁 Script executed:
#!/bin/bash
# Check how other packages handle similar builds
echo "=== Check other package.json files for build:llm or similar patterns ==="
find packages -name "package.json" -exec grep -l "build:llm\|llms" {} \;
echo -e "\n=== Check if there's a pnpm workspace config ==="
cat pnpm-workspace.yaml 2>/dev/null || echo "No pnpm-workspace.yaml found"Repository: TanStack/router
Length of output: 735
🏁 Script executed:
#!/bin/bash
# Check recent changes to the build script
echo "=== Check git history for build script changes ==="
git log --oneline -20 -- packages/react-router/package.json 2>/dev/null | head -10
echo -e "\n=== Look at the specific change context ==="
git show HEAD:packages/react-router/package.json 2>/dev/null | grep -A 5 '"build"' || echo "Could not get git context"Repository: TanStack/router
Length of output: 415
🏁 Script executed:
#!/bin/bash
# Check if there are any imports or references to the ./llms export in the codebase
echo "=== Check for imports of ./llms from react-router ==="
rg "from.*react-router.*llms|import.*from.*react-router/llms" --type ts --type tsx --type js --type jsx -g '!node_modules'
echo -e "\n=== Check if there are test files referencing ./llms ==="
rg "llms" packages/react-router/src --type ts --type tsx || echo "No llms references in src"
echo -e "\n=== Check tsconfig or build config for llms output ==="
cat packages/react-router/vite.config.ts 2>/dev/null | head -50Repository: TanStack/router
Length of output: 1015
🏁 Script executed:
#!/bin/bash
# Check what the vite build actually outputs
echo "=== Check vite.config.ts to see what gets built ==="
cat packages/react-router/vite.config.ts 2>/dev/nullRepository: TanStack/router
Length of output: 800
🏁 Script executed:
#!/bin/bash
# Check if there's an llms directory in src that should be built
echo "=== Check for llms directory in src ==="
ls -la packages/react-router/src/llms/ 2>/dev/null || echo "No src/llms directory"
echo -e "\n=== Check if there's any llms-related code at all ==="
find packages/react-router -name "*llm*" -type f 2>/dev/null
echo -e "\n=== Check if there's a tsconfig for llms ==="
cat packages/react-router/llms/tsconfig.json 2>/dev/null || echo "No llms/tsconfig.json found"Repository: TanStack/router
Length of output: 249
🏁 Script executed:
#!/bin/bash
# Check the llms-generate.mjs script to understand what it was supposed to do
echo "=== Content of llms-generate.mjs ==="
cat scripts/llms-generate.mjsRepository: TanStack/router
Length of output: 5013
🏁 Script executed:
#!/bin/bash
# Let's check if there's any indication this export should be removed in recent changes
echo "=== Check for any removal of llms functionality in git history ==="
git log --oneline --all -30 2>/dev/null | head -20
echo -e "\n=== Check if llms is mentioned in any other package's exports ==="
rg '"llms"' packages/ --type json
echo -e "\n=== Check if this is a deliberate consolidation by looking at nearby exports ==="
git show HEAD:packages/react-router/package.json 2>/dev/null | grep -A 40 '"exports"' | tail -45Repository: TanStack/router
Length of output: 2221
Remove the orphaned ./llms export or restore the build script.
The build:llm script has been removed from the main build (line 41) but the ./llms export (lines 81-86) remains, pointing to artifacts that will never be generated. There is no llms directory in the source, no dist output, and no CI/workflow that calls build:llm. Either remove the export or restore build:llm to the build sequence.
🤖 Prompt for AI Agents
In packages/react-router/package.json around line 41, the package.json still
exports "./llms" but the build step that generated those artifacts was removed;
either delete the "./llms" export block from the "exports" section (lines
~81-86) so no non-existent path is published, or restore a build:llm script and
wire it into the build pipeline (add "build:llm" script and include it in the
"build" lifecycle or CI) so the ./llms output is actually produced; choose one
approach and update package.json (and CI/workflows) accordingly to keep exports
consistent with produced artifacts.
| // Validate the handler argument is an expression (not a SpreadElement, etc.) | ||
| if (!t.isExpression(handlerFnPath.node)) { | ||
| throw codeFrameError( | ||
| context.code, | ||
| handlerFnPath.node.loc!, | ||
| `handler() must be called with an expression, not a ${handlerFnPath.node.type}`, | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential null dereference on loc property.
The handlerFnPath.node.loc may be undefined if the AST node lacks source location information. While this is rare in practice, the non-null assertion (!) on line 287 could fail.
🔎 Suggested defensive handling
if (!t.isExpression(handlerFnPath.node)) {
throw codeFrameError(
context.code,
- handlerFnPath.node.loc!,
+ handlerFnPath.node.loc ?? candidatePath.node.loc!,
`handler() must be called with an expression, not a ${handlerFnPath.node.type}`,
)
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
around lines 283 to 290, the code uses a non-null assertion on
handlerFnPath.node.loc which can be undefined; update the check to defensively
handle missing location information by removing the non-null assertion and
passing a safe fallback to codeFrameError (e.g. handlerFnPath.node.loc ??
undefined or derive a minimal loc/start position if available) so the function
never dereferences loc when it is absent.
| /** | ||
| * The Vite environment name for the server function provider. | ||
| * Defaults to 'ssr' if not specified. | ||
| */ | ||
| providerEnvName: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment-type mismatch: providerEnvName is required but comment says it defaults.
The JSDoc states "Defaults to 'ssr' if not specified" but the property is not optional. Either update the comment to reflect that it's required, or make the property optional with a default applied in the implementation.
🔎 Option A: Fix the comment
/**
- * The Vite environment name for the server function provider.
- * Defaults to 'ssr' if not specified.
+ * The Vite environment name for the server function provider (required).
*/
providerEnvName: string🔎 Option B: Make optional with default
/**
* The Vite environment name for the server function provider.
* Defaults to 'ssr' if not specified.
*/
- providerEnvName: string
+ providerEnvName?: stringThen in implementation:
const providerEnvName = opts.providerEnvName ?? VITE_ENVIRONMENT_NAMES.server📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /** | |
| * The Vite environment name for the server function provider. | |
| * Defaults to 'ssr' if not specified. | |
| */ | |
| providerEnvName: string | |
| /** | |
| * The Vite environment name for the server function provider (required). | |
| */ | |
| providerEnvName: string |
🤖 Prompt for AI Agents
In packages/start-plugin-core/src/start-compiler-plugin/plugin.ts around lines
177 to 181, the JSDoc claims providerEnvName "Defaults to 'ssr' if not
specified" but the property is required; either update the comment to remove the
default claim or make the property optional and apply a default in code. To fix:
(A) if you want it required, change the JSDoc to state it is required and remove
the default text; or (B) if you want a default, make providerEnvName optional in
the type and ensure the implementation uses a fallback (e.g. providerEnvName =
opts.providerEnvName ?? VITE_ENVIRONMENT_NAMES.server) so the default is
actually applied.
| import { createServerRpc } from '@tanstack/react-start/server-rpc'; | ||
| import * as TanStackStart from '@tanstack/react-start'; | ||
| import { z } from 'zod'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Missing imports for axios and PostType.
The code references axios (lines 12, 20, 29) and PostType (lines 12, 20, 29) without importing them, which will cause runtime and compilation errors respectively.
🔎 Proposed fix
import { createServerRpc } from '@tanstack/react-start/server-rpc';
import * as TanStackStart from '@tanstack/react-start';
import { z } from 'zod';
+import axios from 'axios';
+
+// Define or import PostType
+type PostType = {
+ // Add appropriate fields
+};Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In
packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnStarImport.tsx
lines 1-3, the file uses axios and PostType later but does not import them; add
an import for axios (import axios from 'axios') and add an import for PostType
from the module that defines it (e.g., import { PostType } from
'<correct/relative/path/to/types>'), updating the path to the actual location in
the repo so the file compiles and runs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just a snapshot of a test, not actual code. ignore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@schiller-manuel, understood! You're absolutely right—this is a test snapshot file that captures the expected output of the compiler transformation, not production code that needs to be executed. The missing imports are not an issue in this context since snapshots are used for comparison purposes in tests.
I'll skip flagging import issues in snapshot files going forward. Thank you for the clarification!
🧠 Learnings used
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
a1c2737 to
318f268
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (3)
packages/start-plugin-core/tests/envOnly/envOnly.test.ts (1)
7-16: Duplicate: ExtractgetDefaultTestOptionsto shared test utility.This helper is duplicated across multiple test files. Consider extracting to a shared test utility module as suggested in the
createMiddleware.test.tsreview.packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts (1)
278-285: Potential null dereference onlocproperty.The
handlerFnPath.node.locmay beundefinedif the AST node lacks source location information. The non-null assertion on line 282 could fail.🔎 Suggested defensive handling
if (!t.isExpression(handlerFnPath.node)) { throw codeFrameError( context.code, - handlerFnPath.node.loc!, + handlerFnPath.node.loc ?? candidatePath.node.callee.loc!, `handler() must be called with an expression, not a ${handlerFnPath.node.type}`, ) }packages/start-plugin-core/src/start-compiler-plugin/plugin.ts (1)
177-180: Comment-type mismatch:providerEnvNameis required but comment says it defaults.The JSDoc states "Defaults to 'ssr' if not specified" but the property is not optional. Either update the comment to reflect that it's required, or make the property optional with a default.
🔎 Fix the comment
/** - * The Vite environment name for the server function provider. + * The Vite environment name for the server function provider (required). */ providerEnvName: string
🧹 Nitpick comments (1)
packages/start-plugin-core/tests/createMiddleware/createMiddleware.test.ts (1)
6-15: Consider extractinggetDefaultTestOptionsto a shared test utility.This helper function is duplicated in multiple test files (e.g.,
envOnly.test.tsat lines 7-16). Extracting it to a shared test utility module would reduce duplication and ensure consistency across test suites.🔎 Suggested approach
Create a shared test utility file (e.g.,
packages/start-plugin-core/tests/utils.ts):export function getDefaultTestOptions(env: 'client' | 'server') { const envName = env === 'client' ? 'client' : 'ssr' return { envName, root: '/test', framework: 'react' as const, providerEnvName: 'ssr', } }Then import it in test files:
import { getDefaultTestOptions } from '../utils'
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (73)
e2e/react-start/basic/src/routeTree.gen.tslabeler-config.ymlpackage.jsonpackages/directive-functions-plugin/README.mdpackages/directive-functions-plugin/eslint.config.jspackages/directive-functions-plugin/package.jsonpackages/directive-functions-plugin/src/compilers.tspackages/directive-functions-plugin/src/index.tspackages/directive-functions-plugin/tests/compiler.test.tspackages/directive-functions-plugin/tsconfig.jsonpackages/directive-functions-plugin/vite.config.tspackages/server-functions-plugin/README.mdpackages/server-functions-plugin/eslint.config.jspackages/server-functions-plugin/package.jsonpackages/server-functions-plugin/src/index.tspackages/server-functions-plugin/tests/index.test.tspackages/server-functions-plugin/tsconfig.jsonpackages/server-functions-plugin/vite.config.tspackages/start-plugin-core/package.jsonpackages/start-plugin-core/src/create-server-fn-plugin/handleCreateIsomorphicFn.tspackages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.tspackages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.tspackages/start-plugin-core/src/create-server-fn-plugin/handleEnvOnly.tspackages/start-plugin-core/src/create-server-fn-plugin/plugin.tspackages/start-plugin-core/src/create-server-fn-plugin/types.tspackages/start-plugin-core/src/create-server-fn-plugin/utils.tspackages/start-plugin-core/src/plugin.tspackages/start-plugin-core/src/start-compiler-plugin/compiler.tspackages/start-plugin-core/src/start-compiler-plugin/handleClientOnlyJSX.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateIsomorphicFn.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateMiddleware.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.tspackages/start-plugin-core/src/start-compiler-plugin/handleEnvOnly.tspackages/start-plugin-core/src/start-compiler-plugin/plugin.tspackages/start-plugin-core/src/start-compiler-plugin/types.tspackages/start-plugin-core/src/start-compiler-plugin/utils.tspackages/start-plugin-core/src/types.tspackages/start-plugin-core/tests/clientOnlyJSX/clientOnlyJSX.test.tspackages/start-plugin-core/tests/compiler.test.tspackages/start-plugin-core/tests/createIsomorphicFn/createIsomorphicFn.test.tspackages/start-plugin-core/tests/createMiddleware/createMiddleware.test.tspackages/start-plugin-core/tests/createServerFn/createServerFn.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/factory.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnValidator.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/factory.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnValidator.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/factory.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnValidator.tsxpackages/start-plugin-core/tests/envOnly/envOnly.test.tspackages/start-server-core/package.jsonpackages/start-server-core/src/createSsrRpc.tspackages/start-server-core/src/fake-start-server-fn-resolver.tspackages/start-server-core/src/getServerFnById.tspackages/start-server-core/src/tanstack-start.d.tspackages/start-server-core/src/virtual-modules.tspackages/start-server-core/vite.config.tsscripts/publish.js
💤 Files with no reviewable changes (31)
- packages/directive-functions-plugin/eslint.config.js
- packages/start-plugin-core/src/create-server-fn-plugin/utils.ts
- labeler-config.yml
- packages/server-functions-plugin/vite.config.ts
- packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructuredRename.tsx
- packages/directive-functions-plugin/src/index.ts
- packages/start-plugin-core/src/types.ts
- packages/server-functions-plugin/tests/index.test.ts
- packages/start-plugin-core/src/create-server-fn-plugin/plugin.ts
- packages/directive-functions-plugin/README.md
- packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnStarImport.tsx
- packages/directive-functions-plugin/src/compilers.ts
- packages/start-plugin-core/src/create-server-fn-plugin/handleCreateIsomorphicFn.ts
- packages/server-functions-plugin/README.md
- packages/directive-functions-plugin/tests/compiler.test.ts
- packages/server-functions-plugin/tsconfig.json
- packages/start-plugin-core/package.json
- packages/directive-functions-plugin/tsconfig.json
- packages/start-plugin-core/src/create-server-fn-plugin/handleEnvOnly.ts
- packages/start-plugin-core/src/create-server-fn-plugin/handleCreateServerFn.ts
- packages/server-functions-plugin/src/index.ts
- package.json
- packages/directive-functions-plugin/package.json
- packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnDestructured.tsx
- packages/start-plugin-core/src/create-server-fn-plugin/types.ts
- packages/start-plugin-core/src/create-server-fn-plugin/handleCreateMiddleware.ts
- packages/start-plugin-core/tests/createServerFn/snapshots/server/createServerFnValidator.tsx
- packages/server-functions-plugin/eslint.config.js
- packages/server-functions-plugin/package.json
- scripts/publish.js
- packages/directive-functions-plugin/vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (15)
- packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsx
- e2e/react-start/basic/src/routeTree.gen.ts
- packages/start-plugin-core/src/start-compiler-plugin/handleCreateMiddleware.ts
- packages/start-plugin-core/src/start-compiler-plugin/handleEnvOnly.ts
- packages/start-server-core/vite.config.ts
- packages/start-server-core/src/virtual-modules.ts
- packages/start-plugin-core/tests/createServerFn/snapshots/client/isomorphic-fns.tsx
- packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsx
- packages/start-server-core/src/getServerFnById.ts
- packages/start-server-core/src/tanstack-start.d.ts
- packages/start-plugin-core/src/start-compiler-plugin/handleCreateIsomorphicFn.ts
- packages/start-plugin-core/tests/createIsomorphicFn/createIsomorphicFn.test.ts
- packages/start-server-core/src/createSsrRpc.ts
- packages/start-plugin-core/tests/clientOnlyJSX/clientOnlyJSX.test.ts
- packages/start-server-core/package.json
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsxpackages/start-plugin-core/tests/createMiddleware/createMiddleware.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnValidator.tsxpackages/start-plugin-core/src/start-compiler-plugin/utils.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/factory.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnValidator.tsxpackages/start-plugin-core/tests/compiler.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructured.tsxpackages/start-plugin-core/src/start-compiler-plugin/plugin.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsxpackages/start-plugin-core/src/plugin.tspackages/start-plugin-core/src/start-compiler-plugin/compiler.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/factory.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsxpackages/start-plugin-core/src/start-compiler-plugin/types.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/createServerFn.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/factory.tsxpackages/start-plugin-core/tests/envOnly/envOnly.test.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsxpackages/start-plugin-core/tests/createMiddleware/createMiddleware.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnValidator.tsxpackages/start-plugin-core/src/start-compiler-plugin/utils.tspackages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/factory.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnValidator.tsxpackages/start-plugin-core/tests/compiler.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructured.tsxpackages/start-plugin-core/src/start-compiler-plugin/plugin.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsxpackages/start-plugin-core/src/plugin.tspackages/start-plugin-core/src/start-compiler-plugin/compiler.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/factory.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsxpackages/start-plugin-core/src/start-compiler-plugin/types.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/createServerFn.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/client/factory.tsxpackages/start-plugin-core/tests/envOnly/envOnly.test.ts
🧠 Learnings (3)
📚 Learning: 2025-12-16T02:59:11.506Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6104
File: packages/start-plugin-core/tests/split-exports-plugin/snapshots/exports/functionExports.ts:1-1
Timestamp: 2025-12-16T02:59:11.506Z
Learning: In transformation test snapshots (e.g., split-exports plugin), comments at the top of snapshot files often describe the original input scenario being tested (e.g., "Multiple function exports") rather than the transformed output in the snapshot itself. This helps document what transformation is being validated.
Applied to files:
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnStarImport.tsx
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/compiler.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/createServerFn.test.ts
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
packages/start-plugin-core/tests/compiler.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructured.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsxpackages/start-plugin-core/src/plugin.tspackages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsxpackages/start-plugin-core/tests/createServerFn/createServerFn.test.tspackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/isomorphic-fns.tsxpackages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnStarImport.tsxpackages/start-plugin-core/tests/envOnly/envOnly.test.ts
🧬 Code graph analysis (16)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsx (4)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsx (1)
withUseServer(3-5)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructuredRename.tsx (1)
withUseServer(3-5)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnStarImport.tsx (1)
withUseServer(3-5)packages/start-client-core/src/client-rpc/createClientRpc.ts (1)
createClientRpc(4-16)
packages/start-plugin-core/tests/createMiddleware/createMiddleware.test.ts (1)
packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (1)
StartCompiler(315-1316)
packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnValidator.tsx (4)
packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructured.tsx (1)
withUseServer(4-6)packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructuredRename.tsx (1)
withUseServer(3-5)packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnStarImport.tsx (1)
withUseServer(3-5)packages/start-server-core/src/createSsrRpc.ts (1)
createSsrRpc(7-23)
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/factory.tsx (2)
packages/start-plugin-core/tests/createServerFn/snapshots/client/factory.tsx (3)
createAuthServerFn(25-25)myAuthedFn(27-27)deleteUserFn(28-28)packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/factory.tsx (3)
createAuthServerFn(25-25)myAuthedFn(27-27)deleteUserFn(28-28)
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsx (6)
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsx (4)
withUseServer_createServerFn_handler(58-58)withoutUseServer_createServerFn_handler(58-58)withVariable_createServerFn_handler(58-58)withZodValidator_createServerFn_handler(58-58)packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsx (4)
withUseServer_createServerFn_handler(44-44)withoutUseServer_createServerFn_handler(44-44)withVariable_createServerFn_handler(44-44)withZodValidator_createServerFn_handler(44-44)packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnValidator.tsx (1)
withUseServer_createServerFn_handler(10-10)packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsx (4)
withUseServer(3-5)withoutUseServer(12-14)withVariable(15-17)withZodValidator(18-20)packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructured.tsx (4)
withUseServer(4-6)withoutUseServer(13-15)withVariable(16-18)withZodValidator(19-21)packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructuredRename.tsx (4)
withUseServer(3-5)withoutUseServer(6-8)withVariable(9-11)withZodValidator(12-14)
packages/start-plugin-core/tests/compiler.test.ts (1)
packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (1)
StartCompiler(315-1316)
packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructured.tsx (4)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnDestructured.tsx (6)
withUseServer(3-5)withArrowFunction(6-8)withoutUseServer(12-14)withVariable(15-17)withZodValidator(18-20)withValidatorFn(21-23)packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructuredRename.tsx (4)
withUseServer(3-5)withoutUseServer(6-8)withVariable(9-11)withZodValidator(12-14)packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnValidator.tsx (1)
withUseServer(4-6)packages/start-server-core/src/createSsrRpc.ts (1)
createSsrRpc(7-23)
packages/start-plugin-core/src/start-compiler-plugin/plugin.ts (5)
packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (5)
LookupKindsPerEnv(99-114)KindDetectionPatterns(89-96)LookupKind(43-49)LookupConfig(192-196)detectKindsInCode(146-162)packages/start-plugin-core/src/start-compiler-plugin/types.ts (2)
ServerFn(79-93)GenerateFunctionIdFnOptional(107-109)packages/start-server-core/src/virtual-modules.ts (1)
VIRTUAL_MODULES(1-5)packages/start-plugin-core/src/constants.ts (2)
VITE_ENVIRONMENT_NAMES(1-6)TRANSFORM_ID_REGEX(26-26)packages/start-plugin-core/src/start-compiler-plugin/utils.ts (1)
cleanId(28-35)
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsx (2)
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsx (4)
withUseServer_createServerFn_handler(58-58)withoutUseServer_createServerFn_handler(58-58)withVariable_createServerFn_handler(58-58)withZodValidator_createServerFn_handler(58-58)packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructuredRename.tsx (4)
withUseServer(3-5)withoutUseServer(6-8)withVariable(9-11)withZodValidator(12-14)
packages/start-plugin-core/src/plugin.ts (2)
packages/start-plugin-core/src/start-compiler-plugin/plugin.ts (1)
startCompilerPlugin(183-423)packages/start-plugin-core/src/start-router-plugin/plugin.ts (1)
tanStackStartRouter(89-253)
packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (7)
packages/start-plugin-core/src/start-compiler-plugin/types.ts (3)
RewriteCandidate(70-73)CompilationContext(9-31)ServerFn(79-93)packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts (1)
handleCreateServerFn(185-434)packages/start-plugin-core/src/start-compiler-plugin/handleCreateMiddleware.ts (1)
handleCreateMiddleware(10-39)packages/start-plugin-core/src/start-compiler-plugin/handleCreateIsomorphicFn.ts (1)
handleCreateIsomorphicFn(10-54)packages/start-plugin-core/src/start-compiler-plugin/handleEnvOnly.ts (1)
handleEnvOnlyFn(17-56)packages/start-server-core/src/tanstack-start.d.ts (1)
ServerFn(14-14)packages/start-plugin-core/src/start-compiler-plugin/plugin.ts (4)
handler(344-347)handler(358-364)handler(380-382)handler(386-419)
packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructuredRename.tsx (1)
packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnDestructured.tsx (2)
withUseServer(4-6)withVariable(16-18)
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/isomorphic-fns.tsx (2)
packages/start-plugin-core/tests/createServerFn/snapshots/client/isomorphic-fns.tsx (1)
Route(9-16)packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/isomorphic-fns.tsx (1)
Route(9-16)
packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/isomorphic-fns.tsx (1)
packages/start-server-core/src/createSsrRpc.ts (1)
createSsrRpc(7-23)
packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnStarImport.tsx (3)
packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsx (1)
withUseServer(3-5)packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnValidator.tsx (1)
withUseServer(4-6)packages/start-server-core/src/createSsrRpc.ts (1)
createSsrRpc(7-23)
packages/start-plugin-core/tests/envOnly/envOnly.test.ts (1)
packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (2)
compile(656-993)StartCompiler(315-1316)
🪛 ast-grep (0.40.3)
packages/start-plugin-core/src/start-compiler-plugin/plugin.ts
[warning] 234-234: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${SERVER_FN_LOOKUP}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 341-341: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${SERVER_FN_LOOKUP}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 378-378: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(VIRTUAL_MODULES.serverFnResolver)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 384-384: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(resolvedResolverVirtualImportId)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Preview
- GitHub Check: Test
🔇 Additional comments (35)
packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/factory.tsx (4)
1-2: LGTM on the SSR RPC import.The new
createSsrRpcimport aligns with the refactoring to consolidate server function handling via SSR RPC.
3-26: Middleware definitions remain correct.The middleware chain setup with
authMiddleware→createAuthServerFnandadminMiddleware→createAdminServerFnis properly structured.
27-28: SSR RPC handler wiring looks correct.The
createSsrRpcpattern properly encapsulates:
- Base64-encoded metadata containing file path and export identifiers
- Lazy dynamic import for code-split handler loading
The handler naming convention (
myAuthedFn_createServerFn_handler,deleteUserFn_createServerFn_handler) is consistent and follows the expected split pattern.
29-38: Test helpercreateFakeFnserves its purpose.This mock function correctly tests that the compiler transformation only applies to actual
createServerFnchains and doesn't inadvertently transform unrelated.handler()calls.packages/start-plugin-core/tests/createServerFn/snapshots/client/factory.tsx (2)
27-28: LGTM! Transformation pattern correctly implements client RPC delegation.The handler transformations properly delegate to client RPC calls while preserving the middleware chains (
createAuthServerFnandcreateAdminServerFn). The base64-encoded strings contain the necessary routing metadata (file paths and export names) for server-function dispatch, which aligns with the consolidated plugin architecture described in the PR objectives.
1-1: I don't have a review comment to verify and rewrite. Please provide the review comment within<review_comment>tags, and I'll follow the exact output format specified.packages/start-plugin-core/tests/createServerFn/snapshots/client/createServerFnValidator.tsx (2)
3-5: LGTM: Client RPC transformation is correctly applied.The transformation from server handler logic to client RPC invocation is correctly implemented. The encoded payload follows the expected pattern seen in other snapshot files, and the
createClientRpccall properly replaces the previous server execution mechanism.
1-1: No action needed. The import path@tanstack/react-start/client-rpcis correctly configured through the package's re-export mechanism inpackages/react-start/src/client-rpc.ts, which re-exports from@tanstack/start-client-core/client-rpc. Both packages have proper export entries in theirpackage.jsonfiles.packages/start-plugin-core/tests/createServerFn/snapshots/server-caller/createServerFnValidator.tsx (1)
1-6: LGTM! Test snapshot correctly demonstrates SSR RPC transformation.The snapshot shows the expected output where a server function with input validation is wired through
createSsrRpcfor server-to-server calls, consistent with the PR's migration to RPC-based handlers.packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsx (1)
1-58: LGTM! Comprehensive test snapshot covering multiple server function patterns.The snapshot demonstrates the transformation for various server function patterns (async handlers, arrow functions, validators, abstracted functions) with server RPC delegation. This is a test fixture documenting expected output.
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnValidator.tsx (1)
1-10: LGTM! Test snapshot correctly demonstrates input validator transformation.The snapshot shows the expected server-provider output where input validation is chained with the handler function.
packages/start-plugin-core/tests/createMiddleware/createMiddleware.test.ts (2)
4-5: LGTM! Import updated to use StartCompiler.The import correctly reflects the migration from
ServerFnCompilerto the unifiedStartCompilerin the start-compiler-plugin path.
26-28: LGTM! Compiler initialization correctly uses spread options.The
StartCompilerinitialization properly spreads the default test options, providing the required configuration fields (envName,root,framework,providerEnvName).Also applies to: 84-86
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsx (1)
1-44: LGTM! Test snapshot correctly demonstrates star import transformation.The snapshot shows the expected server-provider output for star imports (
import * as TanStackStart), with server RPC-backed handlers. This is a test fixture documenting the transformation output.packages/start-plugin-core/src/start-compiler-plugin/utils.ts (3)
5-26: LGTM! Well-implemented error reporting utility.The
codeFrameErrorfunction correctly uses Babel'scodeFrameColumnsto generate highlighted code frames with error messages, providing clear diagnostic information for compilation errors.
28-35: LGTM! Robust module ID normalization.The
cleanIdfunction correctly handles:
- Virtual module prefixes (null byte used by Vite/Rollup)
- Query string stripping for module resolution
37-52: LGTM! Clear AST manipulation helper.The
stripMethodCallfunction is well-documented and correctly removes method calls from chains by replacing the CallExpression with its base object. The guard check forMemberExpressionensures safe operation.packages/start-plugin-core/tests/envOnly/envOnly.test.ts (2)
5-6: LGTM! Import updated to use StartCompiler.Consistent with the migration from
ServerFnCompilerto the unifiedStartCompilerarchitecture.
23-25: LGTM! Compiler initialization correctly configured.The
StartCompilerinitialization properly uses spread options to provide all required configuration fields.packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/factory.tsx (1)
1-45: LGTM! Test snapshot demonstrates middleware composition and factory patterns.The snapshot correctly shows:
- Middleware chaining (authMiddleware → adminMiddleware)
- Factory pattern for creating configured server functions
- Server RPC-backed handlers
- A fake function factory for testing edge cases
This is a comprehensive test fixture documenting the expected transformation output.
packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts (2)
7-15: Well-structured test helper for default options.The
getDefaultTestOptionshelper cleanly centralizes default test configuration and improves maintainability across test cases.
68-88: Improved test parametrization with clear environment separation.The test structure now clearly separates three compilation scenarios (client, server-caller, server-provider) with appropriate folder mapping. This provides better test coverage of the different compilation paths.
packages/start-plugin-core/src/plugin.ts (1)
355-366: Clean architectural consolidation.The replacement of
TanStackServerFnPluginwithstartCompilerPluginsimplifies the architecture and removes the directive-based approach in favor of explicitproviderEnvNameconfiguration. The inline comments clearly explain the plugin's responsibilities.packages/start-plugin-core/tests/compiler.test.ts (2)
11-20: Consistent test helper pattern.The
getDefaultTestOptionshelper matches the pattern used increateServerFn.test.ts, providing consistent test configuration across the test suite.
217-300: Comprehensive multi-kind compiler testing.The test suite thoroughly validates that a single compiler instance can correctly handle files with different kinds (ServerFn, Middleware, IsomorphicFn, ServerOnlyFn, ClientOnlyFn) in succession, ensuring no state leakage between compilations.
packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsx (1)
1-42: Missing axios import and type declarations.This test snapshot references
axios(lines 10, 18, 27) andPostTypebut doesn't import them, which would cause runtime errors if this code were executed.If this is a test fixture, consider adding the missing imports for completeness:
+import axios from 'axios' import { createServerRpc } from '@tanstack/react-start/server-rpc'; import { createServerFn as serverFn } from '@tanstack/react-start'; import { z } from 'zod'; + +type PostType = { id: number; title: string; body: string }⛔ Skipped due to learnings
Learnt from: nlynzaad Repo: TanStack/router PR: 5402 File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21 Timestamp: 2025-10-08T08:11:47.088Z Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.packages/start-plugin-core/src/start-compiler-plugin/compiler.ts (4)
333-372: LGTM! Well-documented constructor options for multi-environment support.The expanded constructor options properly support the new multi-environment compilation workflow, with clear documentation for each parameter.
377-431: LGTM! Robust function ID generation with proper deduplication.The generateFunctionId method properly handles both dev and build modes:
- Dev: base64url-encoded JSON for direct lookup
- Build: SHA256 hash with collision handling
The deduplication logic ensures uniqueness even with custom generators.
116-141: LGTM! Clean handler registry pattern with good separation of concerns.The KindHandlers registry provides a maintainable way to dispatch candidates to their respective handlers. The exclusion of ClientOnlyJSX is correct since it's handled separately via JSX traversal.
926-961: LGTM! Clean batch processing implementation using handler registry.The new batch processing approach groups candidates by kind and dispatches them to registered handlers, replacing the previous ad-hoc dispatch logic. This is more maintainable and type-safe.
packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts (2)
15-69: LGTM! Excellent use of pre-compiled templates and caching.The pre-compiled Babel templates and runtime code cache are smart optimizations that avoid repeated AST parsing and generation during compilation.
185-434: LGTM! Well-structured createServerFn transformation logic.The handler properly distinguishes between provider and caller files, with appropriate validation and environment-aware RPC stub generation. The function name uniqueness tracking and export management are handled correctly.
packages/start-plugin-core/src/start-compiler-plugin/plugin.ts (2)
183-423: LGTM! Well-structured plugin composition with environment-aware configuration.The startCompilerPlugin properly composes multiple sub-plugins for different purposes (per-environment transforms, dev-mode capture/validation, server function resolver), with clear separation of concerns.
103-168: LGTM! Clean manifest module generation with environment-aware behavior.The generateManifestModule function properly generates the server function resolver with optional client-referenced checks based on the provider environment configuration.
packages/start-plugin-core/src/start-compiler-plugin/types.ts (1)
1-133: LGTM! Comprehensive and well-documented type definitions.The type definitions properly support the multi-environment compilation workflow with clear documentation for all public interfaces. Good use of readonly modifiers for immutable properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts (1)
278-285: Potential null dereference onlocproperty.This issue was already flagged in a previous review. The
handlerFnPath.node.locmay beundefinedif the AST node lacks source location information.
🧹 Nitpick comments (2)
packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts (2)
53-64: Verifybabel.template.astreturn type cast.
babel.template.astreturnsStatement | Statement[], but the code casts directly tot.Statement. While import declarations typically return a single statement, this cast bypasses TypeScript's type safety.Consider adding a runtime check or using a type guard:
🔎 Suggested safer handling
- provider: babel.template.ast( - `import { createServerRpc } from '@tanstack/${framework}-start/server-rpc'`, - { placeholderPattern: false }, - ) as t.Statement, + provider: (() => { + const result = babel.template.ast( + `import { createServerRpc } from '@tanstack/${framework}-start/server-rpc'`, + { placeholderPattern: false }, + ) + if (Array.isArray(result)) { + throw new Error('Expected single statement from template') + } + return result + })(),
484-487: Consider using falsy check instead of strict null comparison.
node.declarationcan benullorundefinedfor re-export statements. Using=== nullmay miss theundefinedcase depending on how Babel parses the AST.🔎 Suggested safer check
- } else if (node.declaration === null) { + } else if (!node.declaration) { // remove e.g. `export { RouteComponent as component }` return [] }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
🧬 Code graph analysis (1)
packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts (5)
packages/start-plugin-core/src/start-compiler-plugin/types.ts (3)
CompilationContext(9-31)RewriteCandidate(70-73)ServerFn(79-93)packages/start-plugin-core/src/constants.ts (1)
VITE_ENVIRONMENT_NAMES(1-6)packages/start-server-core/src/tanstack-start.d.ts (1)
ServerFn(14-14)packages/start-plugin-core/src/start-compiler-plugin/utils.ts (3)
cleanId(28-35)codeFrameError(5-26)stripMethodCall(46-52)packages/start-plugin-core/src/start-compiler-plugin/plugin.ts (4)
handler(344-347)handler(358-364)handler(380-382)handler(386-419)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Preview
- GitHub Check: Test
🔇 Additional comments (5)
packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts (5)
1-10: LGTM!Clean imports with proper separation of external dependencies and local modules. Using
pathefor cross-platform path handling is a good choice.
11-34: LGTM!Pre-compiling Babel templates at module load time is a good performance optimization. The template definitions are clear and well-documented.
71-118: LGTM!The environment configuration logic is well-structured with clear separation of concerns. The
getEnvConfigfunction correctly derives runtime code type based on compilation context.
120-166: LGTM!RPC stub generation utilities are well-implemented with clear logic. The conditional handling for SSR callers (manifest lookup vs dynamic importer) is well-documented.
376-381: Verify binding removal doesn't affect other usages.When the handler is an identifier, this code removes the entire binding (function declaration/expression). If the same identifier is used elsewhere in the file (e.g., for other purposes), this could cause issues.
The current approach assumes the bound function is exclusively used as a server function handler. This is likely correct given the transformation context, but worth verifying.
| if (!t.isIdentifier(variableDeclarator.id)) { | ||
| throw codeFrameError( | ||
| context.code, | ||
| variableDeclarator.id.loc!, | ||
| 'createServerFn must be assigned to a simple identifier, not a destructuring pattern', | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential null dereference on loc property.
The variableDeclarator.id.loc may be undefined if the AST node lacks source location information. While rare in practice, the non-null assertion on line 223 could fail.
🔎 Suggested defensive handling
throw codeFrameError(
context.code,
- variableDeclarator.id.loc!,
+ variableDeclarator.id.loc ?? candidatePath.node.loc!,
'createServerFn must be assigned to a simple identifier, not a destructuring pattern',
)🤖 Prompt for AI Agents
In packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
around lines 220-226, the code uses a non-null assertion on
variableDeclarator.id.loc which can be undefined; update the guard to avoid
dereferencing loc directly — first check if variableDeclarator.id.loc exists and
pass it to codeFrameError, otherwise fall back to a safe alternative (e.g.,
variableDeclarator.loc, context.node?.loc, or a constructed synthetic location
or message) or call codeFrameError with a message/location that handles
undefined; ensure no non-null assertions remain and the error path still
provides useful context.
| if (!handler || !handlerFnPath?.node) { | ||
| throw codeFrameError( | ||
| context.code, | ||
| candidatePath.node.callee.loc!, | ||
| `createServerFn must be called with a "handler" property!`, | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential null dereference on callee.loc property.
Similar to other loc! usages, candidatePath.node.callee.loc may be undefined.
🔎 Suggested defensive handling
throw codeFrameError(
context.code,
- candidatePath.node.callee.loc!,
+ candidatePath.node.callee.loc ?? candidatePath.node.loc!,
`createServerFn must be called with a "handler" property!`,
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!handler || !handlerFnPath?.node) { | |
| throw codeFrameError( | |
| context.code, | |
| candidatePath.node.callee.loc!, | |
| `createServerFn must be called with a "handler" property!`, | |
| ) | |
| } | |
| if (!handler || !handlerFnPath?.node) { | |
| throw codeFrameError( | |
| context.code, | |
| candidatePath.node.callee.loc ?? candidatePath.node.loc!, | |
| `createServerFn must be called with a "handler" property!`, | |
| ) | |
| } |
🤖 Prompt for AI Agents
In packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
around lines 270 to 276, the code unconditionally dereferences
candidatePath.node.callee.loc which can be undefined; change this to safely
derive a location before calling codeFrameError by using
candidatePath.node.callee?.loc || candidatePath.node.loc (or another safe
fallback like context.node?.loc) and pass that fallback (or null/undefined) into
codeFrameError; if no location is available, call codeFrameError with a generic
location-safe overload or construct a descriptive error message without assuming
callee.loc exists.
| function makeIdentifierSafe(identifier: string): string { | ||
| return identifier | ||
| .replace(/[^a-zA-Z0-9_$]/g, '_') // Replace unsafe chars with underscore | ||
| .replace(/^[0-9]/, '_$&') // Prefix leading number with underscore | ||
| .replace(/^\$/, '_$') // Prefix leading $ with underscore | ||
| .replace(/_{2,}/g, '_') // Collapse multiple underscores | ||
| .replace(/^_|_$/g, '') // Trim leading/trailing underscores | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edge case: empty result from makeIdentifierSafe.
If the input consists entirely of special characters (e.g., "@#$%"), the function could return an empty string, which is not a valid JavaScript identifier.
🔎 Suggested defensive handling
function makeIdentifierSafe(identifier: string): string {
- return identifier
+ const result = identifier
.replace(/[^a-zA-Z0-9_$]/g, '_') // Replace unsafe chars with underscore
.replace(/^[0-9]/, '_$&') // Prefix leading number with underscore
.replace(/^\$/, '_$') // Prefix leading $ with underscore
.replace(/_{2,}/g, '_') // Collapse multiple underscores
.replace(/^_|_$/g, '') // Trim leading/trailing underscores
+ return result || '_anon'
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function makeIdentifierSafe(identifier: string): string { | |
| return identifier | |
| .replace(/[^a-zA-Z0-9_$]/g, '_') // Replace unsafe chars with underscore | |
| .replace(/^[0-9]/, '_$&') // Prefix leading number with underscore | |
| .replace(/^\$/, '_$') // Prefix leading $ with underscore | |
| .replace(/_{2,}/g, '_') // Collapse multiple underscores | |
| .replace(/^_|_$/g, '') // Trim leading/trailing underscores | |
| } | |
| function makeIdentifierSafe(identifier: string): string { | |
| const result = identifier | |
| .replace(/[^a-zA-Z0-9_$]/g, '_') // Replace unsafe chars with underscore | |
| .replace(/^[0-9]/, '_$&') // Prefix leading number with underscore | |
| .replace(/^\$/, '_$') // Prefix leading $ with underscore | |
| .replace(/_{2,}/g, '_') // Collapse multiple underscores | |
| .replace(/^_|_$/g, '') // Trim leading/trailing underscores | |
| return result || '_anon' | |
| } |
🤖 Prompt for AI Agents
In packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
around lines 439-446, makeIdentifierSafe can return an empty string for inputs
made only of invalid chars; update it to defensively return a valid JS
identifier when the transformed result is empty (for example return '_' or '_id'
or prefix a fallback string) and keep existing rules (no leading digit, collapse
underscores, trim). Ensure the function returns a non-empty string that starts
with a letter, underscore, or $ (use '_' as the simplest safe fallback).

Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.