diff --git a/README.md b/README.md index 6ba265b..5795b7e 100644 --- a/README.md +++ b/README.md @@ -74,32 +74,7 @@ https://github.com/user-attachments/assets/465451f2-1e1a-48b6-a99e-253ef4f28e2d - NextAuth - Passport -## 📦 Installation - -### Prerequisites - -Make sure you have the following installed on your system: - -- Node.js -- Git - -### CLI Tool - -To scaffold a new full-stack project, run: - -```sh -npm create @shivasankaran18/stackd new proj-name -``` - -This will prompt you with setup questions and generate the project with the selected configurations. - -### Web Tool - -To launch the web-based setup tool locally, use: - -```sh -npx @shivasankaran18/create-stackd setup -```## 🛆 Installation +### 🛆 Installation ### Prerequisites diff --git a/apps/cli/src/generators/auth/jwt.js b/apps/cli/src/generators/auth/jwt.js deleted file mode 100644 index 4b19790..0000000 --- a/apps/cli/src/generators/auth/jwt.js +++ /dev/null @@ -1,83 +0,0 @@ -import { mkdir, writeFile } from 'node:fs/promises'; -import { join } from 'node:path'; -import fs from 'fs'; - -export async function jwtAuthts(config, projectDir,emitLog) { - emitLog('Installing jsonwebtoken...'); - const packageJsonPath = join(projectDir, 'backend','package.json'); - const jsonData = await JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); - emitLog('Updating package.json...'); - jsonData.dependencies = jsonData.dependencies || {}; - jsonData.dependencies["jsonwebtoken"] = "^9.0.2"; - - fs.writeFileSync(packageJsonPath, JSON.stringify(jsonData, null, 2), 'utf8'); - emitLog('Writing jwt.ts...'); - const jwtAuthFile = ` - const jwt = require('jsonwebtoken'); -export const authenticateToken = (req:any, res:any, next:any) => { - const token = req.header('Authorization')?.split(' ')[1]; - if (!token) return res.status(401).json({ error: 'Access Denied' }); - - jwt.verify(token, process.env.JWT_SECRET, (err:any, user:any) => { - if (err) return res.status(403).json({ error: 'Invalid Token' }); - req.user = user; - next(); - }); -}; -`; - emitLog('Writing middleware.ts...'); - const middlewareDir = join(projectDir, 'backend', 'src', 'middleware'); - await mkdir(middlewareDir, { recursive: true }); - emitLog('Writing middleware.ts...'); - await writeFile(join(middlewareDir, 'middleware.ts'), jwtAuthFile, 'utf8'); - emitLog('✅ JWT authentication setup completed successfully!'); -} - -export async function jwtAuthdjango(config , projectDir ,emitLog) { - emitLog('Installing jsonwebtoken...'); - const settingsPath = join(projectDir, 'backend', 'core', 'settings.py'); - emitLog('Updating settings.py...'); - try { - let settingsContent = fs.readFileSync(settingsPath, 'utf8'); - const restFrameworkSettings = ` - -REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': [ - 'rest_framework_simplejwt.authentication.JWTAuthentication', - ], -} -`; - - const installedAppsIndex = settingsContent.indexOf('INSTALLED_APPS'); - const insertPosition = settingsContent.indexOf(']', installedAppsIndex) + 1; - - settingsContent = - settingsContent.slice(0, insertPosition) + - restFrameworkSettings + - settingsContent.slice(insertPosition); - - fs.writeFileSync(settingsPath, settingsContent, 'utf8'); - emitLog('Writing urls.py...'); - let urlsContent = fs.readFileSync(`${projectDir}/backend/core/urls.py`, 'utf8'); - const newUrlsContent = `from django.contrib import admin -from django.urls import path, include -from rest_framework_simplejwt import views as jwt_views - -urlpatterns = [ - path('admin/', admin.site.urls), - path('api/token/', - jwt_views.TokenObtainPairView.as_view(), - name='token_obtain_pair'), - path('api/token/refresh/', - jwt_views.TokenRefreshView.as_view(), - name='token_refresh'), - path('', include('main.urls')), -] -`; - fs.writeFileSync(`${projectDir}/backend/core/urls.py`, newUrlsContent, 'utf8'); - emitLog('✅ JWT authentication setup completed successfully!'); - } catch (error) { - console.error('Error configuring Django settings:', error); - throw error; - } -} diff --git a/apps/cli/src/generators/auth/nextAuth.js b/apps/cli/src/generators/auth/nextAuth.js deleted file mode 100644 index 070c1d8..0000000 --- a/apps/cli/src/generators/auth/nextAuth.js +++ /dev/null @@ -1,146 +0,0 @@ -import { join } from 'node:path' -import { mkdir, writeFile } from 'node:fs/promises' -import 'dotenv/config' - -export async function setupNextAuth(config, projectDir,emitLog) { - try { - const authDir = join(projectDir, 'frontend', 'src', 'app', 'api', 'auth'); - await mkdir(authDir, { recursive: true }); - emitLog('Creating auth directory...'); - const routeCode = ` -import NextAuth from "next-auth"; -import { AuthOptions } from "next-auth"; -import GithubProvider from "next-auth/providers/github"; -import GoogleProvider from "next-auth/providers/google"; -import CredentialsProvider from "next-auth/providers/credentials"; -export const authOptions: AuthOptions = { - providers: [ - GithubProvider({ - clientId: process.env.GITHUB_ID!, - clientSecret: process.env.GITHUB_SECRET!, - }), - GoogleProvider({ - clientId: process.env.GOOGLE_CLIENT_ID!, - clientSecret: process.env.GOOGLE_CLIENT_SECRET!, - }), - CredentialsProvider({ - name: 'Credentials', - credentials: { - email: { label: "Email", type: "email" }, - password: { label: "Password", type: "password" } - }, - async authorize(credentials) { - // Add your credentials logic here - if (!credentials?.email || !credentials?.password) return null; - - try { - // Example user verification - const user = { id: "1", email: credentials.email, name: "User" }; - return user; - } catch (error) { - return null; - } - } - }), - ], - pages: { - signIn: '/auth/signin', - signOut: '/auth/signout', - error: '/auth/error', - }, - callbacks: { - async jwt({ token, user }) { - if (user) { - token.id = user.id; - } - return token; - }, - async session({ session, token }) { - if (session.user) { - (session.user as any).id = token.id; - } - return session; - }, - }, - session: { - strategy: "jwt", - }, - secret: process.env.NEXTAUTH_SECRET, -}; - -const handler = NextAuth(authOptions); -export { handler as GET, handler as POST }; -`; - - await writeFile( - join(authDir, 'route.ts'), - routeCode.trim() + '\n' - ); - - const utilsDir = join(projectDir, 'frontend', 'src', 'utils'); - await mkdir(utilsDir, { recursive: true }); - emitLog('Creating utils directory...'); - const utilsCode = ` -import { getServerSession } from "next-auth/next"; -import { authOptions } from "@/app/api/auth/route"; - -export async function getSession() { - return await getServerSession(authOptions); -} - -export async function getCurrentUser() { - const session = await getSession(); - return session?.user; -} - -export async function isAuthenticated() { - const session = await getSession(); - return !!session; -} -`; - emitLog('Writing utils.ts...'); - await writeFile( - join(utilsDir, 'auth.ts'), - utilsCode.trim() + '\n' - ); - - const envContent = ` -# NextAuth Configuration -NEXTAUTH_SECRET=your-secret-key-here -NEXTAUTH_URL=http://localhost:${config.frontendPort} - -# OAuth Providers -GITHUB_ID=your-github-id -GITHUB_SECRET=your-github-secret - -GOOGLE_CLIENT_ID=your-google-client-id -GOOGLE_CLIENT_SECRET=your-google-client-secret -`; - emitLog('Writing .env file...'); - await writeFile( - join(projectDir, 'frontend', '.env'), - envContent.trim() + '\n' - ); - emitLog('Writing AuthProvider.tsx...'); - const providerCode = ` -'use client'; - -import { SessionProvider } from "next-auth/react"; - -export function AuthProvider({ children }: { children: React.ReactNode }) { - return {children}; -} -`; - emitLog('Creating components directory...'); - const providersDir = join(projectDir, 'frontend', 'src', 'components', 'auth'); - await mkdir(providersDir, { recursive: true }); - await writeFile( - join(providersDir, 'AuthProvider.tsx'), - providerCode.trim() + '\n' - ); - emitLog('✅ NextAuth setup completed successfully!'); - } catch (error) { - emitLog(`❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}`); - throw error; - } -} diff --git a/apps/cli/src/generators/auth/passport.js b/apps/cli/src/generators/auth/passport.js deleted file mode 100644 index 7d6fa6b..0000000 --- a/apps/cli/src/generators/auth/passport.js +++ /dev/null @@ -1,234 +0,0 @@ -import { join } from 'node:path' -import { mkdir, writeFile } from 'node:fs/promises' - -export async function setupPassport(config, projectDir,emitLog) { - emitLog('Setting up Passport...'); - try { - const backendDir = join(projectDir, 'backend'); - const authDir = join(backendDir, 'src', 'auth'); - const configDir = join(backendDir, 'src', 'config'); - emitLog('Creating auth and config directories...'); - await mkdir(authDir, { recursive: true }); - await mkdir(configDir, { recursive: true }); - - const passportConfigCode = ` -import passport from 'passport'; -import { Strategy as LocalStrategy } from 'passport-local'; -import { Strategy as JwtStrategy, ExtractJwt } from 'passport-jwt'; -import { Strategy as GoogleStrategy } from 'passport-google-oauth20'; -import { User } from '../models/user.model'; -import { config } from '../config'; - -// Local Strategy -passport.use(new LocalStrategy( - { usernameField: 'email' }, - async (email, password, done) => { - try { - const user = await User.findOne({ email }); - if (!user) { - return done(null, false, { message: 'Incorrect email.' }); - } - - const isValid = await user.comparePassword(password); - if (!isValid) { - return done(null, false, { message: 'Incorrect password.' }); - } - - return done(null, user); - } catch (error) { - return done(error); - } - } -)); - -// JWT Strategy -passport.use(new JwtStrategy( - { - jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), - secretOrKey: config.jwt.secret, - }, - async (payload, done) => { - try { - const user = await User.findById(payload.sub); - if (!user) { - return done(null, false); - } - return done(null, user); - } catch (error) { - return done(error, false); - } - } -)); - -// Google OAuth Strategy -passport.use(new GoogleStrategy( - { - clientID: config.google.clientId, - clientSecret: config.google.clientSecret, - callbackURL: '/auth/google/callback', - }, - async (accessToken, refreshToken, profile, done) => { - try { - let user = await User.findOne({ googleId: profile.id }); - - if (!user) { - user = await User.create({ - googleId: profile.id, - email: profile.emails?.[0]?.value, - name: profile.displayName, - }); - } - - return done(null, user); - } catch (error) { - return done(error, false); - } - } -)); - -// Serialization -passport.serializeUser((user: any, done) => { - done(null, user.id); -}); - -passport.deserializeUser(async (id: string, done) => { - try { - const user = await User.findById(id); - done(null, user); - } catch (error) { - done(error); - } -}); - -export default passport; -`; - emitLog('Writing passport.config.ts...'); - await writeFile( - join(authDir, 'passport.config.ts'), - passportConfigCode.trim() + '\n' - ); - emitLog('Creating authentication middleware...'); - const authMiddlewareCode = ` -import { Request, Response, NextFunction } from 'express'; -import passport from 'passport'; -import jwt from 'jsonwebtoken'; -import { config } from '../config'; - -export const authenticateJWT = passport.authenticate('jwt', { session: false }); - -export const authenticateLocal = (req: Request, res: Response, next: NextFunction) => { - passport.authenticate('local', { session: false }, (err, user, info) => { - if (err) { - return next(err); - } - if (!user) { - return res.status(401).json({ message: info?.message || 'Authentication failed' }); - } - - const token = jwt.sign({ sub: user.id }, config.jwt.secret, { - expiresIn: config.jwt.expiresIn, - }); - - req.user = user; - res.locals.token = token; - next(); - })(req, res, next); -}; - -export const isAuthenticated = (req: Request, res: Response, next: NextFunction) => { - if (req.isAuthenticated()) { - return next(); - } - res.status(401).json({ message: 'Unauthorized' }); -}; -`; - emitLog('Writing middleware.ts...'); - await writeFile( - join(authDir, 'middleware.ts'), - authMiddlewareCode.trim() + '\n' - ); - emitLog('Creating authentication routes...'); - const authRoutesCode = ` -import { Router } from 'express'; -import passport from 'passport'; -import { authenticateLocal } from './middleware'; - -const router = Router(); - -router.post('/login', authenticateLocal, (req, res) => { - res.json({ - user: req.user, - token: res.locals.token, - }); -}); - -router.post('/register', async (req, res) => { - // Add your registration logic here -}); - -router.get('/google', - passport.authenticate('google', { scope: ['profile', 'email'] }) -); - -router.get('/google/callback', - passport.authenticate('google', { session: false }), - (req, res) => { - // Handle successful authentication - res.redirect('/'); - } -); - -router.post('/logout', (req, res) => { - req.logout(); - res.json({ message: 'Logged out successfully' }); -}); - -export default router; -`; - emitLog('Writing routes.ts...'); - await writeFile( - join(authDir, 'routes.ts'), - authRoutesCode.trim() + '\n' - ); - emitLog('Creating configuration file...'); - const configCode = ` -export const config = { - jwt: { - secret: process.env.JWT_SECRET || 'your-secret-key', - expiresIn: '1d', - }, - google: { - clientId: process.env.GOOGLE_CLIENT_ID, - clientSecret: process.env.GOOGLE_CLIENT_SECRET, - }, - session: { - secret: process.env.SESSION_SECRET || 'session-secret', - }, -}; -`; - emitLog('Writing index.ts...'); - await writeFile( - join(configDir, 'index.ts'), - configCode.trim() + '\n' - ); - emitLog('Adding environment variables...'); - const envContent = ` -# Authentication -JWT_SECRET=your-jwt-secret-key -SESSION_SECRET=your-session-secret - -# Google OAuth -GOOGLE_CLIENT_ID=your-google-client-id -GOOGLE_CLIENT_SECRET=your-google-client-secret -`; - emitLog('Writing .env file...'); - await writeFile( - join(backendDir, '.env'), - envContent.trim() + '\n' - ); - emitLog('✅ Passport.js setup completed successfully!'); - } catch (error) { - emitLog(`❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}`); - throw error; - } -} \ No newline at end of file diff --git a/apps/cli/src/generators/backend/django.js b/apps/cli/src/generators/backend/django.js deleted file mode 100644 index 33f6487..0000000 --- a/apps/cli/src/generators/backend/django.js +++ /dev/null @@ -1,30 +0,0 @@ -import { exec } from 'child_process'; -import { mkdirSync } from 'fs'; -import util from 'util'; - -const execAsync = util.promisify(exec); - -export async function installDjangoDependencies(projectPath) { - try { - - mkdirSync(`${projectPath}/backend`, { recursive: true }); - - await execAsync('python -m venv venv', { cwd: `${projectPath}/backend` }); - - const pythonCmd = process.platform === 'win32' ? 'venv\\Scripts\\python.exe' : 'venv/bin/python'; - - await execAsync(`${pythonCmd} -m pip install django djangorestframework django-cors-headers djangorestframework_simplejwt`, { cwd: `${projectPath}/backend` }); - - await execAsync(`${pythonCmd} -m django startproject core .`, { cwd: `${projectPath}/backend` }); - - await execAsync(`${pythonCmd} manage.py startapp main`, { cwd: `${projectPath}/backend` }); - - console.log("Django project setup completed!"); - - } catch (error) { - console.error('Error installing Django dependencies:', error); - throw error; - } -} - -export default installDjangoDependencies; \ No newline at end of file diff --git a/apps/cli/src/generators/backend/expressjs.js b/apps/cli/src/generators/backend/expressjs.js deleted file mode 100644 index f038244..0000000 --- a/apps/cli/src/generators/backend/expressjs.js +++ /dev/null @@ -1,72 +0,0 @@ -import { execSync } from 'node:child_process' -import { mkdir, writeFile } from 'node:fs/promises' -import { join } from 'node:path' -import { writeFileSync } from 'fs' - -export async function createExpressJS(config, projectDir,emitLog) { - emitLog('Creating ExpressJS project...'); - await mkdir(join(projectDir, 'backend')) - const backendPackageJson = { - name: "backend", - version: "1.0.0", - scripts: { - "dev": "nodemon src/index.js", - "start": "node src/index.js" - }, - dependencies: { - "express": "^4.18.2", - "cors": "^2.8.5", - "dotenv": "^16.3.1" - }, - devDependencies: { - "nodemon": "^2.0.22" - } - } - - emitLog('Writing package.json...'); - await writeFile( - join(projectDir, 'backend', 'package.json'), - JSON.stringify(backendPackageJson, null, 2) - ) - - emitLog('Creating src directory...'); - await mkdir(join(projectDir, 'backend', 'src')) - - const backendIndex = ` -const express = require('express'); -const cors = require('cors'); -const dotenv = require('dotenv'); - -dotenv.config(); - -const app = express(); -const port = process.env.PORT || ${config.backendPort}; - -app.use(cors()); -app.use(express.json()); - -// Test route -app.get('/api/test', (req, res) => { - res.json({ message: 'Hello from Express!' }); -}); - -// Health check route -app.get('/api/health', (req, res) => { - res.json({ status: 'ok', timestamp: new Date() }); -}); - -app.listen(port, () => { - console.log(\`Server running on port \${port}\`); -});` - - emitLog('Writing index.js...'); - await writeFile( - join(projectDir, 'backend', 'src', 'index.js'), - backendIndex.trim() - ) - - emitLog('Installing dependencies...'); - await execSync("npm install",{cwd : projectDir + '/backend',stdio : "inherit"}); - - emitLog('✅ ExpressJS project created successfully!'); -} \ No newline at end of file diff --git a/apps/cli/src/generators/backend/expressts.js b/apps/cli/src/generators/backend/expressts.js deleted file mode 100644 index 30dab73..0000000 --- a/apps/cli/src/generators/backend/expressts.js +++ /dev/null @@ -1,95 +0,0 @@ -import { execSync } from 'node:child_process' -import { mkdir, writeFile } from 'node:fs/promises' -import { join } from 'node:path' - -export async function createExpressTS(config, projectDir ,emitLog) { - emitLog('Creating ExpressTS project...'); - await mkdir(join(projectDir, 'backend')); - emitLog('Writing package.json...'); - const backendPackageJson = { - name: "backend", - version: "1.0.0", - scripts: { - "dev": "ts-node-dev --respawn --transpile-only src/index.ts", - "build": "tsc", - "start": "node dist/index.js" - }, - dependencies: { - "express": "^4.18.2", - "cors": "^2.8.5", - "dotenv": "^16.3.1" - }, - devDependencies: { - "@types/express": "^4.17.17", - "@types/cors": "^2.8.13", - "@types/node": "^20.4.5", - "typescript": "^5.1.6", - "ts-node-dev": "^2.0.0" - } - } - - await writeFile( - join(projectDir, 'backend', 'package.json'), - JSON.stringify(backendPackageJson, null, 2) - ) - emitLog('Writing tsconfig.json...'); - const tsConfig = { - compilerOptions: { - "target": "ES2020", - "module": "CommonJS", - "lib": ["ES2020"], - "moduleResolution": "node", - "outDir": "./dist", - "rootDir": "./src", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true - }, - include: ["src/**/*"], - exclude: ["node_modules"] - } - - await writeFile( - join(projectDir, 'backend', 'tsconfig.json'), - JSON.stringify(tsConfig, null, 2) - ) - emitLog('Creating src directory...'); - await mkdir(join(projectDir, 'backend', 'src')) - emitLog('Writing index.ts...'); - const backendIndex = ` -import express from 'express'; -import cors from 'cors'; -import dotenv from 'dotenv'; - -dotenv.config(); - -const app = express(); -const port = process.env.PORT || ${config.backendPort}; - -app.use(cors()); -app.use(express.json()); - -// Test route -app.get('/api/test', (req, res) => { - res.json({ message: 'Hello from Express!' }); -}); - -// Health check route -app.get('/api/health', (req, res) => { - res.json({ status: 'ok', timestamp: new Date() }); -}); - -app.listen(port, () => { - console.log(\`Server running on port \${port}\`); -});` - emitLog('Writing index.ts...'); - await writeFile( - join(projectDir, 'backend', 'src', 'index.ts'), - backendIndex.trim() - ) - emitLog('Installing dependencies...'); - await execSync("npm install",{cwd : projectDir + '/backend',stdio : "inherit"}); - emitLog('✅ ExpressTS project created successfully!'); -} \ No newline at end of file diff --git a/apps/cli/src/generators/frontend/angularts.js b/apps/cli/src/generators/frontend/angularts.js deleted file mode 100644 index bac6f49..0000000 --- a/apps/cli/src/generators/frontend/angularts.js +++ /dev/null @@ -1,29 +0,0 @@ -import { execSync } from "child_process"; -import path from "path"; - -export default async function createAngularTS(config, projectDir) { - try { - - const projectFullPath = path.join(projectDir, 'frontend'); - - console.log('Installing Angular CLI...'); - await execSync(`npx @angular/cli@latest new frontend --skip-git --style=scss --routing=true --strict`, { - cwd: projectDir, - stdio: 'inherit' - }); - - - console.log('Installing dependencies...'); - await execSync('npm install', { - cwd: projectFullPath, - stdio: 'inherit' - }); - - console.log('Angular project created successfully!'); - - } catch (error) { - console.error('Error creating Angular project:', error); - throw error; - } -} - diff --git a/apps/cli/src/generators/frontend/reactjs.js b/apps/cli/src/generators/frontend/reactjs.js deleted file mode 100644 index 00744bf..0000000 --- a/apps/cli/src/generators/frontend/reactjs.js +++ /dev/null @@ -1,42 +0,0 @@ -import { mkdir, writeFile } from 'fs/promises'; -import { join } from 'path'; -import { execSync } from 'child_process'; - -export async function createReactJS(config, projectDir,emitLog) { - emitLog("Creating React JavaScript frontend..."); - - await execSync(`npm create vite@latest frontend -- --template react`, { - cwd: projectDir, - stdio: 'inherit', - shell: true - }); - - emitLog("Installing dependencies..."); - await execSync('npm install', { - cwd: join(projectDir, 'frontend'), - stdio: 'inherit', - shell: true - }); - - const viteConfig = ` - import { defineConfig } from 'vite' - import react from '@vitejs/plugin-react' - - export default defineConfig({ - plugins: [react()], - server: { - port: ${config.frontendPort}, - proxy: { - '/api': { - target: 'http://localhost:${config.backendPort}', - changeOrigin: true - } - } - } - })`; - - await writeFile( - join(projectDir, 'frontend', 'vite.config.js'), - viteConfig.trim() - ); -} \ No newline at end of file diff --git a/apps/cli/src/generators/frontend/reactts.d.ts b/apps/cli/src/generators/frontend/reactts.d.ts deleted file mode 100644 index 5bd8de8..0000000 --- a/apps/cli/src/generators/frontend/reactts.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -export interface ProjectConfig { - projectName: string; - projectPath: string; - frontendPort: number; - backendPort: number; - dbUrl: string; -} - -export function createReactTS( - config: ProjectConfig, - projectDir: string, - emitLog: (message: string) => void -): Promise; \ No newline at end of file diff --git a/apps/cli/src/generators/frontend/reactts.js b/apps/cli/src/generators/frontend/reactts.js deleted file mode 100644 index 908e923..0000000 --- a/apps/cli/src/generators/frontend/reactts.js +++ /dev/null @@ -1,40 +0,0 @@ -import { writeFile } from 'fs/promises'; -import { join } from 'path'; -import { execSync } from 'child_process'; - -export async function createReactTS(config, projectDir,emitLog) { - emitLog("Creating React TypeScript frontend..."); - - await execSync(`npm create vite@latest frontend -- --template react-ts`, { - cwd: projectDir, - stdio: 'inherit' - }); - - emitLog("Installing dependencies..."); - await execSync('npm install', { - cwd: join(projectDir, 'frontend'), - stdio: 'inherit' - }); - - const viteConfig = ` - import { defineConfig } from 'vite' - import react from '@vitejs/plugin-react' - - export default defineConfig({ - plugins: [react()], - server: { - port: ${config.frontendPort}, - proxy: { - '/api': { - target: 'http://localhost:${config.backendPort}', - changeOrigin: true - } - } - } - })`; - - await writeFile( - join(projectDir, 'frontend', 'vite.config.ts'), - viteConfig.trim() - ); -} \ No newline at end of file diff --git a/apps/cli/src/generators/frontend/vuejs.js b/apps/cli/src/generators/frontend/vuejs.js deleted file mode 100644 index 86432f5..0000000 --- a/apps/cli/src/generators/frontend/vuejs.js +++ /dev/null @@ -1,43 +0,0 @@ -import { mkdir, writeFile } from 'node:fs/promises' -import { join } from 'node:path' -import { execSync } from 'node:child_process' - -export async function createVueJS(config, projectDir,emitLog) { - emitLog('Creating VueJS project...'); - await execSync(`npm create vite@latest frontend -- --template vue`, { - cwd: projectDir, - stdio: 'inherit' - }) - - emitLog('Installing Vite...'); - console.log(projectDir) - console.log(config) - const viteConfig = ` - import { defineConfig } from 'vite' - import vue from '@vitejs/plugin-vue' - - export default defineConfig({ - plugins: [vue()], - server: { - port: ${config.frontendPort}, - proxy: { - '/api': { - target: 'http://localhost:${config.backendPort}', - changeOrigin: true - } - } - } - })` - - emitLog('Writing Vite configuration...'); - await writeFile( - join(projectDir, 'frontend', `vite.config.js`), - viteConfig.trim() - ) - emitLog('Installing Vue Router and Pinia...'); - await execSync('npm install vue-router@4 pinia@2', { - cwd: join(projectDir, 'frontend'), - stdio: 'inherit' - }) - emitLog('✅ VueJS project created successfully!'); -} diff --git a/apps/cli/src/generators/frontend/vuets.js b/apps/cli/src/generators/frontend/vuets.js deleted file mode 100644 index c563360..0000000 --- a/apps/cli/src/generators/frontend/vuets.js +++ /dev/null @@ -1,53 +0,0 @@ -import { mkdir, writeFile } from 'node:fs/promises' -import { join } from 'node:path' -import { execSync } from 'node:child_process' - -export async function createVueTS(config, projectDir,emitLog) { - emitLog('Creating VueTS project...'); - - emitLog('Installing Vite...'); - await execSync(`npm create vite@latest frontend -- --template vue-ts`, { - cwd: projectDir, - stdio: 'inherit' - }) - - emitLog('Configuring Vite...'); - const viteConfig = ` - import { defineConfig } from 'vite' - import vue from '@vitejs/plugin-vue' - - export default defineConfig({ - plugins: [vue()], - server: { - port: ${config.frontendPort}, - proxy: { - '/api': { - target: 'http://localhost:${config.backendPort}', - changeOrigin: true - } - } - } - })` - - emitLog('Writing Vite configuration...'); - await writeFile( - join(projectDir, 'frontend', `vite.config.ts`), - viteConfig.trim() - ) - - emitLog('Installing Vue Router and Pinia...'); - await execSync('npm install vue-router@4 pinia@2', { - cwd: join(projectDir, 'frontend'), - stdio: 'inherit' - }) - - emitLog('Installing TypeScript and other dependencies...'); - if (config.frontend === 'vue-ts') { - await execSync('npm install -D @types/node', { - cwd: join(projectDir, 'frontend'), - stdio: 'inherit' - }) - } - - emitLog('✅ VueTS project created successfully!'); -} diff --git a/apps/cli/src/generators/orm/drizzleSetup.js b/apps/cli/src/generators/orm/drizzleSetup.js deleted file mode 100644 index 1dce473..0000000 --- a/apps/cli/src/generators/orm/drizzleSetup.js +++ /dev/null @@ -1,102 +0,0 @@ -import { join } from 'node:path' -import { mkdir, writeFile } from 'node:fs/promises' -import 'dotenv/config' - -export async function setupDrizzle(config, projectDir, emitLog) { - try { - emitLog('Starting Drizzle ORM setup...'); - const backendDir = join(projectDir, 'backend'); - const dbDir = join(backendDir, 'src', 'db'); - const schemasDir = join(dbDir, 'schema'); - emitLog('Creating directory structure...'); - await mkdir(schemasDir, { recursive: true }); - emitLog('✅ Directory structure created'); - - emitLog('Generating environment configuration...'); - const envContent = ` -# Database Configuration -${config.env?.DATABASE_URL_ENV || 'DATABASE_URL'}=postgres://user:password@localhost:5432/${config.databaseName || 'myapp'} -# Add other environment variables here -NODE_ENV=development -PORT=3000 -`; - await writeFile( - join(backendDir, '.env'), - envContent.trim() + '\n' - ); - emitLog('✅ Environment configuration created'); - - emitLog('Setting up database connection...'); - const dbCode = ` -import { drizzle } from 'drizzle-orm/node-postgres'; -import { Pool } from 'pg'; -import 'dotenv/config'; - -const pool = new Pool({ - connectionString: process.env.${config.env?.DATABASE_URL_ENV || 'DATABASE_URL'}, -}); - -export const db = drizzle(pool); - -export async function connectDB() { - try { - await pool.connect(); - console.log('Connected to PostgreSQL database'); - } catch (error) { - console.error('Database connection error:', error); - process.exit(1); - } -} - -export async function disconnectDB() { - await pool.end(); - console.log('Disconnected from PostgreSQL database'); -} -`; - await writeFile( - join(dbDir, 'index.ts'), - dbCode - ); - emitLog('✅ Database connection setup complete'); - - emitLog('Creating example schema...'); - const exampleSchemaCode = ` -import { pgTable, serial, varchar, timestamp } from 'drizzle-orm/pg-core'; - -export const examples = pgTable('examples', { - id: serial('id').primaryKey(), - name: varchar('name', { length: 256 }).notNull(), - createdAt: timestamp('created_at').defaultNow(), -}); -`; - await writeFile( - join(schemasDir, 'example.ts'), - exampleSchemaCode - ); - emitLog('✅ Example schema created'); - - emitLog('Configuring Drizzle migrations...'); - const drizzleConfigCode = ` -import type { Config } from 'drizzle-kit'; - -export default { - schema: './src/db/schema/*', - out: './src/db/migrations', - driver: 'pg', - dbCredentials: { - connectionString: process.env.${config.env?.DATABASE_URL_ENV || 'DATABASE_URL'}!, - }, -} satisfies Config; -`; - await writeFile( - join(backendDir, 'drizzle.config.ts'), - drizzleConfigCode - ); - emitLog('✅ Drizzle configuration complete'); - - emitLog('✅ Drizzle ORM setup completed successfully!'); - } catch (error) { - emitLog(`❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}`); - throw error; - } -} diff --git a/apps/cli/src/generators/orm/mongoSetup.js b/apps/cli/src/generators/orm/mongoSetup.js deleted file mode 100644 index 679f3fe..0000000 --- a/apps/cli/src/generators/orm/mongoSetup.js +++ /dev/null @@ -1,68 +0,0 @@ -import { join } from 'node:path' -import { mkdir, writeFile } from 'node:fs/promises' -import 'dotenv/config' - -export async function setupMongoose(config, projectDir,emitLog) { - const backendDir = join(projectDir, 'backend'); - const modelsDir = join(backendDir, 'src', 'models'); - await mkdir(modelsDir, { recursive: true }); - - emitLog('Generating environment configuration...'); - const envContent = ` -# MongoDB Configuration -${config.env?.MONGODB_URI_ENV || 'MONGODB_URI'}=mongodb://localhost:27017/${config.databaseName || 'myapp'} - -# Add other environment variables here -NODE_ENV=development -PORT=3000 -`; - - await writeFile( - join(backendDir, '.env'), - envContent.trim() + '\n' - ); - emitLog('✅ Environment configuration created'); - - emitLog('Setting up database connection...'); - const dbCode = ` -import mongoose from 'mongoose'; - -const MONGODB_URI = process.env.${config.env?.MONGODB_URI_ENV || 'MONGODB_URI'} || 'mongodb://localhost:27017/${config.databaseName || 'myapp'}'; - -export async function connectDB() { - try { - await mongoose.connect(MONGODB_URI); - console.log('Connected to MongoDB'); - } catch (error) { - console.error('MongoDB connection error:', error); - process.exit(1); - } -} - -export async function disconnectDB() { - await mongoose.disconnect(); - console.log('Disconnected from MongoDB'); -} -`; - emitLog('✅ Database connection setup complete'); - await writeFile( - join(backendDir, 'db.ts'), - dbCode - ); - - const exampleModelCode = ` -import mongoose from 'mongoose'; - -const exampleSchema = new mongoose.Schema({ - name: { type: String, required: true }, - createdAt: { type: Date, default: Date.now }, -}); - -export const Example = mongoose.model('Example', exampleSchema); -`; - - await writeFile( - join(modelsDir, 'example.ts'), - exampleModelCode - ); -} \ No newline at end of file diff --git a/apps/cli/src/generators/orm/prismaSetup.js b/apps/cli/src/generators/orm/prismaSetup.js deleted file mode 100644 index ecd2ed5..0000000 --- a/apps/cli/src/generators/orm/prismaSetup.js +++ /dev/null @@ -1,14 +0,0 @@ -import { join } from 'node:path' -import { execSync } from 'node:child_process' -import { writeFileSync } from 'node:fs'; - - -export async function setupPrisma(config, projectDir,emitLog) { - emitLog('Setting up Prisma...'); - const backendDir = join(projectDir, 'backend'); - const envContent = `DATABASE_URL=${config.dbUrl}\n`; - writeFileSync(join(projectDir, 'backend', '.env'), envContent); - await execSync('npm install prisma', { cwd: backendDir }); - await execSync('npx prisma init', { cwd: backendDir }); - emitLog('✅ Prisma setup complete'); -} \ No newline at end of file diff --git a/apps/cli/src/generators/ui/shadcn.js b/apps/cli/src/generators/ui/shadcn.js deleted file mode 100644 index ca9f1af..0000000 --- a/apps/cli/src/generators/ui/shadcn.js +++ /dev/null @@ -1,228 +0,0 @@ -import { writeFile, mkdir } from 'fs/promises'; -import { join } from 'path'; -import { execSync } from 'child_process'; -import { existsSync } from 'fs'; - -export async function setupShadcn( - config, - projectDir, - emitLog -) { - try { - const frontendDir = join(projectDir, 'frontend'); - emitLog('📦 Setting up shadcn/ui...'); - - // Make sure Tailwind is set up first - emitLog('Ensuring Tailwind CSS is set up...'); - - // Install shadcn/ui dependencies - emitLog('Installing shadcn/ui dependencies...'); - execSync('npm install @shadcn/ui class-variance-authority clsx tailwind-merge lucide-react', { - cwd: frontendDir, - stdio: 'inherit' - }); - - // Create components.json configuration - const componentsConfig = { - $schema: "https://ui.shadcn.com/schema.json", - style: "default", - rsc: false, - tailwind: { - config: "tailwind.config.js", - css: "src/index.css", - baseColor: "slate", - cssVariables: true, - }, - aliases: { - components: "@/components", - utils: "@/lib/utils" - } - }; - - await writeFile( - join(frontendDir, 'components.json'), - JSON.stringify(componentsConfig, null, 2) - ); - - // Create utils file - const utilsDir = join(frontendDir, 'src', 'lib'); - if (!existsSync(utilsDir)) { - await mkdir(utilsDir, { recursive: true }); - } - - const utilsContent = ` -import { type ClassValue, clsx } from "clsx" -import { twMerge } from "tailwind-merge" - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) -} -`; - - await writeFile( - join(utilsDir, 'utils.ts'), - utilsContent.trim() + '\n' - ); - - emitLog('✅ shadcn/ui setup completed successfully!'); - } catch (error) { - emitLog(`❌ Error setting up shadcn/ui: ${error instanceof Error ? error.message : 'Unknown error'}`); - throw error; - } -} - -function generateShadcnTailwindConfig(frontend) { - const baseConfig = { - darkMode: ["class"], - content: frontend === 'django' - ? ["./templates/**/*.html", "./static/**/*.{js,ts}"] - : ["./index.html", "./src/**/*.{js,ts,jsx,tsx,vue}"], - theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, - }, - extend: { - colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", - }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", - }, - destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, - accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", - }, - }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - keyframes: { - "accordion-down": { - from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: "0" }, - }, - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, - }, - plugins: ["require('tailwindcss-animate')"], - }; - - return `/** @type {import('tailwindcss').Config} */ -export default ${JSON.stringify(baseConfig, null, 2)}`; -} - -function generateShadcnStyles(frontend) { - return `@tailwind base; -@tailwind components; -@tailwind utilities; -@layer base { - :root { - --background: 0 0% 100%; - --foreground: 222.2 84% 4.9%; - - --card: 0 0% 100%; - --card-foreground: 222.2 84% 4.9%; - - --popover: 0 0% 100%; - --popover-foreground: 222.2 84% 4.9%; - - --primary: 222.2 47.4% 11.2%; - --primary-foreground: 210 40% 98%; - - --secondary: 210 40% 96.1%; - --secondary-foreground: 222.2 47.4% 11.2%; - - --muted: 210 40% 96.1%; - --muted-foreground: 215.4 16.3% 46.9%; - - --accent: 210 40% 96.1%; - --accent-foreground: 222.2 47.4% 11.2%; - - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 210 40% 98%; - - --border: 214.3 31.8% 91.4%; - --input: 214.3 31.8% 91.4%; - --ring: 222.2 84% 4.9%; - - --radius: 0.5rem; - } - - .dark { - --background: 222.2 84% 4.9%; - --foreground: 210 40% 98%; - - --card: 222.2 84% 4.9%; - --card-foreground: 210 40% 98%; - - --popover: 222.2 84% 4.9%; - --popover-foreground: 210 40% 98%; - - --primary: 210 40% 98%; - --primary-foreground: 222.2 47.4% 11.2%; - - --secondary: 217.2 32.6% 17.5%; - --secondary-foreground: 210 40% 98%; - - --muted: 217.2 32.6% 17.5%; - --muted-foreground: 215 20.2% 65.1%; - - --accent: 217.2 32.6% 17.5%; - --accent-foreground: 210 40% 98%; - - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 210 40% 98%; - - --border: 217.2 32.6% 17.5%; - --input: 217.2 32.6% 17.5%; - --ring: 212.7 26.8% 83.9%; - } -} - -@layer base { - * { - @apply border-border; - } - body { - @apply bg-background text-foreground; - } -}`; -} diff --git a/apps/cli/src/generators/ui/tailwindcss.js b/apps/cli/src/generators/ui/tailwindcss.js deleted file mode 100644 index 39fd7b4..0000000 --- a/apps/cli/src/generators/ui/tailwindcss.js +++ /dev/null @@ -1,126 +0,0 @@ -import { writeFile } from 'node:fs/promises'; -import { join } from 'node:path'; -import { execSync } from 'child_process'; -import { existsSync } from 'fs'; -import { mkdir } from 'fs/promises'; - -export async function setupTailwindCSS( - config, - projectDir, - emitLog -) { - try { - const frontendDir = join(projectDir, 'frontend'); - const srcDir = join(frontendDir, 'src'); - - // Ensure directories exist - if (!existsSync(frontendDir)) { - emitLog('Creating frontend directory...'); - await mkdir(frontendDir, { recursive: true }); - } - - if (!existsSync(srcDir)) { - emitLog('Creating src directory...'); - await mkdir(srcDir, { recursive: true }); - } - - // Initialize package.json if it doesn't exist - if (!existsSync(join(frontendDir, 'package.json'))) { - emitLog('Initializing package.json...'); - execSync('npm init -y', { - cwd: frontendDir, - stdio: 'inherit' - }); - } - - // Install dependencies using npm directly - emitLog('Installing Tailwind CSS dependencies...'); - execSync('npm install tailwindcss@latest postcss@latest autoprefixer@latest --save-dev', { - cwd: frontendDir, - stdio: 'inherit' - }); - - // Create tailwind.config.js manually instead of using npx - emitLog('Creating Tailwind configuration...'); - const tailwindConfig = generateTailwindConfig(config.frontend); - await writeFile( - join(frontendDir, 'tailwind.config.js'), - tailwindConfig - ); - - // Create postcss.config.js - emitLog('Creating PostCSS configuration...'); - const postcssConfig = ` -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}`; - await writeFile( - join(frontendDir, 'postcss.config.js'), - postcssConfig - ); - - // Add Tailwind directives to CSS - emitLog('Creating CSS file with Tailwind directives...'); - const tailwindDirectives = ` -@tailwind base; -@tailwind components; -@tailwind utilities; -`; - await writeFile( - join(srcDir, 'index.css'), - tailwindDirectives - ); - - emitLog('✅ Tailwind CSS setup completed successfully!'); - } catch (error) { - emitLog(`❌ Error setting up Tailwind CSS: ${error instanceof Error ? error.message : 'Unknown error'}`); - throw error; - } -} - -function generateTailwindConfig(framework) { - const baseConfig = { - content: [ - "./index.html", - "./src/**/*.{js,ts,jsx,tsx}", - ], - theme: { - extend: { - colors: { - background: 'hsl(var(--background))', - foreground: 'hsl(var(--foreground))', - }, - }, - }, - plugins: [], - }; - - switch (framework) { - case 'react-ts': - case 'react': - baseConfig.content = [ - "./index.html", - "./src/**/*.{js,ts,jsx,tsx}", - ]; - break; - case 'vue-ts': - case 'vue': - baseConfig.content = [ - "./index.html", - "./src/**/*.{vue,js,ts,jsx,tsx}", - ]; - break; - case 'django': - baseConfig.content = [ - "./templates/**/*.html", - "./static/**/*.{js,ts}", - ]; - break; - } - - return `/** @type {import('tailwindcss').Config} */ -module.exports = ${JSON.stringify(baseConfig, null, 2)}`; -} \ No newline at end of file diff --git a/apps/cli/src/scripts/Auth/jwt.ts b/apps/cli/src/scripts/Auth/jwt.ts deleted file mode 100644 index 29e2c15..0000000 --- a/apps/cli/src/scripts/Auth/jwt.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { mkdir, writeFile } from 'node:fs/promises'; -import { join } from 'node:path'; -import fs from 'fs'; - -export async function jwtAuthts(config: any, projectDir: any,emitLog: (log: string) => void) { - emitLog('Installing jsonwebtoken...'); - const packageJsonPath = join(projectDir, 'backend','package.json'); - const jsonData = await JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); - emitLog('Updating package.json...'); - jsonData.dependencies = jsonData.dependencies || {}; - jsonData.dependencies["jsonwebtoken"] = "^9.0.2"; - - fs.writeFileSync(packageJsonPath, JSON.stringify(jsonData, null, 2), 'utf8'); - emitLog('Writing jwt.ts...'); - const jwtAuthFile = ` - const jwt = require('jsonwebtoken'); -export const authenticateToken = (req:any, res:any, next:any) => { - const token = req.header('Authorization')?.split(' ')[1]; - if (!token) return res.status(401).json({ error: 'Access Denied' }); - - jwt.verify(token, process.env.JWT_SECRET, (err:any, user:any) => { - if (err) return res.status(403).json({ error: 'Invalid Token' }); - req.user = user; - next(); - }); -}; -`; - emitLog('Writing middleware.ts...'); - const middlewareDir = join(projectDir, 'backend', 'src', 'middleware'); - await mkdir(middlewareDir, { recursive: true }); - emitLog('Writing middleware.ts...'); - await writeFile(join(middlewareDir, 'middleware.ts'), jwtAuthFile, 'utf8'); - emitLog('✅ JWT authentication setup completed successfully!'); -} - -export async function jwtAuthdjango(config: any, projectDir: any,emitLog: (log: string) => void) { - emitLog('Installing jsonwebtoken...'); - const settingsPath = join(projectDir, 'backend', 'core', 'settings.py'); - emitLog('Updating settings.py...'); - try { - let settingsContent = fs.readFileSync(settingsPath, 'utf8'); - const restFrameworkSettings = ` - -REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': [ - 'rest_framework_simplejwt.authentication.JWTAuthentication', - ], -} -`; - - const installedAppsIndex = settingsContent.indexOf('INSTALLED_APPS'); - const insertPosition = settingsContent.indexOf(']', installedAppsIndex) + 1; - - settingsContent = - settingsContent.slice(0, insertPosition) + - restFrameworkSettings + - settingsContent.slice(insertPosition); - - fs.writeFileSync(settingsPath, settingsContent, 'utf8'); - emitLog('Writing urls.py...'); - let urlsContent = fs.readFileSync(`${projectDir}/backend/core/urls.py`, 'utf8'); - const newUrlsContent = `from django.contrib import admin -from django.urls import path, include -from rest_framework_simplejwt import views as jwt_views - -urlpatterns = [ - path('admin/', admin.site.urls), - path('api/token/', - jwt_views.TokenObtainPairView.as_view(), - name='token_obtain_pair'), - path('api/token/refresh/', - jwt_views.TokenRefreshView.as_view(), - name='token_refresh'), - path('', include('main.urls')), -] -`; - fs.writeFileSync(`${projectDir}/backend/core/urls.py`, newUrlsContent, 'utf8'); - emitLog('✅ JWT authentication setup completed successfully!'); - } catch (error) { - console.error('Error configuring Django settings:', error); - throw error; - } -} diff --git a/apps/cli/src/scripts/Auth/nextAuth.ts b/apps/cli/src/scripts/Auth/nextAuth.ts deleted file mode 100644 index 43f323b..0000000 --- a/apps/cli/src/scripts/Auth/nextAuth.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { join } from 'node:path' -import { mkdir, writeFile } from 'node:fs/promises' -import 'dotenv/config' - -export async function setupNextAuth(config: any, projectDir: string,emitLog: (log: string) => void) { - try { - const authDir = join(projectDir, 'frontend', 'src', 'app', 'api', 'auth'); - await mkdir(authDir, { recursive: true }); - emitLog('Creating auth directory...'); - const routeCode = ` -import NextAuth from "next-auth"; -import { AuthOptions } from "next-auth"; -import GithubProvider from "next-auth/providers/github"; -import GoogleProvider from "next-auth/providers/google"; -import CredentialsProvider from "next-auth/providers/credentials"; -export const authOptions: AuthOptions = { - providers: [ - GithubProvider({ - clientId: process.env.GITHUB_ID!, - clientSecret: process.env.GITHUB_SECRET!, - }), - GoogleProvider({ - clientId: process.env.GOOGLE_CLIENT_ID!, - clientSecret: process.env.GOOGLE_CLIENT_SECRET!, - }), - CredentialsProvider({ - name: 'Credentials', - credentials: { - email: { label: "Email", type: "email" }, - password: { label: "Password", type: "password" } - }, - async authorize(credentials) { - // Add your credentials logic here - if (!credentials?.email || !credentials?.password) return null; - - try { - // Example user verification - const user = { id: "1", email: credentials.email, name: "User" }; - return user; - } catch (error) { - return null; - } - } - }), - ], - pages: { - signIn: '/auth/signin', - signOut: '/auth/signout', - error: '/auth/error', - }, - callbacks: { - async jwt({ token, user }) { - if (user) { - token.id = user.id; - } - return token; - }, - async session({ session, token }) { - if (session.user) { - (session.user as any).id = token.id; - } - return session; - }, - }, - session: { - strategy: "jwt", - }, - secret: process.env.NEXTAUTH_SECRET, -}; - -const handler = NextAuth(authOptions); -export { handler as GET, handler as POST }; -`; - - await writeFile( - join(authDir, 'route.ts'), - routeCode.trim() + '\n' - ); - - const utilsDir = join(projectDir, 'frontend', 'src', 'utils'); - await mkdir(utilsDir, { recursive: true }); - emitLog('Creating utils directory...'); - const utilsCode = ` -import { getServerSession } from "next-auth/next"; -import { authOptions } from "@/app/api/auth/route"; - -export async function getSession() { - return await getServerSession(authOptions); -} - -export async function getCurrentUser() { - const session = await getSession(); - return session?.user; -} - -export async function isAuthenticated() { - const session = await getSession(); - return !!session; -} -`; - emitLog('Writing utils.ts...'); - await writeFile( - join(utilsDir, 'auth.ts'), - utilsCode.trim() + '\n' - ); - - const envContent = ` -# NextAuth Configuration -NEXTAUTH_SECRET=your-secret-key-here -NEXTAUTH_URL=http://localhost:${config.frontendPort} - -# OAuth Providers -GITHUB_ID=your-github-id -GITHUB_SECRET=your-github-secret - -GOOGLE_CLIENT_ID=your-google-client-id -GOOGLE_CLIENT_SECRET=your-google-client-secret -`; - emitLog('Writing .env file...'); - await writeFile( - join(projectDir, 'frontend', '.env'), - envContent.trim() + '\n' - ); - emitLog('Writing AuthProvider.tsx...'); - const providerCode = ` -'use client'; - -import { SessionProvider } from "next-auth/react"; - -export function AuthProvider({ children }: { children: React.ReactNode }) { - return {children}; -} -`; - emitLog('Creating components directory...'); - const providersDir = join(projectDir, 'frontend', 'src', 'components', 'auth'); - await mkdir(providersDir, { recursive: true }); - await writeFile( - join(providersDir, 'AuthProvider.tsx'), - providerCode.trim() + '\n' - ); - emitLog('✅ NextAuth setup completed successfully!'); - } catch (error) { - emitLog(`❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}`); - throw error; - } -} diff --git a/apps/cli/src/scripts/Auth/passport.ts b/apps/cli/src/scripts/Auth/passport.ts deleted file mode 100644 index 06aa81e..0000000 --- a/apps/cli/src/scripts/Auth/passport.ts +++ /dev/null @@ -1,234 +0,0 @@ -import { join } from 'node:path' -import { mkdir, writeFile } from 'node:fs/promises' - -export async function setupPassport(config: any, projectDir: string,emitLog: (log: string) => void) { - emitLog('Setting up Passport...'); - try { - const backendDir = join(projectDir, 'backend'); - const authDir = join(backendDir, 'src', 'auth'); - const configDir = join(backendDir, 'src', 'config'); - emitLog('Creating auth and config directories...'); - await mkdir(authDir, { recursive: true }); - await mkdir(configDir, { recursive: true }); - - const passportConfigCode = ` -import passport from 'passport'; -import { Strategy as LocalStrategy } from 'passport-local'; -import { Strategy as JwtStrategy, ExtractJwt } from 'passport-jwt'; -import { Strategy as GoogleStrategy } from 'passport-google-oauth20'; -import { User } from '../models/user.model'; -import { config } from '../config'; - -// Local Strategy -passport.use(new LocalStrategy( - { usernameField: 'email' }, - async (email, password, done) => { - try { - const user = await User.findOne({ email }); - if (!user) { - return done(null, false, { message: 'Incorrect email.' }); - } - - const isValid = await user.comparePassword(password); - if (!isValid) { - return done(null, false, { message: 'Incorrect password.' }); - } - - return done(null, user); - } catch (error) { - return done(error); - } - } -)); - -// JWT Strategy -passport.use(new JwtStrategy( - { - jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), - secretOrKey: config.jwt.secret, - }, - async (payload, done) => { - try { - const user = await User.findById(payload.sub); - if (!user) { - return done(null, false); - } - return done(null, user); - } catch (error) { - return done(error, false); - } - } -)); - -// Google OAuth Strategy -passport.use(new GoogleStrategy( - { - clientID: config.google.clientId, - clientSecret: config.google.clientSecret, - callbackURL: '/auth/google/callback', - }, - async (accessToken, refreshToken, profile, done) => { - try { - let user = await User.findOne({ googleId: profile.id }); - - if (!user) { - user = await User.create({ - googleId: profile.id, - email: profile.emails?.[0]?.value, - name: profile.displayName, - }); - } - - return done(null, user); - } catch (error) { - return done(error, false); - } - } -)); - -// Serialization -passport.serializeUser((user: any, done) => { - done(null, user.id); -}); - -passport.deserializeUser(async (id: string, done) => { - try { - const user = await User.findById(id); - done(null, user); - } catch (error) { - done(error); - } -}); - -export default passport; -`; - emitLog('Writing passport.config.ts...'); - await writeFile( - join(authDir, 'passport.config.ts'), - passportConfigCode.trim() + '\n' - ); - emitLog('Creating authentication middleware...'); - const authMiddlewareCode = ` -import { Request, Response, NextFunction } from 'express'; -import passport from 'passport'; -import jwt from 'jsonwebtoken'; -import { config } from '../config'; - -export const authenticateJWT = passport.authenticate('jwt', { session: false }); - -export const authenticateLocal = (req: Request, res: Response, next: NextFunction) => { - passport.authenticate('local', { session: false }, (err, user, info) => { - if (err) { - return next(err); - } - if (!user) { - return res.status(401).json({ message: info?.message || 'Authentication failed' }); - } - - const token = jwt.sign({ sub: user.id }, config.jwt.secret, { - expiresIn: config.jwt.expiresIn, - }); - - req.user = user; - res.locals.token = token; - next(); - })(req, res, next); -}; - -export const isAuthenticated = (req: Request, res: Response, next: NextFunction) => { - if (req.isAuthenticated()) { - return next(); - } - res.status(401).json({ message: 'Unauthorized' }); -}; -`; - emitLog('Writing middleware.ts...'); - await writeFile( - join(authDir, 'middleware.ts'), - authMiddlewareCode.trim() + '\n' - ); - emitLog('Creating authentication routes...'); - const authRoutesCode = ` -import { Router } from 'express'; -import passport from 'passport'; -import { authenticateLocal } from './middleware'; - -const router = Router(); - -router.post('/login', authenticateLocal, (req, res) => { - res.json({ - user: req.user, - token: res.locals.token, - }); -}); - -router.post('/register', async (req, res) => { - // Add your registration logic here -}); - -router.get('/google', - passport.authenticate('google', { scope: ['profile', 'email'] }) -); - -router.get('/google/callback', - passport.authenticate('google', { session: false }), - (req, res) => { - // Handle successful authentication - res.redirect('/'); - } -); - -router.post('/logout', (req, res) => { - req.logout(); - res.json({ message: 'Logged out successfully' }); -}); - -export default router; -`; - emitLog('Writing routes.ts...'); - await writeFile( - join(authDir, 'routes.ts'), - authRoutesCode.trim() + '\n' - ); - emitLog('Creating configuration file...'); - const configCode = ` -export const config = { - jwt: { - secret: process.env.JWT_SECRET || 'your-secret-key', - expiresIn: '1d', - }, - google: { - clientId: process.env.GOOGLE_CLIENT_ID, - clientSecret: process.env.GOOGLE_CLIENT_SECRET, - }, - session: { - secret: process.env.SESSION_SECRET || 'session-secret', - }, -}; -`; - emitLog('Writing index.ts...'); - await writeFile( - join(configDir, 'index.ts'), - configCode.trim() + '\n' - ); - emitLog('Adding environment variables...'); - const envContent = ` -# Authentication -JWT_SECRET=your-jwt-secret-key -SESSION_SECRET=your-session-secret - -# Google OAuth -GOOGLE_CLIENT_ID=your-google-client-id -GOOGLE_CLIENT_SECRET=your-google-client-secret -`; - emitLog('Writing .env file...'); - await writeFile( - join(backendDir, '.env'), - envContent.trim() + '\n' - ); - emitLog('✅ Passport.js setup completed successfully!'); - } catch (error) { - emitLog(`❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}`); - throw error; - } -} \ No newline at end of file diff --git a/apps/cli/src/scripts/backend/django.ts b/apps/cli/src/scripts/backend/django.ts deleted file mode 100644 index 72fe935..0000000 --- a/apps/cli/src/scripts/backend/django.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { exec } from 'child_process'; -import { mkdirSync } from 'fs'; -import util from 'util'; - -const execAsync = util.promisify(exec); - -export async function installDjangoDependencies(projectPath: string) { - try { - - mkdirSync(`${projectPath}/backend`, { recursive: true }); - - await execAsync('python -m venv venv', { cwd: `${projectPath}/backend` }); - - const pythonCmd = process.platform === 'win32' ? 'venv\\Scripts\\python.exe' : 'venv/bin/python'; - - await execAsync(`${pythonCmd} -m pip install django djangorestframework django-cors-headers djangorestframework_simplejwt`, { cwd: `${projectPath}/backend` }); - - await execAsync(`${pythonCmd} -m django startproject core .`, { cwd: `${projectPath}/backend` }); - - await execAsync(`${pythonCmd} manage.py startapp main`, { cwd: `${projectPath}/backend` }); - - console.log("Django project setup completed!"); - - } catch (error) { - console.error('Error installing Django dependencies:', error); - throw error; - } -} - -export default installDjangoDependencies; \ No newline at end of file diff --git a/apps/cli/src/scripts/backend/expressjs.ts b/apps/cli/src/scripts/backend/expressjs.ts deleted file mode 100644 index 5c59b10..0000000 --- a/apps/cli/src/scripts/backend/expressjs.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { execSync } from 'node:child_process' -import { mkdir, writeFile } from 'node:fs/promises' -import { join } from 'node:path' -import { writeFileSync } from 'fs' - -export async function createExpressJS(config: any, projectDir: string,emitLog: (log: string) => void) { - emitLog('Creating ExpressJS project...'); - await mkdir(join(projectDir, 'backend')) - const backendPackageJson = { - name: "backend", - version: "1.0.0", - scripts: { - "dev": "nodemon src/index.js", - "start": "node src/index.js" - }, - dependencies: { - "express": "^4.18.2", - "cors": "^2.8.5", - "dotenv": "^16.3.1" - }, - devDependencies: { - "nodemon": "^2.0.22" - } - } - - emitLog('Writing package.json...'); - await writeFile( - join(projectDir, 'backend', 'package.json'), - JSON.stringify(backendPackageJson, null, 2) - ) - - emitLog('Creating src directory...'); - await mkdir(join(projectDir, 'backend', 'src')) - - const backendIndex = ` -const express = require('express'); -const cors = require('cors'); -const dotenv = require('dotenv'); - -dotenv.config(); - -const app = express(); -const port = process.env.PORT || ${config.backendPort}; - -app.use(cors()); -app.use(express.json()); - -// Test route -app.get('/api/test', (req, res) => { - res.json({ message: 'Hello from Express!' }); -}); - -// Health check route -app.get('/api/health', (req, res) => { - res.json({ status: 'ok', timestamp: new Date() }); -}); - -app.listen(port, () => { - console.log(\`Server running on port \${port}\`); -});` - - emitLog('Writing index.js...'); - await writeFile( - join(projectDir, 'backend', 'src', 'index.js'), - backendIndex.trim() - ) - - emitLog('Installing dependencies...'); - await execSync("npm install",{cwd : projectDir + '/backend',stdio : "inherit"}); - - emitLog('✅ ExpressJS project created successfully!'); -} \ No newline at end of file diff --git a/apps/cli/src/scripts/backend/expressts.ts b/apps/cli/src/scripts/backend/expressts.ts deleted file mode 100644 index dcd526e..0000000 --- a/apps/cli/src/scripts/backend/expressts.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { execSync } from 'node:child_process' -import { mkdir, writeFile } from 'node:fs/promises' -import { join } from 'node:path' - -export async function createExpressTS(config: any, projectDir: string,emitLog: (log: string) => void) { - emitLog('Creating ExpressTS project...'); - await mkdir(join(projectDir, 'backend')); - emitLog('Writing package.json...'); - const backendPackageJson = { - name: "backend", - version: "1.0.0", - scripts: { - "dev": "ts-node-dev --respawn --transpile-only src/index.ts", - "build": "tsc", - "start": "node dist/index.js" - }, - dependencies: { - "express": "^4.18.2", - "cors": "^2.8.5", - "dotenv": "^16.3.1" - }, - devDependencies: { - "@types/express": "^4.17.17", - "@types/cors": "^2.8.13", - "@types/node": "^20.4.5", - "typescript": "^5.1.6", - "ts-node-dev": "^2.0.0" - } - } - - await writeFile( - join(projectDir, 'backend', 'package.json'), - JSON.stringify(backendPackageJson, null, 2) - ) - emitLog('Writing tsconfig.json...'); - const tsConfig = { - compilerOptions: { - "target": "ES2020", - "module": "CommonJS", - "lib": ["ES2020"], - "moduleResolution": "node", - "outDir": "./dist", - "rootDir": "./src", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true - }, - include: ["src/**/*"], - exclude: ["node_modules"] - } - - await writeFile( - join(projectDir, 'backend', 'tsconfig.json'), - JSON.stringify(tsConfig, null, 2) - ) - emitLog('Creating src directory...'); - await mkdir(join(projectDir, 'backend', 'src')) - emitLog('Writing index.ts...'); - const backendIndex = ` -import express from 'express'; -import cors from 'cors'; -import dotenv from 'dotenv'; - -dotenv.config(); - -const app = express(); -const port = process.env.PORT || ${config.backendPort}; - -app.use(cors()); -app.use(express.json()); - -// Test route -app.get('/api/test', (req, res) => { - res.json({ message: 'Hello from Express!' }); -}); - -// Health check route -app.get('/api/health', (req, res) => { - res.json({ status: 'ok', timestamp: new Date() }); -}); - -app.listen(port, () => { - console.log(\`Server running on port \${port}\`); -});` - emitLog('Writing index.ts...'); - await writeFile( - join(projectDir, 'backend', 'src', 'index.ts'), - backendIndex.trim() - ) - emitLog('Installing dependencies...'); - await execSync("npm install",{cwd : projectDir + '/backend',stdio : "inherit",shell: process.platform === "win32" ? "powershell.exe" : "/bin/sh",}); - emitLog('✅ ExpressTS project created successfully!'); -} \ No newline at end of file diff --git a/apps/cli/src/scripts/frontend/angularjs.ts b/apps/cli/src/scripts/frontend/angularjs.ts deleted file mode 100644 index e69de29..0000000 diff --git a/apps/cli/src/scripts/frontend/angularts.ts b/apps/cli/src/scripts/frontend/angularts.ts deleted file mode 100644 index a268ab7..0000000 --- a/apps/cli/src/scripts/frontend/angularts.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { execSync } from "child_process"; -import path from "path"; - -export default async function createAngularTS(config: any, projectDir: any) { - try { - - const projectFullPath = path.join(projectDir, 'frontend'); - - console.log('Installing Angular CLI...'); - await execSync(`npx @angular/cli@latest new frontend --skip-git --style=scss --routing=true --strict`, { - cwd: projectDir, - stdio: 'inherit', - shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh", - }); - - - console.log('Installing dependencies...'); - await execSync('npm install', { - cwd: projectFullPath, - stdio: 'inherit', - shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh", - }); - - console.log('Angular project created successfully!'); - - } catch (error) { - console.error('Error creating Angular project:', error); - throw error; - } -} - diff --git a/apps/cli/src/scripts/frontend/nextjs.ts b/apps/cli/src/scripts/frontend/nextjs.ts deleted file mode 100644 index 38a38d2..0000000 --- a/apps/cli/src/scripts/frontend/nextjs.ts +++ /dev/null @@ -1,72 +0,0 @@ -// import { join } from 'node:path' -// import { execSync, ExecSyncOptions } from 'child_process' -// import { writeFile, mkdir } from 'node:fs/promises' -// import { existsSync } from 'fs' - -// export async function createNextJS(config: any, projectDir: string, emitLog: (log: string) => void) { -// try { -// const frontendDir = join(projectDir, 'frontend'); -// if (!existsSync(frontendDir)) { -// emitLog('Creating frontend directory...'); -// await mkdir(frontendDir, { recursive: true }); -// } -// emitLog('Creating Next.js project...'); -// const execOptions: ExecSyncOptions = { -// cwd: frontendDir, -// stdio: 'inherit', -// encoding: 'utf-8' -// }; - -// execSync('npx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir --import-alias "@/*" --no-git', execOptions); - -// emitLog('Updating package.json...'); -// const packageJsonPath = join(frontendDir, 'package.json'); -// const packageJson = require(packageJsonPath); - -// packageJson.scripts.dev = `next dev -p ${config.frontendPort}`; - -// await writeFile( -// packageJsonPath, -// JSON.stringify(packageJson, null, 2) -// ); - -// emitLog('Creating environment file...'); -// const envContent = ` -// NEXT_PUBLIC_API_URL=http://localhost:${config.backendPort} -// NEXTAUTH_URL=http://localhost:${config.frontendPort} -// NEXTAUTH_SECRET=your-secret-key-here -// `; - -// await writeFile( -// join(frontendDir, '.env'), -// envContent.trim() + '\n' -// ); - -// emitLog('Setting up API proxy...'); -// const nextConfigContent = ` -// /** @type {import('next').NextConfig} */ -// const nextConfig = { -// async rewrites() { -// return [ -// { -// source: '/api/:path*', -// destination: 'http://localhost:${config.backendPort}/api/:path*' -// } -// ] -// } -// } - -// module.exports = nextConfig -// `; - -// await writeFile( -// join(frontendDir, 'next.config.js'), -// nextConfigContent.trim() + '\n' -// ); - -// emitLog('✅ Next.js setup completed successfully!'); -// } catch (error) { -// emitLog(`❌ Error setting up Next.js: ${error instanceof Error ? error.message : 'Unknown error'}`); -// throw error; -// } -// } \ No newline at end of file diff --git a/apps/cli/src/scripts/frontend/reactjs.ts b/apps/cli/src/scripts/frontend/reactjs.ts deleted file mode 100644 index d031c8d..0000000 --- a/apps/cli/src/scripts/frontend/reactjs.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { mkdir, writeFile } from 'node:fs/promises' -import { join } from 'node:path' -import { execSync } from 'node:child_process' - -export async function createReactJS(config: any, projectDir: string,emitLog: (log: string) => void) { - emitLog('Creating ReactJS project...'); - await execSync(`npm create vite@latest frontend -- --template react`, { - cwd: projectDir, - stdio: 'inherit', - shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh", - }) - emitLog('Installing the dependencies for the frontend...'); - await execSync("npm install",{cwd:projectDir + "/frontend",stdio:"inherit",shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh",}); - emitLog('Writing Vite configuration...'); - const viteConfig = ` - import { defineConfig } from 'vite' - import react from '@vitejs/plugin-react' - - export default defineConfig({ - plugins: [react()], - server: { - port: ${config.frontendPort}, - proxy: { - '/api': { - target: 'http://localhost:${config.backendPort}', - changeOrigin: true - } - } - } - })` - - await writeFile( - join(projectDir, 'frontend', 'vite.config.js'), - viteConfig.trim() - ) - emitLog('✅ ReactJS project created successfully!'); -} \ No newline at end of file diff --git a/apps/cli/src/scripts/frontend/reactts.ts b/apps/cli/src/scripts/frontend/reactts.ts deleted file mode 100644 index 36c397a..0000000 --- a/apps/cli/src/scripts/frontend/reactts.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { mkdir, writeFile } from 'node:fs/promises' -import { join } from 'node:path' -import { execSync } from 'node:child_process' - -export async function createReactTS(config: any, projectDir: string,emitLog: (log: string) => void) { - emitLog('Creating ReactTS project...'); - await execSync(`npm create vite@latest frontend -- --template react-ts`, { - cwd: projectDir, - stdio: 'inherit', - shell: process.platform === "win32" ? "powershell.exe" : "/bin/sh", - }); - emitLog('Installing the dependencies...'); - await execSync('npm install',{cwd : projectDir + '/frontend',stdio : 'inherit',shell: process.platform === "win32" ? "powershell.exe" : "/bin/sh",}); - emitLog('Writing Vite configuration...'); - const viteConfig = ` - import { defineConfig } from 'vite' - import react from '@vitejs/plugin-react' - export default defineConfig({ - plugins: [react()], - server: { - port: ${config.frontendPort}, - proxy: { - '/api': { - target: 'http://localhost:${config.backendPort}', - changeOrigin: true - } - } - } - })` - await writeFile( - join(projectDir, 'frontend', 'vite.config.ts'), - viteConfig.trim() - ) - emitLog('✅ ReactTS project created successfully!'); -} \ No newline at end of file diff --git a/apps/cli/src/scripts/frontend/vuejs.ts b/apps/cli/src/scripts/frontend/vuejs.ts deleted file mode 100644 index bbb793d..0000000 --- a/apps/cli/src/scripts/frontend/vuejs.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { mkdir, writeFile } from 'node:fs/promises' -import { join } from 'node:path' -import { execSync } from 'node:child_process' - -export async function createVueJS(config: any, projectDir: string,emitLog: (log: string) => void) { - emitLog('Creating VueJS project...'); - await execSync(`npm create vite@latest frontend -- --template vue`, { - cwd: projectDir, - stdio: 'inherit' - }) - - emitLog('Installing Vite...'); - console.log(projectDir) - console.log(config) - const viteConfig = ` - import { defineConfig } from 'vite' - import vue from '@vitejs/plugin-vue' - - export default defineConfig({ - plugins: [vue()], - server: { - port: ${config.frontendPort}, - proxy: { - '/api': { - target: 'http://localhost:${config.backendPort}', - changeOrigin: true - } - } - } - })` - - emitLog('Writing Vite configuration...'); - await writeFile( - join(projectDir, 'frontend', `vite.config.js`), - viteConfig.trim() - ) - emitLog('Installing Vue Router and Pinia...'); - await execSync('npm install vue-router@4 pinia@2', { - cwd: join(projectDir, 'frontend'), - stdio: 'inherit' - }) - emitLog('✅ VueJS project created successfully!'); -} diff --git a/apps/cli/src/scripts/frontend/vuets.ts b/apps/cli/src/scripts/frontend/vuets.ts deleted file mode 100644 index 6eca4af..0000000 --- a/apps/cli/src/scripts/frontend/vuets.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { mkdir, writeFile } from 'node:fs/promises' -import { join } from 'node:path' -import { execSync } from 'node:child_process' - -export async function createVueTS(config: any, projectDir: string,emitLog: (log: string) => void) { - emitLog('Creating VueTS project...'); - - emitLog('Installing Vite...'); - await execSync(`npm create vite@latest frontend -- --template vue-ts`, { - cwd: projectDir, - stdio: 'inherit' - }) - - emitLog('Configuring Vite...'); - const viteConfig = ` - import { defineConfig } from 'vite' - import vue from '@vitejs/plugin-vue' - - export default defineConfig({ - plugins: [vue()], - server: { - port: ${config.frontendPort}, - proxy: { - '/api': { - target: 'http://localhost:${config.backendPort}', - changeOrigin: true - } - } - } - })` - - emitLog('Writing Vite configuration...'); - await writeFile( - join(projectDir, 'frontend', `vite.config.ts`), - viteConfig.trim() - ) - - emitLog('Installing Vue Router and Pinia...'); - await execSync('npm install vue-router@4 pinia@2', { - cwd: join(projectDir, 'frontend'), - stdio: 'inherit' - }) - - emitLog('Installing TypeScript and other dependencies...'); - if (config.frontend === 'vue-ts') { - await execSync('npm install -D @types/node', { - cwd: join(projectDir, 'frontend'), - stdio: 'inherit' - }) - } - - emitLog('✅ VueTS project created successfully!'); -} diff --git a/apps/cli/src/scripts/orms/drizzleSetup.ts b/apps/cli/src/scripts/orms/drizzleSetup.ts deleted file mode 100644 index 7c4902f..0000000 --- a/apps/cli/src/scripts/orms/drizzleSetup.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { join } from 'node:path' -import { mkdir, writeFile } from 'node:fs/promises' -import 'dotenv/config' - -export async function setupDrizzle(config: any, projectDir: string, emitLog: (log: string) => void) { - try { - emitLog('Starting Drizzle ORM setup...'); - const backendDir = join(projectDir, 'backend'); - const dbDir = join(backendDir, 'src', 'db'); - const schemasDir = join(dbDir, 'schema'); - emitLog('Creating directory structure...'); - await mkdir(schemasDir, { recursive: true }); - emitLog('✅ Directory structure created'); - - emitLog('Generating environment configuration...'); - const envContent = ` -# Database Configuration -${config.env?.DATABASE_URL_ENV || 'DATABASE_URL'}=postgres://user:password@localhost:5432/${config.databaseName || 'myapp'} -# Add other environment variables here -NODE_ENV=development -PORT=3000 -`; - await writeFile( - join(backendDir, '.env'), - envContent.trim() + '\n' - ); - emitLog('✅ Environment configuration created'); - - emitLog('Setting up database connection...'); - const dbCode = ` -import { drizzle } from 'drizzle-orm/node-postgres'; -import { Pool } from 'pg'; -import 'dotenv/config'; - -const pool = new Pool({ - connectionString: process.env.${config.env?.DATABASE_URL_ENV || 'DATABASE_URL'}, -}); - -export const db = drizzle(pool); - -export async function connectDB() { - try { - await pool.connect(); - console.log('Connected to PostgreSQL database'); - } catch (error) { - console.error('Database connection error:', error); - process.exit(1); - } -} - -export async function disconnectDB() { - await pool.end(); - console.log('Disconnected from PostgreSQL database'); -} -`; - await writeFile( - join(dbDir, 'index.ts'), - dbCode - ); - emitLog('✅ Database connection setup complete'); - - emitLog('Creating example schema...'); - const exampleSchemaCode = ` -import { pgTable, serial, varchar, timestamp } from 'drizzle-orm/pg-core'; - -export const examples = pgTable('examples', { - id: serial('id').primaryKey(), - name: varchar('name', { length: 256 }).notNull(), - createdAt: timestamp('created_at').defaultNow(), -}); -`; - await writeFile( - join(schemasDir, 'example.ts'), - exampleSchemaCode - ); - emitLog('✅ Example schema created'); - - emitLog('Configuring Drizzle migrations...'); - const drizzleConfigCode = ` -import type { Config } from 'drizzle-kit'; - -export default { - schema: './src/db/schema/*', - out: './src/db/migrations', - driver: 'pg', - dbCredentials: { - connectionString: process.env.${config.env?.DATABASE_URL_ENV || 'DATABASE_URL'}!, - }, -} satisfies Config; -`; - await writeFile( - join(backendDir, 'drizzle.config.ts'), - drizzleConfigCode - ); - emitLog('✅ Drizzle configuration complete'); - - emitLog('✅ Drizzle ORM setup completed successfully!'); - } catch (error) { - emitLog(`❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}`); - throw error; - } -} diff --git a/apps/cli/src/scripts/orms/mongoSetup.ts b/apps/cli/src/scripts/orms/mongoSetup.ts deleted file mode 100644 index 5f3f38c..0000000 --- a/apps/cli/src/scripts/orms/mongoSetup.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { join } from 'node:path' -import { mkdir, writeFile } from 'node:fs/promises' -import 'dotenv/config' - -export async function setupMongoose(config: any, projectDir: string,emitLog: (log: string) => void) { - const backendDir = join(projectDir, 'backend'); - const modelsDir = join(backendDir, 'src', 'models'); - await mkdir(modelsDir, { recursive: true }); - - emitLog('Generating environment configuration...'); - const envContent = ` -# MongoDB Configuration -${config.env?.MONGODB_URI_ENV || 'MONGODB_URI'}=mongodb://localhost:27017/${config.databaseName || 'myapp'} - -# Add other environment variables here -NODE_ENV=development -PORT=3000 -`; - - await writeFile( - join(backendDir, '.env'), - envContent.trim() + '\n' - ); - emitLog('✅ Environment configuration created'); - - emitLog('Setting up database connection...'); - const dbCode = ` -import mongoose from 'mongoose'; - -const MONGODB_URI = process.env.${config.env?.MONGODB_URI_ENV || 'MONGODB_URI'} || 'mongodb://localhost:27017/${config.databaseName || 'myapp'}'; - -export async function connectDB() { - try { - await mongoose.connect(MONGODB_URI); - console.log('Connected to MongoDB'); - } catch (error) { - console.error('MongoDB connection error:', error); - process.exit(1); - } -} - -export async function disconnectDB() { - await mongoose.disconnect(); - console.log('Disconnected from MongoDB'); -} -`; - emitLog('✅ Database connection setup complete'); - await writeFile( - join(backendDir, 'db.ts'), - dbCode - ); - - const exampleModelCode = ` -import mongoose from 'mongoose'; - -const exampleSchema = new mongoose.Schema({ - name: { type: String, required: true }, - createdAt: { type: Date, default: Date.now }, -}); - -export const Example = mongoose.model('Example', exampleSchema); -`; - - await writeFile( - join(modelsDir, 'example.ts'), - exampleModelCode - ); -} \ No newline at end of file diff --git a/apps/cli/src/scripts/orms/prismaSetup.ts b/apps/cli/src/scripts/orms/prismaSetup.ts deleted file mode 100644 index 8a8fc4a..0000000 --- a/apps/cli/src/scripts/orms/prismaSetup.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { join } from 'node:path' -import { execSync } from 'node:child_process' -import { writeFileSync } from 'node:fs'; - - -export async function setupPrisma(config: any, projectDir: string,emitLog: (log: string) => void) { - emitLog('Setting up Prisma...'); - const backendDir = join(projectDir, 'backend'); - const envContent = `DATABASE_URL=${config.dbUrl}\n`; - writeFileSync(join(projectDir, 'backend', '.env'), envContent); - await execSync('npm install prisma', { cwd: backendDir,shell: process.platform === "win32" ? "powershell.exe" : "/bin/sh", }); - await execSync('npx prisma init', { cwd: backendDir,shell: process.platform === "win32" ? "powershell.exe" : "/bin/sh", }); - emitLog('✅ Prisma setup complete'); -} \ No newline at end of file diff --git a/apps/cli/src/scripts/ui/shadcn.ts b/apps/cli/src/scripts/ui/shadcn.ts deleted file mode 100644 index 9ef6e7f..0000000 --- a/apps/cli/src/scripts/ui/shadcn.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { writeFile, mkdir } from 'fs/promises'; -import { join } from 'path'; -import { execSync } from 'child_process'; -import { existsSync } from 'fs'; - -export async function setupShadcn( - config: any, - projectDir: string, - emitLog: (log: string) => void -) { - try { - const frontendDir = join(projectDir, 'frontend'); - emitLog('📦 Setting up shadcn/ui...'); - - // Make sure Tailwind is set up first - emitLog('Ensuring Tailwind CSS is set up...'); - - // Install shadcn/ui dependencies - emitLog('Installing shadcn/ui dependencies...'); - execSync('npm install @shadcn/ui class-variance-authority clsx tailwind-merge lucide-react', { - cwd: frontendDir, - stdio: 'inherit' - }); - - // Create components.json configuration - const componentsConfig = { - $schema: "https://ui.shadcn.com/schema.json", - style: "default", - rsc: false, - tailwind: { - config: "tailwind.config.js", - css: "src/index.css", - baseColor: "slate", - cssVariables: true, - }, - aliases: { - components: "@/components", - utils: "@/lib/utils" - } - }; - - await writeFile( - join(frontendDir, 'components.json'), - JSON.stringify(componentsConfig, null, 2) - ); - - // Create utils file - const utilsDir = join(frontendDir, 'src', 'lib'); - if (!existsSync(utilsDir)) { - await mkdir(utilsDir, { recursive: true }); - } - - const utilsContent = ` -import { type ClassValue, clsx } from "clsx" -import { twMerge } from "tailwind-merge" - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) -} -`; - - await writeFile( - join(utilsDir, 'utils.ts'), - utilsContent.trim() + '\n' - ); - - emitLog('✅ shadcn/ui setup completed successfully!'); - } catch (error) { - emitLog(`❌ Error setting up shadcn/ui: ${error instanceof Error ? error.message : 'Unknown error'}`); - throw error; - } -} - -function generateShadcnTailwindConfig(frontend: string): string { - const baseConfig = { - darkMode: ["class"], - content: frontend === 'django' - ? ["./templates/**/*.html", "./static/**/*.{js,ts}"] - : ["./index.html", "./src/**/*.{js,ts,jsx,tsx,vue}"], - theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, - }, - extend: { - colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", - }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", - }, - destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, - accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", - }, - }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - keyframes: { - "accordion-down": { - from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: "0" }, - }, - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, - }, - plugins: ["require('tailwindcss-animate')"], - }; - - return `/** @type {import('tailwindcss').Config} */ -export default ${JSON.stringify(baseConfig, null, 2)}`; -} - -function generateShadcnStyles(frontend: string): string { - return `@tailwind base; -@tailwind components; -@tailwind utilities; -@layer base { - :root { - --background: 0 0% 100%; - --foreground: 222.2 84% 4.9%; - - --card: 0 0% 100%; - --card-foreground: 222.2 84% 4.9%; - - --popover: 0 0% 100%; - --popover-foreground: 222.2 84% 4.9%; - - --primary: 222.2 47.4% 11.2%; - --primary-foreground: 210 40% 98%; - - --secondary: 210 40% 96.1%; - --secondary-foreground: 222.2 47.4% 11.2%; - - --muted: 210 40% 96.1%; - --muted-foreground: 215.4 16.3% 46.9%; - - --accent: 210 40% 96.1%; - --accent-foreground: 222.2 47.4% 11.2%; - - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 210 40% 98%; - - --border: 214.3 31.8% 91.4%; - --input: 214.3 31.8% 91.4%; - --ring: 222.2 84% 4.9%; - - --radius: 0.5rem; - } - - .dark { - --background: 222.2 84% 4.9%; - --foreground: 210 40% 98%; - - --card: 222.2 84% 4.9%; - --card-foreground: 210 40% 98%; - - --popover: 222.2 84% 4.9%; - --popover-foreground: 210 40% 98%; - - --primary: 210 40% 98%; - --primary-foreground: 222.2 47.4% 11.2%; - - --secondary: 217.2 32.6% 17.5%; - --secondary-foreground: 210 40% 98%; - - --muted: 217.2 32.6% 17.5%; - --muted-foreground: 215 20.2% 65.1%; - - --accent: 217.2 32.6% 17.5%; - --accent-foreground: 210 40% 98%; - - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 210 40% 98%; - - --border: 217.2 32.6% 17.5%; - --input: 217.2 32.6% 17.5%; - --ring: 212.7 26.8% 83.9%; - } -} - -@layer base { - * { - @apply border-border; - } - body { - @apply bg-background text-foreground; - } -}`; -} diff --git a/apps/cli/src/scripts/ui/tailwindcss.ts b/apps/cli/src/scripts/ui/tailwindcss.ts deleted file mode 100644 index 991ea3e..0000000 --- a/apps/cli/src/scripts/ui/tailwindcss.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { writeFile } from 'node:fs/promises'; -import { join } from 'node:path'; -import { execSync } from 'child_process'; -import { existsSync } from 'fs'; -import { mkdir } from 'fs/promises'; - -export async function setupTailwindCSS( - config: any, - projectDir: string, - emitLog: (log: string) => void -) { - try { - const frontendDir = join(projectDir, 'frontend'); - const srcDir = join(frontendDir, 'src'); - - // Ensure directories exist - if (!existsSync(frontendDir)) { - emitLog('Creating frontend directory...'); - await mkdir(frontendDir, { recursive: true }); - } - - if (!existsSync(srcDir)) { - emitLog('Creating src directory...'); - await mkdir(srcDir, { recursive: true }); - } - - // Initialize package.json if it doesn't exist - if (!existsSync(join(frontendDir, 'package.json'))) { - emitLog('Initializing package.json...'); - execSync('npm init -y', { - cwd: frontendDir, - stdio: 'inherit' - }); - } - - // Install dependencies using npm directly - emitLog('Installing Tailwind CSS dependencies...'); - execSync('npm install tailwindcss@latest postcss@latest autoprefixer@latest --save-dev', { - cwd: frontendDir, - stdio: 'inherit' - }); - - // Create tailwind.config.js manually instead of using npx - emitLog('Creating Tailwind configuration...'); - const tailwindConfig = generateTailwindConfig(config.frontend); - await writeFile( - join(frontendDir, 'tailwind.config.js'), - tailwindConfig - ); - - // Create postcss.config.js - emitLog('Creating PostCSS configuration...'); - const postcssConfig = ` -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}`; - await writeFile( - join(frontendDir, 'postcss.config.js'), - postcssConfig - ); - - // Add Tailwind directives to CSS - emitLog('Creating CSS file with Tailwind directives...'); - const tailwindDirectives = ` -@tailwind base; -@tailwind components; -@tailwind utilities; -`; - await writeFile( - join(srcDir, 'index.css'), - tailwindDirectives - ); - - emitLog('✅ Tailwind CSS setup completed successfully!'); - } catch (error) { - emitLog(`❌ Error setting up Tailwind CSS: ${error instanceof Error ? error.message : 'Unknown error'}`); - throw error; - } -} - -function generateTailwindConfig(framework: string): string { - const baseConfig = { - content: [ - "./index.html", - "./src/**/*.{js,ts,jsx,tsx}", - ], - theme: { - extend: { - colors: { - background: 'hsl(var(--background))', - foreground: 'hsl(var(--foreground))', - }, - }, - }, - plugins: [], - }; - - switch (framework) { - case 'react-ts': - case 'react': - baseConfig.content = [ - "./index.html", - "./src/**/*.{js,ts,jsx,tsx}", - ]; - break; - case 'vue-ts': - case 'vue': - baseConfig.content = [ - "./index.html", - "./src/**/*.{vue,js,ts,jsx,tsx}", - ]; - break; - case 'django': - baseConfig.content = [ - "./templates/**/*.html", - "./static/**/*.{js,ts}", - ]; - break; - } - - return `/** @type {import('tailwindcss').Config} */ -module.exports = ${JSON.stringify(baseConfig, null, 2)}`; -} \ No newline at end of file