feat: add createTypedAdapter for model-inferred doc types - #401
feat: add createTypedAdapter for model-inferred doc types#401FatahChan wants to merge 11 commits into
Conversation
Convex function references use a fixed return type, so adapter findOne/create results stay `any` even when model is a literal. createTypedAdapter wraps the adapter refs and infers Doc<table> from the model argument at the call site. Co-authored-by: Cursor <cursoragent@cursor.com>
Stub adapter fns with real FunctionReference values so tsc accepts the test file, and align model literals with the current schema. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@FatahChan is attempting to deploy a commit to the Convex Team on Vercel. A member of the Team first needs to authorize it. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds Sequence Diagram(s)sequenceDiagram
participant Caller
participant createClient
participant createTypedAdapter
participant QueryRunner
participant MutationRunner
Caller->>createClient: createClient(config)
createClient->>createTypedAdapter: build typedAdapter(schema, adapter fns)
Caller->>createClient: getAuthUser / getHeaders / getAnyUserById
createClient->>createTypedAdapter: findOne(model, where)
createTypedAdapter->>QueryRunner: runQuery(...)
QueryRunner-->>createTypedAdapter: typed document or null
createTypedAdapter-->>createClient: typed result
createClient-->>Caller: auth data / headers / user
Caller->>createTypedAdapter: create(model, data)
createTypedAdapter->>MutationRunner: runMutation(...)
MutationRunner-->>createTypedAdapter: created document
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/client/create-typed-adapter.ts`:
- Around line 58-67: The helper types SortBy and BatchResult are part of the
public API shape used by findMany, updateMany, and deleteMany, but they are
currently internal-only. Export these type aliases from create-typed-adapter.ts
so consumers can import and reuse them directly, and make sure any related
public signatures still reference the exported symbols consistently across the
typed adapter methods.
In `@src/client/create-typed-adapter.types.test.ts`:
- Around line 34-38: The type test is referencing models that are not defined by
the imported schema, so the `member` and `invitation` checks in
`create-typed-adapter.types.test` must be moved to the plugin-table schema test
setup or removed. Update the assertions to live alongside
`src/component/testProfiles/schema.profile-plugin-table.ts` (or switch the test
to that schema) so `findOne` is validated against the schema that actually
declares `member` and `invitation`.
- Around line 1-63: The type-only Vitest checks in createTypedAdapter are
currently in a filename that the default typecheck glob will not pick up. Rename
this test to match Vitest’s typecheck pattern used by `vitest run --typecheck`,
or add a custom `typecheck.include` so `createTypedAdapter`, `expectTypeOf`, and
the `findOne`/`create`/`findMany` assertions are actually type-checked.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: get-convex/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c9320782-7c62-4e4b-be58-e0bfd6408e9c
📒 Files selected for processing (3)
src/client/create-typed-adapter.tssrc/client/create-typed-adapter.types.test.tssrc/client/index.ts
…syntax Changed type annotations for 'where' and 'select' parameters in createTypedAdapter to use Array<T> syntax for consistency and clarity.
Export SortBy and BatchResult for consumers, include *.types.test.ts in Vitest typecheck, and allow generated Convex files in test tsconfig. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tsconfig.test.json (1)
10-10: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueBroad
_generatedinclusion.Removing
**/_generatedentirely (rather than narrowing it, e.g.!src/component/_generated) makes the test tsconfig pull in all generated Convex artifacts undersrc/**,example/src/**, andexample/convex/**. This is needed for the new type test's_generated/dataModelimport, but broadens the typecheck surface to any other generated code in those trees.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tsconfig.test.json` at line 10, The test tsconfig is now pulling in too many generated Convex artifacts, so narrow the `tsconfig.test.json` exclude/include rules instead of broadly removing `**/_generated`; keep the new `_generated/dataModel` import working, but scope the exception to the specific test fixture or generated path rather than all `src/**`, `example/src/**`, and `example/convex/**`. Update the config around `exclude` so only the needed generated files are typechecked while unrelated generated code stays out of the test surface.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tsconfig.test.json`:
- Line 10: The test tsconfig is now pulling in too many generated Convex
artifacts, so narrow the `tsconfig.test.json` exclude/include rules instead of
broadly removing `**/_generated`; keep the new `_generated/dataModel` import
working, but scope the exception to the specific test fixture or generated path
rather than all `src/**`, `example/src/**`, and `example/convex/**`. Update the
config around `exclude` so only the needed generated files are typechecked while
unrelated generated code stays out of the test surface.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: get-convex/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 88db16f6-b537-4c22-bb59-abf701a2034d
📒 Files selected for processing (4)
src/client/create-typed-adapter.tssrc/client/index.tstsconfig.test.jsonvitest.config.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/client/index.ts
- src/client/create-typed-adapter.ts
Wire createTypedAdapter into the component client and local-install API so adapter calls infer doc types from model, and document the pattern. Co-authored-by: Cursor <cursoragent@cursor.com>
Remove the unused typed export from createApi and add a full local-install example for authComponent.typedAdapter as the single typed entry point. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep generated files out of the test project root while still allowing type tests to import component _generated types via composite: false. Co-authored-by: Cursor <cursoragent@cursor.com>
…d default exports
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/client/create-client.ts`:
- Around line 17-21: The import in create-client.ts mixes value and inline type
specifiers, which triggers the consistent-type-specifier-style rule. Update the
createTypedAdapter import so the type-only names AdapterFunctions and
TypedAdapter are moved into a top-level type-only import, while keeping the
runtime createTypedAdapter import separate or otherwise using a consistent
top-level type import style. Use the existing import block at the top of the
file to make the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: get-convex/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 80754f43-225a-4b56-893b-3eb2caeb6222
📒 Files selected for processing (6)
docs/content/docs/api/component-client.mdxdocs/content/docs/api/type-utilities.mdxdocs/content/docs/features/local-install.mdxpackage.jsonsrc/client/create-client.tstsconfig.test.json
✅ Files skipped from review due to trivial changes (3)
- docs/content/docs/api/component-client.mdx
- docs/content/docs/features/local-install.mdx
- docs/content/docs/api/type-utilities.mdx
Narrow where-clause field and value types from the model argument, with a fallback to the validator shape when the schema type is still generic. Co-authored-by: Cursor <cursoragent@cursor.com>
Narrow findOne/findMany returns from select, validate sortBy.field per model, and document where/select/sortBy narrowing in guides. Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
createTypedAdapter(schema, adapterRefs)— typed wrappers around the Better Auth adapter API (findOne,findMany,create,updateOne,updateMany,deleteOne,deleteMany)authComponent.typedAdapteroncreateClientas the recommended entry point for app code (uses local schema when configured)Doc<table>from themodelliteral at the call site (e.g.model: "user"→Doc<"user"> | null)AdapterWhere<S, T>—fieldandvaluenarrow with the tableselectonfindOne/findMany— return type becomesPick<Doc<table>, …>SortBy<S, T>onfindMany—fieldmust be a document keycreateClient)TypedAdapter,AdapterFunctions,AdapterWhere,SortBy, andBatchResult@convex-dev/better-auth/typed-adaptersubpath export (main entry also exports everything)*.types.test.tsin the typecheck globProblem
createApiusesqueryGeneric/mutationGeneric, so Convex codegen types adapter returns asany. Even with discriminated-union args,FunctionReturnTypeis fixed on the reference and does not narrow from call-sitemodel.Calling
ctx.runQuery(components.betterAuth.adapter.findOne, …)directly has the same limitation —where,select, andsortByaccept anyfield: stringwith no value or return narrowing.Usage
Recommended — via
createClient(local install with schema):Lower-level —
createTypedAdapterdirectly:The cast lives inside the library at the Convex
runQuery/runMutationboundary.Internal changes
createClientusestypedAdapterinternally forsafeGetAuthUser,getHeaders, andgetAnyUserById(removes manual casts)Test plan
npm test(70 tests, vitest--typecheck)npm run buildwhere,select, andsortBy