nautus-npx
Version:
Kelp generator for npm / npx based cli tool 🚀
295 lines (248 loc) • 9.53 kB
JavaScript
const generator = async (prompts, validationRegExes, about, dir, cmd, mergeScript, removeDefault, chalk, fs) => {
/*
DON'T DELETE THIS COMMENT, YOU MIGHT NEED IT LATER
This function will get run when creating boilerplate code.
You can use the above defined methods to generate code
Here's a brief explanation of each:
prompts: contains various prompt functions to get input frome the use
{
async prompt(question, defaultValue = '', validationRegEx = null, canBeEmpty = false, validatorFunction = null) => string // NOTE: The validatorFunction can be async
async confirm(question) => true|false
async numeral(question, validatorFunction) => number
async toggle(question, option1, option2) => option1|option2
async select(question, [...choices]) => choice
async multiSelect(question, [...choices], min = 0, max = Infinity) => [...choices]
}
validationRegExes: contains various RegExes that are useful when dealing with prompts. As of now:
{
identifier: Allows a-z, A-Z, -, _, @, ~ and .
license: Allows valid SPDX licenses, UNKNOWN and SEE LICENSE IN <file>
repository: Allows github repos, eg. username/repo
email: Allows valid emails,
confirmation: Allows yes, no, y and n
username: Allows typically valid usernames
url: Allows urls with optional protocol
phone: Allows international phone numbers
}
about: contains whatever the user specified using nautus me. NOTE: All fields can be empty
{
realName,
githubUsername,
name,
gender,
email
}
dir: path to the directory where the project files are saved
cmd: function that allows you to run commands jsut like in a nautus script
async cmd(command: string) => [exitCode, stdout]
mergeScript: function that allows you to merge code into a script. NOTE: Don't include the boilerplate for a script, jsut include what needs to be put in the function
// scriptName shall not include @ or .js
mergeScript(scriptName, code) => void
removeDefault: function that removes the default error from a script
// scriptName shall not include @ or .js
removeDefault(scriptName) => void
chalk: chalk module to help you style your console.log's. See https://www.npmjs.com/package/chalk for more
fs: like the default fs module, but writeFile and writeFileSync are protected
and ask user before overwriting existing files.
NOTE: Usage of require('fs') is prohibited to protect the users data
*/
const { prompt, confirm, numeral, toggle, select, multiSelect } = prompts
const { identifier, repository } = validationRegExes
const path = require('path')
// Do your prompts here
const pkName = await prompt('Name', '', identifier, false, async (input) => {
// Check if npm module name is availble
try {
const res = await axios.get(`https://registry.npmjs.org/${encodeURIComponent(input)}`)
if (res.data && res.data.error && res.data.error === 'Not found') {
return true
} else {
console.log(chalk.yellow('A package with this name already exists!'))
return false
}
} catch {
return true
}
})
let repo = null
if (!about.githubUsername) about.githubUsername = await prompt('GitHub Username')
if (await confirm('Do you have a GitHub repo?')) {
repo = await prompt('Repository', `${about.githubUsername}/${pkName}`, repository)
}
const description = await prompt('Description', '', null, true)
const license = await prompt('License', 'MIT', validationRegExes.license)
// Do your generation here
const pkgJSON = {
name: `${pkName}`,
version: '0.1.0',
description,
types: 'bin/main.d.ts',
main: 'bin/main.js',
type: 'module',
bin: {
},
scripts: {
test: "echo \"Error: no test specified\" && exit 1"
},
keywords: [],
author: `${about.name || about.githubUsername} (https://github.com/${about.githubUsername})`,
license,
dependencies: {}
}
pkgJSON.bin[pkName] = 'bin/main.js'
if (repo) {
pkgJSON.repository = {
type: 'git',
url: `git+https://github.com/${repo}.git`
}
pkgJSON.bugs = {
url: `https://github.com/${repo}/issues`
}
pkgJSON.homepage = `https://github.com/${repo}#readme`
}
fs.ensureDirSync(path.join(dir, 'bin'))
fs.ensureDirSync(path.join(dir, 'src'))
fs.writeFileSync(path.join(dir, 'src', 'main.ts'), `
import chalk from 'chalk'
const args = process.argv.slice(2)
`)
fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify(pkgJSON, null, 4))
// @Build.js
removeDefault('Build') // Removes the default error message
mergeScript('Build', `exit(await spawn(modules.path.join(process.cwd(), 'node_modules/.bin/tsc'), []))`)
// @Prep.js
mergeScript('Prep', `await cmd(modules.path.join(process.cwd(), 'node_modules/.bin/tsc')).catch(error)`)
// @Run.js
removeDefault('Run') // Removes the default error message
mergeScript('Run', `exit(await spawn('node', ["bin/main.js", ...process.argv.slice(2)]))`)
// @Release.js
removeDefault('Release')
mergeScript('Release', fs.readFileSync(path.join(__dirname, 'templates', '@Release.js')))
fs.ensureFileSync(path.join(dir, 'README.md'))
await cmd('npm i typescript @types/node -D')
await cmd('npm i chalk')
fs.writeFileSync(path.join(dir, 'tsconfig.json'), JSON.stringify({
compilerOptions: {
target: 'ESNext',
module: 'ESNext',
declaration: true,
outDir: './bin',
strict: true,
moduleResolution: 'nodenext'
},
include: [
'./src/'
]
}, null, 4))
// INFO
console.log(chalk.green(`Successfully generated npx cli tool. You can run it by using ${chalk.cyan('nautus run')} or ${chalk.cyan(`npx -y ${pkName}`)} after release. To publish it to npm use ${chalk.cyan('nautus release major|minor|patch')}`))
}
module.exports = {
generator: generator, // This will get run if you use nautus kelp (aka want to create boilerplate in afresh project)
use: generator, // This will get run if you use nautus use (aka want additional boilerplate or support for a framework / runtime). Make sure that this won't replace important stuff
commands: () => {
/*
If you just want to create boilerplate code, this function is irrelevant for you.
If you want to create commands anyways, use "nautus use commands"
in this project to add command support.
*/
},
gitIgnore: `bin/
.dccache
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
pids
*.pid
*.seed
*.pid.lock
lib-cov
coverage
*.lcov
.nyc_output
.grunt
bower_components
.lock-wscript
build/Release
node_modules/
jspm_packages/
web_modules/
*.tsbuildinfo
.npm
.eslintcache
.stylelintcache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
.node_repl_history
*.tgz
.yarn-integrity
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
.cache
.parcel-cache
.next
out
.nuxt
dist
.cache/
.vuepress/dist
.temp
.cache
.serverless/
.fusebox/
.dynamodb/
.tern-port
.vscode-test
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
`
}