feat(auth): add Supabase Auth REST client#42
Conversation
WalkthroughAdds a Supabase Auth REST client (signup, login, refresh), new SupabaseAuthError, tests, README examples, and broadens audience types/normalization for Supabase JWTs. Also bumps package versions: api@0.3.2, auth@0.5.0, types@0.5.0 with changelog updates. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client as App / Consumer
participant Lib as SupabaseAuthClient
participant Fetch as HTTP(fetch)
rect rgb(220,235,255)
Client->>Lib: createSupabaseAuthClient(opts)
Client->>Lib: .signup(email,password, redirect?)
Lib->>Fetch: POST /auth/v1/signup {email,password,redirect_to}
Fetch-->>Lib: 200 / error JSON
alt success
Lib-->>Client: SupabaseTokenPayload
else error
Lib-->>Client: SupabaseAuthError
end
end
rect rgb(235,245,220)
Client->>Lib: .login(email,password)
Lib->>Fetch: POST /auth/v1/token {grant_type=password,...}
Fetch-->>Lib: 200 / error JSON
Lib-->>Client: token or SupabaseAuthError
end
rect rgb(255,240,230)
Client->>Lib: .refresh(refreshToken)
Lib->>Fetch: POST /auth/v1/token {grant_type=refresh_token,...}
Fetch-->>Lib: 200 / error JSON
Lib-->>Client: token or SupabaseAuthError
end
note right of Lib: Token normalization and extractTokenResponse\nhandles nested `data` and multiple payload shapes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–25 minutes
Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 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: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
packages/api/CHANGELOG.md(1 hunks)packages/api/package.json(1 hunks)packages/auth/CHANGELOG.md(1 hunks)packages/auth/README.md(2 hunks)packages/auth/package.json(1 hunks)packages/auth/src/authentication/supabase.ts(2 hunks)packages/auth/src/index.ts(1 hunks)packages/auth/src/supabase/auth-client.test.ts(1 hunks)packages/auth/src/supabase/auth-client.ts(1 hunks)packages/auth/src/supabase/errors.ts(1 hunks)packages/auth/src/supabase/index.ts(1 hunks)packages/types/CHANGELOG.md(1 hunks)packages/types/package.json(1 hunks)packages/types/src/authentication.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
packages/*/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Reference shared dependencies via the "catalog:" protocol in package manifests
Files:
packages/auth/package.jsonpackages/types/package.jsonpackages/api/package.json
packages/*/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
packages/*/src/**/*.{ts,tsx}: Avoid implicit any; TypeScript is run with strict enabled
Prefer type guards or the satisfies operator over as casts where appropriate
Prefer unknown for external inputs
Use PascalCase for types and enums
Use camelCase for variables and functions
Ensure source comments are written in English
Files:
packages/auth/src/authentication/supabase.tspackages/auth/src/supabase/errors.tspackages/auth/src/supabase/auth-client.tspackages/auth/src/index.tspackages/types/src/authentication.tspackages/auth/src/supabase/auth-client.test.tspackages/auth/src/supabase/index.ts
packages/auth/src/authentication/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Place runtime-specific authentication adapters under packages/auth/src/authentication/ (e.g., header.ts, supabase.ts, shared utilities, errors.ts)
Files:
packages/auth/src/authentication/supabase.ts
packages/auth/src/authentication/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Extend Supabase JWT verification (createSupabaseAuthentication using .well-known/jwks.json) only via dedicated modules to keep caching and claim validation centralized
Files:
packages/auth/src/authentication/supabase.ts
packages/*/src/**/{*.test.ts,__tests__/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
packages/*/src/**/{*.test.ts,__tests__/**/*.ts}: Write test names and descriptions in English
Co-locate tests as *.test.ts or under tests/ using Bun’s test runner
Files:
packages/auth/src/supabase/auth-client.test.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: listee-dev/listee-libs PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-02T12:40:33.718Z
Learning: Applies to packages/auth/src/authentication/**/*.ts : Extend Supabase JWT verification (createSupabaseAuthentication using .well-known/jwks.json) only via dedicated modules to keep caching and claim validation centralized
Learnt from: CR
Repo: listee-dev/listee-libs PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-02T12:40:33.718Z
Learning: Applies to packages/auth/src/authentication/**/*.{ts,tsx} : Place runtime-specific authentication adapters under packages/auth/src/authentication/ (e.g., header.ts, supabase.ts, shared utilities, errors.ts)
📚 Learning: 2025-10-02T12:40:33.718Z
Learnt from: CR
Repo: listee-dev/listee-libs PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-02T12:40:33.718Z
Learning: Applies to packages/auth/src/authentication/**/*.ts : Extend Supabase JWT verification (createSupabaseAuthentication using .well-known/jwks.json) only via dedicated modules to keep caching and claim validation centralized
Applied to files:
packages/auth/src/authentication/supabase.tspackages/auth/src/supabase/errors.tspackages/auth/src/supabase/auth-client.tspackages/auth/src/index.tspackages/types/src/authentication.tspackages/auth/src/supabase/auth-client.test.tspackages/auth/src/supabase/index.tspackages/auth/README.md
📚 Learning: 2025-10-02T12:40:33.718Z
Learnt from: CR
Repo: listee-dev/listee-libs PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-02T12:40:33.718Z
Learning: Applies to packages/auth/src/authentication/**/*.{ts,tsx} : Place runtime-specific authentication adapters under packages/auth/src/authentication/ (e.g., header.ts, supabase.ts, shared utilities, errors.ts)
Applied to files:
packages/auth/src/authentication/supabase.tspackages/auth/src/supabase/errors.tspackages/auth/src/supabase/auth-client.tspackages/auth/src/index.tspackages/types/src/authentication.tspackages/auth/src/supabase/auth-client.test.tspackages/auth/src/supabase/index.tspackages/auth/README.md
📚 Learning: 2025-10-02T12:40:33.718Z
Learnt from: CR
Repo: listee-dev/listee-libs PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-02T12:40:33.718Z
Learning: Applies to packages/auth/src/authorization/**/*.{ts,tsx} : Place domain authorization policies under packages/auth/src/authorization/ (e.g., policies/chat.ts exporting canAccessChat)
Applied to files:
packages/auth/src/supabase/auth-client.tspackages/auth/src/index.tspackages/auth/src/supabase/index.ts
🧬 Code graph analysis (3)
packages/auth/src/supabase/errors.ts (2)
packages/auth/src/index.ts (1)
SupabaseAuthError(25-25)packages/auth/src/supabase/index.ts (1)
SupabaseAuthError(7-7)
packages/auth/src/supabase/auth-client.ts (1)
packages/auth/src/supabase/errors.ts (1)
SupabaseAuthError(1-8)
packages/auth/src/supabase/auth-client.test.ts (2)
packages/auth/src/supabase/auth-client.ts (1)
createSupabaseAuthClient(124-226)packages/auth/src/supabase/errors.ts (1)
SupabaseAuthError(1-8)
🪛 GitHub Actions: CI
packages/auth/src/supabase/auth-client.test.ts
[error] 7-7: TS2741: Property 'preconnect' is missing in type '(input: RequestInfo, init?: RequestInit) => Promise' but required in type 'typeof fetch'.
[error] 97-97: TS2769: No overload matches this call. Overload 1 of 2, '(expected: null): void', gave the following error. Argument of type 'string' is not assignable to parameter of type 'null'. Overload 2 of 2, '(expected: null): void', gave the following error. Argument of type 'string' is not assignable to parameter of type 'null'.
🪛 LanguageTool
packages/auth/README.md
[grammar] ~51-~51: Use a hyphen to join words.
Context: ...l adapters and tests demonstrating error handling scenarios. ## Development - B...
(QB_NEW_EN_HYPHEN)
🔇 Additional comments (27)
packages/api/CHANGELOG.md (1)
3-9: LGTM! Changelog entry is clear and consistent.The patch version bump and dependency update entry accurately reflect the changes in this release.
packages/auth/CHANGELOG.md (1)
3-12: LGTM! Changelog accurately documents the new features.The minor version bump is appropriate for introducing the Supabase Auth REST client and audience array support.
packages/types/CHANGELOG.md (1)
3-7: LGTM! Changelog is consistent with related package changes.The version and description align with the broader feature introduction across the monorepo.
packages/auth/package.json (1)
3-3: LGTM! Version bump is consistent with changelog.The minor version increment to 0.5.0 correctly reflects the new Supabase Auth REST client feature.
packages/types/package.json (1)
3-3: LGTM! Version bump aligns with changelog.The 0.5.0 version correctly reflects the new authentication types and audience config changes.
packages/auth/src/index.ts (1)
18-26: LGTM! Clean public API exports.The new Supabase Auth client types and factory function are properly exposed through the public API with appropriate separation of type and value exports.
packages/api/package.json (1)
3-3: LGTM! Patch version bump for dependency updates.The version increment to 0.3.2 appropriately reflects the dependency updates to @listee/auth@0.5.0 and @listee/types@0.5.0.
packages/types/src/authentication.ts (1)
24-24: LGTM! Backward-compatible type widening.The audience type change from
stringtostring | readonly string[]enables multiple audience values while maintaining full backward compatibility with existing single-string usage.packages/auth/src/supabase/auth-client.test.ts (5)
13-51: LGTM!The login test thoroughly verifies token payload normalization and request body formatting.
53-77: LGTM!The refresh test correctly validates nested data payload handling.
102-117: LGTM!Error propagation test correctly validates error message extraction from Supabase response payloads.
119-131: LGTM!Network failure test correctly validates that low-level errors are wrapped in SupabaseAuthError.
133-142: LGTM!Validation test correctly ensures empty project URLs are rejected with a clear error message.
packages/auth/src/supabase/errors.ts (1)
1-8: LGTM!The SupabaseAuthError class provides clear error context with HTTP status codes and is properly structured for use throughout the auth client.
packages/auth/src/authentication/supabase.ts (2)
72-75: LGTM!The audience normalization correctly handles both single and multiple audiences, converting readonly arrays to mutable arrays as required by jose's JWTVerifyOptions.
116-123: LGTM!The normalized audience is properly typed and applied to the token payload, maintaining consistency with the verification logic.
packages/auth/README.md (2)
13-16: LGTM!The features list clearly documents the new Supabase Auth REST client alongside existing functionality.
20-51: LGTM!The quick start examples are clear and demonstrate both JWT verification and REST endpoint usage patterns. The examples properly reference the new
createSupabaseAuthClientimplementation.packages/auth/src/supabase/index.ts (1)
1-7: LGTM!The module exports provide a clean public API surface for the Supabase auth client and related types.
packages/auth/src/supabase/auth-client.ts (8)
40-56: LGTM!The type guards are well-implemented with proper checks for all required token fields, including finite number validation for
expires_in.
67-86: LGTM!Input validation for project URL and publishable key is thorough, with clear error messages for empty values and invalid URLs.
88-105: LGTM!The error message extraction logic tries multiple common error field names and falls back gracefully to a default message.
107-122: LGTM!JSON parsing is safely handled with proper error wrapping, including handling of empty response bodies.
137-174: LGTM!The request function properly handles network errors, response parsing, and maps HTTP errors to SupabaseAuthError with user-friendly messages. The headers include both
apikeyandAuthorizationas required by Supabase.
176-189: LGTM!Token response extraction correctly handles both direct token payloads and nested data payloads, matching the test expectations.
191-226: LGTM!The public methods (signup, login, refresh) are well-implemented:
- Signup correctly encodes the redirect URL as a query parameter
- Login and refresh use the appropriate grant types
- All methods properly transform responses to the public SupabaseTokenPayload type
3-7: The review comment is based on a misunderstanding of the Fetch API.The
fetch?: typeof fetchtype is correctly used. The Fetch API'sRequestInitdoes not include apreconnectproperty—that's an HTML link relation attribute, not part of the fetch specification. The code properly callsfetchImplwith only standard parameters (method,headers,body), and the test file successfully demonstrates that mock fetch implementations work correctly with this type signature. No changes needed.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/auth/src/supabase/auth-client.test.ts (2)
122-137: Consider verifying error type and status code.The test successfully verifies error message propagation. For more complete coverage, consider also asserting the error type and status code:
- await expect( - client.login({ email: "user@example.com", password: "bad" }), - ).rejects.toThrow("Invalid login"); + const error = await client.login({ + email: "user@example.com", + password: "bad" + }).catch((e) => e); + + expect(error).toBeInstanceOf(SupabaseAuthError); + expect(error.statusCode).toBe(400); + expect(error.message).toContain("Invalid login");
139-151: Consider more specific assertions for network errors.While the test correctly verifies that network failures throw
SupabaseAuthError, you could add assertions for the status code and message to ensure proper error wrapping:- await expect( - client.refresh({ refreshToken: "refresh-token" }), - ).rejects.toThrow(SupabaseAuthError); + const error = await client.refresh({ + refreshToken: "refresh-token" + }).catch((e) => e); + + expect(error).toBeInstanceOf(SupabaseAuthError); + expect(error.statusCode).toBe(500); + expect(error.message).toContain("connection reset");
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/auth/src/supabase/auth-client.test.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
packages/*/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
packages/*/src/**/*.{ts,tsx}: Avoid implicit any; TypeScript is run with strict enabled
Prefer type guards or the satisfies operator over as casts where appropriate
Prefer unknown for external inputs
Use PascalCase for types and enums
Use camelCase for variables and functions
Ensure source comments are written in English
Files:
packages/auth/src/supabase/auth-client.test.ts
packages/*/src/**/{*.test.ts,__tests__/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
packages/*/src/**/{*.test.ts,__tests__/**/*.ts}: Write test names and descriptions in English
Co-locate tests as *.test.ts or under tests/ using Bun’s test runner
Files:
packages/auth/src/supabase/auth-client.test.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: listee-dev/listee-libs PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-02T12:40:33.718Z
Learning: Applies to packages/auth/src/authentication/**/*.ts : Extend Supabase JWT verification (createSupabaseAuthentication using .well-known/jwks.json) only via dedicated modules to keep caching and claim validation centralized
Learnt from: CR
Repo: listee-dev/listee-libs PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-02T12:40:33.718Z
Learning: Applies to packages/auth/src/authentication/**/*.{ts,tsx} : Place runtime-specific authentication adapters under packages/auth/src/authentication/ (e.g., header.ts, supabase.ts, shared utilities, errors.ts)
📚 Learning: 2025-10-02T12:40:33.718Z
Learnt from: CR
Repo: listee-dev/listee-libs PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-02T12:40:33.718Z
Learning: Applies to packages/auth/src/authentication/**/*.ts : Extend Supabase JWT verification (createSupabaseAuthentication using .well-known/jwks.json) only via dedicated modules to keep caching and claim validation centralized
Applied to files:
packages/auth/src/supabase/auth-client.test.ts
📚 Learning: 2025-10-02T12:40:33.718Z
Learnt from: CR
Repo: listee-dev/listee-libs PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-02T12:40:33.718Z
Learning: Applies to packages/auth/src/authentication/**/*.{ts,tsx} : Place runtime-specific authentication adapters under packages/auth/src/authentication/ (e.g., header.ts, supabase.ts, shared utilities, errors.ts)
Applied to files:
packages/auth/src/supabase/auth-client.test.ts
🧬 Code graph analysis (1)
packages/auth/src/supabase/auth-client.test.ts (2)
packages/auth/src/supabase/auth-client.ts (1)
createSupabaseAuthClient(124-226)packages/auth/src/supabase/errors.ts (1)
SupabaseAuthError(1-8)
🔇 Additional comments (6)
packages/auth/src/supabase/auth-client.test.ts (6)
6-11: Good pattern for type narrowing in tests.The
ensureValuehelper is well-implemented and successfully addresses the previous TypeScript type narrowing issue withreceivedUrl. This approach is clear and explicit for test assertions.
13-26: Mock fetch implementation correctly addresses the TypeScript error.The use of
Object.assignto add thepreconnectmethod successfully resolves the previous TS2741 compilation error. This minimal mock implementation is appropriate for testing purposes.
29-66: LGTM! Comprehensive test for login normalization.The test effectively verifies that the login method correctly normalizes Supabase's snake_case token response to camelCase and sends the expected request body.
68-92: LGTM! Verifies nested data payload handling.The test correctly validates that the refresh method can extract tokens from Supabase's nested
datawrapper format.
94-120: Type narrowing issue resolved correctly.The use of
ensureValuesuccessfully addresses the previous TS2769 error by narrowingreceivedUrlfromstring | nulltostringbefore the assertion. The test effectively verifies redirect URL forwarding with proper encoding.
153-162: LGTM! Input validation test is clear.The test effectively verifies project URL validation with an appropriate inline snapshot for the error message.
Summary
Testing
Summary by CodeRabbit
New Features
Documentation
Chores