feat(*): more questions, better handling, better ui

This commit is contained in:
EvolutionX
2022-04-21 21:50:47 +05:30
parent 0e97b7db8a
commit f9318024bb
7 changed files with 791 additions and 1677 deletions

View File

@@ -1,130 +1,108 @@
import { findUp } from 'find-up';
import pkg from 'inquirer';
const { prompt } = pkg;
// TODO refactor the intents stuff and add more questions
const Intents = [
'DIRECT_MESSAGES',
'DIRECT_MESSAGE_REACTIONS',
'DIRECT_MESSAGE_TYPING',
'GUILDS',
'GUILD_BANS',
'GUILD_EMOJIS_AND_STICKERS',
'GUILD_INTEGRATIONS',
'GUILD_INVITES',
'GUILD_MEMBERS',
'GUILD_MESSAGES',
'GUILD_MESSAGE_REACTIONS',
'GUILD_MESSAGE_TYPING',
'GUILD_PRESENCES',
'GUILD_SCHEDULED_EVENTS',
'GUILD_VOICE_STATES',
'GUILD_VOICE_STATES',
'GUILD_WEBHOOKS',
].map((i, j) => ({ name: i, value: j, short: `${j}` }));
import prompts from 'prompts';
import ora from 'ora';
import { redBright, yellowBright } from 'colorette';
import { execa } from 'execa';
import {
cmds_dir,
default_prefix,
intent,
lang,
main_dir,
token,
npmInit,
gitInit,
} from '../prompts/init.js';
const { prompt } = prompts;
// TODO make this functional and better!
export async function init({ flags }) {
if (flags?.includes('y')) {
console.log("I see a flag there! Seems like you're lazy!\nBye!");
process.exit(0);
}
const pkg = await findUp('package.json');
if (!pkg) {
console.log('No package.json found');
const node = await execa('node', ['--version']);
if (node.stdout.match(/v1(([0-6]\.[2-9])|([0-5]\.[0-9]))/gm)?.length) {
console.log(
yellowBright(
`\nYou are using Node ${node.stdout}\nPlease upgrade to Node 16.10.x or higher!\n`
)
);
return process.exit(1);
}
await whichLang();
const input = await kindPrefix();
if (input.prefix !== 'app_cmds') {
await legacy();
const pkg = await findUp('package.json');
if (!pkg) {
console.log(`No ${redBright('package.json')} found!`);
const npm = await prompt([npmInit]);
if (!npm.npminit) {
console.log(
`${redBright('Failed')} to initialize Sern!` +
'\nMaybe you should run npm init?'
);
return process.exit(1);
} else {
const spin = ora({
text: 'Initializing npm...',
spinner: 'aesthetic',
}).start();
const exee = await execa('npm', ['init', '-y']).catch(
() => null
); /* .stdout.pipe(process.stdout) */
await wait(300);
if (!exee || exee?.failed) {
spin.fail(
`${redBright('Failed')} to initialize npm!` +
'\nMaybe you should run npm init?'
);
return process.exit(1);
} else spin.succeed('Npm initialized!');
}
}
await intents();
}
const lang = {
message: 'What language you want the project to be in?',
name: 'lang',
type: 'list',
choices: [
{
name: 'JavaScript',
value: 'js',
type: 'choice',
},
{
name: 'TypeScript',
value: 'ts',
type: 'choice',
},
],
};
const intent = {
message: 'What intents do you want to keep?',
type: 'checkbox',
name: 'intents',
choices: Intents,
validate(a) {
if (a.length < 1) {
return 'You must choose at least one intent!';
const git = await findUp('.git/config');
if (!git) {
console.log(`No ${redBright('Git Repository')} found!`);
const git_init = await prompt([gitInit]);
if (!git_init.gitinit) {
console.log(
'Maybe you should run git init?\n' + `Alright Moving on...`
);
} else {
const spin = ora({
text: 'Initializing git...',
spinner: 'aesthetic',
}).start();
const exe = await execa('git', [
'init',
]); /* .stdout.pipe(process.stdout) */
await wait(300);
if (!exe || exe?.failed) {
spin.fail(
`${redBright('Failed')} to initialize git!` +
'\nMaybe you should run git init?'
);
return process.exit(1);
} else spin.succeed('Git initialized!');
return;
}
if (a.length === 17) {
return 'You do NOT need all intents!';
}
return true;
},
default: [3, 9],
};
}
const legacy_prefix = {
message: 'What is the legacy prefix for your bot?',
name: 'prefix',
type: 'input',
default: '!',
validate(a) {
if (a.length < 1) {
return 'You must choose a prefix!';
}
return true;
},
};
const kind_prefix = {
message:
'What kind of prefix your bot will use? Select "Both" for both prefixes.',
name: 'prefix',
type: 'list',
choices: [
{
name: 'Prefix [Message Based]',
value: 'legacy',
},
{
name: 'Interactions [Slash Commands, Context Menu Commands]',
value: 'app_cmds',
},
{
name: 'Both',
value: 'both',
type: 'choice',
},
],
};
async function whichLang() {
const a = await prompt([lang]);
return a;
const data = await prompt([
lang,
main_dir,
cmds_dir,
default_prefix,
token,
intent,
]);
console.log(data);
}
async function kindPrefix() {
const a = await prompt([kind_prefix]);
return a;
}
async function legacy() {
const a = await prompt([legacy_prefix]);
return a;
}
async function intents() {
const a = await prompt([intent]);
return a;
/**
* @param {number} ms
*/
async function wait(ms) {
const wait = (await import('util')).promisify(setTimeout);
return wait(ms);
}

17
src/commands/test.js Normal file
View File

@@ -0,0 +1,17 @@
//@ts-check
import { readFile, writeFile } from 'node:fs/promises';
import { findUp } from 'find-up';
/**
* @param {string} name
*/
export async function editMain(name) {
const pjLocation = await findUp('package.json');
const output = JSON.parse(await readFile(pjLocation, 'utf8'));
if (!output) throw new Error("Can't read file.");
output.main = name;
const result = () => writeFile(pjLocation, JSON.stringify(output, null, 2));
return result();
}

View File

@@ -1,19 +1,21 @@
#!/usr/bin/env node
import { init } from './commands/init.js';
const regex = /(?<=--|-)\w+/gm;
const flags = process.argv.slice(2).join(' ').match(regex);
// TODO codegolf it maybe? @HighArcs @jacoobes
const args = process.argv
.slice(2)
const rawArgs = process.argv.slice(2);
const args = rawArgs
.join(' ')
.trim()
.split(/ +/)
.filter((e) => !/(--|-)\w+/gm.test(e));
const cmdName = args[0];
const commands = new Map([['init', init]]);
const found = commands.get(cmdName);
if (found) {
await found({ args, flags });
} else console.log('Unknown Command // in future help maybe??');
} else console.log('Unknown Command');

102
src/prompts/init.js Normal file
View File

@@ -0,0 +1,102 @@
import { blueBright } from 'colorette';
// TODO refactor the intents stuff and add more questions
const Intents = [
'DIRECT_MESSAGES',
'DIRECT_MESSAGE_REACTIONS',
'DIRECT_MESSAGE_TYPING',
'GUILDS',
'GUILD_BANS',
'GUILD_EMOJIS_AND_STICKERS',
'GUILD_INTEGRATIONS',
'GUILD_INVITES',
'GUILD_MEMBERS',
'GUILD_MESSAGES',
'GUILD_MESSAGE_REACTIONS',
'GUILD_MESSAGE_TYPING',
'GUILD_PRESENCES',
'GUILD_SCHEDULED_EVENTS',
'GUILD_VOICE_STATES',
'GUILD_VOICE_STATES',
'GUILD_WEBHOOKS',
].map((i, j) => ({ title: i, value: j, short: `${j}` })); //! bad way
export const lang = {
message: 'What language you want the project to be in?',
name: 'lang',
type: 'select',
choices: [
{
title: 'JavaScript',
description: 'JS',
},
{
title: 'TypeScript',
description: 'TS',
},
],
};
export const intent = {
message: 'What intents do you want to keep?',
type: 'multiselect',
name: 'intents',
choices: Intents,
min: 1,
max: 16, //? 17 is max, i dont allow all
};
export const default_prefix = {
message:
'What is the default prefix for your bot? Type "none" if it is completely based on Application Commands',
name: 'prefix',
type: 'text',
initial: '!',
};
export const token = {
message: 'What is your bot token?',
name: 'token',
type: 'password',
validate: (/** @type {string} */ token) =>
token.match(
/(?<mfaToken>mfa\.[a-z0-9_-]{20,})|(?<basicToken>[a-z0-9_-]{23,28}\.[a-z0-9_-]{6,7}\.[a-z0-9_-]{27})/i
)?.length
? true
: 'Invalid token',
};
export const main_dir = {
message: 'What is the main directory of your project?',
name: 'main_dir',
type: 'text',
initial: 'src',
};
export const cmds_dir = {
message: 'What is the directory of your commands?',
name: 'cmds_dir',
type: 'text',
initial: 'commands',
validate: (dir) =>
dir === 'src' ? 'You can not use src as a directory' : true,
};
/**
* @type {import('prompts').PromptObject}
*/
export const npmInit = {
name: 'npminit',
type: 'confirm',
message: `Do you want to ${blueBright('me')} to initialize npm?`,
initial: true,
};
export const gitInit = {
name: 'gitinit',
type: 'confirm',
message: `Do you want to ${blueBright('me')} to initialize git?`,
initial: true,
};