Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ async function createAction(projectName, options) {
initGit: options.git !== false,
enableSecurity: defaults.enableSecurity,
noInstall: options.install === false,
verbose: options.verbose || false,
repo: options.repo || 'Ebyte-Lab/opusify-templates',
token: options.token || process.env.OPUSIFY_GITHUB_TOKEN || process.env.GITHUB_TOKEN,
};
Expand Down Expand Up @@ -295,6 +296,7 @@ async function createAction(projectName, options) {
initGit: options.git === false ? false : (answers.initGit !== undefined ? answers.initGit : true),
enableSecurity: answers.enableSecurity !== undefined ? answers.enableSecurity : true,
noInstall: options.install === false,
verbose: options.verbose || false,
repo: options.repo || 'Ebyte-Lab/opusify-templates',
token: options.token || process.env.OPUSIFY_GITHUB_TOKEN || process.env.GITHUB_TOKEN,
};
Expand Down Expand Up @@ -412,6 +414,7 @@ program
.option('-r, --repo <repository>', 'Custom GitHub repository (e.g., "username/repo")')
.option('--token <token>', 'GitHub Personal Access Token for private repositories')
.option('-y, --yes', 'Accept all defaults (non-interactive)')
.option('--verbose', 'Show detailed output during generation')
.action(createAction);

program
Expand Down
28 changes: 22 additions & 6 deletions src/dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import path from 'path';
import chalk from 'chalk';

export function resolveDependencies(projectPath, config) {
const verbose = config.verbose || false;

console.log(chalk.cyan('\n🧩 Resolving dynamic dependencies...'));

const pkgPath = path.join(projectPath, 'package.json');

// Safety check: Ensure a package.json actually exists to modify
Expand All @@ -20,24 +22,38 @@ export function resolveDependencies(projectPath, config) {
if (!pkg.dependencies) pkg.dependencies = {};
if (!pkg.devDependencies) pkg.devDependencies = {};

const added = [];

// 2. Inject specific packages based on the Design System choice
if (config.design === 'Glassmorphism') {
pkg.dependencies['framer-motion'] = '^11.2.0';
pkg.dependencies['clsx'] = '^2.1.1';
pkg.dependencies['tailwind-merge'] = '^2.3.0';
added.push({ pkg: 'framer-motion', reason: 'Glassmorphism animations' });
added.push({ pkg: 'clsx', reason: 'Glassmorphism class merging' });
added.push({ pkg: 'tailwind-merge', reason: 'Glassmorphism class merging' });
} else if (config.design === 'Dark Terminal') {
pkg.dependencies['lucide-react'] = '^0.378.0'; // For terminal icons
pkg.dependencies['lucide-react'] = '^0.378.0';
added.push({ pkg: 'lucide-react', reason: 'Dark Terminal icons' });
} else if (config.design === 'Neon Cyberpunk') {
pkg.dependencies['framer-motion'] = '^11.2.0'; // For glow/hover animations
pkg.dependencies['framer-motion'] = '^11.2.0';
added.push({ pkg: 'framer-motion', reason: 'Neon Cyberpunk glow animations' });
}

// 3. Inject routing tools based on Sidebar choice
if (config.includeSidebar && config.architecture.includes('vite')) {
pkg.dependencies['react-router-dom'] = '^6.23.0';
added.push({ pkg: 'react-router-dom', reason: 'Vite sidebar routing' });
}

// 4. Save the modified package.json back to the project folder
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));

console.log(chalk.green(' ✔ package.json dynamically tailored to your configuration!'));
}

if (verbose && added.length > 0) {
for (const dep of added) {
console.log(chalk.gray(` [deps] +${dep.pkg} — ${dep.reason}`));
}
}

console.log(chalk.green(` ✔ package.json dynamically tailored to your configuration!${added.length > 0 ? ` (${added.length} packages added)` : ''}`));
}
31 changes: 31 additions & 0 deletions src/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,16 @@ function getAllFiles(dirPath, arrayOfFiles = []) {
}

export async function generateProject(config) {
const verbose = config.verbose || false;
const totalStart = Date.now();

console.log(chalk.cyan('\n⚙️ Starting the File Generation Engine...'));
if (verbose) {
console.log(chalk.gray(` [config] Template: ${config.template}/${config.architecture}`));
console.log(chalk.gray(` [config] Design: ${config.design}`));
console.log(chalk.gray(` [config] Variant: ${config.variant}`));
console.log(chalk.gray(` [config] Nav: ${config.navCount}, Sidebar: ${config.includeSidebar}`));
}

// Inject token into environment for tiged to access private repos
if (config.token) {
Expand Down Expand Up @@ -69,8 +78,13 @@ export async function generateProject(config) {
spinner: 'dots',
color: 'blue'
}).start();
const copyStart = Date.now();
fs.cpSync(localTemplatePath, projectPath, { recursive: true });
spinner.succeed(`Files copied to ./${projectName}`);
if (verbose) {
console.log(chalk.gray(` [copy] Source: ${localTemplatePath}`));
console.log(chalk.gray(` [copy] Duration: ${Date.now() - copyStart}ms`));
}
} else {
// 🔵 PRODUCTION MODE: Fetch from GitHub
const targetRepo = config.repo || 'Ebyte-Lab/opusify-templates';
Expand Down Expand Up @@ -112,7 +126,9 @@ export async function generateProject(config) {
spinner: 'dots',
color: 'cyan'
}).start();
const compileStart = Date.now();
const allFiles = getAllFiles(projectPath);
let compiledCount = 0;

for (const file of allFiles) {
if (file.match(/\.(tsx|ts|json|md|html|css|mjs)$/)) {
Expand All @@ -121,10 +137,18 @@ export async function generateProject(config) {
const template = Handlebars.compile(content);
const result = template(config);
fs.writeFileSync(file, result);
compiledCount++;
if (verbose) {
const relPath = path.relative(projectPath, file);
console.log(chalk.gray(` [compile] Processed — ${relPath}`));
}
}
}
}
compileSpinner.succeed('Template customization complete!');
if (verbose) {
console.log(chalk.gray(` [compile] ${compiledCount} files compiled, ${allFiles.length} total scanned (${Date.now() - compileStart}ms)`));
}

// 4. Save the config blueprint
const configFilePath = path.join(projectPath, 'opusify.config.json');
Expand Down Expand Up @@ -155,8 +179,12 @@ export async function generateProject(config) {
color: 'yellow'
}).start();
try {
const installStart = Date.now();
execSync('npm install', { cwd: projectPath, stdio: 'pipe' });
installSpinner.succeed('Dependencies installed successfully!');
if (verbose) {
console.log(chalk.gray(` [install] Duration: ${((Date.now() - installStart) / 1000).toFixed(1)}s`));
}
} catch (installError) {
installSpinner.fail('Could not install dependencies.');
console.log(chalk.red(` ✖ NPM Error: ${installError.message}`));
Expand Down Expand Up @@ -189,6 +217,9 @@ export async function generateProject(config) {

// 8. Final Success Message
console.log(chalk.magenta(`\n🎉 Project ${projectName} is ready!`));
if (verbose) {
console.log(chalk.gray(` [total] Generation completed in ${((Date.now() - totalStart) / 1000).toFixed(1)}s`));
}
console.log(chalk.white('\nNext steps:'));
console.log(chalk.cyan(` cd ${projectName}`));
console.log(chalk.cyan(' npm run dev\n'));
Expand Down
Loading