easy-api.ts
Version:
A powerful library to create your own API with ease.
173 lines (156 loc) • 6.07 kB
JavaScript
const { AsciiTable3, AlignmentEnum } = require('ascii-table3')
const { isBoolean, isNumber, isString } = require('lodash')
const version = require('../package.json').version
const Spinnies = require('spinnies')
const fs = require('fs/promises')
const { join } = require('path')
const yargs = require('yargs')
const x = require('colors')
const allowedCommands = Object.freeze({
create: {
aliases: ['c'],
flags: ['port', 'folder', 'host'/*, 'logger'*/]
}
})
const spinnies = new Spinnies()
const table = new AsciiTable3(`EA${x.blue('.TS')}`)
.setAlign(3, AlignmentEnum.AUTO)
.setStyle('none')
.setHeading('Command Name', 'Description', 'Aliases', 'Flags')
.addRowMatrix([
[
'create', 'Creates an easy-api.ts setup.',
allowedCommands.create.aliases.map(t => `${t}`).join(', '),
allowedCommands.create.flags.map(t => `${x.blue('--' + t)}`).join(', ')
]
])
/**
* Resolves a placeholder.
* @param {string} name - The placeholder name.
* @param {string} replaceTo - Text to replace placeholders with.
* @param {string} text - The text to work on.
* @returns {string}
*/
function resolve(name, replaceTo, text) {
const regex = new RegExp(`{${name}}`, 'ig')
return text.replace(regex, replaceTo)
}
/**
* Sleeps the code for the given time.
* @param {number} duration - Sleep duration in milliseconds.
* @returns {Promise<any>}
*/
function sleep(duration) {
return new Promise((res) => setTimeout(res, duration))
}
/**
* The main program of the EATS CLI.
* @returns {Promise<boolean>}
*/
async function main() {
let returnCode = true
const flags = yargs.parse(process.argv.slice(2)), [command] = process.argv.slice(2)
if (!command) {
console.log(table.toString())
return returnCode
}
if (['create'].concat(allowedCommands.create.aliases).includes(command)) {
let logger = false, folder = `'routes'`, port = 3000, host = `'0.0.0.0'`;
// ------------- FLAGS PARSING -------------
if (flags.port && isNumber(flags.port))
port = Number(flags.port)
if (flags.path && isString(flags.path))
folder = `'${flags.path}'`
if (flags.host && isString(flags.host))
host = `'${flags.host}'`
if (flags.logger && isBoolean(flags.logger))
logger = flags.logger
// ------------- FLAGS PARSING -------------
// ------------- MAIN FILE FETCHING -------------
spinnies.add('MAIN_FILE_FETCH', {
text: 'Fetching bundled main file...'
}), await sleep(500);
let MAIN_FILE = await fs.readFile(join(__dirname, 'prebundled', 'SETUP.js'), {
encoding:'utf-8'
})
if (MAIN_FILE === '') spinnies.fail('MAIN_FILE_FETCH', {
text: 'Cannot fetch main file.'
})
else spinnies.succeed('MAIN_FILE_FETCH', { text: 'Bundled main file fetched!' })
// ------------- MAIN FILE FETCHING -------------
// ------------- MAIN FILE REPLACER -------------
spinnies.add('MAIN_FILE_REPLACER', {
text: 'Replacing values...'
}), await sleep(500);
Object.entries({ logger, host, folder, port }).forEach(async ([key, value]) => {
spinnies.update('MAIN_FILE_REPLACER', {
text: `Replacing "${key}"...`
}), await sleep(500);
MAIN_FILE = resolve(key, value, MAIN_FILE)
await sleep(500);
})
spinnies.succeed('MAIN_FILE_REPLACER', {
text: 'All values replaced!'
})
// ------------- MAIN FILE REPLACER -------------
// --------------- FOLDER CREATOR ---------------
spinnies.add('FOLDER_READER', {
text: `Reading ${process.cwd()}...`
}), await sleep(500);
let dirs = await fs.readdir(join(process.cwd()))
const folders = folder.slice(1, -1).split(/(\/|\/\/|\\)/)
for (let i = 0; i < folders.length; i++) {
const fold = folders[i]
if (!dirs.includes(fold)) {
const subfolder = join(process.cwd(), ...folders.slice(i))
spinnies.update('FOLDER_READER', {
text: `Creating "${fold}"...`
}), await sleep(500);
await fs.mkdir(subfolder)
dirs = await fs.readdir(subfolder)
}
}
spinnies.succeed('FOLDER_READER', {
text: 'Folders created!'
}), await sleep(500);
// --------------- FOLDER CREATOR ---------------
// ---------------- FILE BUNDLER ----------------
spinnies.add('FILE_BUNDLER', {
text: 'Bundling files into your file system...'
}), await sleep(500);
try {
await fs.cp(
join(__dirname, 'prebundled', 'routes'),
join(process.cwd(), ...folders), {
recursive: true
}
)
spinnies.succeed('FILE_BUNDLER', {
text: 'Files copied successfully!'
})
} catch {
spinnies.fail('FILE_BUNDLER', {
text: 'Unable to bundle files to your file system.'
})
returnCode = false
}
// ---------------- FILE BUNDLER ----------------
// ---------------- FILE CREATOR ----------------
await fs.writeFile(join(process.cwd(), 'main.js'), MAIN_FILE)
// ---------------- FILE CREATOR ----------------
} else {
console.log(
`${x.red('EATS_CLI_ERROR')}: Invalid command name provided!`
)
returnCode = false
}
return returnCode
}
main().then((code) => {
console.log(
`CLI finished with: ${code === true ? x.green('SUCCESS') : x.red('ERROR')}`,
`\nEA${x.blue('.TS')}`,
`CLI ${version}`
)
})