diff --git a/README.md b/README.md index 105f168..f9f43db 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,22 @@ This project pairs well with this [React Template](https://github.com/saisilinus/react-redux-typescript-boilerplate) +By running a single command, you will get a production-ready Node.js TypeScript app installed and fully configured on your machine. The app comes with many built-in features, such as authentication using JWT, request validation, unit and integration tests, continuous integration, docker support, API documentation, pagination, etc. For more details, check the features list below. + +## Quick Start + +To create a project, simply run: + +```bash +npx create-nodejs-ts-app +``` + +Or + +```bash +npm init nodejs-ts-app +``` + ## Manual Installation Clone the repo: diff --git a/bin/createNodetsApp.cjs b/bin/createNodetsApp.cjs new file mode 100644 index 0000000..a494fcb --- /dev/null +++ b/bin/createNodetsApp.cjs @@ -0,0 +1,109 @@ +#!/usr/bin/env node +const util = require('util'); +const path = require('path'); +const fs = require('fs'); +const { execSync } = require('child_process'); + +// Utility functions +const exec = util.promisify(require('child_process').exec); +async function runCmd(command) { + try { + const { stdout, stderr } = await exec(command); + console.log(stdout); + console.log(stderr); + } catch { + (error) => { + console.log(error); + }; + } +} + +async function hasYarn() { + try { + await execSync('yarnpkg --version', { stdio: 'ignore' }); + return true; + } catch { + return false; + } +} + +// Validate arguments +if (process.argv.length < 3) { + console.log('Please specify the target project directory.'); + console.log('For example:'); + console.log(' npx create-nodejs-app my-app'); + console.log(' OR'); + console.log(' npm init nodejs-app my-app'); + process.exit(1); +} + +// Define constants +const ownPath = process.cwd(); +const folderName = process.argv[2]; +const appPath = path.join(ownPath, folderName); +const repo = 'https://github.com/saisilinus/node-express-mongoose-typescript-boilerplate.git'; + +// Check if directory already exists +try { + fs.mkdirSync(appPath); +} catch (err) { + if (err.code === 'EEXIST') { + console.log('Directory already exists. Please choose another name for the project.'); + } else { + console.log(err); + } + process.exit(1); +} + +async function setup() { + try { + // Clone repo + console.log(`Downloading files from repo ${repo}`); + await runCmd(`git clone --depth 1 ${repo} ${folderName}`); + console.log('Cloned successfully.'); + console.log(''); + + // Change directory + process.chdir(appPath); + + // Install dependencies + const useYarn = await hasYarn(); + console.log('Installing dependencies...'); + if (useYarn) { + await runCmd('yarn install'); + } else { + await runCmd('npm install'); + } + console.log('Dependencies installed successfully.'); + console.log(); + + // Copy envornment variables + fs.copyFileSync(path.join(appPath, '.env.example'), path.join(appPath, '.env')); + console.log('Environment files copied.'); + + // Delete .git folder + await runCmd('npx rimraf ./.git'); + + // Remove extra files + fs.unlinkSync(path.join(appPath, 'CHANGELOG.md')); + fs.unlinkSync(path.join(appPath, 'CODE_OF_CONDUCT.md')); + fs.unlinkSync(path.join(appPath, 'CONTRIBUTING.md')); + if (!useYarn) { + fs.unlinkSync(path.join(appPath, 'yarn.lock')); + } + + console.log('Installation is now complete!'); + console.log(); + + console.log('We suggest that you start by typing:'); + console.log(` cd ${folderName}`); + console.log(useYarn ? ' yarn dev' : ' npm run dev'); + console.log(); + console.log('Enjoy your production-ready Node.js app, which already supports a large number of ready-made features!'); + console.log('Check README.md for more info.'); + } catch (error) { + console.log(error); + } +} + +setup(); \ No newline at end of file diff --git a/package.json b/package.json index 5bcad94..0ef6615 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,14 @@ { - "name": "node-express-mongoose-typescript-boilerplate", + "name": "create-nodejs-ts-app", "version": "2.2.1", "description": "Node express mongoose typescript boilerplate", "main": "dist/index.js", + "bin": "bin/createNodetsApp.cjs", "repository": "https://github.com/saisilinus/node-express-mongoose-typescript-boilerplate.git", "bugs": { "url": "https://github.com/saisilinus/node-express-mongoose-typescript-boilerplate/issues" }, - "author": "wafula saisi ", + "author": "linus wafula saisi ", "license": "MIT", "type": "module", "engines": {