known-ui
Version:
A CLI tool for integrating Known UI components into your Next.js projects.
142 lines (118 loc) • 4.19 kB
JavaScript
import { execSync } from 'child_process';
import path from 'path';
import fs from 'fs';
// executing shell commands
const runCommand = (command) => {
try {
execSync(command, { stdio: 'inherit' });
} catch (error) {
console.error(`Command failed: ${command}`);
console.error(error.message);
process.exit(1);
}
};
// Adding lib folder with utils
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)) {
let utilsContent;
if (isTypeScript) {
utilsContent = `import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
`;
} else {
utilsContent = `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 };
}
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
const isNextJs = !!packageJson.dependencies?.next;
const isTypeScript = !!packageJson.dependencies?.typescript ||
!!packageJson.devDependencies?.typescript ||
fs.existsSync(path.join(projectDir, 'tsconfig.json'));
return { isNextJs, isTypeScript };
};
const installDependencies = (dependencies) => {
try {
console.log('Installing required dependencies...');
runCommand(`npm install ${dependencies.join(' ')} --save`);
} catch (error) {
console.error('Failed to install dependencies:', error);
}
};
// Main initialization function
const init = async () => {
const projectDir = process.cwd();
const { isNextJs, isTypeScript } = detectProjectType(projectDir);
if (!isNextJs) {
const createReactCommand = isTypeScript
? 'npx create-react-app my-app --template typescript'
: 'npx create-react-app my-app';
console.log('Creating new React project...');
runCommand(createReactCommand);
process.chdir(path.join(process.cwd(), 'my-app'));
// Install additional dependencies for React project
const reactDependencies = [
'clsx',
'tailwind-merge',
'tailwindcss',
'postcss',
'autoprefixer'
];
installDependencies(reactDependencies);
// Setup Tailwind for React
console.log('Setting up Tailwind CSS...');
runCommand('npx tailwindcss init -p');
// Create Tailwind config
const tailwindConfig = `/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}`;
fs.writeFileSync(path.join(process.cwd(), 'tailwind.config.js'), tailwindConfig);
// Update index.css
const cssContent = `@tailwind base;
@tailwind components;
@tailwind utilities;`;
fs.writeFileSync(path.join(process.cwd(), 'src', 'index.css'), cssContent);
} else {
console.log('Next.js is already set up in this project.');
}
// Create utils file for both React and Next.js projects
const currentProjectType = detectProjectType(process.cwd());
createLibUtilsFile(process.cwd(), currentProjectType.isTypeScript);
// Install common dependencies if they don't exist
const commonDependencies = [
'clsx',
'tailwind-merge'
];
installDependencies(commonDependencies);
console.log('Your project is now fully set up. You can now add components!');
};
export default init;