y3-app
Version:
CLI to add your project structure
313 lines (285 loc) • 9.07 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.nodeTsStructure = void 0;
const docker_1 = require("../config/docker");
exports.nodeTsStructure = {
src: {
'app.ts': `
import 'dotenv/config';
import express, {
type Express,
type Request,
type Response,
type NextFunction,
} from 'express';
import session from 'express-session';
import passport from './config/passport.config';
import authRoutes from './routes/auth.routes';
import cors from 'cors';
const app: Express = express();
app.get('/', (_req: Request, res: Response) => {
res.send('<h1>Hello World</h1>');
});
// Middleware
app.use(
cors({
origin: process.env.CLIENT_URL || 'http://localhost:3000',
credentials: true,
})
);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Session configuration
app.use(
session({
secret: process.env.SESSION_SECRET || 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'production',
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000, // 24 hours
},
})
);
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Routes
app.use(authRoutes);
// Health check endpoint
app.get('/health', (_req: Request, res: Response) => {
res.json({ status: 'OK', timestamp: new Date().toISOString() });
});
// Error handling middleware
app.use(
(
err: Error & { status?: number },
_req: Request,
res: Response,
_next: NextFunction
) => {
console.error(err.stack);
res.status(err.status || 500).json({
message: err.message || 'Internal Server Error',
...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
});
}
);
export default app;`,
'server.ts': `// import app from './app';
import app from './app';
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(\`Server is running on port \${PORT}\`);
console.log(\`Environment: \${process.env.NODE_ENV || 'development'}\`);
});
`,
config: {
'db.config.ts': '// Database configuration\n',
'env.config.ts': `// Environment configuration\n
export const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
export const GOOGLE_CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET;
export const GOOGLE_CALLBACK_URL = process.env.GOOGLE_CALLBACK_URL;
export const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID;
export const GITHUB_CLIENT_SECRET = process.env.GITHUB_CLIENT_SECRET;
export const GITHUB_CALLBACK_URL = process.env.GITHUB_CALLBACK_URL;
`,
'passport.config.ts': `// Passport configuration\n
import passport, { type Profile } from 'passport';
import { Strategy as GoogleStrategy } from 'passport-google-oauth20';
import { Strategy as GithubStrategy } from 'passport-github2';
import {
GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET,
GOOGLE_CALLBACK_URL,
GITHUB_CALLBACK_URL,
GITHUB_CLIENT_SECRET,
GITHUB_CLIENT_ID,
} from './env.config';
// Temporary in-memory user store (replace with database later)
const userStore = new Map<string, Profile>();
// Google OAuth Strategy
passport.use(
new GoogleStrategy(
{
clientID: GOOGLE_CLIENT_ID!,
clientSecret: GOOGLE_CLIENT_SECRET!,
callbackURL: GOOGLE_CALLBACK_URL!,
scope: ['profile', 'email'],
},
(
accessToken: string,
refreshToken: string,
profile: Profile,
done: (error: Error | null, user: Profile) => void
) => {
console.log('Google OAuth:', { accessToken, refreshToken, profile });
// TODO: Save or update user in database
// For now, store in memory
userStore.set(profile.id, profile);
done(null, profile);
}
)
);
// GitHub OAuth Strategy
passport.use(
new GithubStrategy(
{
clientID: GITHUB_CLIENT_ID!,
clientSecret: GITHUB_CLIENT_SECRET!,
callbackURL: GITHUB_CALLBACK_URL!,
},
(
accessToken: string,
refreshToken: string,
profile: Profile,
done: (error: Error | null, user: Profile) => void
) => {
console.log('GitHub OAuth:', { accessToken, refreshToken, profile });
// TODO: Save or update user in database
// For now, store in memory
userStore.set(profile.id, profile);
done(null, profile);
}
)
);
// Serialize and deserialize user for session management
passport.serializeUser((user, done) => {
// Type assertion since we know our user objects have an id
const profile = user as Profile;
done(null, profile.id);
});
passport.deserializeUser((id: string, done) => {
// TODO: Fetch user from database
// For now, retrieve from in-memory store
const user = userStore.get(id);
if (user) {
done(null, user);
} else {
done(new Error('User not found'));
}
});
export default passport;
`,
},
controllers: {
'auth.controller.ts': '// Authentication controller\n',
'blog.controller.ts': '// Blog controller\n',
'booking.controller.ts': '// Booking controller\n',
'payment.controller.ts': '// Payment controller\n',
'product.controller.ts': '// Product controller\n',
},
middleware: {
'auth.middleware.ts': `// Authentication middleware\n
import { Request, Response, NextFunction } from 'express';
// Middleware to check if user is authenticated
export const isAuthenticated = (
req: Request,
res: Response,
next: NextFunction
) => {
if (req.isAuthenticated()) {
return next();
}
res.status(401).json({ error: 'Authentication required' });
};
// Middleware to check if user is NOT authenticated (for login/register pages)
export const isNotAuthenticated = (
req: Request,
res: Response,
next: NextFunction
) => {
if (!req.isAuthenticated()) {
return next();
}
res.redirect('/dashboard'); // Redirect to dashboard if already authenticated
};
// Middleware to check specific roles (if you implement role-based access)
export const hasRole = (role: string) => {
return (req: Request, res: Response, next: NextFunction) => {
interface User {
role?: string;
}
if (req.isAuthenticated() && (req.user as User)?.role === role) {
return next();
}
res.status(403).json({ error: 'Insufficient permissions' });
};
};
`,
'error.middleware.ts': '// Error handling middleware\n',
},
models: {
'blog.model.ts': '// Blog model\n',
'booking.model.ts': '// Booking model\n',
'payment.model.ts': '// Payment model\n',
'product.model.ts': '// Product model\n',
'user.model.ts': '// User model\n',
},
routes: {
'auth.routes.ts': `
// Authentication routes
import { Router, type Request, type Response } from 'express';
import passport from '../config/passport.config';
const router = Router();
// Google OAuth routes
router.get(
'/auth/google',
passport.authenticate('google', { scope: ['profile', 'email'] })
);
router.get(
'/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
(_req: Request, res: Response) => {
// Successful authentication
res.redirect('/dashboard'); // Redirect to dashboard or home page
}
);
// GitHub OAuth routes
router.get('/auth/github', passport.authenticate('github'));
router.get(
'/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/login' }),
(_req: Request, res: Response) => {
// Successful authentication
res.redirect('/dashboard'); // Redirect to dashboard or home page
}
);
// Logout route
router.get('/auth/logout', (req: Request, res: Response) => {
req.logout(err => {
if (err) {
return res.status(500).json({ error: 'Failed to logout' });
}
res.redirect('/');
});
});
// Check authentication status
router.get('/auth/status', (req: Request, res: Response) => {
if (req.isAuthenticated()) {
res.json({ authenticated: true, user: req.user });
} else {
res.json({ authenticated: false });
}
});
export default router;`,
'blog.routes.ts': '// Blog routes\n',
'booking.routes.ts': '// Booking routes\n',
'payment.routes.ts': '// Payment routes\n',
'product.routes.ts': '// Product routes\n',
'index.ts': '// Barrel file for routes\n',
},
services: {
'email.service.ts': '// Email service\n',
'payment.service.ts': '// Payment service\n',
},
utils: {
'email.utils.ts': '// Email utilities\n',
'logger.ts': '// Logger utility\n',
'payment.utils.ts': '// Payment utilities\n',
},
views: {},
},
...docker_1.dockerStructure,
};