create-solostack 1.3.0 → 1.3.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 +67 -42
- package/package.json +1 -1
- package/src/index.js +37 -46
- package/src/utils/logger.js +64 -54
- package/src/utils/pro-api.js +71 -0
package/README.md
CHANGED
|
@@ -1,26 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# 🚀 SoloStack
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Features
|
|
5
|
+
**The complete SaaS boilerplate for indie hackers**
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
[](https://github.com/danish296/create-solostack)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](https://nodejs.org/)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Generate a production-ready Next.js 15 SaaS application with authentication, payments, database, and email - all pre-configured and working out of the box.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
**Built with ❤️ by [Danish Akhtar](https://github.com/danish296)**
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
[Documentation](#) • [Report Bug](#) • [Request Feature](#)
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
</div>
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
---
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
## ✨ Features
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
| Feature | Description |
|
|
24
|
+
|---------|-------------|
|
|
25
|
+
| 🚀 **Quick Setup** | Get a full SaaS up and running in minutes, not weeks |
|
|
26
|
+
| 🔐 **Authentication** | NextAuth.js with email/password and OAuth (Google, GitHub) |
|
|
27
|
+
| 💳 **Payments** | Stripe integration for subscriptions and one-time payments |
|
|
28
|
+
| 📧 **Emails** | Resend for transactional emails with React Email templates |
|
|
29
|
+
| 🗄️ **Database** | Prisma + PostgreSQL with pre-built models |
|
|
30
|
+
| 🎨 **UI Components** | shadcn/ui components with Tailwind CSS |
|
|
31
|
+
| 📱 **Responsive** | Mobile-first design out of the box |
|
|
32
|
+
| 🔒 **Type-Safe** | Full TypeScript support |
|
|
24
33
|
|
|
25
34
|
## Workflows & Architecture
|
|
26
35
|
|
|
@@ -74,13 +83,15 @@ sequenceDiagram
|
|
|
74
83
|
A-->>U: Access Granted
|
|
75
84
|
```
|
|
76
85
|
|
|
77
|
-
## Installation
|
|
86
|
+
## 🚀 Installation
|
|
87
|
+
|
|
88
|
+
Get started in seconds with one command:
|
|
78
89
|
|
|
79
90
|
```bash
|
|
80
91
|
npx create-solostack my-saas-app
|
|
81
92
|
```
|
|
82
93
|
|
|
83
|
-
|
|
94
|
+
**Alternative package managers:**
|
|
84
95
|
|
|
85
96
|
```bash
|
|
86
97
|
# pnpm
|
|
@@ -90,22 +101,23 @@ pnpm create solostack my-saas-app
|
|
|
90
101
|
yarn create solostack my-saas-app
|
|
91
102
|
```
|
|
92
103
|
|
|
93
|
-
## Usage
|
|
104
|
+
## 📖 Usage
|
|
94
105
|
|
|
95
|
-
Run the CLI and
|
|
106
|
+
Run the CLI and follow the interactive prompts:
|
|
96
107
|
|
|
97
108
|
```bash
|
|
98
109
|
npx create-solostack my-app
|
|
99
110
|
```
|
|
100
111
|
|
|
101
|
-
The CLI will
|
|
102
|
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
112
|
+
**The CLI will guide you through:**
|
|
113
|
+
|
|
114
|
+
- 📝 Project name
|
|
115
|
+
- 🔐 Authentication provider (NextAuth.js)
|
|
116
|
+
- 🗄️ Database (PostgreSQL + Prisma)
|
|
117
|
+
- 💳 Payment provider (Stripe)
|
|
118
|
+
- 📧 Email provider (Resend)
|
|
119
|
+
- 🎨 Include shadcn/ui components? (Y/n)
|
|
120
|
+
- 🔧 Initialize git repository? (Y/n)
|
|
109
121
|
|
|
110
122
|
## What's Included
|
|
111
123
|
|
|
@@ -262,36 +274,43 @@ For GitHub OAuth:
|
|
|
262
274
|
2. Create a new OAuth App
|
|
263
275
|
3. Add to `.env`
|
|
264
276
|
|
|
265
|
-
## Tech Stack
|
|
277
|
+
## 🛠️ Tech Stack
|
|
266
278
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
279
|
+
<div align="center">
|
|
280
|
+
|
|
281
|
+
| Category | Technology |
|
|
282
|
+
|----------|-----------|
|
|
283
|
+
| **Framework** | Next.js 15 (App Router) |
|
|
284
|
+
| **Language** | TypeScript |
|
|
285
|
+
| **Styling** | Tailwind CSS |
|
|
286
|
+
| **UI Components** | shadcn/ui + Radix UI |
|
|
287
|
+
| **Database** | PostgreSQL + Prisma |
|
|
288
|
+
| **Authentication** | NextAuth.js 5 |
|
|
289
|
+
| **Payments** | Stripe |
|
|
290
|
+
| **Email** | Resend + React Email |
|
|
291
|
+
| **Form Handling** | React Hook Form + Zod |
|
|
292
|
+
|
|
293
|
+
</div>
|
|
276
294
|
|
|
277
295
|
## Requirements
|
|
278
296
|
|
|
279
297
|
- Node.js 18 or higher
|
|
280
298
|
- PostgreSQL database (local or hosted)
|
|
281
299
|
|
|
282
|
-
## Support
|
|
300
|
+
## 📚 Support & Resources
|
|
283
301
|
|
|
284
|
-
- [Documentation](https://github.com/
|
|
285
|
-
- [Issues](https://github.com/
|
|
286
|
-
- [Discussions](https://github.com/
|
|
302
|
+
- 📖 [Documentation](https://github.com/danish296/create-solostack)
|
|
303
|
+
- 🐛 [Report Issues](https://github.com/danish296/create-solostack/issues)
|
|
304
|
+
- 💬 [Discussions](https://github.com/danish296/create-solostack/discussions)
|
|
305
|
+
- ⭐ [Star on GitHub](https://github.com/danish296/create-solostack)
|
|
287
306
|
|
|
288
307
|
## License
|
|
289
308
|
|
|
290
309
|
MIT © Danish Akhtar
|
|
291
310
|
|
|
292
|
-
## Roadmap
|
|
311
|
+
## 🗺️ Roadmap
|
|
293
312
|
|
|
294
|
-
### Free Version
|
|
313
|
+
### ✅ Free Version
|
|
295
314
|
- ✅ Next.js 15 + TypeScript
|
|
296
315
|
- ✅ Authentication (NextAuth.js)
|
|
297
316
|
- ✅ Database (Prisma + PostgreSQL)
|
|
@@ -299,7 +318,7 @@ MIT © Danish Akhtar
|
|
|
299
318
|
- ✅ Emails (Resend)
|
|
300
319
|
- ✅ UI Components (shadcn/ui)
|
|
301
320
|
|
|
302
|
-
### Pro Version ($99)
|
|
321
|
+
### 💎 Pro Version ($99)
|
|
303
322
|
- 🔜 Multi-tenancy support
|
|
304
323
|
- 🔜 Team/workspace management
|
|
305
324
|
- 🔜 Advanced admin dashboard
|
|
@@ -311,4 +330,10 @@ MIT © Danish Akhtar
|
|
|
311
330
|
|
|
312
331
|
---
|
|
313
332
|
|
|
333
|
+
<div align="center">
|
|
334
|
+
|
|
314
335
|
**Built with ❤️ for indie hackers and solo founders**
|
|
336
|
+
|
|
337
|
+
Made by [Danish Akhtar](https://github.com/danish296) • [GitHub](https://github.com/danish296/create-solostack) • Version 1.3.1
|
|
338
|
+
|
|
339
|
+
</div>
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -16,13 +16,7 @@ import { generateEmails } from './generators/emails.js';
|
|
|
16
16
|
import { generateSetup } from './generators/setup.js';
|
|
17
17
|
import { generateUI } from './generators/ui.js';
|
|
18
18
|
import { validateLicense, isLicenseKeyFormat } from './utils/license.js';
|
|
19
|
-
|
|
20
|
-
import { generateOAuth } from './generators/pro/oauth.js';
|
|
21
|
-
import { generateFullDatabase } from './generators/pro/database-full.js';
|
|
22
|
-
import { generateAdvancedStripe } from './generators/pro/stripe-advanced.js';
|
|
23
|
-
import { generateAdvancedEmails } from './generators/pro/emails.js';
|
|
24
|
-
import { generateAdmin } from './generators/pro/admin.js';
|
|
25
|
-
import { generateApiKeys } from './generators/pro/api-keys.js';
|
|
19
|
+
import { generateProFromServer } from './utils/pro-api.js';
|
|
26
20
|
import {
|
|
27
21
|
AUTH_PROVIDERS,
|
|
28
22
|
DATABASES,
|
|
@@ -34,16 +28,23 @@ import {
|
|
|
34
28
|
* Main CLI function - orchestrates the entire project generation
|
|
35
29
|
*/
|
|
36
30
|
export async function main() {
|
|
37
|
-
// Display banner
|
|
31
|
+
// Display enhanced banner
|
|
38
32
|
console.log(chalk.cyan(`
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
34
|
+
║ ║
|
|
35
|
+
║ ███████╗ ██████╗ ██╗ ██████╗ ███████╗████████╗ ║
|
|
36
|
+
║ ██╔════╝██╔═══██╗██║ ██╔═══██╗██╔════╝╚══██╔══╝ ║
|
|
37
|
+
║ ███████╗██║ ██║██║ ██║ ██║███████╗ ██║ ║
|
|
38
|
+
║ ╚════██║██║ ██║██║ ██║ ██║╚════██║ ██║ ║
|
|
39
|
+
║ ███████║╚██████╔╝███████╗╚██████╔╝███████║ ██║ ║
|
|
40
|
+
║ ╚══════╝ ╚═════╝ ╚══════╝ ╚═════╝ ╚══════╝ ╚═╝ ║
|
|
41
|
+
║ ║
|
|
42
|
+
║ The complete SaaS boilerplate for indie hackers ║
|
|
43
|
+
║ ║
|
|
44
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
45
|
+
`));
|
|
46
|
+
|
|
47
|
+
console.log(chalk.gray(` Version ${chalk.cyan('1.3.1')} • Built by ${chalk.cyan('Danish Akhtar')} • ${chalk.blue('github.com/danish296')}\n`));
|
|
47
48
|
|
|
48
49
|
// Parse command line arguments
|
|
49
50
|
program
|
|
@@ -159,6 +160,7 @@ export async function main() {
|
|
|
159
160
|
|
|
160
161
|
if (licenseData.valid) {
|
|
161
162
|
hasProLicense = true;
|
|
163
|
+
licenseData.licenseKey = licenseAnswer.licenseKey; // Store key for server-side generation
|
|
162
164
|
spinner.succeed(chalk.green(`Pro license validated! Welcome ${licenseData.email} 💎`));
|
|
163
165
|
} else {
|
|
164
166
|
spinner.fail(chalk.red('Invalid license key'));
|
|
@@ -226,38 +228,27 @@ export async function main() {
|
|
|
226
228
|
await generateSetup(projectPath, config);
|
|
227
229
|
spinner.succeed('Added diagnostics page (/setup)');
|
|
228
230
|
|
|
229
|
-
// Pro Features Generation
|
|
231
|
+
// Pro Features Generation (Server-Side)
|
|
230
232
|
if (hasProLicense) {
|
|
231
|
-
console.log(chalk.cyan('\n💎
|
|
232
|
-
|
|
233
|
-
spinner = ora('
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
spinner.succeed('Stripe subscriptions and webhooks configured');
|
|
244
|
-
|
|
245
|
-
spinner = ora('Adding email templates').start();
|
|
246
|
-
await generateAdvancedEmails(projectPath);
|
|
247
|
-
spinner.succeed('Email templates created');
|
|
248
|
-
|
|
249
|
-
spinner = ora('Creating admin panel').start();
|
|
250
|
-
await generateAdmin(projectPath);
|
|
251
|
-
spinner.succeed('Admin panel created');
|
|
252
|
-
|
|
253
|
-
spinner = ora('Setting up API key system').start();
|
|
254
|
-
await generateApiKeys(projectPath);
|
|
255
|
-
spinner.succeed('API key system configured');
|
|
233
|
+
console.log(chalk.cyan('\n💎 Fetching Pro features from server...\n'));
|
|
234
|
+
|
|
235
|
+
spinner = ora('Downloading Pro features (OAuth, Admin, API Keys, Billing...)').start();
|
|
236
|
+
try {
|
|
237
|
+
const fileCount = await generateProFromServer(projectPath, licenseData.licenseKey, config);
|
|
238
|
+
spinner.succeed(`Pro features downloaded (${fileCount} files)`);
|
|
239
|
+
} catch (error) {
|
|
240
|
+
spinner.fail('Failed to download Pro features');
|
|
241
|
+
console.log(chalk.yellow('\n⚠️ Error: ' + error.message));
|
|
242
|
+
console.log(chalk.yellow(' Continuing with free version...\n'));
|
|
243
|
+
hasProLicense = false;
|
|
244
|
+
}
|
|
256
245
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
246
|
+
if (hasProLicense) {
|
|
247
|
+
// Install Pro-specific packages
|
|
248
|
+
spinner = ora('Installing Pro packages...').start();
|
|
249
|
+
await installProPackages(projectPath);
|
|
250
|
+
spinner.succeed('Pro packages installed');
|
|
251
|
+
}
|
|
261
252
|
}
|
|
262
253
|
|
|
263
254
|
// Install dependencies
|
package/src/utils/logger.js
CHANGED
|
@@ -6,35 +6,40 @@ import chalk from 'chalk';
|
|
|
6
6
|
* @param {string} projectPath - Absolute path to the project
|
|
7
7
|
*/
|
|
8
8
|
export function printSuccess(projectName, projectPath) {
|
|
9
|
-
console.log(chalk.green('\n
|
|
10
|
-
|
|
11
|
-
console.log(chalk.
|
|
12
|
-
console.log(chalk.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
console.log(chalk.
|
|
16
|
-
console.log(chalk.white(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
console.log(chalk.
|
|
20
|
-
console.log(chalk.white('
|
|
21
|
-
console.log(chalk.white('
|
|
22
|
-
|
|
23
|
-
console.log(chalk.cyan('
|
|
24
|
-
console.log(chalk.white('
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
console.log(chalk.
|
|
28
|
-
console.log(chalk.white('
|
|
29
|
-
|
|
30
|
-
console.log(chalk.
|
|
31
|
-
|
|
32
|
-
console.log(chalk.
|
|
33
|
-
console.log(chalk.white('
|
|
34
|
-
console.log(chalk.white('
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
console.log(chalk.
|
|
9
|
+
console.log(chalk.green.bold('\n╔═══════════════════════════════════════════════════════════╗'));
|
|
10
|
+
console.log(chalk.green.bold('║ ║'));
|
|
11
|
+
console.log(chalk.green.bold('║ ✅ Success! Your SaaS boilerplate is ready! ║'));
|
|
12
|
+
console.log(chalk.green.bold('║ ║'));
|
|
13
|
+
console.log(chalk.green.bold('╚═══════════════════════════════════════════════════════════╝\n'));
|
|
14
|
+
|
|
15
|
+
console.log(chalk.cyan.bold('📁 Project Location:'));
|
|
16
|
+
console.log(chalk.white(` ${chalk.gray('→')} ${projectPath}\n`));
|
|
17
|
+
|
|
18
|
+
console.log(chalk.cyan.bold('🚀 Quick Start:\n'));
|
|
19
|
+
console.log(chalk.white(` ${chalk.gray('$')} ${chalk.yellow(`cd ${projectName}`)}`));
|
|
20
|
+
console.log(chalk.white(` ${chalk.gray('$')} ${chalk.yellow('cp .env.example .env')}`));
|
|
21
|
+
console.log(chalk.white(` ${chalk.gray('#')} ${chalk.gray('Add your environment variables to .env')}\n`));
|
|
22
|
+
|
|
23
|
+
console.log(chalk.cyan.bold('🗄️ Database Setup:\n'));
|
|
24
|
+
console.log(chalk.white(` ${chalk.gray('$')} ${chalk.yellow('npm run db:push')} ${chalk.gray('# Push schema to database')}`));
|
|
25
|
+
console.log(chalk.white(` ${chalk.gray('$')} ${chalk.yellow('npm run db:seed')} ${chalk.gray('# Seed with sample data')}\n`));
|
|
26
|
+
|
|
27
|
+
console.log(chalk.cyan.bold('⚡ Start Development:\n'));
|
|
28
|
+
console.log(chalk.white(` ${chalk.gray('$')} ${chalk.yellow('npm run dev')}\n`));
|
|
29
|
+
|
|
30
|
+
console.log(chalk.cyan.bold('📚 Documentation & Resources:\n'));
|
|
31
|
+
console.log(chalk.white(` ${chalk.gray('•')} NextAuth: ${chalk.blue('https://next-auth.js.org')}`));
|
|
32
|
+
console.log(chalk.white(` ${chalk.gray('•')} Prisma: ${chalk.blue('https://prisma.io')}`));
|
|
33
|
+
console.log(chalk.white(` ${chalk.gray('•')} Stripe: ${chalk.blue('https://stripe.com/docs')}`));
|
|
34
|
+
console.log(chalk.white(` ${chalk.gray('•')} Resend: ${chalk.blue('https://resend.com/docs')}\n`));
|
|
35
|
+
|
|
36
|
+
console.log(chalk.yellow.bold('⚠️ Important Reminders:\n'));
|
|
37
|
+
console.log(chalk.white(` ${chalk.gray('•')} Set up a PostgreSQL database (Neon, Supabase, etc.)`));
|
|
38
|
+
console.log(chalk.white(` ${chalk.gray('•')} Get API keys for Stripe and Resend`));
|
|
39
|
+
console.log(chalk.white(` ${chalk.gray('•')} Configure OAuth providers (optional)\n`));
|
|
40
|
+
|
|
41
|
+
console.log(chalk.magenta.bold('💡 Happy building! 🚀\n'));
|
|
42
|
+
console.log(chalk.gray(` Built with ❤️ by ${chalk.cyan('Danish Akhtar')} • ${chalk.blue('github.com/danish296')}\n`));
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
/**
|
|
@@ -67,29 +72,34 @@ export function printInfo(message) {
|
|
|
67
72
|
* @param {string} projectPath - Absolute path to the project
|
|
68
73
|
*/
|
|
69
74
|
export function printProSuccess(projectName, projectPath) {
|
|
70
|
-
console.log(chalk.green.bold('\n
|
|
71
|
-
|
|
72
|
-
console.log(chalk.
|
|
73
|
-
console.log(chalk.
|
|
74
|
-
console.log(chalk.
|
|
75
|
-
|
|
76
|
-
console.log(chalk.
|
|
77
|
-
console.log(chalk.white('
|
|
78
|
-
console.log(chalk.white('
|
|
79
|
-
|
|
80
|
-
console.log(chalk.
|
|
81
|
-
console.log(chalk.white(`
|
|
82
|
-
console.log(chalk.white(`
|
|
83
|
-
|
|
84
|
-
console.log(chalk.
|
|
85
|
-
console.log(chalk.white(`
|
|
86
|
-
|
|
87
|
-
console.log(chalk.
|
|
88
|
-
console.log(chalk.white('
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
console.log(chalk.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
console.log(chalk.
|
|
75
|
+
console.log(chalk.green.bold('\n╔═══════════════════════════════════════════════════════════╗'));
|
|
76
|
+
console.log(chalk.green.bold('║ ║'));
|
|
77
|
+
console.log(chalk.green.bold('║ 💎 Your Pro SaaS is ready! 🎉 ║'));
|
|
78
|
+
console.log(chalk.green.bold('║ ║'));
|
|
79
|
+
console.log(chalk.green.bold('╚═══════════════════════════════════════════════════════════╝\n'));
|
|
80
|
+
|
|
81
|
+
console.log(chalk.cyan.bold('💎 Pro Features Included:\n'));
|
|
82
|
+
console.log(chalk.white(` ${chalk.green('✓')} OAuth (Google & GitHub)`));
|
|
83
|
+
console.log(chalk.white(` ${chalk.green('✓')} Advanced Stripe (subscriptions, webhooks)`));
|
|
84
|
+
console.log(chalk.white(` ${chalk.green('✓')} Admin panel`));
|
|
85
|
+
console.log(chalk.white(` ${chalk.green('✓')} API key system`));
|
|
86
|
+
console.log(chalk.white(` ${chalk.green('✓')} Email templates (verification, reset, etc.)`));
|
|
87
|
+
console.log(chalk.white(` ${chalk.green('✓')} Full database schema\n`));
|
|
88
|
+
|
|
89
|
+
console.log(chalk.yellow.bold('📝 Next Steps:\n'));
|
|
90
|
+
console.log(chalk.white(` ${chalk.gray('1.')} ${chalk.yellow(`cd ${projectName}`)}`));
|
|
91
|
+
console.log(chalk.white(` ${chalk.gray('2.')} ${chalk.yellow('cp .env.example .env')}`));
|
|
92
|
+
console.log(chalk.white(` ${chalk.gray('3.')} Add your API keys to .env`));
|
|
93
|
+
console.log(chalk.white(` ${chalk.gray('4.')} ${chalk.yellow('npx prisma db push')}`));
|
|
94
|
+
console.log(chalk.white(` ${chalk.gray('5.')} ${chalk.yellow('npm run dev')}\n`));
|
|
95
|
+
|
|
96
|
+
console.log(chalk.cyan.bold('🔧 Setup Verification:\n'));
|
|
97
|
+
console.log(chalk.white(` ${chalk.gray('→')} Visit ${chalk.blue('http://localhost:3000/setup')} to verify all integrations\n`));
|
|
98
|
+
|
|
99
|
+
console.log(chalk.cyan.bold('👤 Admin Access:\n'));
|
|
100
|
+
console.log(chalk.white(` ${chalk.gray('→')} Visit ${chalk.blue('http://localhost:3000/admin')} (requires admin role)\n`));
|
|
101
|
+
|
|
102
|
+
console.log(chalk.gray(' Need help? Join our Discord: ') + chalk.blue('https://discord.gg/solostack'));
|
|
103
|
+
console.log(chalk.gray(' Documentation: ') + chalk.blue('https://solostack.dev/docs'));
|
|
104
|
+
console.log(chalk.gray(`\n Built with ❤️ by ${chalk.cyan('Danish Akhtar')} • ${chalk.blue('github.com/danish296')}\n`));
|
|
95
105
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pro API Client
|
|
3
|
+
* Fetches Pro files from the server-side generation API
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { writeFile, ensureDir } from './files.js';
|
|
8
|
+
|
|
9
|
+
// Pro generation API endpoint
|
|
10
|
+
const PRO_API = 'https://solostack-license-api.solo-stack.workers.dev/generate-pro';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Fetch Pro files from the server
|
|
14
|
+
* @param {string} licenseKey - Valid Pro license key
|
|
15
|
+
* @param {object} config - Project configuration
|
|
16
|
+
* @returns {Promise<object>} - Object with file paths and contents
|
|
17
|
+
*/
|
|
18
|
+
export async function fetchProFiles(licenseKey, config = {}) {
|
|
19
|
+
const response = await fetch(PRO_API, {
|
|
20
|
+
method: 'POST',
|
|
21
|
+
headers: {
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
},
|
|
24
|
+
body: JSON.stringify({
|
|
25
|
+
license: licenseKey,
|
|
26
|
+
config: config,
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
const error = await response.json().catch(() => ({ error: 'Server error' }));
|
|
32
|
+
throw new Error(error.error || 'Failed to generate Pro files');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const data = await response.json();
|
|
36
|
+
|
|
37
|
+
if (!data.success) {
|
|
38
|
+
throw new Error(data.error || 'Pro generation failed');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return data.files;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Write Pro files to the project directory
|
|
46
|
+
* @param {string} projectPath - Path to the project
|
|
47
|
+
* @param {object} files - Object with { "path/to/file": "content" }
|
|
48
|
+
*/
|
|
49
|
+
export async function writeProFiles(projectPath, files) {
|
|
50
|
+
for (const [filePath, content] of Object.entries(files)) {
|
|
51
|
+
const fullPath = path.join(projectPath, filePath);
|
|
52
|
+
|
|
53
|
+
// Ensure directory exists
|
|
54
|
+
await ensureDir(path.dirname(fullPath));
|
|
55
|
+
|
|
56
|
+
// Write file
|
|
57
|
+
await writeFile(fullPath, content);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Generate Pro features for a project
|
|
63
|
+
* @param {string} projectPath - Path to the project
|
|
64
|
+
* @param {string} licenseKey - Valid Pro license key
|
|
65
|
+
* @param {object} config - Project configuration
|
|
66
|
+
*/
|
|
67
|
+
export async function generateProFromServer(projectPath, licenseKey, config = {}) {
|
|
68
|
+
const files = await fetchProFiles(licenseKey, config);
|
|
69
|
+
await writeProFiles(projectPath, files);
|
|
70
|
+
return Object.keys(files).length;
|
|
71
|
+
}
|