mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-15 11:03:30 +01:00
feat: create-discord-bot (#9420)
* feat: basic initialisation * fix: no scope * chore: add options for issues * feat: good word, Monbrey * feat: basic README.md * fix: no documentation for this * feat: install for them * chore: update licencing * chore: fix year * fix: build tsup * feat: add TypeScript option * feat: add `name` option * chore: ignore annoying errors * chore: add tsconfig.json * refactor: remove name We can just use the name of the directory instead. * chore: update cliff jumper rc * chore: bump dependencies * chore: bump dependencies * fix: build in prepack * fix: configure ESLint correctly * feat: infer package manager * docs(packageManager): document `install()` * fix(packageManager): do not emit a warning for `npm` * refactor: change project name colour to yellow * docs(constants): basic documentation * feat: add link * chore: add `verbatimModuleSyntax` * chore: bump discord.js * refactor: switch to @sapphire/ts-config * refactor: file name changes * refactor: tweak description * chore: update yarn.lock * fix: add .env * chore: bump dependencies * feat: event handler * refactor: use `default` * refactor: simpler event * chore: bump discord.js * fix: add release script and reorder * style: reorder package.json * chore: remove unneeded ignores * chore: bump minimum Node.js version * chore: add @types/node to TypeScript package.json * chore: apply requested changes Co-authored-by: Noel <buechler.noel@outlook.com> * style: run ESLint + Prettier * refactor: prefer "the" * refactor: remove some comments * feat: add ESLint + Prettier * chore: requested changes Co-authored-by: Noel <buechler.noel@outlook.com> * chore: more requested changes Co-authored-by: Noel <buechler.noel@outlook.com> --------- Co-authored-by: Noel <buechler.noel@outlook.com>
This commit is contained in:
64
packages/create-discord-bot/src/create-discord-bot.ts
Executable file
64
packages/create-discord-bot/src/create-discord-bot.ts
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// eslint-disable-next-line n/shebang
|
||||
import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import { URL } from 'node:url';
|
||||
import chalk from 'chalk';
|
||||
import { program } from 'commander';
|
||||
import validateProjectName from 'validate-npm-package-name';
|
||||
import { install, resolvePackageManager } from './helpers/packageManager.js';
|
||||
import { GUIDE_URL } from './util/constants.js';
|
||||
|
||||
program
|
||||
.description('Create a basic discord.js bot.')
|
||||
.option('--typescript', 'Whether to use the TypeScript template.')
|
||||
.argument('<directory>', 'The directory where this will be created.')
|
||||
.parse();
|
||||
|
||||
const { typescript } = program.opts();
|
||||
const [directory] = program.args;
|
||||
|
||||
if (!directory) {
|
||||
console.error(chalk.red('Please specify the project directory.'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const root = path.resolve(directory);
|
||||
const directoryName = path.basename(root);
|
||||
|
||||
// We'll use the directory name as the project name. Check npm name validity.
|
||||
const validationResult = validateProjectName(directoryName);
|
||||
|
||||
if (!validationResult.validForNewPackages) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`Cannot create a project named ${chalk.yellow(`"${directoryName}"`)} due to npm naming restrictions.\n\nErrors:`,
|
||||
),
|
||||
);
|
||||
|
||||
for (const error of [...(validationResult.errors ?? []), ...(validationResult.warnings ?? [])]) {
|
||||
console.error(chalk.red(`- ${error}`));
|
||||
}
|
||||
|
||||
console.error(chalk.red('\nSee https://docs.npmjs.com/cli/configuring-npm/package-json for more details.'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!existsSync(root)) {
|
||||
mkdirSync(root, { recursive: true });
|
||||
}
|
||||
|
||||
console.log(`Creating ${directoryName} in ${chalk.green(root)}.`);
|
||||
cpSync(new URL(`../template/${typescript ? 'TypeScript' : 'JavaScript'}`, import.meta.url), root, { recursive: true });
|
||||
|
||||
process.chdir(root);
|
||||
|
||||
const newPackageJSON = readFileSync('./package.json', { encoding: 'utf8' }).replace('[REPLACE-NAME]', directoryName);
|
||||
writeFileSync('./package.json', newPackageJSON);
|
||||
|
||||
const packageManager = resolvePackageManager();
|
||||
install(packageManager);
|
||||
console.log(chalk.green('All done! Be sure to read through the discord.js guide for help on your journey.'));
|
||||
console.log(`Link: ${chalk.cyan(GUIDE_URL)}`);
|
||||
64
packages/create-discord-bot/src/helpers/packageManager.ts
Normal file
64
packages/create-discord-bot/src/helpers/packageManager.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { execSync } from 'node:child_process';
|
||||
import process from 'node:process';
|
||||
import chalk from 'chalk';
|
||||
import { DEFAULT_PACKAGE_MANAGER } from '../util/constants.js';
|
||||
|
||||
/**
|
||||
* A union of supported package managers.
|
||||
*/
|
||||
export type PackageManager = 'npm' | 'pnpm' | 'yarn';
|
||||
|
||||
/**
|
||||
* Resolves the package manager from `npm_config_user_agent`.
|
||||
*/
|
||||
export function resolvePackageManager(): PackageManager {
|
||||
const npmConfigUserAgent = process.env.npm_config_user_agent;
|
||||
|
||||
// If this is not present, return the default package manager.
|
||||
if (!npmConfigUserAgent) {
|
||||
return DEFAULT_PACKAGE_MANAGER;
|
||||
}
|
||||
|
||||
if (npmConfigUserAgent.startsWith('npm')) {
|
||||
return 'npm';
|
||||
}
|
||||
|
||||
if (npmConfigUserAgent.startsWith('yarn')) {
|
||||
return 'yarn';
|
||||
}
|
||||
|
||||
if (npmConfigUserAgent.startsWith('pnpm')) {
|
||||
return 'pnpm';
|
||||
}
|
||||
|
||||
console.error(
|
||||
chalk.yellow(
|
||||
`Detected an unsupported package manager (${npmConfigUserAgent}). Falling back to ${DEFAULT_PACKAGE_MANAGER}.`,
|
||||
),
|
||||
);
|
||||
|
||||
// Fallback to the default package manager.
|
||||
return DEFAULT_PACKAGE_MANAGER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs with a provided package manager.
|
||||
*
|
||||
* @param packageManager - The package manager to use
|
||||
*/
|
||||
export function install(packageManager: PackageManager) {
|
||||
let installCommand;
|
||||
|
||||
switch (packageManager) {
|
||||
case 'npm':
|
||||
case 'pnpm':
|
||||
installCommand = `${packageManager} install`;
|
||||
break;
|
||||
case 'yarn':
|
||||
installCommand = packageManager;
|
||||
break;
|
||||
}
|
||||
|
||||
console.log(`Installing dependencies with ${packageManager}...`);
|
||||
execSync(installCommand);
|
||||
}
|
||||
9
packages/create-discord-bot/src/util/constants.ts
Normal file
9
packages/create-discord-bot/src/util/constants.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* The default package manager.
|
||||
*/
|
||||
export const DEFAULT_PACKAGE_MANAGER = 'npm' as const;
|
||||
|
||||
/**
|
||||
* The URL to the guide.
|
||||
*/
|
||||
export const GUIDE_URL = 'https://guide.discordjs.dev' as const;
|
||||
Reference in New Issue
Block a user