create-solostack 1.2.2 → 1.2.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-solostack",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "The complete SaaS boilerplate for indie hackers - Next.js 15 with auth, payments, database, and email",
5
5
  "type": "module",
6
6
  "bin": {
@@ -398,20 +398,21 @@ export default function Home() {
398
398
  icon={<Database className="w-5 h-5 text-emerald-400" />}
399
399
  status={status?.database?.connected}
400
400
  loading={loading}
401
- description="PostgreSQL + Prisma"
401
+ description="${config?.database === 'Supabase' ? 'Supabase' : 'PostgreSQL + Prisma'}"
402
402
  details={status?.database?.connected ? \`User count: \${status.database.userCount}\` : status?.database?.error || "Not connected"}
403
- actionLabel="Open Studio"
404
- actionCommand="npm run db:studio"
403
+ actionLabel="${config?.database === 'Supabase' ? 'Dashboard' : 'Open Studio'}"
404
+ actionCommand="${config?.database === 'Supabase' ? '' : 'npm run db:studio'}"
405
+ actionUrl="${config?.database === 'Supabase' ? 'https://supabase.com/dashboard' : ''}"
405
406
  />
406
407
  <StatusCard
407
408
  title="Authentication"
408
409
  icon={<Shield className="w-5 h-5 text-blue-400" />}
409
410
  status={status?.auth?.configured}
410
411
  loading={loading}
411
- description={status?.auth?.providers?.map((p: any) => p.name).join(', ') || "No providers"}
412
+ description={status?.auth?.type || status?.auth?.providers?.map((p: any) => p.name).join(', ') || "Not configured"}
412
413
  details={status?.auth?.configured ? "Ready to authenticate users" : "Missing secrets"}
413
414
  actionLabel="Read Docs"
414
- actionUrl="https://next-auth.js.org"
415
+ actionUrl="${config?.auth === 'Supabase Auth' ? 'https://supabase.com/docs/guides/auth' : 'https://next-auth.js.org'}"
415
416
  />
416
417
  <StatusCard
417
418
  title="Payments"
@@ -1,15 +1,17 @@
1
1
  import path from 'path';
2
2
  import { writeFile, ensureDir } from '../utils/files.js';
3
3
 
4
- export async function generateSetup(projectPath) {
5
- // Create setup page directory
6
- await ensureDir(path.join(projectPath, 'src/app/setup'));
4
+ export async function generateSetup(projectPath, config) {
5
+ const isSupabaseAuth = config?.auth === 'Supabase Auth';
6
+ // Create setup page directory
7
+ await ensureDir(path.join(projectPath, 'src/app/setup'));
7
8
 
8
- // Generate setup page UI
9
- const setupPage = `'use client';
9
+ // Generate setup page UI
10
+ const setupPage = `'use client';
10
11
 
11
12
  import { useState, useEffect } from 'react';
12
- import { CheckCircle, XCircle, Loader2, AlertCircle, RefreshCw, Mail } from 'lucide-react';
13
+ import Link from 'next/link';
14
+ import { CheckCircle, XCircle, Loader2, AlertCircle, RefreshCw, Mail, ArrowLeft } from 'lucide-react';
13
15
 
14
16
  export default function SetupPage() {
15
17
  const [data, setData] = useState<any>(null);
@@ -70,6 +72,15 @@ export default function SetupPage() {
70
72
  return (
71
73
  <div className="min-h-screen bg-gray-50 p-8">
72
74
  <div className="mx-auto max-w-4xl space-y-8">
75
+ {/* Back to Home */}
76
+ <Link
77
+ href="/"
78
+ className="inline-flex items-center gap-2 text-sm font-medium text-gray-600 hover:text-gray-900 transition-colors"
79
+ >
80
+ <ArrowLeft className="h-4 w-4" />
81
+ Back to Home
82
+ </Link>
83
+
73
84
  <div className="flex items-center justify-between">
74
85
  <div>
75
86
  <h1 className="text-3xl font-bold tracking-tight">Setup & Diagnostics</h1>
@@ -240,14 +251,13 @@ function StatusIcon({ status }: { status: boolean }) {
240
251
  }
241
252
  `;
242
253
 
243
- await writeFile(path.join(projectPath, 'src/app/setup/page.tsx'), setupPage);
254
+ await writeFile(path.join(projectPath, 'src/app/setup/page.tsx'), setupPage);
244
255
 
245
- // Create API routes directory
246
- await ensureDir(path.join(projectPath, 'src/app/api/setup'));
256
+ // Create API routes directory
257
+ await ensureDir(path.join(projectPath, 'src/app/api/setup'));
247
258
 
248
- // Generate Setup API route
249
- const setupApi = `import { NextResponse } from 'next/server';
250
- import { db } from '@/lib/db';
259
+ // Generate Setup API route
260
+ const setupApi = `import { NextResponse } from 'next/server';
251
261
 
252
262
  export async function GET() {
253
263
  if (process.env.NODE_ENV !== 'development') {
@@ -259,12 +269,15 @@ export async function GET() {
259
269
  connected: false,
260
270
  userCount: 0,
261
271
  error: null as string | null,
262
- provider: 'PostgreSQL'
272
+ provider: '${isSupabaseAuth ? 'Supabase' : 'PostgreSQL'}'
263
273
  },
264
274
  auth: {
265
275
  configured: false,
266
- hasSecret: !!process.env.NEXTAUTH_SECRET,
267
- providers: [
276
+ type: '${isSupabaseAuth ? 'Supabase Auth' : 'NextAuth.js'}',
277
+ hasSecret: ${isSupabaseAuth ? '!!(process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY)' : '!!process.env.NEXTAUTH_SECRET'},
278
+ providers: ${isSupabaseAuth ? `[
279
+ { name: 'Supabase', configured: !!(process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY) }
280
+ ]` : `[
268
281
  {
269
282
  name: 'Google',
270
283
  clientId: !!process.env.GOOGLE_CLIENT_ID,
@@ -277,7 +290,7 @@ export async function GET() {
277
290
  clientSecret: !!process.env.GITHUB_CLIENT_SECRET,
278
291
  configured: !!(process.env.GITHUB_CLIENT_ID && process.env.GITHUB_CLIENT_SECRET)
279
292
  }
280
- ]
293
+ ]`}
281
294
  },
282
295
  stripe: {
283
296
  configured: false,
@@ -293,6 +306,10 @@ export async function GET() {
293
306
 
294
307
  // Check Database
295
308
  try {
309
+ if (!process.env.DATABASE_URL${isSupabaseAuth ? ' && !process.env.NEXT_PUBLIC_SUPABASE_URL' : ''}) {
310
+ throw new Error('DATABASE_URL is not configured in .env');
311
+ }
312
+ const { db } = await import('@/lib/db');
296
313
  const userCount = await db.user.count();
297
314
  results.database.connected = true;
298
315
  results.database.userCount = userCount;
@@ -315,12 +332,12 @@ export async function GET() {
315
332
  }
316
333
  `;
317
334
 
318
- await writeFile(path.join(projectPath, 'src/app/api/setup/route.ts'), setupApi);
335
+ await writeFile(path.join(projectPath, 'src/app/api/setup/route.ts'), setupApi);
319
336
 
320
- // Generate Test Email API route
321
- await ensureDir(path.join(projectPath, 'src/app/api/setup/test-email'));
337
+ // Generate Test Email API route
338
+ await ensureDir(path.join(projectPath, 'src/app/api/setup/test-email'));
322
339
 
323
- const testEmailApi = `import { NextResponse, NextRequest } from 'next/server';
340
+ const testEmailApi = `import { NextResponse, NextRequest } from 'next/server';
324
341
  import { Resend } from 'resend';
325
342
 
326
343
  export async function POST(req: NextRequest) {
@@ -355,5 +372,5 @@ export async function POST(req: NextRequest) {
355
372
  }
356
373
  `;
357
374
 
358
- await writeFile(path.join(projectPath, 'src/app/api/setup/test-email/route.ts'), testEmailApi);
375
+ await writeFile(path.join(projectPath, 'src/app/api/setup/test-email/route.ts'), testEmailApi);
359
376
  }
package/src/index.js CHANGED
@@ -153,7 +153,7 @@ export async function main() {
153
153
 
154
154
  // Generate setup & diagnostics
155
155
  spinner = ora('Adding diagnostics page').start();
156
- await generateSetup(projectPath);
156
+ await generateSetup(projectPath, config);
157
157
  spinner.succeed('Added diagnostics page (/setup)');
158
158
 
159
159
  // Install dependencies