stackpatch 1.1.2 → 1.1.4

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.
Files changed (36) hide show
  1. package/README.md +123 -114
  2. package/bin/stackpatch.ts +2 -2441
  3. package/boilerplate/auth/app/auth/login/page.tsx +50 -24
  4. package/boilerplate/auth/app/auth/signup/page.tsx +69 -56
  5. package/boilerplate/auth/app/stackpatch/page.tsx +269 -0
  6. package/boilerplate/auth/components/auth-wrapper.tsx +61 -0
  7. package/package.json +4 -2
  8. package/src/auth/generator.ts +569 -0
  9. package/src/auth/index.ts +372 -0
  10. package/src/auth/setup.ts +293 -0
  11. package/src/commands/add.ts +112 -0
  12. package/src/commands/create.ts +128 -0
  13. package/src/commands/revert.ts +389 -0
  14. package/src/config.ts +52 -0
  15. package/src/fileOps/copy.ts +224 -0
  16. package/src/fileOps/layout.ts +304 -0
  17. package/src/fileOps/protected.ts +67 -0
  18. package/src/index.ts +215 -0
  19. package/src/manifest.ts +87 -0
  20. package/src/ui/logo.ts +24 -0
  21. package/src/ui/progress.ts +82 -0
  22. package/src/utils/dependencies.ts +114 -0
  23. package/src/utils/deps-check.ts +45 -0
  24. package/src/utils/files.ts +58 -0
  25. package/src/utils/paths.ts +217 -0
  26. package/src/utils/scanner.ts +109 -0
  27. package/boilerplate/auth/app/api/auth/[...nextauth]/route.ts +0 -124
  28. package/boilerplate/auth/app/api/auth/signup/route.ts +0 -45
  29. package/boilerplate/auth/app/dashboard/page.tsx +0 -82
  30. package/boilerplate/auth/app/login/page.tsx +0 -136
  31. package/boilerplate/auth/app/page.tsx +0 -48
  32. package/boilerplate/auth/components/auth-button.tsx +0 -43
  33. package/boilerplate/auth/components/auth-navbar.tsx +0 -118
  34. package/boilerplate/auth/components/protected-route.tsx +0 -74
  35. package/boilerplate/auth/components/session-provider.tsx +0 -11
  36. package/boilerplate/auth/middleware.ts +0 -51
package/README.md CHANGED
@@ -10,7 +10,7 @@ StackPatch is a CLI tool that helps you quickly add production-ready features to
10
10
  ## ✨ Features
11
11
 
12
12
  - 🚀 **Zero Configuration** - Add features with a single command
13
- - 🔐 **Authentication** - Full NextAuth.js setup with customizable OAuth providers
13
+ - 🔐 **Authentication** - Full Better Auth setup with customizable OAuth providers
14
14
  - 🛡️ **Protected Routes** - Easy route protection with components or middleware
15
15
  - 🎨 **UI Components** - Pre-built, production-ready components
16
16
  - 📦 **Composable** - Add only what you need, when you need it
@@ -89,31 +89,40 @@ This will:
89
89
 
90
90
  ## 📖 What Gets Added
91
91
 
92
- ### Authentication Setup
92
+ ### Setup Flow
93
93
 
94
- When you run `npx stackpatch add auth`, StackPatch:
94
+ When you run `npx stackpatch add auth`, StackPatch will guide you through an interactive setup:
95
95
 
96
- 1. **Asks which OAuth providers** you want to configure:
97
- - Google OAuth
98
- - GitHub OAuth
99
- - Email/Password (Credentials)
96
+ 1. **Session Mode**: Choose between Database (persistent sessions) or Stateless (JWT only)
97
+ 2. **Database** (if database mode): Select PostgreSQL, MySQL, SQLite, or MongoDB
98
+ 3. **ORM** (if database mode): Choose Drizzle, Prisma, or Raw SQL driver
99
+ 4. **Auth Providers**: Enable Email/Password and select OAuth providers (Google, GitHub)
100
+ 5. **UI Components**: Choose whether to add prebuilt login/signup pages
101
+ 6. **Protected Routes**: Select which routes to protect (supports wildcards like `/dashboard/*`)
100
102
 
101
- 2. **Adds the following files**:
102
- - ✅ NextAuth.js configuration with your selected providers
103
- - ✅ Login and signup pages (`/auth/login`, `/auth/signup`)
104
- - ✅ OAuth buttons for selected providers with email/password forms
105
- - ✅ Protected route component (`components/protected-route.tsx` or `src/components/protected-route.tsx`)
106
- - ✅ Middleware for route protection (`middleware.ts`)
107
- - ✅ Session provider and toaster components
108
- - ✅ Environment file template (`.env.example`)
103
+ ### Files Generated
109
104
 
110
- 3. **Smart file placement**:
111
- - Detects if your app is in `app/` or `src/app/`
112
- - Places components in matching location (`components/` or `src/components/`)
113
- - Uses your `tsconfig.json` path aliases for imports
114
- - Generates correct import paths automatically
105
+ After the interactive setup, StackPatch automatically generates:
115
106
 
116
- 4. **Tracks all changes** in `.stackpatch/manifest.json` for safe reversion
107
+ - **Better Auth configuration** (`lib/auth.ts` or `src/lib/auth.ts`)
108
+ - ✅ **Auth client utilities** (`lib/auth-client.ts` or `src/lib/auth-client.ts`)
109
+ - ✅ **Protected routes config** (`lib/protected-routes.ts` - only if protected routes are configured)
110
+ - ✅ **API route handler** (`app/api/auth/[...all]/route.ts`)
111
+ - ✅ **Middleware** (`middleware.ts` - only if protected routes are configured)
112
+ - ✅ **Login/Signup pages** (`app/auth/login/page.tsx`, `app/auth/signup/page.tsx` - if UI enabled)
113
+ - ✅ **Landing page** (`app/stackpatch/page.tsx` - if UI enabled)
114
+ - ✅ **Auth wrapper** (`components/auth-wrapper.tsx` - if UI enabled, added to layout.tsx)
115
+ - ✅ **Toaster component** (`components/toaster.tsx` - if UI enabled, added to layout.tsx)
116
+ - ✅ **Environment template** (`.env.example`)
117
+
118
+ ### Smart File Placement
119
+
120
+ StackPatch automatically:
121
+ - ✅ Detects if your app is in `app/` or `src/app/`
122
+ - ✅ Places components in matching location (`components/` or `src/components/`)
123
+ - ✅ Uses your `tsconfig.json` path aliases for imports
124
+ - ✅ Generates correct import paths automatically
125
+ - ✅ Tracks all changes in `.stackpatch/manifest.json` for safe reversion
117
126
 
118
127
  ## 🔐 OAuth Setup
119
128
 
@@ -126,7 +135,7 @@ If you selected Google OAuth:
126
135
  1. Go to [Google Cloud Console](https://console.cloud.google.com/)
127
136
  2. Create a project → APIs & Services → Credentials
128
137
  3. Create OAuth client ID (Web application)
129
- 4. Add redirect URI: `http://localhost:3000/api/auth/callback/google`
138
+ 4. Add redirect URI: `http://localhost:3000/api/auth/callback/google` (or your production URL)
130
139
  5. Copy Client ID and Secret to `.env.local`:
131
140
  ```env
132
141
  GOOGLE_CLIENT_ID=your_client_id
@@ -139,7 +148,7 @@ If you selected GitHub OAuth:
139
148
 
140
149
  1. Go to [GitHub Developer Settings](https://github.com/settings/developers)
141
150
  2. New OAuth App
142
- 3. Set callback URL: `http://localhost:3000/api/auth/callback/github`
151
+ 3. Set callback URL: `http://localhost:3000/api/auth/callback/github` (or your production URL)
143
152
  4. Copy Client ID and generate Secret
144
153
  5. Add to `.env.local`:
145
154
  ```env
@@ -152,8 +161,8 @@ If you selected GitHub OAuth:
152
161
  Your `.env.local` will include only the variables for providers you selected:
153
162
 
154
163
  ```env
155
- NEXTAUTH_URL=http://localhost:3000
156
- NEXTAUTH_SECRET=your_generated_secret
164
+ BETTER_AUTH_SECRET=your_generated_secret
165
+ BETTER_AUTH_URL=http://localhost:3000
157
166
 
158
167
  # Only included if you selected Google
159
168
  GOOGLE_CLIENT_ID=your_google_client_id
@@ -164,85 +173,76 @@ GITHUB_CLIENT_ID=your_github_client_id
164
173
  GITHUB_CLIENT_SECRET=your_github_client_secret
165
174
  ```
166
175
 
167
- ## 🧭 Auth Navbar (Demo)
176
+ ## 🛡️ Protecting Routes
168
177
 
169
- An example navbar component (`components/auth-navbar.tsx`) is included that shows:
170
- - **When logged out**: Sign In button
171
- - **When logged in**: User name/email, avatar, and Sign Out button
178
+ StackPatch automatically protects routes based on your configuration. Routes are protected via:
179
+ - **Middleware** - Server-side protection with automatic redirects
180
+ - **AuthWrapper** - Client-side protection in your root layout
172
181
 
173
- > **Note**: This is a demo component named `auth-navbar.tsx` to avoid conflicts with existing navbars. You can rename it or use it as reference.
182
+ ### How It Works
174
183
 
175
- ### Usage
184
+ 1. **During Setup**: You'll be prompted to select which routes to protect
185
+ 2. **Automatic Protection**: StackPatch configures middleware and AuthWrapper automatically
186
+ 3. **Redirects**: Unauthenticated users are redirected to `/auth/login?redirect=<original-path>`
187
+ 4. **After Login**: Users are automatically redirected back to the original protected route
176
188
 
177
- ```tsx
178
- // app/layout.tsx or any page
179
- import { AuthNavbar } from "@/components/auth-navbar";
180
-
181
- export default function Layout({ children }) {
182
- return (
183
- <>
184
- <AuthNavbar />
185
- {children}
186
- </>
187
- );
188
- }
189
- ```
189
+ ### Wildcard Routes
190
190
 
191
- The auth navbar is included in example pages (`app/page.tsx` and `app/dashboard/page.tsx`) as a reference.
191
+ Use `/*` to protect a route and all its sub-routes:
192
192
 
193
- ## 🛡️ Protecting Routes
193
+ - `/dashboard` Protects only `/dashboard`
194
+ - `/dashboard/*` → Protects `/dashboard` and ALL sub-routes (`/dashboard/settings`, `/dashboard/users`, etc.)
194
195
 
195
- ### Method 1: Component-Based (Recommended)
196
+ **Examples:**
197
+ ```
198
+ /dashboard/* → Protects /dashboard and all sub-routes
199
+ /admin/* → Protects /admin and all sub-routes
200
+ /profile → Protects only /profile (not sub-routes)
201
+ ```
196
202
 
197
- Wrap any page or component:
203
+ **To Modify Protected Routes:**
204
+ Edit `lib/protected-routes.ts` (or `src/lib/protected-routes.ts`):
198
205
 
199
- ```tsx
200
- // app/dashboard/page.tsx
201
- import { ProtectedRoute } from "@/components/protected-route";
202
- import { AuthNavbar } from "@/components/auth-navbar";
203
-
204
- export default function Dashboard() {
205
- return (
206
- <ProtectedRoute>
207
- <AuthNavbar />
208
- <h1>Protected Dashboard</h1>
209
- </ProtectedRoute>
210
- );
211
- }
206
+ ```ts
207
+ export const PROTECTED_ROUTES = [
208
+ "/dashboard/*", // Protects /dashboard and all sub-routes
209
+ "/admin/*", // Protects /admin and all sub-routes
210
+ "/profile", // Protects only /profile
211
+ ] as const;
212
212
  ```
213
213
 
214
- ### Method 2: Middleware-Based
214
+ ## ⚙️ Configuration Options
215
215
 
216
- Edit `middleware.ts` and add routes to protect:
216
+ ### Session Modes
217
217
 
218
- ```ts
219
- // middleware.ts
220
- export const config = {
221
- matcher: [
222
- "/dashboard/:path*", // Protect all dashboard routes
223
- "/profile/:path*", // Protect all profile routes
224
- ],
225
- };
226
- ```
218
+ **Database Mode** (Recommended for production):
219
+ - Persistent sessions stored in your database
220
+ - Supports session management and revocation
221
+ - Requires database setup (PostgreSQL, MySQL, SQLite, or MongoDB)
222
+ - Choose an ORM: Drizzle, Prisma, or Raw SQL
227
223
 
228
- ## ⚠️ Email/Password Auth (Demo Mode)
224
+ **Stateless Mode** (JWT/JWE):
225
+ - No database required
226
+ - Sessions stored in encrypted cookies
227
+ - Perfect for serverless deployments
228
+ - Limited session management features
229
229
 
230
- The email/password authentication is in **demo mode** with placeholder credentials:
230
+ ### Email/Password Authentication
231
231
 
232
- - **Demo credentials**: `demo@example.com` / `demo123`
232
+ Email/password authentication works out of the box with Better Auth. If you selected database mode:
233
233
 
234
- ### To Implement Real Auth:
234
+ 1. **Generate database schema**:
235
+ ```bash
236
+ npx @better-auth/cli generate
237
+ # or
238
+ npx @better-auth/cli migrate
239
+ ```
235
240
 
236
- 1. **Set up a database** (PostgreSQL, MongoDB, Prisma, etc.)
237
- 2. **Install bcrypt**: `npm install bcryptjs @types/bcryptjs`
238
- 3. **Update `app/api/auth/[...nextauth]/route.ts`**:
239
- - Replace the `authorize` function with database lookup
240
- - Hash and compare passwords using bcrypt
241
- 4. **Create signup API** (`app/api/auth/signup/route.ts`):
242
- - Hash passwords before storing
243
- - Validate and create users in database
241
+ 2. **Configure in `lib/auth.ts`** (already set up by StackPatch):
242
+ - Database adapter is configured based on your selection
243
+ - Email/password is enabled if you selected it
244
244
 
245
- See code comments in the files for detailed implementation examples.
245
+ See Better Auth documentation for advanced configuration: https://better-auth.dev/docs
246
246
 
247
247
  ## 📁 File Locations
248
248
 
@@ -250,16 +250,20 @@ After running `npx stackpatch add auth`, you'll find files in locations that mat
250
250
 
251
251
  ### If your app is in `app/`:
252
252
  - **Auth pages**: `app/auth/login/page.tsx`, `app/auth/signup/page.tsx`
253
- - **NextAuth config**: `app/api/auth/[...nextauth]/route.ts`
254
- - **Components**: `components/auth-navbar.tsx`, `components/protected-route.tsx`, etc.
253
+ - **Auth config**: `lib/auth.ts`, `lib/auth-client.ts`
254
+ - **Protected routes config**: `lib/protected-routes.ts`
255
+ - **API routes**: `app/api/auth/[...all]/route.ts`
256
+ - **Components**: `components/auth-wrapper.tsx`, `components/toaster.tsx`
255
257
  - **Middleware**: `middleware.ts` (root)
256
258
  - **Environment**: `.env.example`, `.env.local`
257
259
  - **Tracking**: `.stackpatch/manifest.json` (for revert)
258
260
 
259
261
  ### If your app is in `src/app/`:
260
262
  - **Auth pages**: `src/app/auth/login/page.tsx`, `src/app/auth/signup/page.tsx`
261
- - **NextAuth config**: `src/app/api/auth/[...nextauth]/route.ts`
262
- - **Components**: `src/components/auth-navbar.tsx`, `src/components/protected-route.tsx`, etc.
263
+ - **Auth config**: `src/lib/auth.ts`, `src/lib/auth-client.ts`
264
+ - **Protected routes config**: `src/lib/protected-routes.ts`
265
+ - **API routes**: `src/app/api/auth/[...all]/route.ts`
266
+ - **Components**: `src/components/auth-wrapper.tsx`, `src/components/toaster.tsx`
263
267
  - **Middleware**: `middleware.ts` (root)
264
268
  - **Environment**: `.env.example`, `.env.local`
265
269
  - **Tracking**: `.stackpatch/manifest.json` (for revert)
@@ -271,36 +275,35 @@ StackPatch automatically detects your project structure and places files accordi
271
275
 
272
276
  ## 🔧 Customization
273
277
 
274
- ### Change Login Redirect
278
+ ### Change Default Redirect After Login
275
279
 
276
- Edit `app/api/auth/[...nextauth]/route.ts`:
280
+ The login/signup pages automatically redirect users based on:
281
+ 1. The `redirect` query parameter (set by middleware when protecting routes)
282
+ 2. Fallback to `/stackpatch` if no redirect parameter
277
283
 
278
- ```ts
279
- pages: {
280
- signIn: "/your-custom-login", // Change this
281
- }
282
- ```
283
-
284
- ### Custom Protected Route Redirect
284
+ To change the fallback route, edit `app/auth/login/page.tsx` and `app/auth/signup/page.tsx`:
285
285
 
286
286
  ```tsx
287
- <ProtectedRoute redirectTo="/custom-login">
288
- <YourComponent />
289
- </ProtectedRoute>
287
+ // Change the fallback route (default: "/stackpatch")
288
+ const redirectTo = searchParams.get("redirect") || "/your-custom-route";
290
289
  ```
291
290
 
292
291
  ### Protect API Routes
293
292
 
294
293
  ```ts
295
294
  // app/api/protected/route.ts
296
- import { getServerSession } from "next-auth";
297
- import { authOptions } from "@/app/api/auth/[...nextauth]/route";
295
+ import { auth } from "@/lib/auth";
296
+ import { headers } from "next/headers";
298
297
 
299
298
  export async function GET() {
300
- const session = await getServerSession(authOptions);
301
- if (!session) {
299
+ const session = await auth.api.getSession({
300
+ headers: await headers(),
301
+ });
302
+
303
+ if (!session || !session.user) {
302
304
  return Response.json({ error: "Unauthorized" }, { status: 401 });
303
305
  }
306
+
304
307
  return Response.json({ data: "Protected data" });
305
308
  }
306
309
  ```
@@ -310,7 +313,7 @@ export async function GET() {
310
313
  ### OAuth redirect_uri_mismatch
311
314
 
312
315
  - Ensure redirect URIs match exactly in OAuth provider settings
313
- - Check `NEXTAUTH_URL` matches your app URL
316
+ - Check `BETTER_AUTH_URL` matches your app URL (defaults to `http://localhost:3000` in development)
314
317
 
315
318
  ### OAuth buttons not working
316
319
 
@@ -346,11 +349,14 @@ your-project/
346
349
  │ │ └── signup/page.tsx # Signup page
347
350
  │ └── api/
348
351
  │ └── auth/
349
- │ └── [...nextauth]/route.ts # NextAuth config
352
+ │ └── [...all]/route.ts # Better Auth API route
353
+ ├── lib/
354
+ │ ├── auth.ts # Better Auth configuration
355
+ │ ├── auth-client.ts # Client-side auth utilities
356
+ │ └── protected-routes.ts # Protected routes configuration
350
357
  ├── components/
351
- │ ├── protected-route.tsx # Route protection component
352
- ├── auth-button.tsx # Auth button component
353
- │ └── session-provider.tsx # Session provider
358
+ │ ├── auth-wrapper.tsx # Automatic route protection wrapper
359
+ └── toaster.tsx # Toast notifications
354
360
  ├── middleware.ts # Route protection middleware
355
361
  ├── .env.local # Your environment variables
356
362
  └── .stackpatch/ # Tracking for revert (git-ignored)
@@ -369,11 +375,14 @@ your-project/
369
375
  │ │ │ └── signup/page.tsx
370
376
  │ │ └── api/
371
377
  │ │ └── auth/
372
- │ │ └── [...nextauth]/route.ts
378
+ │ │ └── [...all]/route.ts
379
+ │ ├── lib/
380
+ │ │ ├── auth.ts
381
+ │ │ ├── auth-client.ts
382
+ │ │ └── protected-routes.ts
373
383
  │ └── components/
374
- │ ├── protected-route.tsx
375
- ├── auth-button.tsx
376
- │ └── session-provider.tsx
384
+ │ ├── auth-wrapper.tsx
385
+ └── toaster.tsx
377
386
  ├── middleware.ts
378
387
  ├── .env.local
379
388
  └── .stackpatch/