@coderebus/react-archetype
Version:
React-archetype is a cli tool (or a generator) that will generate apps based on the rendering pattern (CSR,SSR, SSG, ISR etc) of your choice.
250 lines (249 loc) • 11.2 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLatestVersion = exports.displayNextSteps = exports.handleEmptyCwd = exports.identifyPackageManager = exports.identifyMonorepoWorkspace = exports.getListOfDirectories = exports.fileYielder = exports.isPnpm = exports.currentDateTime = void 0;
const tslib_1 = require("tslib");
const chalk_1 = tslib_1.__importDefault(require("chalk"));
const path_1 = tslib_1.__importDefault(require("path"));
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
const node_emoji_1 = tslib_1.__importDefault(require("node-emoji"));
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
const fileDirOps_1 = require("./fileDirOps");
const constants_1 = require("./constants");
/**
* @description : method to get the current date and time
* @returns {string} current date and time
*/
const currentDateTime = () => {
const date = new Date();
const str = date.getMonth() +
1 +
'/' +
date.getDate() +
'/' +
date.getFullYear() +
' ' +
date.getHours() +
':' +
date.getMinutes() +
':' +
date.getSeconds();
return str;
};
exports.currentDateTime = currentDateTime;
/**
* @description : method to check if commandName is pnpm or not
* @returns {boolean} true if commandName is pnpm else false
*/
const isPnpm = (commandName) => commandName === 'pnpm';
exports.isPnpm = isPnpm;
/**
* @description : js generator to yield all files from a directory recursively
* @param {string} directoryPath : location of the directory
*/
function* fileYielder(directoryPath) {
const files = fs_extra_1.default.readdirSync(directoryPath, { withFileTypes: true });
for (const file of files) {
if (file.isDirectory()) {
yield* fileYielder(path_1.default.join(directoryPath, file.name));
}
else {
yield path_1.default.join(directoryPath, file.name);
}
}
}
exports.fileYielder = fileYielder;
/**
* @description : js generator to yield all directories from a directory
* @param {string} directoryPath : location of the directory
*/
function* dirYielder(directoryPath) {
const items = fs_extra_1.default.readdirSync(directoryPath, { withFileTypes: true });
for (const item of items) {
if (item.isDirectory()) {
yield path_1.default.join(directoryPath, item.name);
}
}
}
/**
* @description : function to return all the directories from a given path
* @param {string} directoryPath : location of the directory
* @param {boolean} filter : boolean to filter the directories
* @returns {string[]} list of directories
*/
function getListOfDirectories(directoryPath, filter) {
const directories = [];
if (filter) {
for (const dirPath of dirYielder(directoryPath)) {
const dirName = path_1.default.basename(dirPath);
if (!constants_1.ignoreDirs.includes(dirName) && !dirName.startsWith('.')) {
directories.push(dirName);
}
}
}
else {
for (const dirPath of dirYielder(directoryPath)) {
directories.push(path_1.default.basename(dirPath));
}
}
return directories;
}
exports.getListOfDirectories = getListOfDirectories;
/**
* @description : function to identify monorepo workspace in a directory
* @param {string} directoryPath : location of the directory
* @param {PackageJson} packageJson : package.json object
* @returns {string} monorepo workspace type
*/
function identifyMonorepoWorkspace(directoryPath, packageJson) {
try {
const isNxWorkspace = (0, fileDirOps_1.dirFileExists)(path_1.default.join(directoryPath, 'nx.json')) || packageJson.nx !== undefined;
const isTurboWorkspace = (0, fileDirOps_1.dirFileExists)(path_1.default.join(directoryPath, 'turbo.json')) || packageJson.turbo !== undefined;
const isLernaWorkspace = (0, fileDirOps_1.dirFileExists)(path_1.default.join(directoryPath, 'lerna.json')) || packageJson.lerna !== undefined;
switch (true) {
case isNxWorkspace:
return 'nx';
case isTurboWorkspace:
return 'turbo';
case isLernaWorkspace:
return 'lerna';
default:
return '';
}
}
catch (err) {
console.error(err);
return '';
}
}
exports.identifyMonorepoWorkspace = identifyMonorepoWorkspace;
/**
* @description : method to identify which command type need to be used
* @param {string} directoryPath : location of the lock files
* @returns {CommandTypeObject} command type object which contains the name of the package manager and the corresponding lock filename
*/
const identifyPackageManager = (directoryPath) => {
const packageLock = path_1.default.join(directoryPath, constants_1.appConstants.PACKAGE_LOCK);
const pnpmLock = path_1.default.join(directoryPath, constants_1.appConstants.PNPM_LOCK);
const yarnLock = path_1.default.join(directoryPath, constants_1.appConstants.YARN_LOCK);
switch (true) {
case (0, fileDirOps_1.dirFileExists)(yarnLock):
return {
command: constants_1.commandTypes.YARN,
fileName: constants_1.appConstants.YARN_LOCK,
};
case (0, fileDirOps_1.dirFileExists)(pnpmLock):
return {
command: constants_1.commandTypes.PNPM,
fileName: constants_1.appConstants.PNPM_LOCK,
};
case (0, fileDirOps_1.dirFileExists)(packageLock):
return {
command: constants_1.commandTypes.NPM,
fileName: constants_1.appConstants.PACKAGE_LOCK,
};
default:
return {
command: '',
fileName: '',
};
}
};
exports.identifyPackageManager = identifyPackageManager;
/**
* @description : method to log info if empty cwd detected
*/
const handleEmptyCwd = () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
console.info(chalk_1.default.greenBright(`
${chalk_1.default.bold('We recommend having a monorepo structure for:')}
${node_emoji_1.default.get('chart_with_upwards_trend')} Easier ${chalk_1.default.bold.cyanBright('SCALABILITY')}
${node_emoji_1.default.get('books')} Code ${chalk_1.default.bold.cyanBright('REUSABILITY')}
${node_emoji_1.default.get('handshake')} Improved ${chalk_1.default.bold.cyanBright('COLLABORATION')}
${node_emoji_1.default.get('wrench')} Streamlined ${chalk_1.default.bold.cyanBright('MAINTENANCE')}
`));
console.log();
console.info(`
${chalk_1.default.bold.greenBright('For more info on monorepo, visit: ')} ${chalk_1.default.bold.cyanBright('https://circleci.com/blog/monorepo-dev-practices/')}
`.trimStart());
const createMonorepoQuestions = [
{
type: 'confirm',
name: `createMonorepo`,
message: `Would you like to use a monorepo workspace?`,
default: true,
},
];
const createMonorepoAnswers = yield inquirer_1.default.prompt(createMonorepoQuestions);
if (createMonorepoAnswers.createMonorepo) {
console.info(chalk_1.default.greenBright(`
${chalk_1.default.bold('To create a monorepo workspace, follow the below steps:')}
1. Install the GenesisX's create workspace package - ${node_emoji_1.default.get('package')} ${chalk_1.default.bold.cyanBright('[yarn add -g @genesisx/create-workspace]')}
2. Run the plugin in a blank directory - ${node_emoji_1.default.get('rocket')} ${chalk_1.default.bold.cyanBright('[npx @genesisx/create-workspace]')}
3. Provide a suitable name for your workspace ${node_emoji_1.default.get('pencil2')} ${chalk_1.default.bold.cyanBright('(eg. test-workspace)')}
4. Select the plugins you want to install ${node_emoji_1.default.get('heavy_plus_sign')} ${chalk_1.default.bold.cyanBright('(Press ENTER to skip)')}
`));
console.log();
console.info(chalk_1.default.bold.greenBright(`Once your workspace is ready, you can try running - ${chalk_1.default.bold.cyanBright(`[npx ${constants_1.OFFICIAL_PACKAGE_NAME}]`)}`.trimStart()));
process.exit(1);
}
});
exports.handleEmptyCwd = handleEmptyCwd;
/**
* @description : method to display the next steps after app generation
* @param {ArchGeneratorOptions} options : default app options object
*/
const displayNextSteps = (options) => {
const { parentDir, pkgManager, appName, noInstall, monorepo } = options;
const pathToApp = parentDir ? `${parentDir}/${appName}` : appName;
console.log();
console.info(chalk_1.default.bgGreenBright.white.bold(' NEXT STEPS '));
console.log();
// change directory step
const cdStep = !monorepo
? `Change directory - ${node_emoji_1.default.get('cd')} ${chalk_1.default.bold.cyanBright(`cd ${pathToApp}`)}`
: null;
// installation step
const installStep = noInstall
? `Install the dependencies - ${node_emoji_1.default.get('package')} ${chalk_1.default.bold.cyanBright(`${pkgManager} install`)}`
: null;
// app serving step
let serveStep = '';
if (monorepo) {
// if monorepo
switch (pkgManager) {
case 'npm':
serveStep = `Serve the app - ${node_emoji_1.default.get('rocket')} ${chalk_1.default.bold.cyanBright(`${pkgManager} run dev -w=${appName}`)}`;
break;
case 'pnpm':
serveStep = `Serve the app - ${node_emoji_1.default.get('rocket')} ${chalk_1.default.bold.cyanBright(`${pkgManager} --filter ${appName} dev`)}`;
break;
case 'yarn':
serveStep = `Serve the app - ${node_emoji_1.default.get('rocket')} ${chalk_1.default.bold.cyanBright(`${pkgManager} workspace ${appName} dev`)}`;
break;
default:
break;
}
}
else {
// if not monorepo
serveStep = `Serve the app - ${node_emoji_1.default.get('rocket')} ${chalk_1.default.bold.cyanBright(`${pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`}`)}`;
}
// list of steps to be displayed
const steps = [cdStep, installStep, serveStep].filter(step => step !== null);
let output = '';
steps.forEach((step, index) => {
if (step) {
output += `${index + 1}. ${step}\n`;
}
});
console.info(chalk_1.default.greenBright(output));
};
exports.displayNextSteps = displayNextSteps;
function getLatestVersion(dep) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const response = yield fetch(`https://registry.npmjs.org/${dep}`);
const data = yield response.json();
const latestVersion = data['dist-tags'].latest;
return latestVersion;
});
}
exports.getLatestVersion = getLatestVersion;
;