rtk-ready
Version:
Redux utilities package for a boilerplate setup with persisted state, authentication handling, API integration, and typed hooks, providing a structured and scalable state management solution for React applications.
115 lines (101 loc) • 3.49 kB
text/typescript
import fs from 'fs';
import path from 'path';
import { execSync } from 'child_process';
const mainProjectRoot = process.env.INIT_CWD || process.cwd();
const srcPath = path.join(mainProjectRoot, 'src');
const reduxPath = fs.existsSync(srcPath)
? path.join(srcPath, 'redux')
: path.join(mainProjectRoot, 'redux');
const templatePath = path.join(
mainProjectRoot,
'./node_modules/rtk-ready/src/redux'
);
const markerFilePath = path.join(reduxPath, '.rtk-ready-installed');
// Utility to copy folder content recursively
function copyFolderSync(from: string, to: string) {
if (!fs.existsSync(from)) {
console.log(`Source folder does not exist: ${from}`);
return;
}
fs.mkdirSync(to, { recursive: true });
fs.readdirSync(from).forEach((element) => {
const stat = fs.lstatSync(path.join(from, element));
if (stat.isFile()) {
fs.copyFileSync(path.join(from, element), path.join(to, element));
} else if (stat.isDirectory()) {
copyFolderSync(path.join(from, element), path.join(to, element));
}
});
}
// Utility to find a unique folder name
function getUniqueFolderName(basePath: string, folderName: string): string {
let uniqueName = folderName;
let counter = 0;
while (fs.existsSync(path.join(basePath, uniqueName))) {
counter++;
uniqueName = `${folderName}(${counter})`;
}
return path.join(basePath, uniqueName);
}
// Create the Redux folder structure
function createReduxFolder() {
if (!fs.existsSync(templatePath)) {
console.error(
'Template folder does not exist. Please ensure the src/redux-template folder exists.'
);
return;
}
let targetPath = reduxPath;
if (fs.existsSync(reduxPath)) {
// Find a unique folder name if redux already exists
console.log(
'Redux folder already exists. Searching for a unique folder name...'
);
targetPath = getUniqueFolderName(
fs.existsSync(srcPath) ? srcPath : mainProjectRoot,
'redux'
);
}
console.log(`Creating Redux folder at ${targetPath}...`);
copyFolderSync(templatePath, targetPath);
fs.writeFileSync(path.join(targetPath, '.rtk-ready-installed'), 'true');
console.log('Redux folder created.');
}
// Install required dependencies
function installDependencies() {
const dependencies = [
'@reduxjs/toolkit@latest',
'js-cookie@latest',
'react-redux@latest',
'redux-persist@latest',
];
const devDependencies = [
'@types/js-cookie@latest',
'@types/react-redux@latest',
];
console.log('Installing dependencies in the main project...');
try {
execSync(`npm install ${dependencies.join(' ')}`, {
cwd: mainProjectRoot,
stdio: 'inherit',
});
// Check for TypeScript support
const tsconfigPath = path.join(mainProjectRoot, 'tsconfig.json');
if (fs.existsSync(tsconfigPath)) {
console.log('TypeScript detected. Installing dev dependencies...');
execSync(`npm install --save-dev ${devDependencies.join(' ')}`, {
cwd: mainProjectRoot,
stdio: 'inherit',
});
}
console.log('Dependencies installed successfully.');
} catch (error: any) {
console.error('Error installing dependencies:', error.message);
// Exit process with a success code to prevent npm from failing.
process.exit(0);
}
}
// Main execution
createReduxFolder();
installDependencies();