create-commandkit 1.2.0-rc.12 → 1.2.0-rc.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{COPYING.md → LICENSE.md} +3 -3
- package/README.md +73 -4
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +39 -0
- package/dist/functions/fetchExample.d.ts +6 -0
- package/dist/functions/fetchExample.js +63 -0
- package/dist/functions/validate.d.ts +12 -0
- package/dist/functions/validate.js +70 -0
- package/dist/index.js +188 -86
- package/dist/types.d.ts +15 -1
- package/dist/utils.d.ts +20 -7
- package/dist/utils.js +75 -23
- package/package.json +12 -8
- package/dist/functions/copyTemplates.d.ts +0 -5
- package/dist/functions/copyTemplates.js +0 -47
- package/dist/functions/installDeps.d.ts +0 -10
- package/dist/functions/installDeps.js +0 -49
- package/dist/functions/setup.d.ts +0 -10
- package/dist/functions/setup.js +0 -68
- package/templates/JavaScript/README.md +0 -16
- package/templates/JavaScript/commandkit-env.d.ts +0 -1
- package/templates/JavaScript/commandkit.config.mjs +0 -3
- package/templates/JavaScript/jsconfig.json +0 -30
- package/templates/JavaScript/src/app/commands/ping.js +0 -27
- package/templates/JavaScript/src/app/events/clientReady/log.js +0 -10
- package/templates/JavaScript/src/app.js +0 -7
- package/templates/TypeScript/README.md +0 -16
- package/templates/TypeScript/commandkit-env.d.ts +0 -1
- package/templates/TypeScript/commandkit.config.ts +0 -3
- package/templates/TypeScript/src/app/commands/ping.ts +0 -20
- package/templates/TypeScript/src/app/events/clientReady/log.ts +0 -8
- package/templates/TypeScript/src/app.ts +0 -7
- package/templates/TypeScript/tsconfig.json +0 -29
|
@@ -639,8 +639,8 @@ attach them to the start of each source file to most effectively state
|
|
|
639
639
|
the exclusion of warranty; and each file should have at least the
|
|
640
640
|
"copyright" line and a pointer to where the full notice is found.
|
|
641
641
|
|
|
642
|
-
|
|
643
|
-
Copyright (C)
|
|
642
|
+
CommandKit is a discord.js metaframework
|
|
643
|
+
Copyright (C) 2026 Neplex
|
|
644
644
|
|
|
645
645
|
This program is free software: you can redistribute it and/or modify
|
|
646
646
|
it under the terms of the GNU General Public License as published by
|
|
@@ -661,7 +661,7 @@ mail.
|
|
|
661
661
|
If the program does terminal interaction, make it output a short
|
|
662
662
|
notice like this when it starts in an interactive mode:
|
|
663
663
|
|
|
664
|
-
|
|
664
|
+
CommandKit Copyright (C) 2026 Neplex
|
|
665
665
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
666
666
|
This is free software, and you are welcome to redistribute it
|
|
667
667
|
under certain conditions; type `show c' for details.
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<img src="https://raw.githubusercontent.com/
|
|
2
|
+
<img src="https://raw.githubusercontent.com/neplextech/commandkit/main/apps/website/static/img/ckit_logo.svg" width="60%" />
|
|
3
3
|
<br />
|
|
4
|
-
<a href="https://
|
|
4
|
+
<a href="https://commandkit.dev/discord"><img src="https://img.shields.io/discord/1055188344188973066?color=5865F2&logo=discord&logoColor=white" alt="support server" /></a>
|
|
5
5
|
<a href="https://www.npmjs.com/package/create-commandkit"><img src="https://img.shields.io/npm/v/create-commandkit?maxAge=3600" alt="npm version" /></a>
|
|
6
6
|
<a href="https://www.npmjs.com/package/create-commandkit"><img src="https://img.shields.io/npm/dt/create-commandkit?maxAge=3600" alt="npm downloads" /></a>
|
|
7
7
|
</div>
|
|
@@ -14,6 +14,9 @@ create-commandkit is a CLI utility to quickly instantiate a Discord bot with Com
|
|
|
14
14
|
|
|
15
15
|
- Interactive, beautiful command-line interface 🖥️
|
|
16
16
|
- Supports CommonJS and ES Modules 📦
|
|
17
|
+
- Dynamic template system with examples from GitHub 🚀
|
|
18
|
+
- Support for all major package managers (npm, pnpm, yarn, bun, deno) 📦
|
|
19
|
+
- TypeScript and JavaScript support 🔧
|
|
17
20
|
|
|
18
21
|
## Documentation
|
|
19
22
|
|
|
@@ -21,12 +24,78 @@ You can find the full documentation [here](https://commandkit.dev).
|
|
|
21
24
|
|
|
22
25
|
## Usage
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
### Basic Usage
|
|
25
28
|
|
|
26
29
|
```sh
|
|
27
30
|
npx create-commandkit@latest
|
|
28
31
|
```
|
|
29
32
|
|
|
33
|
+
### With Project Name
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
npx create-commandkit@latest my-bot
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Using Examples
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
# Use a curated example
|
|
43
|
+
npx create-commandkit@latest --example with-database
|
|
44
|
+
|
|
45
|
+
# Use a custom GitHub repository
|
|
46
|
+
npx create-commandkit@latest --example "https://github.com/user/repo"
|
|
47
|
+
|
|
48
|
+
# Use a specific path within a repository
|
|
49
|
+
npx create-commandkit@latest --example "https://github.com/user/repo" --example-path "examples/bot"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### CLI Options
|
|
53
|
+
|
|
54
|
+
- `-h, --help` - Show all available options
|
|
55
|
+
- `-V, --version` - Output the version number
|
|
56
|
+
- `-e, --example <name-or-url>` - An example to bootstrap the app with
|
|
57
|
+
- `--example-path <path>` - Specify the path to the example separately
|
|
58
|
+
- `--use-npm` - Use npm as package manager
|
|
59
|
+
- `--use-pnpm` - Use pnpm as package manager
|
|
60
|
+
- `--use-yarn` - Use yarn as package manager
|
|
61
|
+
- `--use-bun` - Use bun as package manager
|
|
62
|
+
- `--use-deno` - Use deno as package manager
|
|
63
|
+
- `--skip-install` - Skip installing packages
|
|
64
|
+
- `--no-git` - Skip git initialization
|
|
65
|
+
- `--yes` - Use defaults for all options
|
|
66
|
+
- `--list-examples` - List all available examples from the official repository
|
|
67
|
+
|
|
68
|
+
### Available Examples
|
|
69
|
+
|
|
70
|
+
<!-- BEGIN_AVAILABLE_EXAMPLES -->
|
|
71
|
+
- `basic-js` - [examples/basic-js](https://github.com/neplextech/commandkit/tree/main/examples/basic-js)
|
|
72
|
+
- `basic-ts` - [examples/basic-ts](https://github.com/neplextech/commandkit/tree/main/examples/basic-ts)
|
|
73
|
+
- `deno-ts` - [examples/deno-ts](https://github.com/neplextech/commandkit/tree/main/examples/deno-ts)
|
|
74
|
+
- `with-ai` - [examples/with-ai](https://github.com/neplextech/commandkit/tree/main/examples/with-ai)
|
|
75
|
+
- `with-leveling-system` - [examples/with-leveling-system](https://github.com/neplextech/commandkit/tree/main/examples/with-leveling-system)
|
|
76
|
+
- `with-workflow` - [examples/with-workflow](https://github.com/neplextech/commandkit/tree/main/examples/with-workflow)
|
|
77
|
+
- `without-cli` - [examples/without-cli](https://github.com/neplextech/commandkit/tree/main/examples/without-cli)
|
|
78
|
+
<!-- END_AVAILABLE_EXAMPLES -->
|
|
79
|
+
|
|
80
|
+
### Examples
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
# Create a basic TypeScript bot, skip installation
|
|
84
|
+
npx create-commandkit@latest --example basic-ts --skip-install
|
|
85
|
+
|
|
86
|
+
# Create a bot with all defaults (no prompts)
|
|
87
|
+
npx create-commandkit@latest --yes
|
|
88
|
+
|
|
89
|
+
# Create a bot from custom repository
|
|
90
|
+
npx create-commandkit@latest --example "https://github.com/username/my-commandkit-template"
|
|
91
|
+
|
|
92
|
+
# Create a bot with pnpm
|
|
93
|
+
npx create-commandkit@latest --use-pnpm
|
|
94
|
+
|
|
95
|
+
# List all available examples
|
|
96
|
+
npx create-commandkit@latest --list-examples
|
|
97
|
+
```
|
|
98
|
+
|
|
30
99
|
## Support and Suggestions
|
|
31
100
|
|
|
32
|
-
Submit any queries or suggestions in our [Discord community](https://
|
|
101
|
+
Submit any queries or suggestions in our [Discord community](https://commandkit.dev/discord).
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export function parseCLI() {
|
|
3
|
+
const program = new Command();
|
|
4
|
+
program
|
|
5
|
+
.name('create-commandkit')
|
|
6
|
+
.description('Effortlessly create a CommandKit project')
|
|
7
|
+
.version(process.env.npm_package_version || '1.0.0')
|
|
8
|
+
.argument('[project-directory]', 'Project directory name')
|
|
9
|
+
.option('-h, --help', 'Show all available options')
|
|
10
|
+
.option('-e, --example <name-or-url>', 'An example to bootstrap the app with')
|
|
11
|
+
.option('--example-path <path>', 'Specify the path to the example separately')
|
|
12
|
+
.option('--use-npm', 'Explicitly tell the CLI to bootstrap using npm')
|
|
13
|
+
.option('--use-pnpm', 'Explicitly tell the CLI to bootstrap using pnpm')
|
|
14
|
+
.option('--use-yarn', 'Explicitly tell the CLI to bootstrap using yarn')
|
|
15
|
+
.option('--use-bun', 'Explicitly tell the CLI to bootstrap using bun')
|
|
16
|
+
.option('--use-deno', 'Explicitly tell the CLI to bootstrap using deno')
|
|
17
|
+
.option('--skip-install', 'Explicitly tell the CLI to skip installing packages')
|
|
18
|
+
.option('--no-git', 'Explicitly tell the CLI to disable git initialization')
|
|
19
|
+
.option('--yes', 'Use previous preferences or defaults for all options')
|
|
20
|
+
.option('--list-examples', 'List all available examples from the official repository');
|
|
21
|
+
program.parse();
|
|
22
|
+
const options = program.opts();
|
|
23
|
+
const args = program.args;
|
|
24
|
+
return {
|
|
25
|
+
help: options.help,
|
|
26
|
+
example: options.example,
|
|
27
|
+
examplePath: options.examplePath,
|
|
28
|
+
useNpm: options.useNpm,
|
|
29
|
+
usePnpm: options.usePnpm,
|
|
30
|
+
useYarn: options.useYarn,
|
|
31
|
+
useBun: options.useBun,
|
|
32
|
+
useDeno: options.useDeno,
|
|
33
|
+
skipInstall: options.skipInstall,
|
|
34
|
+
noGit: options.noGit,
|
|
35
|
+
yes: options.yes,
|
|
36
|
+
listExamples: options.listExamples,
|
|
37
|
+
projectDirectory: args[0],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import tiged from 'tiged';
|
|
5
|
+
import { validateExampleName } from './validate.js';
|
|
6
|
+
export async function fetchExample({ example, examplePath, targetDir, }) {
|
|
7
|
+
const validation = validateExampleName(example);
|
|
8
|
+
if (!validation.valid) {
|
|
9
|
+
throw new Error(validation.error);
|
|
10
|
+
}
|
|
11
|
+
let sourceUrl;
|
|
12
|
+
// Check if it's a GitHub URL
|
|
13
|
+
if (example.startsWith('http://') || example.startsWith('https://')) {
|
|
14
|
+
sourceUrl = example;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
// Construct URL for curated examples
|
|
18
|
+
sourceUrl = `neplextech/commandkit/examples/${example}`;
|
|
19
|
+
}
|
|
20
|
+
// Create temporary directory for download
|
|
21
|
+
const tempDir = path.join(targetDir, '.temp-example');
|
|
22
|
+
try {
|
|
23
|
+
// Download the example
|
|
24
|
+
const emitter = tiged(sourceUrl, {
|
|
25
|
+
mode: 'tar',
|
|
26
|
+
disableCache: true,
|
|
27
|
+
});
|
|
28
|
+
await emitter.clone(tempDir);
|
|
29
|
+
// If examplePath is specified, navigate to that subdirectory
|
|
30
|
+
const sourceDir = examplePath ? path.join(tempDir, examplePath) : tempDir;
|
|
31
|
+
if (examplePath && !fs.existsSync(sourceDir)) {
|
|
32
|
+
throw new Error(`Example path '${examplePath}' not found in the repository`);
|
|
33
|
+
}
|
|
34
|
+
// Copy contents to target directory
|
|
35
|
+
const contents = fs.readdirSync(sourceDir);
|
|
36
|
+
for (const item of contents) {
|
|
37
|
+
const srcPath = path.join(sourceDir, item);
|
|
38
|
+
const destPath = path.join(targetDir, item);
|
|
39
|
+
if (fs.statSync(srcPath).isDirectory()) {
|
|
40
|
+
await fs.copy(srcPath, destPath);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
await fs.copy(srcPath, destPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Clean up temporary directory
|
|
47
|
+
await fs.remove(tempDir);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
// Clean up on error
|
|
51
|
+
if (fs.existsSync(tempDir)) {
|
|
52
|
+
await fs.remove(tempDir);
|
|
53
|
+
}
|
|
54
|
+
if (error instanceof Error) {
|
|
55
|
+
if (error.message.includes('not found') ||
|
|
56
|
+
error.message.includes('404')) {
|
|
57
|
+
throw new Error(`Example '${example}' not found. Available examples: basic-ts, basic-js, deno-ts, without-cli`);
|
|
58
|
+
}
|
|
59
|
+
throw new Error(`Failed to fetch example: ${error.message}`);
|
|
60
|
+
}
|
|
61
|
+
throw new Error('Failed to fetch example due to an unknown error');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function validateProjectName(name: string): {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
error?: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function validateDirectory(dir: string): {
|
|
6
|
+
valid: boolean;
|
|
7
|
+
error?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function validateExampleName(example: string): {
|
|
10
|
+
valid: boolean;
|
|
11
|
+
error?: string;
|
|
12
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import validateNpmPackageName from 'validate-npm-package-name';
|
|
4
|
+
export function validateProjectName(name) {
|
|
5
|
+
const result = validateNpmPackageName(name);
|
|
6
|
+
if (!result.validForNewPackages) {
|
|
7
|
+
const errors = result.errors || [];
|
|
8
|
+
const warnings = result.warnings || [];
|
|
9
|
+
const allIssues = [...errors, ...warnings];
|
|
10
|
+
return {
|
|
11
|
+
valid: false,
|
|
12
|
+
error: allIssues.length > 0 ? allIssues[0] : 'Invalid project name',
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
return { valid: true };
|
|
16
|
+
}
|
|
17
|
+
export function validateDirectory(dir) {
|
|
18
|
+
const resolvedDir = path.resolve(process.cwd(), dir);
|
|
19
|
+
try {
|
|
20
|
+
const exists = fs.existsSync(resolvedDir);
|
|
21
|
+
if (!exists) {
|
|
22
|
+
return { valid: true };
|
|
23
|
+
}
|
|
24
|
+
const contents = fs.readdirSync(resolvedDir);
|
|
25
|
+
const isEmpty = contents.length === 0;
|
|
26
|
+
if (!isEmpty) {
|
|
27
|
+
return {
|
|
28
|
+
valid: false,
|
|
29
|
+
error: 'Directory is not empty!',
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return { valid: true };
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
return {
|
|
36
|
+
valid: false,
|
|
37
|
+
error: 'Unable to access directory',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function validateExampleName(example) {
|
|
42
|
+
// Check if it's a GitHub URL
|
|
43
|
+
if (example.startsWith('http://') || example.startsWith('https://')) {
|
|
44
|
+
try {
|
|
45
|
+
const url = new URL(example);
|
|
46
|
+
if (url.hostname === 'github.com' || url.hostname === 'www.github.com') {
|
|
47
|
+
return { valid: true };
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
valid: false,
|
|
51
|
+
error: 'Only GitHub URLs are supported',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return {
|
|
56
|
+
valid: false,
|
|
57
|
+
error: 'Invalid URL format',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Check if it's a valid example name (alphanumeric, hyphens, underscores)
|
|
62
|
+
const exampleNameRegex = /^[a-zA-Z0-9-_]+$/;
|
|
63
|
+
if (!exampleNameRegex.test(example)) {
|
|
64
|
+
return {
|
|
65
|
+
valid: false,
|
|
66
|
+
error: 'Example name can only contain letters, numbers, hyphens, and underscores',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return { valid: true };
|
|
70
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,107 +1,209 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { confirm, intro, outro, password, select, text } from '@clack/prompts';
|
|
2
|
+
import { confirm, intro, outro, password, text } from '@clack/prompts';
|
|
4
3
|
import fs from 'fs-extra';
|
|
5
4
|
import gradient from 'gradient-string';
|
|
6
5
|
import { execSync } from 'node:child_process';
|
|
7
|
-
import path from 'node:path';
|
|
6
|
+
import path, { join } from 'node:path';
|
|
8
7
|
import colors from 'picocolors';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
import { parseCLI } from './cli.js';
|
|
9
|
+
import { fetchExample } from './functions/fetchExample.js';
|
|
10
|
+
import { validateDirectory, validateProjectName, } from './functions/validate.js';
|
|
11
|
+
import { fetchAvailableExamples, getDefaultExample, getInstallCommand, isOfficialExample, resolvePackageManager, textColors, } from './utils.js';
|
|
12
|
+
import { readFile } from 'node:fs/promises';
|
|
13
|
+
async function main() {
|
|
14
|
+
const cliOptions = parseCLI();
|
|
15
|
+
// Handle help and version flags
|
|
16
|
+
if (cliOptions.help) {
|
|
17
|
+
console.log(`
|
|
18
|
+
Usage: create-commandkit [options] [project-directory]
|
|
19
|
+
|
|
20
|
+
Options:
|
|
21
|
+
-h, --help Show all available options
|
|
22
|
+
-V, --version Output the version number
|
|
23
|
+
-e, --example <name-or-url> An example to bootstrap the app with
|
|
24
|
+
--example-path <path> Specify the path to the example separately
|
|
25
|
+
--use-npm Explicitly tell the CLI to bootstrap using npm
|
|
26
|
+
--use-pnpm Explicitly tell the CLI to bootstrap using pnpm
|
|
27
|
+
--use-yarn Explicitly tell the CLI to bootstrap using yarn
|
|
28
|
+
--use-bun Explicitly tell the CLI to bootstrap using bun
|
|
29
|
+
--use-deno Explicitly tell the CLI to bootstrap using deno
|
|
30
|
+
--skip-install Explicitly tell the CLI to skip installing packages
|
|
31
|
+
--no-git Explicitly tell the CLI to disable git initialization
|
|
32
|
+
--yes Use previous preferences or defaults for all options
|
|
33
|
+
--list-examples List all available examples from the official repository
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
npx create-commandkit@latest
|
|
37
|
+
npx create-commandkit@latest my-bot
|
|
38
|
+
npx create-commandkit@latest --example basic-ts
|
|
39
|
+
npx create-commandkit@latest --example "https://github.com/user/repo" --example-path "examples/bot"
|
|
40
|
+
npx create-commandkit@latest --use-pnpm --yes
|
|
41
|
+
npx create-commandkit@latest --list-examples
|
|
42
|
+
`);
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
// Handle list examples flag
|
|
46
|
+
if (cliOptions.listExamples) {
|
|
47
|
+
console.log(colors.cyan('Fetching available examples...'));
|
|
22
48
|
try {
|
|
23
|
-
const
|
|
24
|
-
|
|
49
|
+
const examples = await fetchAvailableExamples();
|
|
50
|
+
console.log(colors.green('\nAvailable examples:'));
|
|
51
|
+
console.log('');
|
|
52
|
+
for (const example of examples) {
|
|
53
|
+
console.log(` ${colors.magenta(example)}`);
|
|
54
|
+
}
|
|
55
|
+
console.log('');
|
|
56
|
+
console.log(colors.gray('Usage: npx create-commandkit@latest --example <example-name>'));
|
|
57
|
+
console.log(colors.gray('Example: npx create-commandkit@latest --example basic-ts'));
|
|
25
58
|
}
|
|
26
|
-
catch {
|
|
27
|
-
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error(colors.red('Failed to fetch examples list. Please check your internet connection.'));
|
|
61
|
+
process.exit(1);
|
|
28
62
|
}
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
process.exit(0);
|
|
64
|
+
}
|
|
65
|
+
const commandkitGradient = gradient(textColors.commandkit)('CommandKit');
|
|
66
|
+
intro(`Welcome to ${commandkitGradient}!`);
|
|
67
|
+
// Determine project directory
|
|
68
|
+
let projectDir;
|
|
69
|
+
if (cliOptions.projectDirectory) {
|
|
70
|
+
projectDir = path.resolve(process.cwd(), cliOptions.projectDirectory);
|
|
71
|
+
// Validate project name if provided
|
|
72
|
+
const projectName = path.basename(projectDir);
|
|
73
|
+
const nameValidation = validateProjectName(projectName);
|
|
74
|
+
if (!nameValidation.valid) {
|
|
75
|
+
console.error(colors.red(`Error: ${nameValidation.error}`));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (cliOptions.yes) {
|
|
80
|
+
projectDir = path.resolve(process.cwd(), 'commandkit-project');
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
projectDir = path.resolve(process.cwd(), (await text({
|
|
84
|
+
message: 'Enter a project directory:',
|
|
85
|
+
placeholder: 'Leave blank for current directory',
|
|
86
|
+
defaultValue: '.',
|
|
87
|
+
validate: (value) => {
|
|
88
|
+
value = path.resolve(process.cwd(), value);
|
|
89
|
+
const validation = validateDirectory(value);
|
|
90
|
+
return validation.valid ? undefined : validation.error;
|
|
91
|
+
},
|
|
92
|
+
})));
|
|
93
|
+
}
|
|
94
|
+
// Validate directory
|
|
95
|
+
const dirValidation = validateDirectory(projectDir);
|
|
96
|
+
if (!dirValidation.valid) {
|
|
97
|
+
console.error(colors.red(`Error: ${dirValidation.error}`));
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
// Get Discord token
|
|
101
|
+
let token;
|
|
102
|
+
if (cliOptions.yes) {
|
|
103
|
+
token = '';
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
token = (await password({
|
|
107
|
+
message: 'Enter your Discord bot token (stored in .env, optional):',
|
|
108
|
+
mask: colors.gray('*'),
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
// Determine git initialization
|
|
112
|
+
const gitInit = cliOptions.noGit
|
|
113
|
+
? false
|
|
114
|
+
: cliOptions.yes
|
|
115
|
+
? true
|
|
116
|
+
: await confirm({
|
|
117
|
+
message: 'Initialize a git repository?',
|
|
118
|
+
initialValue: true,
|
|
119
|
+
});
|
|
120
|
+
outro(colors.cyan('Setup complete.'));
|
|
121
|
+
const example = cliOptions.example || getDefaultExample(cliOptions);
|
|
122
|
+
// Determine package manager
|
|
123
|
+
const manager = resolvePackageManager(cliOptions, example);
|
|
124
|
+
// Fetch example from GitHub
|
|
67
125
|
try {
|
|
68
|
-
|
|
126
|
+
await fetchExample({
|
|
127
|
+
example,
|
|
128
|
+
examplePath: cliOptions.examplePath,
|
|
129
|
+
targetDir: projectDir,
|
|
130
|
+
});
|
|
131
|
+
// Create .env file with token
|
|
132
|
+
await fs.writeFile(`${projectDir}/.env`, `DISCORD_TOKEN="${token || ''}"`);
|
|
133
|
+
// Install packages for official examples
|
|
134
|
+
if (isOfficialExample(example) && !cliOptions.skipInstall) {
|
|
135
|
+
console.log(colors.cyan('Installing dependencies for official example...'));
|
|
136
|
+
try {
|
|
137
|
+
const tagMap = [
|
|
138
|
+
['-dev.', 'dev'],
|
|
139
|
+
['-rc.', 'next'],
|
|
140
|
+
];
|
|
141
|
+
const tag = await readFile(join(import.meta.dirname, '..', 'package.json'), 'utf-8')
|
|
142
|
+
.then((data) => {
|
|
143
|
+
const version = JSON.parse(data).version;
|
|
144
|
+
return (tagMap.find(([suffix]) => version.includes(suffix))?.[1] ||
|
|
145
|
+
'latest');
|
|
146
|
+
})
|
|
147
|
+
.catch(() => 'latest');
|
|
148
|
+
// Install dependencies
|
|
149
|
+
const depsCommand = getInstallCommand(manager, [
|
|
150
|
+
`commandkit@${tag}`,
|
|
151
|
+
'discord.js',
|
|
152
|
+
]);
|
|
153
|
+
execSync(depsCommand, { cwd: projectDir, stdio: 'pipe' });
|
|
154
|
+
// Install dev dependencies
|
|
155
|
+
const devDepsCommand = getInstallCommand(manager, ['typescript', '@types/node'], true);
|
|
156
|
+
execSync(devDepsCommand, { cwd: projectDir, stdio: 'pipe' });
|
|
157
|
+
console.log(colors.green('Dependencies installed successfully!'));
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
console.log(colors.yellow('Warning: Failed to install dependencies. You may need to install them manually.'));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
69
163
|
}
|
|
70
164
|
catch (error) {
|
|
71
|
-
console.
|
|
165
|
+
console.error(colors.red(`Error fetching example: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
166
|
+
process.exit(1);
|
|
72
167
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
switch (manager) {
|
|
82
|
-
case 'npm':
|
|
83
|
-
// bun build runs bundler instead of the build script
|
|
84
|
-
case 'bun':
|
|
85
|
-
return `${manager} run ${cmd}`;
|
|
86
|
-
case 'pnpm':
|
|
87
|
-
case 'yarn':
|
|
88
|
-
return `${manager} ${cmd}`;
|
|
89
|
-
case 'deno':
|
|
90
|
-
return `deno task ${cmd}`;
|
|
91
|
-
default:
|
|
92
|
-
return manager;
|
|
168
|
+
// Initialize git if requested
|
|
169
|
+
if (gitInit) {
|
|
170
|
+
try {
|
|
171
|
+
execSync('git init', { cwd: projectDir, stdio: 'pipe' });
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
console.log(colors.yellow('Warning: Git initialization failed. Make sure Git is installed on your system.'));
|
|
175
|
+
}
|
|
93
176
|
}
|
|
94
|
-
|
|
95
|
-
|
|
177
|
+
const command = (cmd) => {
|
|
178
|
+
switch (manager) {
|
|
179
|
+
case 'npm':
|
|
180
|
+
// bun build runs bundler instead of the build script
|
|
181
|
+
case 'bun':
|
|
182
|
+
return `${manager} run ${cmd}`;
|
|
183
|
+
case 'pnpm':
|
|
184
|
+
case 'yarn':
|
|
185
|
+
return `${manager} ${cmd}`;
|
|
186
|
+
case 'deno':
|
|
187
|
+
return `deno task ${cmd}`;
|
|
188
|
+
default:
|
|
189
|
+
return manager;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
console.log(`${gradient(textColors.commandkit)('Thank you for choosing CommandKit!')}
|
|
96
193
|
|
|
97
|
-
To start your bot
|
|
194
|
+
To start your bot${projectDir !== '.' ? `, ${colors.magenta(`cd ${projectDir}`)}` : ''}${projectDir !== '.' ? ' and' : ''} use the following commands:
|
|
98
195
|
${colors.magenta(command('dev'))} - Run your bot in development mode
|
|
99
196
|
${colors.magenta(command('build'))} - Build your bot for production
|
|
100
197
|
${colors.magenta(command('start'))} - Run your bot in production mode
|
|
101
198
|
|
|
102
199
|
• Documentation: ${colors.blue('https://commandkit.dev')}
|
|
103
|
-
• GitHub: ${colors.blue('https://github.com/
|
|
104
|
-
•
|
|
105
|
-
• Discord community: ${colors.blue('https://
|
|
200
|
+
• GitHub: ${colors.blue('https://github.com/neplextech/commandkit')}
|
|
201
|
+
• Neplex: ${colors.blue('https://neplextech.com')}
|
|
202
|
+
• Discord community: ${colors.blue('https://commandkit.dev/discord')}
|
|
106
203
|
|
|
107
204
|
Happy coding! 🚀`);
|
|
205
|
+
}
|
|
206
|
+
main().catch((error) => {
|
|
207
|
+
console.error(colors.red(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
208
|
+
process.exit(1);
|
|
209
|
+
});
|
package/dist/types.d.ts
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
export type Language = 'js' | 'ts';
|
|
2
1
|
export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'deno';
|
|
2
|
+
export interface CLIOptions {
|
|
3
|
+
help?: boolean;
|
|
4
|
+
example?: string;
|
|
5
|
+
examplePath?: string;
|
|
6
|
+
useNpm?: boolean;
|
|
7
|
+
usePnpm?: boolean;
|
|
8
|
+
useYarn?: boolean;
|
|
9
|
+
useBun?: boolean;
|
|
10
|
+
useDeno?: boolean;
|
|
11
|
+
skipInstall?: boolean;
|
|
12
|
+
noGit?: boolean;
|
|
13
|
+
yes?: boolean;
|
|
14
|
+
listExamples?: boolean;
|
|
15
|
+
projectDirectory?: string;
|
|
16
|
+
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
|
-
import type { PackageManager } from './types';
|
|
1
|
+
import type { CLIOptions, PackageManager } from './types';
|
|
2
2
|
export declare const textColors: {
|
|
3
3
|
commandkit: string[];
|
|
4
4
|
js: string[];
|
|
5
5
|
ts: string[];
|
|
6
6
|
};
|
|
7
|
-
export declare const commands: {
|
|
8
|
-
init: {
|
|
9
|
-
yarn: string;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
7
|
export declare function detectPackageManager(): PackageManager;
|
|
13
|
-
export declare function
|
|
8
|
+
export declare function getPackageManagerFromCLI(options: {
|
|
9
|
+
useNpm?: boolean;
|
|
10
|
+
usePnpm?: boolean;
|
|
11
|
+
useYarn?: boolean;
|
|
12
|
+
useBun?: boolean;
|
|
13
|
+
useDeno?: boolean;
|
|
14
|
+
}): PackageManager | null;
|
|
15
|
+
export declare function resolvePackageManager(cliOptions: {
|
|
16
|
+
useNpm?: boolean;
|
|
17
|
+
usePnpm?: boolean;
|
|
18
|
+
useYarn?: boolean;
|
|
19
|
+
useBun?: boolean;
|
|
20
|
+
useDeno?: boolean;
|
|
21
|
+
}, name: string): PackageManager;
|
|
22
|
+
export declare function getDefaultExample(cliOptions: CLIOptions): string;
|
|
23
|
+
export declare function isOfficialExample(example: string): boolean;
|
|
24
|
+
export declare function getInstallCommand(manager: PackageManager, deps: string[], dev?: boolean): string;
|
|
25
|
+
export declare function fetchAvailableExamples(): Promise<string[]>;
|
|
26
|
+
export declare function isDenoProject(example: string): boolean;
|
package/dist/utils.js
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
1
|
export const textColors = {
|
|
5
2
|
commandkit: ['#fdba74', '#e4a5a2', '#c288de', '#b27bf9'],
|
|
6
3
|
js: ['#f7e01c', '#f7e01c'],
|
|
7
4
|
ts: ['#2480c5', '#2480c5'],
|
|
8
5
|
};
|
|
9
|
-
export const commands = {
|
|
10
|
-
init: {
|
|
11
|
-
yarn: 'yarn set version stable; yarn config set nodeLinker node-modules;',
|
|
12
|
-
},
|
|
13
|
-
};
|
|
14
6
|
export function detectPackageManager() {
|
|
15
7
|
const packageManager = process.env.npm_config_user_agent;
|
|
16
8
|
if (packageManager?.includes('pnpm'))
|
|
@@ -25,25 +17,85 @@ export function detectPackageManager() {
|
|
|
25
17
|
return 'deno';
|
|
26
18
|
return 'npm';
|
|
27
19
|
}
|
|
28
|
-
export function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
20
|
+
export function getPackageManagerFromCLI(options) {
|
|
21
|
+
if (options.useNpm)
|
|
22
|
+
return 'npm';
|
|
23
|
+
if (options.usePnpm)
|
|
24
|
+
return 'pnpm';
|
|
25
|
+
if (options.useYarn)
|
|
26
|
+
return 'yarn';
|
|
27
|
+
if (options.useBun)
|
|
28
|
+
return 'bun';
|
|
29
|
+
if (options.useDeno)
|
|
30
|
+
return 'deno';
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
export function resolvePackageManager(cliOptions, name) {
|
|
34
|
+
const cliManager = getPackageManagerFromCLI(cliOptions);
|
|
35
|
+
return cliManager || (isDenoProject(name) ? 'deno' : detectPackageManager());
|
|
36
|
+
}
|
|
37
|
+
export function getDefaultExample(cliOptions) {
|
|
38
|
+
if (cliOptions.useDeno) {
|
|
39
|
+
return 'deno-ts';
|
|
40
|
+
}
|
|
41
|
+
return 'basic-ts';
|
|
42
|
+
}
|
|
43
|
+
export function isOfficialExample(example) {
|
|
44
|
+
// Check if it's a GitHub URL pointing to neplextech/commandkit
|
|
45
|
+
if (example.startsWith('http://') || example.startsWith('https://')) {
|
|
46
|
+
try {
|
|
47
|
+
const url = new URL(example);
|
|
48
|
+
return (url.hostname === 'github.com' &&
|
|
49
|
+
url.pathname.startsWith('/neplextech/commandkit'));
|
|
37
50
|
}
|
|
38
|
-
|
|
39
|
-
return
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
40
53
|
}
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
}
|
|
55
|
+
// If it's just an example name, it's official
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
export function getInstallCommand(manager, deps, dev = false) {
|
|
59
|
+
switch (manager) {
|
|
60
|
+
case 'npm':
|
|
61
|
+
case 'pnpm':
|
|
62
|
+
case 'yarn':
|
|
63
|
+
case 'bun':
|
|
64
|
+
return `${manager} add ${dev ? '-D' : ''} ${deps.join(' ')}`;
|
|
65
|
+
case 'deno':
|
|
66
|
+
return `deno add ${dev ? '--dev' : ''} ${deps.map((d) => `npm:${d}`).join(' ')}`;
|
|
67
|
+
default:
|
|
68
|
+
return manager;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export async function fetchAvailableExamples() {
|
|
72
|
+
try {
|
|
73
|
+
const response = await fetch('https://api.github.com/repos/neplextech/commandkit/contents/examples', {
|
|
74
|
+
signal: AbortSignal.timeout(10_000),
|
|
75
|
+
headers: {
|
|
76
|
+
'User-Agent': 'create-commandkit',
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
throw new Error(`GitHub API error: ${response.status}`);
|
|
43
81
|
}
|
|
82
|
+
const data = (await response.json());
|
|
83
|
+
// Filter for directories only and return their names
|
|
84
|
+
return data
|
|
85
|
+
.filter((item) => item.type === 'dir')
|
|
86
|
+
.map((item) => item.name)
|
|
87
|
+
.sort();
|
|
44
88
|
}
|
|
45
89
|
catch (error) {
|
|
46
|
-
|
|
47
|
-
return '
|
|
90
|
+
// Fallback to few known examples if API fails
|
|
91
|
+
return ['basic-ts', 'basic-js', 'deno-ts', 'without-cli'];
|
|
48
92
|
}
|
|
49
93
|
}
|
|
94
|
+
export function isDenoProject(example) {
|
|
95
|
+
const isOfficial = isOfficialExample(example);
|
|
96
|
+
// if it's not an official example, we can assume it's not a Deno project
|
|
97
|
+
// the user may use --use-deno to force a Deno project
|
|
98
|
+
if (!isOfficial)
|
|
99
|
+
return false;
|
|
100
|
+
return example.startsWith('deno-') || example.startsWith('with-deno-');
|
|
101
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-commandkit",
|
|
3
3
|
"description": "Effortlessly create a CommandKit project",
|
|
4
|
-
"version": "1.2.0-rc.
|
|
4
|
+
"version": "1.2.0-rc.13",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
7
7
|
"bin": "./dist/index.js",
|
|
@@ -18,32 +18,36 @@
|
|
|
18
18
|
"commands"
|
|
19
19
|
],
|
|
20
20
|
"files": [
|
|
21
|
-
"dist"
|
|
22
|
-
"templates"
|
|
21
|
+
"dist"
|
|
23
22
|
],
|
|
24
23
|
"repository": {
|
|
25
24
|
"type": "git",
|
|
26
|
-
"url": "https://github.com/
|
|
25
|
+
"url": "https://github.com/neplextech/commandkit",
|
|
27
26
|
"directory": "packages/create-commandkit"
|
|
28
27
|
},
|
|
29
28
|
"homepage": "https://commandkit.dev",
|
|
30
29
|
"dependencies": {
|
|
31
30
|
"@clack/prompts": "^0.11.0",
|
|
31
|
+
"commander": "^14.0.1",
|
|
32
32
|
"fs-extra": "^11.1.1",
|
|
33
33
|
"gradient-string": "^3.0.0",
|
|
34
34
|
"ora": "^8.0.1",
|
|
35
|
-
"picocolors": "^1.1.1"
|
|
35
|
+
"picocolors": "^1.1.1",
|
|
36
|
+
"tiged": "^2.12.7",
|
|
37
|
+
"validate-npm-package-name": "^6.0.2"
|
|
36
38
|
},
|
|
37
39
|
"devDependencies": {
|
|
38
40
|
"@types/fs-extra": "^11.0.4",
|
|
39
41
|
"@types/gradient-string": "^1.1.5",
|
|
40
42
|
"@types/node": "^22.0.0",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
+
"@types/validate-npm-package-name": "^4.0.2",
|
|
44
|
+
"tsx": "^4.20.6",
|
|
45
|
+
"typescript": "^5.9.3",
|
|
46
|
+
"tsconfig": "0.0.0-rc.13"
|
|
43
47
|
},
|
|
44
48
|
"scripts": {
|
|
45
49
|
"check-types": "tsc --noEmit",
|
|
46
50
|
"dev": "tsc --watch",
|
|
47
|
-
"build": "tsc"
|
|
51
|
+
"build": "tsc && tsx scripts/sync-available-examples.ts"
|
|
48
52
|
}
|
|
49
53
|
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
const templates = {
|
|
4
|
-
js: path.join(import.meta.dirname, '..', '..', 'templates', 'JavaScript'),
|
|
5
|
-
ts: path.join(import.meta.dirname, '..', '..', 'templates', 'TypeScript'),
|
|
6
|
-
};
|
|
7
|
-
const gitignore = `
|
|
8
|
-
# dependencies
|
|
9
|
-
node_modules
|
|
10
|
-
|
|
11
|
-
# build output
|
|
12
|
-
build
|
|
13
|
-
out
|
|
14
|
-
dist
|
|
15
|
-
|
|
16
|
-
# commandkit
|
|
17
|
-
.commandkit
|
|
18
|
-
dist
|
|
19
|
-
compiled-commandkit.config.mjs
|
|
20
|
-
|
|
21
|
-
# env
|
|
22
|
-
**/*.env*
|
|
23
|
-
!**/*.env.example*
|
|
24
|
-
|
|
25
|
-
# logging
|
|
26
|
-
logs
|
|
27
|
-
*.log
|
|
28
|
-
npm-debug.log*
|
|
29
|
-
yarn-debug.log*
|
|
30
|
-
yarn-error.log*
|
|
31
|
-
lerna-debug.log*
|
|
32
|
-
.pnpm-debug.log*
|
|
33
|
-
|
|
34
|
-
# yarn v2+
|
|
35
|
-
.yarn/cache
|
|
36
|
-
.yarn/unplugged
|
|
37
|
-
.yarn/build-state.yml
|
|
38
|
-
.yarn/install-state.gz
|
|
39
|
-
.pnp.*
|
|
40
|
-
|
|
41
|
-
# other
|
|
42
|
-
**/*.DS_Store
|
|
43
|
-
`;
|
|
44
|
-
export async function copyTemplates({ dir, lang, }) {
|
|
45
|
-
await fs.copy(templates[lang], dir);
|
|
46
|
-
await fs.writeFile(path.join(dir, '.gitignore'), gitignore);
|
|
47
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { type IOType } from 'node:child_process';
|
|
2
|
-
import type { Language, PackageManager } from '../types';
|
|
3
|
-
interface InstallDepsProps {
|
|
4
|
-
manager: PackageManager;
|
|
5
|
-
dir: string;
|
|
6
|
-
lang: Language;
|
|
7
|
-
stdio: IOType;
|
|
8
|
-
}
|
|
9
|
-
export declare function installDeps({ manager, dir, lang, stdio, }: InstallDepsProps): void;
|
|
10
|
-
export {};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'node:child_process';
|
|
2
|
-
import ora from 'ora';
|
|
3
|
-
import { getCommandKitVersion } from '../utils.js';
|
|
4
|
-
const getBaseDependencies = () => [
|
|
5
|
-
`commandkit${getCommandKitVersion()}`,
|
|
6
|
-
'discord.js',
|
|
7
|
-
];
|
|
8
|
-
const getDependencies = () => ({
|
|
9
|
-
js: {
|
|
10
|
-
dependencies: getBaseDependencies(),
|
|
11
|
-
devDependencies: ['@types/node', 'typescript', 'prettier'],
|
|
12
|
-
},
|
|
13
|
-
ts: {
|
|
14
|
-
dependencies: getBaseDependencies(),
|
|
15
|
-
devDependencies: ['@types/node', 'typescript', 'prettier'],
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
function getInstallCommand(manager, deps, dev = false) {
|
|
19
|
-
switch (manager) {
|
|
20
|
-
case 'npm':
|
|
21
|
-
case 'pnpm':
|
|
22
|
-
case 'yarn':
|
|
23
|
-
case 'bun':
|
|
24
|
-
return `${manager} add ${dev ? '-D' : ''} ${deps.join(' ')}`;
|
|
25
|
-
case 'deno':
|
|
26
|
-
return `deno add ${dev ? '--dev' : ''} ${deps.map((d) => `npm:${d}`).join(' ')}`;
|
|
27
|
-
default:
|
|
28
|
-
return manager;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
export function installDeps({ manager, dir, lang, stdio = 'inherit', }) {
|
|
32
|
-
const spinner = ora('Installing dependencies...').start();
|
|
33
|
-
try {
|
|
34
|
-
const dependencies = getDependencies();
|
|
35
|
-
if (dependencies[lang].dependencies.length) {
|
|
36
|
-
const depsCommand = getInstallCommand(manager, dependencies[lang].dependencies);
|
|
37
|
-
execSync(depsCommand, { cwd: dir, stdio });
|
|
38
|
-
}
|
|
39
|
-
if (dependencies[lang].devDependencies.length) {
|
|
40
|
-
const devDepsCommand = getInstallCommand(manager, dependencies[lang].devDependencies, true);
|
|
41
|
-
execSync(devDepsCommand, { cwd: dir, stdio });
|
|
42
|
-
}
|
|
43
|
-
spinner.succeed('Dependencies installed successfully!');
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
spinner.fail('Failed to install dependencies');
|
|
47
|
-
throw error;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { type IOType } from 'child_process';
|
|
2
|
-
import type { PackageManager } from '../types';
|
|
3
|
-
interface SetupProps {
|
|
4
|
-
manager: PackageManager;
|
|
5
|
-
token: string;
|
|
6
|
-
dir: string;
|
|
7
|
-
stdio?: IOType;
|
|
8
|
-
}
|
|
9
|
-
export declare function setup({ manager, token, dir, stdio, }: SetupProps): Promise<void>;
|
|
10
|
-
export {};
|
package/dist/functions/setup.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { commands } from '../utils.js';
|
|
5
|
-
export async function setup({ manager, token, dir, stdio = 'pipe', }) {
|
|
6
|
-
await fs.emptyDir(dir);
|
|
7
|
-
if (manager === 'yarn') {
|
|
8
|
-
execSync(commands.init.yarn, { cwd: dir, stdio });
|
|
9
|
-
}
|
|
10
|
-
if (manager === 'deno') {
|
|
11
|
-
const denoJsonPath = path.join(dir, 'deno.json');
|
|
12
|
-
const denoJson = {
|
|
13
|
-
compilerOptions: {
|
|
14
|
-
jsx: 'react-jsx',
|
|
15
|
-
jsxImportSource: 'commandkit',
|
|
16
|
-
},
|
|
17
|
-
nodeModulesDir: 'auto',
|
|
18
|
-
lock: true,
|
|
19
|
-
lint: {
|
|
20
|
-
include: ['src/'],
|
|
21
|
-
exclude: ['node_modules/', 'dist/', '.commandkit/'],
|
|
22
|
-
},
|
|
23
|
-
fmt: {
|
|
24
|
-
useTabs: false,
|
|
25
|
-
lineWidth: 120,
|
|
26
|
-
indentWidth: 2,
|
|
27
|
-
endOfLine: 'lf',
|
|
28
|
-
semiColons: true,
|
|
29
|
-
singleQuote: true,
|
|
30
|
-
include: ['src/'],
|
|
31
|
-
exclude: ['node_modules/', 'dist/', '.commandkit/'],
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
await fs.writeJSON(denoJsonPath, denoJson, { spaces: 2, EOL: '\n' });
|
|
35
|
-
}
|
|
36
|
-
const prettierrc = path.join(dir, '.prettierrc');
|
|
37
|
-
const prettierConfig = {
|
|
38
|
-
printWidth: 120,
|
|
39
|
-
tabWidth: 2,
|
|
40
|
-
useTabs: false,
|
|
41
|
-
semi: true,
|
|
42
|
-
endOfLine: 'lf',
|
|
43
|
-
singleQuote: true,
|
|
44
|
-
trailingComma: 'all',
|
|
45
|
-
arrowParens: 'always',
|
|
46
|
-
};
|
|
47
|
-
await fs.writeJSON(prettierrc, prettierConfig, { spaces: 2, EOL: '\n' });
|
|
48
|
-
const packageJsonPath = path.join(dir, 'package.json');
|
|
49
|
-
const packageJson = {
|
|
50
|
-
name: dir.replaceAll('\\', '/').split('/').pop()?.toLowerCase() ||
|
|
51
|
-
'commandkit-project',
|
|
52
|
-
description: 'A CommandKit project',
|
|
53
|
-
version: '0.1.0',
|
|
54
|
-
type: 'module',
|
|
55
|
-
private: true,
|
|
56
|
-
main: 'dist/index.js',
|
|
57
|
-
scripts: {
|
|
58
|
-
dev: 'commandkit dev',
|
|
59
|
-
build: 'commandkit build',
|
|
60
|
-
start: 'commandkit start',
|
|
61
|
-
format: 'prettier --write "src/**/*.{js,ts}"',
|
|
62
|
-
},
|
|
63
|
-
devDependencies: {},
|
|
64
|
-
dependencies: {},
|
|
65
|
-
};
|
|
66
|
-
await fs.writeJSON(packageJsonPath, packageJson, { spaces: 2 });
|
|
67
|
-
await fs.writeFile(`${dir}/.env`, `DISCORD_TOKEN="${token || ''}"`);
|
|
68
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Welcome to CommandKit
|
|
2
|
-
|
|
3
|
-
> This project was generated by [create-commandkit](https://npmjs.com/package/create-commandkit).
|
|
4
|
-
|
|
5
|
-
Thanks for choosing CommandKit to build your Discord bot!
|
|
6
|
-
|
|
7
|
-
## To run this project
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
npx commandkit dev
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Useful links
|
|
14
|
-
|
|
15
|
-
- [Documentation](https://commandkit.dev)
|
|
16
|
-
- [Discord](https://ctrl.lol/discord)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/// <reference path="node_modules/commandkit-types/index.d.ts" />
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"lib": ["ESNext", "DOM"],
|
|
5
|
-
"target": "ESNext",
|
|
6
|
-
"moduleResolution": "Node",
|
|
7
|
-
"module": "Preserve",
|
|
8
|
-
"allowImportingTsExtensions": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"resolveJsonModule": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"skipDefaultLibCheck": true,
|
|
13
|
-
"noUncheckedIndexedAccess": true,
|
|
14
|
-
"removeComments": true,
|
|
15
|
-
"allowJs": true,
|
|
16
|
-
"checkJs": false,
|
|
17
|
-
"strict": true,
|
|
18
|
-
"alwaysStrict": true,
|
|
19
|
-
"noEmit": true,
|
|
20
|
-
"declaration": false,
|
|
21
|
-
"jsx": "react-jsx",
|
|
22
|
-
"jsxImportSource": "commandkit",
|
|
23
|
-
"baseUrl": ".",
|
|
24
|
-
"paths": {
|
|
25
|
-
"@/*": ["./src/*"]
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"include": ["src", "commandkit.config.mjs", "commandkit-env.d.ts"],
|
|
29
|
-
"exclude": ["dist", "node_modules", ".commandkit"]
|
|
30
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @type {import('commandkit').CommandData}
|
|
3
|
-
*/
|
|
4
|
-
export const command = {
|
|
5
|
-
name: 'ping',
|
|
6
|
-
description: "Ping the bot to check if it's online.",
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @param {import('commandkit').ChatInputCommandContext} ctx
|
|
11
|
-
*/
|
|
12
|
-
export const chatInput = async (ctx) => {
|
|
13
|
-
const latency = (ctx.client.ws.ping ?? -1).toString();
|
|
14
|
-
const response = `Pong! Latency: ${latency}ms`;
|
|
15
|
-
|
|
16
|
-
await ctx.interaction.reply(response);
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @param {import('commandkit').MessageCommandContext} ctx
|
|
21
|
-
*/
|
|
22
|
-
export const message = async (ctx) => {
|
|
23
|
-
const latency = (ctx.client.ws.ping ?? -1).toString();
|
|
24
|
-
const response = `Pong! Latency: ${latency}ms`;
|
|
25
|
-
|
|
26
|
-
await ctx.message.reply(response);
|
|
27
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Welcome to CommandKit
|
|
2
|
-
|
|
3
|
-
> This project was generated by [create-commandkit](https://npmjs.com/package/create-commandkit).
|
|
4
|
-
|
|
5
|
-
Thanks for choosing CommandKit to build your Discord bot!
|
|
6
|
-
|
|
7
|
-
## To run this project
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
npx commandkit dev
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Useful links
|
|
14
|
-
|
|
15
|
-
- [Documentation](https://commandkit.dev)
|
|
16
|
-
- [Discord](https://ctrl.lol/discord)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/// <reference path="node_modules/commandkit-types/index.d.ts" />
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { ChatInputCommand, MessageCommand, CommandData } from 'commandkit';
|
|
2
|
-
|
|
3
|
-
export const command: CommandData = {
|
|
4
|
-
name: 'ping',
|
|
5
|
-
description: "Ping the bot to check if it's online.",
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export const chatInput: ChatInputCommand = async (ctx) => {
|
|
9
|
-
const latency = (ctx.client.ws.ping ?? -1).toString();
|
|
10
|
-
const response = `Pong! Latency: ${latency}ms`;
|
|
11
|
-
|
|
12
|
-
await ctx.interaction.reply(response);
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const message: MessageCommand = async (ctx) => {
|
|
16
|
-
const latency = (ctx.client.ws.ping ?? -1).toString();
|
|
17
|
-
const response = `Pong! Latency: ${latency}ms`;
|
|
18
|
-
|
|
19
|
-
await ctx.message.reply(response);
|
|
20
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"lib": ["ESNext", "DOM"],
|
|
5
|
-
"target": "ESNext",
|
|
6
|
-
"moduleResolution": "Node",
|
|
7
|
-
"module": "Preserve",
|
|
8
|
-
"allowImportingTsExtensions": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"resolveJsonModule": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"skipDefaultLibCheck": true,
|
|
13
|
-
"noUncheckedIndexedAccess": true,
|
|
14
|
-
"removeComments": true,
|
|
15
|
-
"allowJs": true,
|
|
16
|
-
"strict": true,
|
|
17
|
-
"alwaysStrict": true,
|
|
18
|
-
"noEmit": true,
|
|
19
|
-
"declaration": false,
|
|
20
|
-
"jsx": "react-jsx",
|
|
21
|
-
"jsxImportSource": "commandkit",
|
|
22
|
-
"baseUrl": ".",
|
|
23
|
-
"paths": {
|
|
24
|
-
"@/*": ["./src/*"]
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
"include": ["src", "commandkit.config.ts", "commandkit-env.d.ts"],
|
|
28
|
-
"exclude": ["dist", "node_modules", ".commandkit"]
|
|
29
|
-
}
|