vibe-cli-tool
Version:
VibeCLI v1.9 - 模板商店生态,智能部署生成,多语言支持,交互式学习系统,企业级Web全栈应用CLI工具
150 lines (146 loc) • 5.11 kB
JavaScript
import fsExtra from 'fs-extra';
import path from 'path';
export class VibeCLICore {
async createProject(config) {
const projectName = config.name || 'app';
const cwd = process.cwd();
const projectRoot = path.join(cwd, projectName);
// create dirs & minimal files
await fsExtra.ensureDir(path.join(projectRoot, 'src', 'app'));
await fsExtra.ensureDir(path.join(projectRoot, 'prisma'));
const pkg = {
name: projectName,
version: '0.1.0',
scripts: {},
dependencies: {
next: 'latest',
'@prisma/client': '^5.0.0',
'@radix-ui/react-slot': '^1.0.0',
'class-variance-authority': '^0.7.0',
'clsx': '^2.0.0',
'tailwind-merge': '^2.0.0'
},
devDependencies: {
tailwindcss: '^3.4.0',
autoprefixer: '^10.4.0',
postcss: '^8.4.0'
}
};
await fsExtra.writeFile(path.join(projectRoot, 'package.json'), JSON.stringify(pkg, null, 2));
// TypeScript config
const tsConfig = {
compilerOptions: {
target: 'es5',
lib: ['dom', 'dom.iterable', 'es6'],
allowJs: true,
skipLibCheck: true,
strict: true,
forceConsistentCasingInFileNames: true,
noEmit: true,
esModuleInterop: true,
module: 'esnext',
moduleResolution: 'node',
resolveJsonModule: true,
isolatedModules: true,
jsx: 'preserve',
incremental: true,
plugins: [{ name: 'next' }],
paths: { '@/*': ['./src/*'] }
},
include: ['next-env.d.ts', '**/*.ts', '**/*.tsx', '.next/types/**/*.ts'],
exclude: ['node_modules']
};
await fsExtra.writeFile(path.join(projectRoot, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
await fsExtra.writeFile(path.join(projectRoot, 'next.config.js'), 'module.exports = {}');
// Tailwind config
await fsExtra.writeFile(path.join(projectRoot, 'tailwind.config.js'), `
module.exports = {
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: { extend: {} },
plugins: [],
}`);
await fsExtra.writeFile(path.join(projectRoot, 'postcss.config.js'), `
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}`);
// App files
await fsExtra.ensureDir(path.join(projectRoot, 'src', 'components'));
await fsExtra.ensureDir(path.join(projectRoot, 'src', 'lib'));
await fsExtra.writeFile(path.join(projectRoot, 'src', 'app', 'layout.tsx'), `
import './globals.css'
export const metadata = {
title: 'Generated by VibeCLI',
description: 'Generated by VibeCLI',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}`);
await fsExtra.writeFile(path.join(projectRoot, 'src', 'app', 'page.tsx'), `
export default function Home() {
return (
<main>
<h1>欢迎使用 VibeCLI</h1>
</main>
)
}`);
await fsExtra.writeFile(path.join(projectRoot, 'src', 'app', 'globals.css'), `
@tailwind base;
@tailwind components;
@tailwind utilities;`);
// Environment file
const provider = config.database === 'mysql' ? 'mysql' : (config.database === 'sqlite' ? 'sqlite' : 'postgresql');
const dbUrl = provider === 'mysql'
? 'mysql://username:password@localhost:5432/database'
: provider === 'sqlite'
? 'file:./dev.db'
: 'postgresql://username:password@localhost:5432/database';
await fsExtra.writeFile(path.join(projectRoot, '.env.example'), `DATABASE_URL="${dbUrl}"`);
const prismaSchema = `
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "${provider}"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}`;
await fsExtra.writeFile(path.join(projectRoot, 'prisma', 'schema.prisma'), prismaSchema);
// Don't simulate install steps here, let createApp handle them
// execSync('npm install', { stdio: 'pipe' })
// if (provider !== 'sqlite') {
// execSync('npx prisma generate', { stdio: 'pipe' })
// }
return {
success: true,
generatedFiles: [
'package.json',
'tsconfig.json',
'next.config.js',
'src/app/layout.tsx',
'src/app/page.tsx',
'prisma/schema.prisma'
],
nextSteps: ['cd ' + projectName, 'npm install']
};
}
}
//# sourceMappingURL=vibecli-core-mock.js.map