Thread the app's Prisma client type through TypeInfo into hook context - #1214
Merged
Conversation
TypeInfo gains a `prisma` member (defaulted to PrismaClientLike, fully additive) and every list/field hook-args type now types `context` as StackContext<TTypeInfo['prisma']> / AccessContext<TTypeInfo['prisma']> instead of the unparameterised default. Previously context.db resolved through AccessControlledDB<any> - a mapped type over keyof any that contributes no named property - so a hook's context was assignable to nothing app-specific and consumers needed `context as unknown as Context` to use it anywhere typed. The CLI generator emits the new `prisma` member on each list's Lists.<List>.TypeInfo, pointing at the project's own generated PrismaClient, so no config changes are required downstream. Adds a dedicated compile-time regression test (against core's real built types, not a stub) proving context.db is now assignable to the generated CustomDB with no cast and resolves real per-list row types, and extends the #952 large-schema fixture to also generate the Lists namespace and exercise list-level/field-level hooks reading context.db without reintroducing TS2589. Closes #1211 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UUfo5pf9kkNAYQ54X9EEhp
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
🦋 Changeset detectedLatest commit: d7c3fbb The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Coverage Report for Core Package Coverage (./packages/core)
File CoverageNo changed files found. |
Contributor
Coverage Report for UI Package Coverage (./packages/ui)
File CoverageNo changed files found. |
Contributor
Coverage Report for CLI Package Coverage (./packages/cli)
File Coverage
|
||||||||||||||||||||||||||||||||||||||
Contributor
Coverage Report for Auth Package Coverage (./packages/auth)
File CoverageNo changed files found. |
Contributor
Coverage Report for Storage Package Coverage (./packages/storage)
File CoverageNo changed files found. |
Contributor
Coverage Report for RAG Package Coverage (./packages/rag)
File CoverageNo changed files found. |
Contributor
Coverage Report for Storage S3 Package Coverage (./packages/storage-s3)
File CoverageNo changed files found. |
Contributor
Coverage Report for Storage Vercel Package Coverage (./packages/storage-vercel)
File CoverageNo changed files found. |
Merged
This was referenced Sep 6, 2026
Closed
borisno2
pushed a commit
that referenced
this pull request
Sep 7, 2026
Addresses a review finding on #1268: TypeInfo's new db member is required, so an app that upgrades without re-running `opensaas generate` sees a stale Lists.<List>.TypeInfo fail to type-check until it regenerates — the same accepted trade-off #1214 made for the prisma member. Calling it out explicitly rather than changing the fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FtUdHuNi2yY4vRW2wBfyVN
This was referenced Sep 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TypeInfogains aprismamember (defaulted to the existingPrismaClientLike, so this is fully additive) carrying the consuming app's own generated Prisma client type.ResolveInputHookArgs,ValidateHookArgs,BeforeOperationHookArgs,AfterOperationHookArgs,BeforeTransactionHookArgs,AfterTransactionHookArgs) gains aTPrismaparameter and typescontextasStackContext<TPrisma>/AccessContext<TPrisma>instead of the unparameterised default.Hooksforwards it through to all of them.TTypeInfo) now typescontextasStackContext<TTypeInfo['prisma']>/AccessContext<TTypeInfo['prisma']>.ListConfig<TTypeInfo>forwardsTTypeInfo['prisma']intoHooks, the same way it already forwardsitemandinputs.lists.ts) emits the newprismamember on each list's generatedLists.<List>.TypeInfo, pointing at the project's own generatedPrismaClient— noopensaas.config.tschanges required downstream.Before:
context.dbinside any hook resolved throughAccessControlledDB<any>(a mapped type overkeyof anythat contributes no named property), so a hook'scontextwas assignable to nothing app-specific — consumers neededcontext as unknown as Contextto pass it into their own typed functions.After: a hook authored the documented way (
list<Lists.Post.TypeInfo>({ hooks: {...} })) gets acontextkeyed to the app's own Prisma client —context.db.<list>resolves to a real, named delegate, andcontext.dbis assignable to the app's generatedCustomDBwith no cast.Known, deliberately out-of-scope limitation:
AccessControlledDB's catch-all& { [key: string]: any }index signature is unchanged by this fix, so a misspelled delegate name (context.db.typoedListName) still silently type-checks rather than failing to compile — closing that needs narrowing/removing that index signature, which is tracked separately under the Prisma 8 contract-keying migration (ADR-0052), not here. Covered by a dedicated test asserting this documented limitation.Also found while verifying against a real example project (not touched by this PR, filed separately if warranted): a singleton list's generated
.get()sugar andStackContext.session'sSession | nullare both pre-existing, unrelated structural gaps between core's generic context types and the generator's own narrowedContext/CustomDB— fullContext/BaseContextassignability (as opposed tocontext.db→CustomDB) still needs a cast in those cases, orthogonal to the Prisma-client typing this issue is about.Test plan
pnpm buildacross all 11 packages (core, cli, auth, ui, rag, storage/-s3/-vercel, tiptap, create-opensaas-app, docs)pnpm testfor core (1259 tests) and cli (384 tests, including 2 new)packages/cli/src/generator/types-hook-context.test.ts), built against core's real compiled types rather than a stub, asserting:context.dbis assignable to the generatedCustomDBwith no cast, real per-list row types are resolved (notany), and the documented typo-permissiveness limitationtypes-large-schema.test.ts(Generated Context/CustomDB type hits TS2589 (excessively deep instantiation) once schema grows past ~7-8 lists #952's regression fixture) to also generate theListsnamespace and exercise a list-level and field-level hook readingcontext.dbacross 21 lists, confirming noTS2589instantiation-depth regressionexamples/blog(pnpm generate && tsc --noEmit) with a throwaway hook consumingcontext.db.post/context.db.userand assigningcontext.dbto the generatedCustomDBpnpm lint,pnpm manypkg fix,pnpm format@opensaas/stack-coreand@opensaas/stack-cli, minor)Closes #1211
🤖 Generated with Claude Code
https://claude.ai/code/session_01UUfo5pf9kkNAYQ54X9EEhp
Generated by Claude Code