@neondatabase/neon-js 0.1.0-alpha.1 → 0.1.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,388 +1,519 @@
1
- # neon-js
1
+ # @neondatabase/neon-js
2
2
 
3
- A unified TypeScript SDK for Neon services, providing seamless integration with **Neon Auth** (authentication service) and **Neon Data API** (PostgreSQL database queries). Built with a Supabase-compatible interface for easy migration and familiar developer experience.
3
+ [![npm downloads](https://img.shields.io/npm/dm/@neondatabase/neon-js.svg)](https://www.npmjs.com/package/@neondatabase/neon-js)
4
4
 
5
- ## Features
5
+ The official TypeScript SDK for Neon, combining authentication and database querying in a familiar interface.
6
6
 
7
- - **Unified SDK**: Single client for Neon Auth and Neon Data API
8
- - **Supabase-Compatible**: Drop-in replacement for easy migration from Supabase
9
- - **Adapter Pattern**: Pluggable authentication providers (Stack Auth included)
10
- - **Automatic Token Injection**: Auth-aware fetch wrapper for seamless API calls
11
- - **TypeScript**: Full type safety with strict mode enabled
12
- - **Performance Optimized**: Leverages Stack Auth's internal session cache for <5ms session reads
13
- - **CLI Tool**: Generate TypeScript types from your database schema
7
+ ## Overview
14
8
 
15
- ## Installation
9
+ `@neondatabase/neon-js` is a comprehensive SDK that brings together Neon Auth and Neon Data API. It provides a unified client for managing authentication and querying PostgreSQL databases with a familiar, intuitive interface.
10
+
11
+ **Key Features:**
16
12
 
17
- ### From npm
13
+ - **Integrated Authentication** - Works out of the box with optional adapters (Supabase-compatible, React hooks)
14
+ - **PostgreSQL Querying** - Full PostgREST client with type-safe queries
15
+ - **High Performance** - Session caching, request deduplication
16
+ - **Automatic Token Management** - Seamless token injection for database queries
17
+ - **TypeScript First** - Fully typed with strict type checking
18
+ - **Universal** - Works in Node.js, browsers, and edge runtimes
19
+
20
+ ## Installation
18
21
 
19
22
  ```bash
20
23
  npm install @neondatabase/neon-js
24
+ # or
25
+ bun add @neondatabase/neon-js
21
26
  ```
22
27
 
23
- ## Using neon-js
28
+ ## Quick Start
24
29
 
25
- 1. Create a Neon project with Data API enabled
26
- 2. Copy env vars from the Data API page and set them in your environment
27
- ```bash
28
- VITE_STACK_PROJECT_ID=
29
- VITE_STACK_PUBLISHABLE_CLIENT_KEY=
30
- VITE_NEON_DATA_API_URL=
31
- ```
32
- 3. Instantiate `createClient` with the correct parameters
33
30
  ```typescript
34
- import { createClient } from 'neon-js';
31
+ import { createClient } from '@neondatabase/neon-js';
35
32
 
36
- const client = createClient({
37
- url: 'https://your-api.com',
33
+ const client = createClient<Database>({
38
34
  auth: {
39
- projectId: 'your-project-id',
40
- publishableClientKey: 'pk_...',
41
- tokenStore: 'cookie', // or 'memory'
35
+ url: import.meta.env.VITE_NEON_AUTH_URL,
42
36
  },
43
- options: {
44
- // Optional: custom configuration
45
- global: {
46
- headers: { 'X-Custom-Header': 'value' },
47
- },
48
- db: {
49
- schema: 'public',
50
- },
37
+ dataApi: {
38
+ url: import.meta.env.VITE_NEON_DATA_API_URL,
51
39
  },
52
40
  });
41
+
42
+ // Authenticate
43
+ await client.auth.signIn.email({
44
+ email: 'user@example.com',
45
+ password: 'secure-password',
46
+ });
47
+
48
+ // Query database (token automatically injected)
49
+ const { data: users } = await client
50
+ .from('users')
51
+ .select('*')
52
+ .eq('status', 'active');
53
53
  ```
54
54
 
55
- ## Migrating from Supabase
55
+ ### Using Adapters
56
+
57
+ You can optionally specify an adapter for different API styles:
58
+
59
+ #### SupabaseAuthAdapter (Supabase-compatible API)
56
60
 
57
- neon-js provides a Supabase-compatible API, making migration straightforward with minimal code changes. Here's a real-world migration example from the [Todo Guardian Pro project](https://github.com/pffigueiredo/todo-guardian-pro/pull/1).
61
+ Use this adapter if you're migrating from Supabase or prefer the Supabase API style:
58
62
 
59
- ### Migration Steps
63
+ ```typescript
64
+ import { createClient, SupabaseAuthAdapter } from '@neondatabase/neon-js';
60
65
 
61
- **1. Update Dependencies**
66
+ const client = createClient<Database>({
67
+ auth: {
68
+ adapter: SupabaseAuthAdapter(),
69
+ url: import.meta.env.VITE_NEON_AUTH_URL,
70
+ },
71
+ dataApi: {
72
+ url: import.meta.env.VITE_NEON_DATA_API_URL,
73
+ },
74
+ });
62
75
 
63
- Replace `@supabase/supabase-js` with `neon-js` in your `package.json`:
76
+ // Supabase-compatible API
77
+ await client.auth.signInWithPassword({
78
+ email: 'user@example.com',
79
+ password: 'secure-password',
80
+ });
64
81
 
65
- ```diff
66
- - "@supabase/supabase-js": "^2.74.0"
67
- + "neon-js": "^0.0.0"
82
+ const { data: session } = await client.auth.getSession();
68
83
  ```
69
84
 
70
- **2. Update Environment Variables**
85
+ #### BetterAuthReactAdapter (React Hooks)
71
86
 
72
- Replace Supabase environment variables with Neon equivalents:
87
+ Use this adapter in React applications to get access to hooks like `useSession`:
73
88
 
74
- ```diff
75
- - VITE_SUPABASE_PROJECT_ID="..."
76
- - VITE_SUPABASE_PUBLISHABLE_KEY="..."
77
- - VITE_SUPABASE_URL="https://xxx.supabase.co"
78
- + VITE_NEON_DATA_API_URL="https://xxx.apirest.c-2.us-east-1.aws.neon.tech/neondb/rest/v1"
79
- + VITE_STACK_PROJECT_ID="..."
80
- + VITE_STACK_PUBLISHABLE_CLIENT_KEY="..."
81
- ```
89
+ ```typescript
90
+ import { createClient, BetterAuthReactAdapter } from '@neondatabase/neon-js';
82
91
 
83
- Get these values from your Neon dashboard:
84
- - **Data API URL**: Available in the Neon console under "Data API"
85
- - **Stack Auth credentials**: Project ID and Publishable Client Key from Neon Auth setup
86
-
87
- **3. Update Client Initialization**
88
-
89
- Update your client configuration to use neon-js:
90
-
91
- ```diff
92
- - import { createClient } from '@supabase/supabase-js';
93
- + import { createClient } from 'neon-js';
94
-
95
- - export const supabase = createClient(
96
- - import.meta.env.VITE_SUPABASE_URL,
97
- - import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
98
- - );
99
- + export const supabase = createClient({
100
- + url: import.meta.env.VITE_NEON_DATA_API_URL,
101
- + auth: {
102
- + tokenStore: 'cookie',
103
- + projectId: import.meta.env.VITE_STACK_PROJECT_ID,
104
- + publishableClientKey: import.meta.env.VITE_STACK_PUBLISHABLE_CLIENT_KEY,
105
- + },
106
- + });
107
- ```
92
+ const client = createClient<Database>({
93
+ auth: {
94
+ adapter: BetterAuthReactAdapter(),
95
+ url: import.meta.env.VITE_NEON_AUTH_URL,
96
+ },
97
+ dataApi: {
98
+ url: import.meta.env.VITE_NEON_DATA_API_URL,
99
+ },
100
+ });
108
101
 
109
- **4. Done!**
102
+ // Use in React components
103
+ function MyComponent() {
104
+ const session = client.auth.useSession();
110
105
 
111
- That's it! The rest of your code remains unchanged. All authentication methods (`signInWithPassword`, `signOut`, `getUser`, etc.) and database queries (`from().select()`, etc.) work exactly the same.
106
+ if (session.isPending) return <div>Loading...</div>;
107
+ if (!session.data) return <div>Not logged in</div>;
112
108
 
113
- ### What Stays the Same
109
+ return <div>Hello, {session.data.user.name}</div>;
110
+ }
111
+ ```
114
112
 
115
- - ✅ All authentication method signatures
116
- - ✅ All database query methods
117
- - ✅ Session management APIs
118
- - ✅ User management APIs
119
- - ✅ OAuth flows
120
- - ✅ Error handling patterns
113
+ ## Authentication
121
114
 
122
- ### Real-World Example
115
+ ### Sign Up
123
116
 
124
- See the complete migration in this PR: [pffigueiredo/todo-guardian-pro#1](https://github.com/pffigueiredo/todo-guardian-pro/pull/1)
117
+ ```typescript
118
+ await client.auth.signUp.email({
119
+ email: 'user@example.com',
120
+ password: 'secure-password',
121
+ name: 'John Doe',
122
+ });
123
+ ```
125
124
 
126
- The migration changed only:
127
- - 1 dependency in `package.json`
128
- - 3 environment variables in `.env`
129
- - Client initialization in `src/integrations/supabase/client.ts`
125
+ ### Sign In
130
126
 
131
- Everything else stayed the same!
127
+ ```typescript
128
+ // Email & Password
129
+ await client.auth.signIn.email({
130
+ email: 'user@example.com',
131
+ password: 'secure-password',
132
+ });
132
133
 
133
- ## Quick Start
134
+ // OAuth
135
+ await client.auth.signIn.social({
136
+ provider: 'google',
137
+ callbackURL: '/dashboard',
138
+ });
139
+ ```
140
+
141
+ ### Session Management
134
142
 
135
143
  ```typescript
136
- import { createClient } from 'neon-js';
144
+ // Get current session
145
+ const session = await client.auth.getSession();
137
146
 
138
- // Create client with Stack Auth integration
139
- const client = createClient({
140
- url: 'https://your-api.com',
141
- auth: {
142
- projectId: 'your-project-id',
143
- publishableClientKey: 'pk_...',
144
- tokenStore: 'cookie', // or 'memory'
147
+ // Sign out
148
+ await client.auth.signOut();
149
+ ```
150
+
151
+ ### SupabaseAuthAdapter API
152
+
153
+ When using `SupabaseAuthAdapter`, you get access to the Supabase-compatible API:
154
+
155
+ ```typescript
156
+ // Sign up with metadata
157
+ await client.auth.signUp({
158
+ email: 'user@example.com',
159
+ password: 'secure-password',
160
+ options: {
161
+ data: { name: 'John Doe' },
145
162
  },
146
163
  });
147
164
 
148
165
  // Sign in
149
166
  await client.auth.signInWithPassword({
150
167
  email: 'user@example.com',
151
- password: 'password123',
168
+ password: 'secure-password',
152
169
  });
153
170
 
154
- // Get current session
155
- const { data } = await client.auth.getSession();
171
+ // OAuth
172
+ await client.auth.signInWithOAuth({
173
+ provider: 'google',
174
+ options: { redirectTo: '/dashboard' },
175
+ });
176
+
177
+ // Session with data wrapper
178
+ const { data: session } = await client.auth.getSession();
179
+ const { data: user } = await client.auth.getUser();
156
180
 
157
- // Make authenticated API calls (tokens injected automatically)
158
- const { data: items } = await client.from('items').select();
181
+ // Auth state changes
182
+ client.auth.onAuthStateChange((event, session) => {
183
+ console.log(event, session);
184
+ });
159
185
  ```
160
186
 
161
- ## Environment Support
187
+ ## Database Querying
188
+
189
+ ### SELECT Queries
162
190
 
163
- The SDK works in both browser and Node.js environments:
191
+ ```typescript
192
+ // Simple select
193
+ const { data } = await client
194
+ .from('users')
195
+ .select('id, name, email');
196
+
197
+ // With filters
198
+ const { data } = await client
199
+ .from('posts')
200
+ .select('*')
201
+ .eq('status', 'published')
202
+ .gt('views', 100)
203
+ .order('created_at', { ascending: false })
204
+ .limit(10);
205
+
206
+ // Joins
207
+ const { data } = await client
208
+ .from('posts')
209
+ .select(`
210
+ id,
211
+ title,
212
+ author:users(name, email)
213
+ `)
214
+ .eq('status', 'published');
215
+ ```
164
216
 
165
- ### Browser
217
+ ### INSERT Queries
166
218
 
167
219
  ```typescript
168
- // Full feature support including cross-tab sync
169
- import { createClient } from 'neon-js';
220
+ // Insert single row
221
+ const { data } = await client
222
+ .from('users')
223
+ .insert({
224
+ name: 'Alice',
225
+ email: 'alice@example.com',
226
+ })
227
+ .select();
228
+
229
+ // Insert multiple rows
230
+ const { data } = await client
231
+ .from('users')
232
+ .insert([
233
+ { name: 'Bob', email: 'bob@example.com' },
234
+ { name: 'Carol', email: 'carol@example.com' },
235
+ ])
236
+ .select();
237
+ ```
170
238
 
171
- const client = createClient({
172
- url: 'https://your-api.com',
173
- auth: {
174
- projectId: 'your-project-id',
175
- publishableClientKey: 'pk_...',
176
- tokenStore: 'cookie', // Use cookies in browser
177
- },
178
- });
239
+ ### UPDATE Queries
240
+
241
+ ```typescript
242
+ const { data } = await client
243
+ .from('users')
244
+ .update({ status: 'inactive' })
245
+ .eq('last_login', null)
246
+ .select();
179
247
  ```
180
248
 
181
- ### Node.js
249
+ ### DELETE Queries
182
250
 
183
251
  ```typescript
184
- // All auth methods work, cross-tab features automatically disabled
185
- import { createClient } from 'neon-js';
252
+ const { data } = await client
253
+ .from('users')
254
+ .delete()
255
+ .eq('status', 'deleted')
256
+ .select();
257
+ ```
186
258
 
187
- const client = createClient({
188
- url: 'https://your-api.com',
189
- auth: {
190
- projectId: 'your-project-id',
191
- publishableClientKey: 'pk_...',
192
- tokenStore: 'memory', // Use memory storage in Node.js
193
- },
194
- });
259
+ ### RPC (Stored Procedures)
260
+
261
+ ```typescript
262
+ const { data } = await client
263
+ .rpc('get_user_stats', {
264
+ user_id: 123,
265
+ start_date: '2024-01-01',
266
+ });
195
267
  ```
196
268
 
197
- ### Server-Side (with secret key)
269
+ ## Configuration
270
+
271
+ ### Client Options
198
272
 
199
273
  ```typescript
200
- import { createClient } from 'neon-js';
274
+ import { createClient } from '@neondatabase/neon-js';
201
275
 
202
276
  const client = createClient({
203
- url: 'https://your-api.com',
277
+ // Auth configuration
204
278
  auth: {
205
- projectId: 'your-project-id',
206
- secretServerKey: 'sk_...', // Server key for server-side operations
207
- tokenStore: 'memory',
279
+ url: 'https://your-auth-server.neon.tech/auth',
280
+ },
281
+
282
+ // Data API configuration
283
+ dataApi: {
284
+ url: 'https://your-data-api.neon.tech/rest/v1',
285
+ options: {
286
+ db: {
287
+ schema: 'public', // Default schema
288
+ },
289
+ global: {
290
+ headers: {
291
+ 'X-Custom-Header': 'value',
292
+ },
293
+ },
294
+ },
208
295
  },
209
296
  });
210
297
  ```
211
298
 
212
- ## Architecture
213
-
214
- - **NeonClient**: Unified client for Neon Auth and Data API (extends PostgrestClient)
215
- - **AuthClient Interface**: Supabase-compatible authentication interface for easy migration
216
- - **Adapter Pattern**: Pluggable authentication providers (Stack Auth included)
217
- - **Factory Pattern**: `createClient()` handles initialization and wiring
218
- - **Performance Optimized**: Session caching, automatic token injection, and retry logic
219
-
220
- ## Development
221
-
222
- Install dependencies:
299
+ ### Environment Variables
223
300
 
224
301
  ```bash
225
- bun install
302
+ # Auth URL
303
+ NEON_AUTH_URL=https://your-auth-server.neon.tech/auth
304
+
305
+ # Data API URL
306
+ NEON_DATA_API_URL=https://your-data-api.neon.tech/rest/v1
226
307
  ```
227
308
 
228
- Run development server with watch mode:
309
+ ```typescript
310
+ import { createClient } from '@neondatabase/neon-js';
229
311
 
230
- ```bash
231
- bun dev
312
+ const client = createClient({
313
+ auth: {
314
+ url: process.env.NEON_AUTH_URL!,
315
+ },
316
+ dataApi: {
317
+ url: process.env.NEON_DATA_API_URL!,
318
+ },
319
+ });
232
320
  ```
233
321
 
234
- Build the library:
322
+ ## TypeScript
323
+
324
+ Generate TypeScript types from your database schema:
235
325
 
236
326
  ```bash
237
- bun build
327
+ npx neon-js gen-types --db-url "postgresql://user:pass@host/db"
238
328
  ```
239
329
 
240
- Run tests:
330
+ Use generated types for full type safety:
241
331
 
242
- ```bash
243
- bun test
244
- ```
332
+ ```typescript
333
+ import type { Database } from './types/database';
334
+ import { createClient } from '@neondatabase/neon-js';
245
335
 
246
- Type check:
336
+ const client = createClient<Database>({
337
+ auth: {
338
+ url: process.env.NEON_AUTH_URL!,
339
+ },
340
+ dataApi: {
341
+ url: process.env.NEON_DATA_API_URL!,
342
+ },
343
+ });
247
344
 
248
- ```bash
249
- bun typecheck
345
+ // Fully typed queries!
346
+ const { data } = await client
347
+ .from('users') // Autocomplete for table names
348
+ .select('id, name, email') // Autocomplete for column names
349
+ .eq('status', 'active'); // Type checking for values
250
350
  ```
251
351
 
252
- ## Publishing
352
+ ## CLI Tool
253
353
 
254
- Bump version and publish to npm:
354
+ Generate TypeScript types from your database:
255
355
 
256
356
  ```bash
257
- bun release
357
+ # Generate types
358
+ npx neon-js gen-types \
359
+ --db-url "postgresql://user:pass@host/db" \
360
+ --output ./types/database.ts
361
+
362
+ # With schema filtering
363
+ npx neon-js gen-types \
364
+ --db-url "postgresql://user:pass@host/db" \
365
+ --schemas public,auth \
366
+ --output ./types/database.ts
258
367
  ```
259
368
 
260
- ## Project Structure
369
+ **Options:**
370
+ - `--db-url`, `-c` - PostgreSQL connection string (required)
371
+ - `--output`, `-o` - Output file path (default: `./types/database.ts`)
372
+ - `--schemas`, `-s` - Comma-separated list of schemas (default: `public`)
261
373
 
262
- ```
263
- src/
264
- ├── auth/
265
- │ ├── auth-interface.ts # Core AuthClient interface
266
- │ ├── utils.ts # Shared utility functions
267
- │ ├── __tests__/ # Comprehensive test suite
268
- │ │ ├── auth-flows.test.ts
269
- │ │ ├── session-management.test.ts
270
- │ │ ├── error-handling.test.ts
271
- │ │ ├── oauth.test.ts
272
- │ │ ├── oauth.browser.test.ts
273
- │ │ ├── otp.test.ts
274
- │ │ ├── user-management.test.ts
275
- │ │ ├── stack-auth-helpers.test.ts
276
- │ │ ├── supabase-compatibility.test.ts
277
- │ │ ├── msw-setup.ts
278
- │ │ ├── msw-handlers.ts
279
- │ │ └── README.md
280
- │ └── adapters/
281
- │ └── stack-auth/
282
- │ ├── stack-auth-adapter.ts # Stack Auth implementation (2000+ lines)
283
- │ ├── stack-auth-types.ts # Type definitions and interfaces
284
- │ ├── stack-auth-schemas.ts # Zod schemas for JWT validation
285
- │ └── stack-auth-helpers.ts # Helper utilities
286
- ├── client/
287
- │ ├── neon-client.ts # NeonClient class (extends PostgrestClient)
288
- │ ├── client-factory.ts # createClient() factory function
289
- │ ├── neon-client.test.ts # Client tests
290
- │ └── fetch-with-auth.ts # Auth-aware fetch wrapper
291
- ├── cli/
292
- │ ├── index.ts # CLI entry point (bin: neon-js)
293
- │ ├── commands/
294
- │ │ ├── gen-types.ts # Type generation command
295
- │ │ └── generate-types.ts # Core type generation logic
296
- │ └── utils/
297
- │ └── parse-duration.ts # Duration parsing utility
298
- └── index.ts # Public exports
299
- ```
374
+ ## Performance
300
375
 
301
- ## CLI Tool: Generate Types
376
+ ### Session Caching
302
377
 
303
- The `neon-js` package includes a CLI tool for generating TypeScript types from your database schema.
378
+ Sessions are cached in memory with intelligent TTL:
379
+ - **Cold start:** ~200ms (single network request)
380
+ - **Cached reads:** <1ms (in-memory, no I/O)
381
+ - **Cache TTL:** 60 seconds or until JWT expires
382
+ - **Smart expiration:** Automatic based on JWT claims
304
383
 
305
- ### Installation
384
+ ### Request Deduplication
306
385
 
307
- No installation required! Use via npx:
386
+ Concurrent authentication calls are automatically deduplicated:
387
+ - **Without deduplication:** 10 concurrent calls = 10 requests (~2000ms)
388
+ - **With deduplication:** 10 concurrent calls = 1 request (~200ms)
389
+ - **Result:** 10x faster, N-1 fewer server requests
308
390
 
309
- ```bash
310
- npx neon-js gen-types --db-url "postgresql://..."
311
- ```
391
+ ## Environment Compatibility
312
392
 
313
- ### Usage
393
+ - **Node.js** 14+ (with native fetch or polyfill)
394
+ - **Browser** (all modern browsers)
395
+ - **Edge Runtime** (Vercel, Cloudflare Workers, Deno, etc.)
396
+ - **Bun** (native support)
314
397
 
315
- ```bash
316
- npx neon-js gen-types --db-url <url> [flags]
398
+ ## Error Handling
399
+
400
+ ```typescript
401
+ import { AuthError } from '@neondatabase/neon-js';
402
+
403
+ // Auth errors (SupabaseAuthAdapter)
404
+ try {
405
+ await client.auth.signInWithPassword({ email, password });
406
+ } catch (error) {
407
+ if (error instanceof AuthError) {
408
+ console.error('Auth error:', error.message);
409
+ }
410
+ }
411
+
412
+ // Database errors
413
+ const { data, error } = await client.from('users').select();
414
+ if (error) {
415
+ console.error('Database error:', error.message);
416
+ }
317
417
  ```
318
418
 
319
- #### Required Flags
419
+ ## Examples
320
420
 
321
- - `--db-url <url>` - Database connection string
421
+ ### Next.js App Router
322
422
 
323
- #### Optional Flags
423
+ ```typescript
424
+ // app/lib/neon.ts
425
+ import { createClient } from '@neondatabase/neon-js';
324
426
 
325
- - `--output <path>`, `-o <path>` - Output file path (default: `database.types.ts`)
326
- - `--schema <name>`, `-s <name>` - Schema to include (can be used multiple times, default: `public`)
327
- - `--postgrest-v9-compat` - Disable one-to-one relationship detection
328
- - `--query-timeout <duration>` - Query timeout (default: `15s`, format: `30s`, `1m`, `90s`)
427
+ export const neon = createClient({
428
+ auth: {
429
+ url: process.env.NEON_AUTH_URL!,
430
+ },
431
+ dataApi: {
432
+ url: process.env.NEON_DATA_API_URL!,
433
+ },
434
+ });
329
435
 
330
- #### Examples
436
+ // app/api/users/route.ts
437
+ import { neon } from '@/lib/neon';
331
438
 
332
- ```bash
333
- # Basic usage
334
- npx neon-js gen-types --db-url "postgresql://user:pass@host:5432/db"
439
+ export async function GET() {
440
+ const { data: users } = await neon.from('users').select('*');
441
+ return Response.json(users);
442
+ }
443
+ ```
335
444
 
336
- # Custom output path
337
- npx neon-js gen-types --db-url "postgresql://..." --output src/types/db.ts
445
+ ### React Hook with BetterAuthReactAdapter
338
446
 
339
- # Multiple schemas
340
- npx neon-js gen-types --db-url "postgresql://..." -s public -s auth
447
+ ```typescript
448
+ import { createClient, BetterAuthReactAdapter } from '@neondatabase/neon-js';
341
449
 
342
- # PostgREST v9 compatibility
343
- npx neon-js gen-types --db-url "postgresql://..." --postgrest-v9-compat
450
+ const client = createClient({
451
+ auth: {
452
+ adapter: BetterAuthReactAdapter(),
453
+ url: process.env.NEXT_PUBLIC_NEON_AUTH_URL!,
454
+ },
455
+ dataApi: {
456
+ url: process.env.NEXT_PUBLIC_NEON_DATA_API_URL!,
457
+ },
458
+ });
344
459
 
345
- # Custom timeout
346
- npx neon-js gen-types --db-url "postgresql://..." --query-timeout 30s
460
+ export function useAuth() {
461
+ const session = client.auth.useSession();
462
+
463
+ return {
464
+ user: session.data?.user ?? null,
465
+ isPending: session.isPending,
466
+ signIn: (email: string, password: string) =>
467
+ client.auth.signIn.email({ email, password }),
468
+ signOut: () => client.auth.signOut(),
469
+ };
470
+ }
347
471
  ```
348
472
 
349
- ## Authentication Methods
473
+ ## Related Packages
350
474
 
351
- The SDK supports the following authentication methods via the Stack Auth adapter:
475
+ This package combines two underlying packages:
352
476
 
353
- ### Fully Supported Methods
354
- - **Email/Password**: `signUp()`, `signInWithPassword()`
355
- - **OAuth**: `signInWithOAuth()` (supports all Stack Auth OAuth providers)
356
- - **Magic Link**: `signInWithOtp()`, `verifyOtp()` (email-based passwordless authentication)
357
- - **Session Management**: `getSession()`, `refreshSession()`, `setSession()`, `signOut()`
358
- - **User Management**: `getUser()`, `updateUser()`, `getClaims()`, `getUserIdentities()`
359
- - **Identity Linking**: `linkIdentity()`, `unlinkIdentity()`
360
- - **Password Reset**: `resetPasswordForEmail()`, `resend()`
361
- - **OAuth Callback**: `exchangeCodeForSession()`
362
- - **State Monitoring**: `onAuthStateChange()`
477
+ - [`@neondatabase/neon-auth`](../neon-auth) - Authentication adapters (can be used standalone)
478
+ - [`@neondatabase/postgrest-js`](../postgrest-js) - PostgreSQL client (can be used standalone)
363
479
 
364
- ### Unsupported Methods (Return Detailed Errors)
365
- - **OIDC ID Token**: `signInWithIdToken()` - Stack Auth uses OAuth redirects only
366
- - **SAML SSO**: `signInWithSSO()` - Stack Auth only supports OAuth social providers
367
- - **Web3/Crypto**: `signInWithWeb3()` - Stack Auth does not support blockchain authentication
368
- - **Anonymous**: `signInAnonymously()` - Use OAuth or email/password instead
480
+ ## Migration from Previous Version
369
481
 
370
- For unsupported methods, the adapter returns comprehensive error messages explaining the limitation and suggesting alternatives.
482
+ If you're migrating from the old API that used `dataApiUrl` and `authUrl` directly:
371
483
 
372
- ## Performance
484
+ ```typescript
485
+ // Before (old API)
486
+ const client = createClient({
487
+ dataApiUrl: 'https://data-api.example.com/rest/v1',
488
+ authUrl: 'https://auth.example.com',
489
+ });
490
+
491
+ // After (new API with adapters)
492
+ import { createClient, SupabaseAuthAdapter } from '@neondatabase/neon-js';
493
+
494
+ const client = createClient({
495
+ auth: {
496
+ adapter: SupabaseAuthAdapter(),
497
+ url: 'https://auth.example.com',
498
+ },
499
+ dataApi: {
500
+ url: 'https://data-api.example.com/rest/v1',
501
+ },
502
+ });
503
+ ```
373
504
 
374
- The Stack Auth adapter is optimized for performance:
505
+ ## Resources
375
506
 
376
- - **Cached `getSession()`**: <5ms (reads from Stack Auth internal cache, no I/O)
377
- - **First `getSession()` after reload**: <50ms (Stack Auth reads from tokenStore)
378
- - **Token refresh**: <200ms (network call to Stack Auth, happens automatically)
507
+ - [Neon Documentation](https://neon.tech/docs)
508
+ - [Neon Auth Documentation](https://neon.tech/docs/neon-auth)
509
+ - [Better Auth Documentation](https://www.better-auth.com/docs)
510
+ - [PostgREST Documentation](https://postgrest.org)
379
511
 
380
- ## License
512
+ ## Support
381
513
 
382
- MIT
514
+ - [GitHub Issues](https://github.com/neondatabase/neon-js/issues)
515
+ - [Neon Community Discord](https://discord.gg/H24eC2UN)
383
516
 
384
- ## Links
517
+ ## License
385
518
 
386
- - [Stack Auth Documentation](https://docs.stack-auth.com/)
387
- - [Supabase Auth Documentation](https://supabase.com/docs/guides/auth)
388
- - [PostgrestClient Documentation](https://github.com/supabase/postgrest-js)
519
+ Apache-2.0