Commit 33faa05
fix(e2e): split createServerFn handlers out of base-service.ts to satisfy import-protection
The TanStack Start v1.167 dep bump (from 1.149) ships a new `tanstack-start-core:import-protection` Vite plugin that walks the import graph and rejects any module reachable from a client route that imports `@tanstack/react-start/server` — even via dynamic `await import(...)`. The failure trace:
router.tsx → routeTree.gen → routes/tasks/$taskId.tsx → utils/query/queries.ts
→ functions/base-service.ts:161 → "@tanstack/react-start/server" ❌ DENIED
This bricked the marketing + admin-users e2e tests because the dev server returned a 500 on the entry route. CI's other gates passed because they don't actually load the client bundle.
Root cause is a pre-existing design flaw in base-service.ts that 1.149 didn't enforce: it housed BOTH the entity registry / auth helpers AND every createServerFn surface (deleteEntity/createEntity/updateEntity/findFirst/findMany), so any client-reachable module importing one of those handlers dragged the whole server-only chain into the compile pass.
gell-v2's actual structure (verified by inspection — `C:\Users\enalm\code\gell\gell-v2\src\functions\find-first.ts` et al) splits each createServerFn into its own per-handler file; `base-service.ts` becomes types/validators/helpers only. The framework-extracted handler body holds the dynamic imports of `base-service.ts`, and since extraction strips those bodies from the client bundle, the chain never lands in the client compile pass.
Applied the same split:
- NEW src/functions/find-first.ts — exports findFirst createServerFn + handleFindFirst
- NEW src/functions/find-many.ts — exports findMany createServerFn + handleFindMany
- NEW src/functions/create-entity.ts — exports createEntity createServerFn + handleCreateEntity
- NEW src/functions/update-entity.ts — exports updateEntity createServerFn + handleUpdateEntity
- NEW src/functions/delete-entity.ts — exports deleteEntity createServerFn + handleDeleteEntity
- src/functions/base-service.ts (slim): now only types (EntityType, *Payload), validators (validateDeleteEntity/etc.), the error formatter (formatIssues), createWhereSchema, loadEntityConfig, and getUser. No createServerFn. No handler functions.
- src/utils/query/queries.ts: imports findFirst from ~/functions/find-first, findMany from ~/functions/find-many.
- src/utils/query/mutations.ts: imports createEntity / updateEntity / deleteEntity from the new per-handler files.
- src/utils/query/__tests__/queries.test.ts: vi.mock updated to mock the per-handler files instead of base-service.
- src/functions/__tests__/base-service.test.ts: imports deleteEntity from delete-entity.ts.
Subject-specific schema validation (drizzle-valibot insert/update schemas) was previously inlined in createEntity / updateEntity's chained .inputValidator. The new files move that into the handler body so the input validator stays drizzle-free. Same correctness, cleaner separation.
Local: bun run check-types ✓, bun run lint ✓ (biome auto-sorted imports in 5 new files), bun run check-tss-2 ✓ (now scans 8 createServerFn files, all clean), bun run test:unit ✓ (62 tests pass).
Test-e2e: should now pass — the import-protection block is gone because base-service.ts is no longer reached from any client-route compile pass. CI will verify.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>1 parent 37dd3b6 commit 33faa05
10 files changed
Lines changed: 375 additions & 333 deletions
File tree
- src
- functions
- __tests__
- utils/query
- __tests__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
| 54 | + | |
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| |||
0 commit comments