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 CHANGED
@@ -1,26 +1,35 @@
1
- # create-solostack
1
+ <div align="center">
2
2
 
3
- > The complete SaaS boilerplate for indie hackers
3
+ # 🚀 SoloStack
4
4
 
5
- Generate a production-ready Next.js 15 SaaS application with authentication, payments, database, and email - all pre-configured and working out of the box.
6
-
7
- ## Features
5
+ **The complete SaaS boilerplate for indie hackers**
8
6
 
9
- 🚀 **Quick Setup** - Get a full SaaS up and running in minutes, not weeks
7
+ [![Version](https://img.shields.io/badge/version-1.3.1-blue.svg)](https://github.com/danish296/create-solostack)
8
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
9
+ [![Node](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org/)
10
10
 
11
- 🔐 **Authentication** - NextAuth.js with email/password and OAuth (Google, GitHub)
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
- 💳 **Payments** - Stripe integration for subscriptions and one-time payments
13
+ **Built with ❤️ by [Danish Akhtar](https://github.com/danish296)**
14
14
 
15
- 📧 **Emails** - Resend for transactional emails with React Email templates
15
+ [Documentation](#) [Report Bug](#) [Request Feature](#)
16
16
 
17
- 🗄️ **Database** - Prisma + PostgreSQL with pre-built models
17
+ </div>
18
18
 
19
- 🎨 **UI Components** - shadcn/ui components with Tailwind CSS
19
+ ---
20
20
 
21
- 📱 **Responsive** - Mobile-first design out of the box
21
+ ## Features
22
22
 
23
- 🔒 **Type-Safe** - Full TypeScript support
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
- Or with other package managers:
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 answer the prompts:
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 ask you:
102
- - Project name
103
- - Authentication provider (NextAuth.js)
104
- - Database (PostgreSQL + Prisma)
105
- - Payment provider (Stripe)
106
- - Email provider (Resend)
107
- - Include shadcn/ui components? (Y/n)
108
- - Initialize git repository? (Y/n)
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
- - **Framework**: Next.js 15 (App Router)
268
- - **Language**: TypeScript
269
- - **Styling**: Tailwind CSS
270
- - **UI Components**: shadcn/ui + Radix UI
271
- - **Database**: PostgreSQL + Prisma
272
- - **Authentication**: NextAuth.js 5
273
- - **Payments**: Stripe
274
- - **Email**: Resend + React Email
275
- - **Form Handling**: React Hook Form + Zod
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/yourusername/create-solostack)
285
- - [Issues](https://github.com/yourusername/create-solostack/issues)
286
- - [Discussions](https://github.com/yourusername/create-solostack/discussions)
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-solostack",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
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": {
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
- // Pro generators
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
- The complete SaaS boilerplate for indie hackers
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💎 Adding Pro features...\n'));
232
-
233
- spinner = ora('Adding OAuth providers (Google, GitHub)').start();
234
- await generateOAuth(projectPath);
235
- spinner.succeed('OAuth providers configured');
236
-
237
- spinner = ora('Upgrading database schema').start();
238
- await generateFullDatabase(projectPath);
239
- spinner.succeed('Full database schema created');
240
-
241
- spinner = ora('Setting up advanced Stripe integration').start();
242
- await generateAdvancedStripe(projectPath);
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
- // Install Pro-specific packages
258
- spinner = ora('Installing Pro packages...').start();
259
- await installProPackages(projectPath);
260
- spinner.succeed('Pro packages installed');
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
@@ -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✅ Success! Your SaaS boilerplate is ready.\n'));
10
-
11
- console.log(chalk.cyan('📁 Project created at:'));
12
- console.log(chalk.white(` ${projectPath}\n`));
13
-
14
- console.log(chalk.cyan('🚀 Next steps:\n'));
15
- console.log(chalk.white(` cd ${projectName}`));
16
- console.log(chalk.white(' cp .env.example .env'));
17
- console.log(chalk.white(' # Add your environment variables to .env\n'));
18
-
19
- console.log(chalk.cyan('🗄️ Database setup:\n'));
20
- console.log(chalk.white(' npm run db:push # Push schema to database'));
21
- console.log(chalk.white(' npm run db:seed # Seed with sample data\n'));
22
-
23
- console.log(chalk.cyan(' Start development:\n'));
24
- console.log(chalk.white(' npm run dev\n'));
25
-
26
- console.log(chalk.cyan('📚 Documentation:\n'));
27
- console.log(chalk.white(' - NextAuth: https://next-auth.js.org'));
28
- console.log(chalk.white(' - Prisma: https://prisma.io'));
29
- console.log(chalk.white(' - Stripe: https://stripe.com/docs'));
30
- console.log(chalk.white(' - Resend: https://resend.com/docs\n'));
31
-
32
- console.log(chalk.yellow('⚠️ Remember to:'));
33
- console.log(chalk.white(' - Set up a PostgreSQL database'));
34
- console.log(chalk.white(' - Get API keys for Stripe and Resend'));
35
- console.log(chalk.white(' - Configure OAuth providers (optional)\n'));
36
-
37
- console.log(chalk.magenta('💡 Happy building! 🚀\n'));
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🎉 Your Pro SaaS is ready!\n'));
71
-
72
- console.log(chalk.cyan('💎 Pro Features Included:'));
73
- console.log(chalk.white(' ✓ OAuth (Google & GitHub)'));
74
- console.log(chalk.white(' ✓ Advanced Stripe (subscriptions, webhooks)'));
75
- console.log(chalk.white(' ✓ Admin panel'));
76
- console.log(chalk.white(' API key system'));
77
- console.log(chalk.white(' Email templates (verification, reset, etc.)'));
78
- console.log(chalk.white(' Full database schema\n'));
79
-
80
- console.log(chalk.yellow('📝 Next steps:\n'));
81
- console.log(chalk.white(` 1. ${chalk.cyan(`cd ${projectName}`)}`));
82
- console.log(chalk.white(` 2. ${chalk.cyan('cp .env.example .env')}`));
83
- console.log(chalk.white(' 3. Add your API keys to .env'));
84
- console.log(chalk.white(` 4. ${chalk.cyan('npx prisma db push')}`));
85
- console.log(chalk.white(` 5. ${chalk.cyan('npm run dev')}\n`));
86
-
87
- console.log(chalk.cyan('🔧 Setup verification:'));
88
- console.log(chalk.white(' Visit http://localhost:3000/setup to verify all integrations\n'));
89
-
90
- console.log(chalk.cyan('👤 Admin access:'));
91
- console.log(chalk.white(' Visit http://localhost:3000/admin (requires admin role)\n'));
92
-
93
- console.log(chalk.gray('Need help? Join our Discord: https://discord.gg/solostack'));
94
- console.log(chalk.gray('Documentation: https://solostack.dev/docs\n'));
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
+ }