Skip to content

fix(better-auth): array support#2617

Merged
ymc9 merged 1 commit into
zenstackhq:devfrom
pkudinov:fix/better-auth-array-support
Apr 28, 2026
Merged

fix(better-auth): array support#2617
ymc9 merged 1 commit into
zenstackhq:devfrom
pkudinov:fix/better-auth-array-support

Conversation

@pkudinov
Copy link
Copy Markdown
Contributor

@pkudinov pkudinov commented Apr 25, 2026

Summary

Fixes #2615.

This updates the ZenStack Better Auth adapter so Better Auth array fields are preserved for PostgreSQL-backed ZenStack schemas instead of being JSON-stringified before ZenStack validation. The adapter config now exposes supportsArrays, defaulting to native array support for PostgreSQL and disabled array support for SQLite.

Schema generation now uses the same capability decision as runtime: string[] and number[] become native String[] and Int[] when arrays are supported, and fall back to Json fields when they are not.

This problem prevents normal use of Better Auth OAuth Provider plugin.

Validation

  • pnpm --filter @zenstackhq/better-auth lint
  • pnpm --filter @zenstackhq/better-auth build
  • pnpm --filter @zenstackhq/better-auth test

Summary by CodeRabbit

Release Notes

  • Refactor

    • Enhanced Better Auth adapter configuration to intelligently handle array-type fields based on database provider—arrays are natively supported on PostgreSQL, while other databases use JSON serialization for compatibility.
  • Tests

    • Added test suite validating array field handling and schema generation behavior across different database configurations.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 25, 2026

📝 Walkthrough

Walkthrough

The PR refactors Better Auth adapter configuration to properly handle array field support. It introduces a new config module defining AdapterConfig and a getSupportsArrays helper that defaults array support to true for PostgreSQL and false for other providers. The adapter now forwards this capability to Better Auth's factory, while schema generation conditionally emits native arrays or JSON fields based on this flag.

Changes

Cohort / File(s) Summary
Configuration Management
packages/auth-adapters/better-auth/src/adapter.ts, packages/auth-adapters/better-auth/src/config.ts
Extracted AdapterConfig into dedicated module with getSupportsArrays helper. Adapter now computes and passes supportsArrays to Better Auth factory, defaulting to true for PostgreSQL and false for other providers.
Schema Generation
packages/auth-adapters/better-auth/src/schema-generator.ts
Updated field mapping to conditionally generate native array fields (String[], Int[]) when arrays are supported, or Json fields when not, based on getSupportsArrays(config).
Test Coverage
packages/auth-adapters/better-auth/test/adapter.test.ts
New test suite validating array handling: PostgreSQL preserves arrays as native types, SQLite converts to JSON; schema generation produces correct field types per provider capability.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Array fields now hop with proper care,
Each database gets what it can bear—
PostgreSQL arrays run free and wild,
While JSON fields keep others reconciled.
The schema and runtime, at last aligned! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The code changes fully address issue #2615 by adding array support configuration and conditional schema generation based on database provider capabilities.
Out of Scope Changes check ✅ Passed All changes directly support the objective of fixing array handling in the Better Auth adapter; no out-of-scope modifications detected.
Title check ✅ Passed The title directly addresses the main change: fixing array field handling in the Better Auth adapter for PostgreSQL and other database providers.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkudinov pkudinov force-pushed the fix/better-auth-array-support branch from 4957aa1 to b5a1b44 Compare April 25, 2026 05:25
@pkudinov pkudinov marked this pull request as ready for review April 25, 2026 05:25
@pkudinov pkudinov marked this pull request as draft April 25, 2026 05:25
@pkudinov pkudinov marked this pull request as ready for review April 25, 2026 05:26
@pkudinov pkudinov changed the title fix better-auth array support fix(better-auth): array support Apr 25, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/auth-adapters/better-auth/test/adapter.test.ts (1)

41-51: Minor: mock $transaction recursion creates a fresh oauthClient mock per call.

$transaction calls makeDb(captured) again, so the inner oauthClient.create is a new function instance each time. captured is shared by reference so test assertions still work, but if a future test relies on identity (e.g., expect(spy).toHaveBeenCalled() on the outer mock), it'll silently miss the tx path. Not an issue for the current assertions — flagging only as a forward-looking note.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/auth-adapters/better-auth/test/adapter.test.ts` around lines 41 -
51, The mock created by makeDb recreates oauthClient for each $transaction
because $transaction calls makeDb(captured) again; instead, build the db object
once inside makeDb and have $transaction invoke cb(db) so the same
oauthClient.create instance is used across transactions (refer to makeDb,
$transaction, and oauthClient.create) to preserve identity for spies while still
sharing the captured object.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/auth-adapters/better-auth/test/adapter.test.ts`:
- Around line 41-51: The mock created by makeDb recreates oauthClient for each
$transaction because $transaction calls makeDb(captured) again; instead, build
the db object once inside makeDb and have $transaction invoke cb(db) so the same
oauthClient.create instance is used across transactions (refer to makeDb,
$transaction, and oauthClient.create) to preserve identity for spies while still
sharing the captured object.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 982bdf4c-802c-47e1-9010-00cca1b01e3d

📥 Commits

Reviewing files that changed from the base of the PR and between 8609d5b and b5a1b44.

📒 Files selected for processing (4)
  • packages/auth-adapters/better-auth/src/adapter.ts
  • packages/auth-adapters/better-auth/src/config.ts
  • packages/auth-adapters/better-auth/src/schema-generator.ts
  • packages/auth-adapters/better-auth/test/adapter.test.ts

Copy link
Copy Markdown
Member

@ymc9 ymc9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me! Thanks for making this fix @pkudinov .

@ymc9 ymc9 merged commit 0bc1f48 into zenstackhq:dev Apr 28, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@zenstackhq/better-auth adapter serializes Better Auth string[] fields before ZenStack validation

2 participants