next-supa-utils 0.1.0 → 0.1.2
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 +30 -65
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,47 +16,24 @@
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
## Why
|
|
19
|
+
## 🚀 Why Use This Over Raw `@supabase/ssr`?
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
If you use `@supabase/ssr` directly, you have to write boilerplate for *every* environment. **next-supa-utils** eliminates this entirely:
|
|
22
22
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
|
|
23
|
+
1. **One-Line Middleware**: No more manually copying the 40-line chunking/cookie-setting logic from the Supabase docs. Just pass your routes to `withSupaAuth()`.
|
|
24
|
+
2. **Type-Safe Server Actions**: Stop writing `try/catch` and `cookies().getAll()` in every server action. `createAction()` handles it automatically and forces you to check for errors.
|
|
25
|
+
3. **Instant Client Hooks**: `useSupaUser()` and `useSupaSession()` wrap `createBrowserClient`, fetch the initial state, *and* subscribe to real-time `onAuthStateChange` events out of the box.
|
|
26
|
+
4. **App Router Ready**: Strictly separated entry points (`/client` and `/server`) guarantee you won't accidentally import server code into client components.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
## Features
|
|
30
|
-
|
|
31
|
-
- 🔐 **`withSupaAuth`** — Drop-in middleware for route protection with redirect support
|
|
32
|
-
- ⚡ **`createAction`** — Higher-order function that wraps server actions with automatic Supabase client creation and error handling
|
|
33
|
-
- 👤 **`useSupaUser`** — React hook for real-time user state with auth change subscriptions
|
|
34
|
-
- 🔑 **`useSupaSession`** — React hook for real-time session state
|
|
35
|
-
- 🧩 **Separate entry points** — `next-supa-utils/client` and `next-supa-utils/server` to respect the `"use client"` boundary
|
|
36
|
-
- 📦 **Dual format** — Ships ESM and CJS with full TypeScript declarations
|
|
37
|
-
|
|
38
|
-
## Installation
|
|
28
|
+
## 📦 Installation
|
|
39
29
|
|
|
40
30
|
```bash
|
|
41
31
|
npm install next-supa-utils
|
|
42
32
|
```
|
|
43
33
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
Make sure you have the following installed in your project:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
npm install react next @supabase/supabase-js @supabase/ssr
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
| Package | Version |
|
|
53
|
-
|---|---|
|
|
54
|
-
| `react` | `>=18` |
|
|
55
|
-
| `next` | `>=14` |
|
|
56
|
-
| `@supabase/supabase-js` | `^2.0.0` |
|
|
57
|
-
| `@supabase/ssr` | `>=0.5.0` |
|
|
34
|
+
*Requires `react >=18`, `next >=14`, `@supabase/supabase-js ^2`, and `@supabase/ssr >=0.5`.*
|
|
58
35
|
|
|
59
|
-
|
|
36
|
+
### Environment Variables
|
|
60
37
|
|
|
61
38
|
Add these to your `.env.local`:
|
|
62
39
|
|
|
@@ -65,73 +42,61 @@ NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
|
65
42
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
|
66
43
|
```
|
|
67
44
|
|
|
68
|
-
Both variables are required. All helpers in this library read from these environment variables automatically.
|
|
69
|
-
|
|
70
45
|
---
|
|
71
46
|
|
|
72
|
-
## Quick Start
|
|
47
|
+
## ⚡ Quick Start
|
|
48
|
+
|
|
49
|
+
### 1. Middleware (Route Protection in 1 Line)
|
|
73
50
|
|
|
74
|
-
|
|
51
|
+
Protect your routes and auto-refresh sessions without copying boilerplate.
|
|
75
52
|
|
|
76
53
|
```ts
|
|
77
54
|
// middleware.ts
|
|
78
55
|
import { withSupaAuth } from "next-supa-utils/server";
|
|
79
56
|
|
|
80
57
|
export default withSupaAuth({
|
|
81
|
-
protectedRoutes: ["/dashboard", "/admin"
|
|
58
|
+
protectedRoutes: ["/dashboard", "/admin"],
|
|
82
59
|
redirectTo: "/login",
|
|
83
|
-
publicRoutes: ["/admin/login"],
|
|
84
60
|
});
|
|
85
61
|
|
|
86
|
-
export const config = {
|
|
87
|
-
matcher: [
|
|
88
|
-
"/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
|
|
89
|
-
],
|
|
90
|
-
};
|
|
62
|
+
export const config = { matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"] };
|
|
91
63
|
```
|
|
92
64
|
|
|
93
|
-
### 2.
|
|
65
|
+
### 2. Server Actions (No More Try/Catch)
|
|
66
|
+
|
|
67
|
+
Automatically initializes the server client with cookies and returns a type-safe `{ data, error }` object.
|
|
94
68
|
|
|
95
69
|
```ts
|
|
96
|
-
// app/actions
|
|
70
|
+
// app/actions.ts
|
|
97
71
|
"use server";
|
|
98
72
|
import { createAction } from "next-supa-utils/server";
|
|
99
73
|
|
|
100
74
|
export const getProfile = createAction(async (supabase, userId: string) => {
|
|
101
|
-
const { data, error } = await supabase
|
|
102
|
-
|
|
103
|
-
.select("*")
|
|
104
|
-
.eq("id", userId)
|
|
105
|
-
.single();
|
|
106
|
-
|
|
107
|
-
if (error) throw error;
|
|
75
|
+
const { data, error } = await supabase.from("profiles").select().eq("id", userId).single();
|
|
76
|
+
if (error) throw error; // Handled automatically!
|
|
108
77
|
return data;
|
|
109
78
|
});
|
|
110
79
|
```
|
|
111
80
|
|
|
112
81
|
```tsx
|
|
113
|
-
// Usage
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
if (result.error) {
|
|
117
|
-
console.error(result.error.message);
|
|
118
|
-
} else {
|
|
119
|
-
console.log(result.data);
|
|
120
|
-
}
|
|
82
|
+
// Usage
|
|
83
|
+
const { data, error } = await getProfile("123");
|
|
84
|
+
if (error) console.error(error.message);
|
|
121
85
|
```
|
|
122
86
|
|
|
123
|
-
### 3.
|
|
87
|
+
### 3. Client Components (Real-Time User State)
|
|
88
|
+
|
|
89
|
+
Get the user and listen to auth changes immediately.
|
|
124
90
|
|
|
125
91
|
```tsx
|
|
126
92
|
"use client";
|
|
127
93
|
import { useSupaUser } from "next-supa-utils/client";
|
|
128
94
|
|
|
129
95
|
export default function Avatar() {
|
|
130
|
-
const { user, loading
|
|
96
|
+
const { user, loading } = useSupaUser();
|
|
131
97
|
|
|
132
|
-
if (loading) return <p>Loading
|
|
133
|
-
if (
|
|
134
|
-
if (!user) return <p>Not signed in</p>;
|
|
98
|
+
if (loading) return <p>Loading...</p>;
|
|
99
|
+
if (!user) return <p>Please sign in</p>;
|
|
135
100
|
|
|
136
101
|
return <p>Hello, {user.email}!</p>;
|
|
137
102
|
}
|
package/package.json
CHANGED