@reuvenorg/react-native-boilerplate-ultimate
Version:
A powerful CLI tool for creating React Native projects with modular architecture. Generate, manage, and scaffold React Native applications with pre-built modules and best practices.
105 lines • 4.07 kB
JavaScript
import fs from 'fs-extra';
import * as path from 'path';
export function generateReplacements(projectName) {
const lowercaseName = projectName.toLowerCase();
const uppercaseName = projectName.toUpperCase();
// Generate bundle identifier based on project name
const bundleId = `com.anonymous.${lowercaseName.replace(/[^a-z0-9]/g, '')}`;
return {
ExApp: projectName,
exapp: lowercaseName,
EXAPP: uppercaseName,
'com.anonymous.exapp': bundleId,
};
}
export function replaceInFile(filePath, replacements) {
if (!fs.existsSync(filePath)) {
return;
}
let content = fs.readFileSync(filePath, 'utf8');
let hasChanges = false;
// Apply replacements in order of specificity (longest first to avoid partial replacements)
const sortedReplacements = Object.entries(replacements).sort(([a], [b]) => b.length - a.length);
for (const [search, replace] of sortedReplacements) {
const regex = new RegExp(escapeRegExp(search), 'g');
if (regex.test(content)) {
content = content.replace(regex, replace);
hasChanges = true;
}
}
if (hasChanges) {
fs.writeFileSync(filePath, content, 'utf8');
}
}
export function replaceInDirectory(dirPath, replacements, options = {}) {
const { extensions = [], excludePatterns = [] } = options;
if (!fs.existsSync(dirPath)) {
return;
}
const items = fs.readdirSync(dirPath);
for (const item of items) {
const itemPath = path.join(dirPath, item);
const relativePath = path.relative(dirPath, itemPath);
// Skip excluded patterns
if (excludePatterns.some(pattern => relativePath.includes(pattern))) {
continue;
}
const stats = fs.statSync(itemPath);
if (stats.isDirectory()) {
// Handle directory renaming (ExApp folder -> ProjectName folder)
if (item === 'ExApp') {
const newDirPath = path.join(dirPath, replacements.ExApp);
fs.renameSync(itemPath, newDirPath);
replaceInDirectory(newDirPath, replacements, options);
}
else {
replaceInDirectory(itemPath, replacements, options);
}
}
else if (stats.isFile()) {
// Handle file renaming and content replacement
let shouldReplace = true;
// Check file extension filter
if (extensions.length > 0) {
const ext = path.extname(item);
shouldReplace = extensions.includes(ext);
}
// Skip binary files and certain file types
const skipExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.ico', '.jar', '.keystore'];
if (skipExtensions.includes(path.extname(item).toLowerCase())) {
shouldReplace = false;
}
if (shouldReplace) {
replaceInFile(itemPath, replacements);
}
// Handle file renaming
if (item.includes('ExApp')) {
const newFileName = item.replace(/ExApp/g, replacements.ExApp);
const newFilePath = path.join(dirPath, newFileName);
if (newFilePath !== itemPath) {
fs.renameSync(itemPath, newFilePath);
}
}
}
}
}
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
export function replaceTemplateVariables(templatePath, destinationPath, projectName) {
const replacements = generateReplacements(projectName);
// Define files that should not be processed for text replacement
const excludePatterns = [
'node_modules',
'.git',
'ios/Pods',
'ios/build',
'android/build',
'android/.gradle',
'package-lock.json', // Keep this as is for template integrity
];
replaceInDirectory(destinationPath, replacements, {
excludePatterns,
});
}
//# sourceMappingURL=template-replacer.js.map