anvy
Version:
A CLI tool for integrating Anvy UI components into your React.js and Next.js projects.
165 lines (163 loc) • 5.6 kB
JavaScript
import { execSync } from 'child_process';
import path from 'path';
import fs from 'fs';
import chalk from 'chalk';
const runCommand = (command) => {
try {
execSync(command, { stdio: 'inherit' });
}
catch (error) {
console.error(`Command failed: ${command}`);
console.error(error.message);
process.exit(1);
}
};
const createLibUtilsFile = (projectDir, isTypeScript) => {
const utilsDir = path.join(projectDir, 'lib');
const utilsPath = path.join(utilsDir, isTypeScript ? 'utils.ts' : 'utils.js');
if (!fs.existsSync(utilsDir)) {
fs.mkdirSync(utilsDir, { recursive: true });
}
if (!fs.existsSync(utilsPath)) {
const utilsContent = isTypeScript
? `import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}`
: `import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs) {
return twMerge(clsx(inputs));
}`;
fs.writeFileSync(utilsPath, utilsContent);
console.log(`Created lib/utils${isTypeScript ? '.ts' : '.js'}`);
}
else {
console.log(`lib/utils${isTypeScript ? '.ts' : '.js'} already exists`);
}
};
const detectProjectType = (projectDir) => {
const packageJsonPath = path.join(projectDir, 'package.json');
if (!fs.existsSync(packageJsonPath)) {
return { isNextJs: false, isTypeScript: false, isReact: false };
}
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
const isNextJs = !!packageJson.dependencies?.next;
const isReact = !!packageJson.dependencies?.react;
const isTypeScript = !!packageJson.dependencies?.typescript ||
!!packageJson.devDependencies?.typescript ||
fs.existsSync(path.join(projectDir, 'tsconfig.json'));
return { isNextJs, isTypeScript, isReact };
};
const createTailwindConfig = (projectDir, isNextJs) => {
const configPath = path.join(projectDir, 'tailwind.config.js');
if (fs.existsSync(configPath)) {
console.log('Tailwind config already exists, skipping creation...');
return;
}
const tailwindConfig = isNextJs
? `/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./app/**/*.{js,ts,jsx,tsx,mdx}",
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./lib/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {},
},
plugins: [],
}`
: `/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
"./public/index.html",
"./lib/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}`;
fs.writeFileSync(configPath, tailwindConfig);
console.log('Created tailwind.config.js');
};
const createPostCssConfig = (projectDir) => {
const configPath = path.join(projectDir, 'postcss.config.js');
if (fs.existsSync(configPath)) {
console.log('PostCSS config already exists, skipping creation...');
return;
}
const postCssConfig = `module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}`;
fs.writeFileSync(configPath, postCssConfig);
console.log('Created postcss.config.js');
};
const setupTailwind = async (projectDir, isNextJs) => {
const tailwindDeps = [
'tailwindcss',
'postcss',
'autoprefixer'
];
console.log('Installing Tailwind dependencies...');
runCommand(`npm install ${tailwindDeps.join(' ')} --save-dev`);
createTailwindConfig(projectDir, isNextJs);
createPostCssConfig(projectDir);
const cssContent = ` base;
components;
utilities;`;
const cssPath = isNextJs
? path.join(projectDir, 'app', 'globals.css')
: path.join(projectDir, 'src', 'index.css');
if (fs.existsSync(cssPath)) {
const existingCss = fs.readFileSync(cssPath, 'utf-8');
if (!existingCss.includes('@tailwind')) {
console.log('Adding Tailwind directives to existing CSS file...');
fs.writeFileSync(cssPath, cssContent + '\n\n' + existingCss);
}
}
else {
console.log('Creating new CSS file with Tailwind directives...');
fs.writeFileSync(cssPath, cssContent);
}
};
const installDependencies = (dependencies) => {
try {
console.log('Installing required dependencies...');
runCommand(`npm install ${dependencies.join(' ')} --save-dev`);
}
catch (error) {
console.error('Failed to install dependencies:', error);
}
};
export const initCommand = async () => {
const projectDir = process.cwd();
const { isNextJs, isTypeScript, isReact } = detectProjectType(projectDir);
if (!isNextJs && !isReact) {
console.error('No React or Next.js project detected in the current directory.');
console.log('Please run this command in an existing React or Next.js project.');
process.exit(1);
}
if (isReact) {
console.log('Detected existing React project...');
}
else if (isNextJs) {
console.log('Detected Next.js project...');
}
await setupTailwind(projectDir, isNextJs);
createLibUtilsFile(projectDir, isTypeScript);
const commonDependencies = [
'clsx',
'tailwind-merge'
];
installDependencies(commonDependencies);
console.log(chalk.green('Your project is now fully set up with utils and dependencies!'));
};
//# sourceMappingURL=init.js.map