mirror of
https://github.com/sern-handler/cli
synced 2026-06-21 07:12:23 +00:00
feat(*): more questions, better handling, better ui
This commit is contained in:
99
dumpfiles.js
Normal file
99
dumpfiles.js
Normal file
@@ -0,0 +1,99 @@
|
||||
//! message for sern devs: ignore this!!!
|
||||
|
||||
const SpinnerName = [
|
||||
'dots',
|
||||
'dots2',
|
||||
'dots3',
|
||||
'dots4',
|
||||
'dots5',
|
||||
'dots6',
|
||||
'dots7',
|
||||
'dots8',
|
||||
'dots9',
|
||||
'dots10',
|
||||
'dots11',
|
||||
'dots12',
|
||||
'dots8Bit',
|
||||
'line',
|
||||
'line2',
|
||||
'pipe',
|
||||
'simpleDots',
|
||||
'simpleDotsScrolling',
|
||||
'star',
|
||||
'star2',
|
||||
'flip',
|
||||
'hamburger',
|
||||
'growVertical',
|
||||
'growHorizontal',
|
||||
'balloon',
|
||||
'balloon2',
|
||||
'noise',
|
||||
'bounce',
|
||||
'boxBounce',
|
||||
'boxBounce2',
|
||||
'triangle',
|
||||
'arc',
|
||||
'circle',
|
||||
'squareCorners',
|
||||
'circleQuarters',
|
||||
'circleHalves',
|
||||
'squish',
|
||||
'toggle',
|
||||
'toggle2',
|
||||
'toggle3',
|
||||
'toggle4',
|
||||
'toggle5',
|
||||
'toggle6',
|
||||
'toggle7',
|
||||
'toggle8',
|
||||
'toggle9',
|
||||
'toggle10',
|
||||
'toggle11',
|
||||
'toggle12',
|
||||
'toggle13',
|
||||
'arrow',
|
||||
'arrow2',
|
||||
'arrow3',
|
||||
'bouncingBar',
|
||||
'bouncingBall',
|
||||
'smiley',
|
||||
'monkey',
|
||||
'hearts',
|
||||
'clock',
|
||||
'earth',
|
||||
'material',
|
||||
'moon',
|
||||
'runner',
|
||||
'pong',
|
||||
'shark',
|
||||
'dqpb',
|
||||
'weather',
|
||||
'christmas',
|
||||
'grenade',
|
||||
'point',
|
||||
'layer',
|
||||
'betaWave',
|
||||
'fingerDance',
|
||||
'fistBump',
|
||||
'soccerHeader',
|
||||
'mindblown',
|
||||
'speaker',
|
||||
'orangePulse',
|
||||
'bluePulse',
|
||||
'orangeBluePulse',
|
||||
'timeTravel',
|
||||
'aesthetic',
|
||||
];
|
||||
|
||||
// const p = new Promise((resolve) => {
|
||||
// SpinnerName.forEach((spin, i, ar) => {
|
||||
// setTimeout(() => {
|
||||
// spinner.spinner = spin;
|
||||
// spinner.text = `Initializing... ${spin}`;
|
||||
// if (i === ar.length - 1) {
|
||||
// resolve();
|
||||
// }
|
||||
// }, i * 1000);
|
||||
// });
|
||||
// });
|
||||
// p.then(() => spinner.succeed('Finished!'));
|
||||
2019
package-lock.json
generated
2019
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@sern-handler/cli",
|
||||
"name": "@sern/cli",
|
||||
"version": "0.1.0",
|
||||
"description": "A CLI for @sern-handler",
|
||||
"exports": "./src/index.js",
|
||||
@@ -8,7 +8,9 @@
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"release": "standard-version",
|
||||
"preview": "standard-version --dry-run"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -28,8 +30,11 @@
|
||||
},
|
||||
"homepage": "https://github.com/sern-handler/cli#readme",
|
||||
"dependencies": {
|
||||
"colorette": "^2.0.16",
|
||||
"execa": "^6.1.0",
|
||||
"find-up": "6.3.0",
|
||||
"inquirer": "8.2.2"
|
||||
"ora": "^6.1.0",
|
||||
"prompts": "2.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
|
||||
@@ -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
17
src/commands/test.js
Normal 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();
|
||||
}
|
||||
12
src/index.js
12
src/index.js
@@ -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
102
src/prompts/init.js
Normal 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,
|
||||
};
|
||||
Reference in New Issue
Block a user