djs-next 1.0.0-dev.1 → 1.0.0-dev.3
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.
Potentially problematic release.
This version of djs-next might be problematic. Click here for more details.
- package/README.md +61 -30
- package/bin/create-djs-next.js +78 -0
- package/dist/index.d.mts +57 -5
- package/dist/index.d.ts +57 -5
- package/dist/index.js +620 -256
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +620 -246
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +277 -68
- package/src/index.ts +4 -1
- package/src/plugins/dnxt.ts +215 -176
- package/src/templates/cjs.ts +11 -6
- package/src/templates/esm.ts +11 -4
- package/src/templates/ts.ts +11 -5
- package/src/types.ts +27 -2
- package/src/utils/PaginationBuilder.ts +94 -0
- package/src/utils/paginate.ts +32 -13
- package/src/utils/prompts.ts +76 -0
- package/test_payload.js +3 -0
- package/test_reply.js +4 -0
- package/tsup.config.ts +1 -1
- package/dist/cli.d.mts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -344
- package/dist/cli.js.map +0 -1
- package/dist/cli.mjs +0 -321
- package/dist/cli.mjs.map +0 -1
- package/src/cli.ts +0 -203
package/src/types.ts
CHANGED
|
@@ -8,11 +8,25 @@ import {
|
|
|
8
8
|
AutocompleteInteraction,
|
|
9
9
|
MessageComponentInteraction,
|
|
10
10
|
ModalSubmitInteraction,
|
|
11
|
-
Interaction
|
|
11
|
+
Interaction,
|
|
12
|
+
Message
|
|
12
13
|
} from 'discord.js';
|
|
13
14
|
|
|
15
|
+
export interface CooldownAdapter {
|
|
16
|
+
get(commandId: string, userId: string): Promise<number | null> | number | null;
|
|
17
|
+
set(commandId: string, userId: string, expirationTime: number): Promise<void> | void;
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
export interface DJSNextConfig {
|
|
15
21
|
devGuildId?: string;
|
|
22
|
+
errorLogChannelId?: string;
|
|
23
|
+
responses?: {
|
|
24
|
+
developerOnly?: string | null;
|
|
25
|
+
guildOnly?: string | null;
|
|
26
|
+
cooldown?: string | null;
|
|
27
|
+
missingPerms?: string | null;
|
|
28
|
+
errorBoundary?: string | null;
|
|
29
|
+
};
|
|
16
30
|
locales?: string[];
|
|
17
31
|
defaultLocale?: string;
|
|
18
32
|
directories?: {
|
|
@@ -22,6 +36,7 @@ export interface DJSNextConfig {
|
|
|
22
36
|
tasks?: string;
|
|
23
37
|
locales?: string;
|
|
24
38
|
};
|
|
39
|
+
cooldownAdapter?: CooldownAdapter;
|
|
25
40
|
}
|
|
26
41
|
|
|
27
42
|
export interface DJSNextClientOptions extends ClientOptions {
|
|
@@ -32,8 +47,14 @@ export interface DJSNextClientOptions extends ClientOptions {
|
|
|
32
47
|
clientId?: string;
|
|
33
48
|
guildId?: string;
|
|
34
49
|
developers?: string[];
|
|
35
|
-
|
|
50
|
+
prefixes?: string[] | string;
|
|
51
|
+
enableSlashCommands?: boolean;
|
|
52
|
+
enableTextCommands?: boolean;
|
|
53
|
+
enableMentionPrefix?: boolean | string[];
|
|
54
|
+
enableNoPrefix?: boolean | string[];
|
|
55
|
+
middleware?: (interaction: Interaction | Message, client: Client) => Promise<boolean> | boolean;
|
|
36
56
|
config?: DJSNextConfig;
|
|
57
|
+
db?: any;
|
|
37
58
|
}
|
|
38
59
|
|
|
39
60
|
export interface FileTask<DB = any> {
|
|
@@ -51,13 +72,17 @@ export interface FileCommand<DB = any> {
|
|
|
51
72
|
botPermissions?: PermissionResolvable[];
|
|
52
73
|
developerOnly?: boolean;
|
|
53
74
|
guildOnly?: boolean;
|
|
75
|
+
aliases?: string[];
|
|
76
|
+
preconditions?: string[];
|
|
54
77
|
execute?: (interaction: ChatInputCommandInteraction, client: Client & { db: DB; t: Function; config: DJSNextConfig }) => Promise<void> | void;
|
|
78
|
+
executeText?: (message: Message, args: string[], client: Client & { db: DB; t: Function; config: DJSNextConfig }) => Promise<void> | void;
|
|
55
79
|
autocomplete?: (interaction: AutocompleteInteraction, client: Client & { db: DB; t: Function; config: DJSNextConfig }) => Promise<void> | void;
|
|
56
80
|
}
|
|
57
81
|
|
|
58
82
|
export interface FileComponent<DB = any> {
|
|
59
83
|
filepath?: string;
|
|
60
84
|
customId?: string;
|
|
85
|
+
preconditions?: string[];
|
|
61
86
|
execute: (interaction: MessageComponentInteraction | ModalSubmitInteraction, client: Client & { db: DB; t: Function; config: DJSNextConfig }, params?: Record<string, string>) => Promise<void> | void;
|
|
62
87
|
}
|
|
63
88
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ActionRowBuilder,
|
|
3
|
+
ButtonBuilder,
|
|
4
|
+
ButtonStyle,
|
|
5
|
+
CommandInteraction,
|
|
6
|
+
EmbedBuilder,
|
|
7
|
+
Message,
|
|
8
|
+
ComponentType
|
|
9
|
+
} from 'discord.js';
|
|
10
|
+
|
|
11
|
+
export class PaginationBuilder {
|
|
12
|
+
private pages: EmbedBuilder[] = [];
|
|
13
|
+
private timeout: number = 60000;
|
|
14
|
+
|
|
15
|
+
constructor(pages?: EmbedBuilder[]) {
|
|
16
|
+
if (pages) this.pages = pages;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public addPage(embed: EmbedBuilder): this {
|
|
20
|
+
this.pages.push(embed);
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public setPages(pages: EmbedBuilder[]): this {
|
|
25
|
+
this.pages = pages;
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public setTimeout(ms: number): this {
|
|
30
|
+
this.timeout = ms;
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public async build(target: CommandInteraction | Message): Promise<Message | null> {
|
|
35
|
+
if (this.pages.length === 0) throw new Error('[djs-next] PaginationBuilder requires at least one page.');
|
|
36
|
+
|
|
37
|
+
if (this.pages.length === 1) {
|
|
38
|
+
if (target instanceof CommandInteraction) {
|
|
39
|
+
if (target.deferred || target.replied) {
|
|
40
|
+
return await target.editReply({ embeds: [this.pages[0]] }) as Message;
|
|
41
|
+
}
|
|
42
|
+
return await target.reply({ embeds: [this.pages[0]], fetchReply: true }) as Message;
|
|
43
|
+
} else {
|
|
44
|
+
return await target.reply({ embeds: [this.pages[0]] });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let currentPage = 0;
|
|
49
|
+
|
|
50
|
+
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
|
51
|
+
new ButtonBuilder().setCustomId('prev').setLabel('◀').setStyle(ButtonStyle.Primary).setDisabled(true),
|
|
52
|
+
new ButtonBuilder().setCustomId('page').setLabel(`1 / ${this.pages.length}`).setStyle(ButtonStyle.Secondary).setDisabled(true),
|
|
53
|
+
new ButtonBuilder().setCustomId('next').setLabel('▶').setStyle(ButtonStyle.Primary)
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
let replyMsg: Message;
|
|
57
|
+
if (target instanceof CommandInteraction) {
|
|
58
|
+
if (target.deferred || target.replied) {
|
|
59
|
+
replyMsg = await target.editReply({ embeds: [this.pages[0]], components: [row] }) as Message;
|
|
60
|
+
} else {
|
|
61
|
+
replyMsg = await target.reply({ embeds: [this.pages[0]], components: [row], fetchReply: true }) as Message;
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
replyMsg = await target.reply({ embeds: [this.pages[0]], components: [row] });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const userId = target instanceof CommandInteraction ? target.user.id : target.author.id;
|
|
68
|
+
|
|
69
|
+
const collector = replyMsg.createMessageComponentCollector({
|
|
70
|
+
componentType: ComponentType.Button,
|
|
71
|
+
time: this.timeout,
|
|
72
|
+
filter: i => i.user.id === userId
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
collector.on('collect', async i => {
|
|
76
|
+
if (i.customId === 'prev') currentPage--;
|
|
77
|
+
else if (i.customId === 'next') currentPage++;
|
|
78
|
+
|
|
79
|
+
const newRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
|
80
|
+
new ButtonBuilder().setCustomId('prev').setLabel('◀').setStyle(ButtonStyle.Primary).setDisabled(currentPage === 0),
|
|
81
|
+
new ButtonBuilder().setCustomId('page').setLabel(`${currentPage + 1} / ${this.pages.length}`).setStyle(ButtonStyle.Secondary).setDisabled(true),
|
|
82
|
+
new ButtonBuilder().setCustomId('next').setLabel('▶').setStyle(ButtonStyle.Primary).setDisabled(currentPage === this.pages.length - 1)
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
await i.update({ embeds: [this.pages[currentPage]], components: [newRow] });
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
collector.on('end', () => {
|
|
89
|
+
replyMsg.edit({ components: [] }).catch(() => null);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return replyMsg;
|
|
93
|
+
}
|
|
94
|
+
}
|
package/src/utils/paginate.ts
CHANGED
|
@@ -4,20 +4,29 @@ import {
|
|
|
4
4
|
ButtonStyle,
|
|
5
5
|
CommandInteraction,
|
|
6
6
|
EmbedBuilder,
|
|
7
|
+
Message,
|
|
7
8
|
MessageComponentInteraction
|
|
8
9
|
} from 'discord.js';
|
|
9
10
|
|
|
10
11
|
export async function paginate(
|
|
11
|
-
|
|
12
|
+
context: Message | CommandInteraction | MessageComponentInteraction,
|
|
12
13
|
pages: EmbedBuilder[],
|
|
13
14
|
time: number = 60000
|
|
14
15
|
) {
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
const isMessage = 'author' in context;
|
|
17
|
+
|
|
18
|
+
if (!isMessage) {
|
|
19
|
+
if (!context.deferred && !context.replied) {
|
|
20
|
+
await context.deferReply();
|
|
21
|
+
}
|
|
17
22
|
}
|
|
18
23
|
|
|
19
24
|
if (pages.length === 1) {
|
|
20
|
-
|
|
25
|
+
if (isMessage) {
|
|
26
|
+
return context.reply({ embeds: [pages[0]], components: [] });
|
|
27
|
+
} else {
|
|
28
|
+
return context.editReply({ embeds: [pages[0]], components: [] });
|
|
29
|
+
}
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
let index = 0;
|
|
@@ -35,17 +44,25 @@ export async function paginate(
|
|
|
35
44
|
|
|
36
45
|
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(prevButton, nextButton);
|
|
37
46
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
let message: Message;
|
|
48
|
+
if (isMessage) {
|
|
49
|
+
message = await context.reply({
|
|
50
|
+
embeds: [pages[index]],
|
|
51
|
+
components: [row],
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
message = await context.editReply({
|
|
55
|
+
embeds: [pages[index]],
|
|
56
|
+
components: [row],
|
|
57
|
+
});
|
|
58
|
+
}
|
|
42
59
|
|
|
43
60
|
const collector = message.createMessageComponentCollector({
|
|
44
|
-
filter: (i) => i.user.id ===
|
|
61
|
+
filter: (i) => i.user.id === (isMessage ? context.author.id : context.user.id),
|
|
45
62
|
time
|
|
46
63
|
});
|
|
47
64
|
|
|
48
|
-
collector.on('collect', async (i) => {
|
|
65
|
+
collector.on('collect', async (i: MessageComponentInteraction) => {
|
|
49
66
|
if (i.customId === 'djs_prev') {
|
|
50
67
|
index = index > 0 ? index - 1 : index;
|
|
51
68
|
} else if (i.customId === 'djs_next') {
|
|
@@ -64,8 +81,10 @@ export async function paginate(
|
|
|
64
81
|
collector.on('end', async () => {
|
|
65
82
|
prevButton.setDisabled(true);
|
|
66
83
|
nextButton.setDisabled(true);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
84
|
+
if (message.editable) {
|
|
85
|
+
await message.edit({
|
|
86
|
+
components: [new ActionRowBuilder<ButtonBuilder>().addComponents(prevButton, nextButton)]
|
|
87
|
+
}).catch(() => {});
|
|
88
|
+
}
|
|
70
89
|
});
|
|
71
90
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ActionRowBuilder,
|
|
3
|
+
ButtonBuilder,
|
|
4
|
+
ButtonStyle,
|
|
5
|
+
CommandInteraction,
|
|
6
|
+
EmbedBuilder,
|
|
7
|
+
Message,
|
|
8
|
+
MessageComponentInteraction
|
|
9
|
+
} from 'discord.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Sends a confirmation prompt (Yes/No) to the user.
|
|
13
|
+
* @param context The message or interaction context.
|
|
14
|
+
* @param content The text or embed to display in the prompt.
|
|
15
|
+
* @param time Time to wait for a response in milliseconds.
|
|
16
|
+
* @returns Boolean indicating true for Yes, false for No, or null if timed out.
|
|
17
|
+
*/
|
|
18
|
+
export async function confirmPrompt(
|
|
19
|
+
context: Message | CommandInteraction | MessageComponentInteraction,
|
|
20
|
+
content: string | EmbedBuilder,
|
|
21
|
+
time: number = 30000
|
|
22
|
+
): Promise<boolean | null> {
|
|
23
|
+
const isMessage = 'author' in context;
|
|
24
|
+
|
|
25
|
+
if (!isMessage) {
|
|
26
|
+
if (!context.deferred && !context.replied) {
|
|
27
|
+
await context.deferReply();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const yesButton = new ButtonBuilder()
|
|
32
|
+
.setCustomId('djs_prompt_yes')
|
|
33
|
+
.setLabel('Yes')
|
|
34
|
+
.setStyle(ButtonStyle.Success);
|
|
35
|
+
|
|
36
|
+
const noButton = new ButtonBuilder()
|
|
37
|
+
.setCustomId('djs_prompt_no')
|
|
38
|
+
.setLabel('No')
|
|
39
|
+
.setStyle(ButtonStyle.Danger);
|
|
40
|
+
|
|
41
|
+
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(yesButton, noButton);
|
|
42
|
+
|
|
43
|
+
const payload: any = { components: [row] };
|
|
44
|
+
if (typeof content === 'string') {
|
|
45
|
+
payload.content = content;
|
|
46
|
+
} else {
|
|
47
|
+
payload.embeds = [content];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let message: Message;
|
|
51
|
+
if (isMessage) {
|
|
52
|
+
message = await context.reply(payload);
|
|
53
|
+
} else {
|
|
54
|
+
message = await context.editReply(payload);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const interaction = await message.awaitMessageComponent({
|
|
59
|
+
filter: (i) => i.user.id === (isMessage ? context.author.id : context.user.id),
|
|
60
|
+
time
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (interaction.customId === 'djs_prompt_yes') {
|
|
64
|
+
await interaction.update({ components: [] });
|
|
65
|
+
return true;
|
|
66
|
+
} else {
|
|
67
|
+
await interaction.update({ components: [] });
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (message.editable) {
|
|
72
|
+
await message.edit({ components: [] }).catch(() => {});
|
|
73
|
+
}
|
|
74
|
+
return null; // Timed out
|
|
75
|
+
}
|
|
76
|
+
}
|
package/test_payload.js
ADDED
package/test_reply.js
ADDED
package/tsup.config.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineConfig } from 'tsup';
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
|
-
entry: ['src/index.ts'
|
|
4
|
+
entry: ['src/index.ts'],
|
|
5
5
|
format: ['cjs', 'esm'], // Build for CommonJS and ES Modules
|
|
6
6
|
dts: true, // Generate declaration file (.d.ts)
|
|
7
7
|
splitting: false,
|
package/dist/cli.d.mts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
package/dist/cli.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
package/dist/cli.js
DELETED
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
-
mod
|
|
24
|
-
));
|
|
25
|
-
|
|
26
|
-
// src/cli.ts
|
|
27
|
-
var import_fs = __toESM(require("fs"));
|
|
28
|
-
var import_path = __toESM(require("path"));
|
|
29
|
-
var import_prompts = require("@inquirer/prompts");
|
|
30
|
-
|
|
31
|
-
// src/templates/ts.ts
|
|
32
|
-
var tsTemplates = {
|
|
33
|
-
index: `import { DJSNextClient, GatewayIntentBits } from 'djs-next';
|
|
34
|
-
import 'dotenv/config';
|
|
35
|
-
|
|
36
|
-
const client = new DJSNextClient({
|
|
37
|
-
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
|
|
38
|
-
commandsDir: './src/commands',
|
|
39
|
-
eventsDir: './src/events',
|
|
40
|
-
componentsDir: './src/components',
|
|
41
|
-
tasksDir: './src/tasks',
|
|
42
|
-
clientId: process.env.CLIENT_ID
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
client.start(process.env.DISCORD_TOKEN!);
|
|
46
|
-
`,
|
|
47
|
-
ping: `import { FileCommand } from 'djs-next';
|
|
48
|
-
|
|
49
|
-
export const command: FileCommand = {
|
|
50
|
-
description: 'Replies with Pong!',
|
|
51
|
-
execute: async (interaction) => {
|
|
52
|
-
await interaction.reply('Pong!');
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
`,
|
|
56
|
-
ready: `import { DJSNextEvent, Events } from 'djs-next';
|
|
57
|
-
|
|
58
|
-
export const event: DJSNextEvent<Events.ClientReady> = {
|
|
59
|
-
name: Events.ClientReady,
|
|
60
|
-
once: true,
|
|
61
|
-
execute: (client) => {
|
|
62
|
-
console.log('Ready! Logged in as ' + client.user?.tag);
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
`,
|
|
66
|
-
healthcheck: `import { FileTask } from 'djs-next';
|
|
67
|
-
|
|
68
|
-
export const task: FileTask = {
|
|
69
|
-
interval: 60000,
|
|
70
|
-
execute: async (client) => {
|
|
71
|
-
console.log('[Task] Healthcheck completed.');
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
`
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// src/templates/esm.ts
|
|
78
|
-
var esmTemplates = {
|
|
79
|
-
index: `import { DJSNextClient, GatewayIntentBits } from 'djs-next';
|
|
80
|
-
import 'dotenv/config';
|
|
81
|
-
|
|
82
|
-
const client = new DJSNextClient({
|
|
83
|
-
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
|
|
84
|
-
commandsDir: './src/commands',
|
|
85
|
-
eventsDir: './src/events',
|
|
86
|
-
componentsDir: './src/components',
|
|
87
|
-
tasksDir: './src/tasks',
|
|
88
|
-
clientId: process.env.CLIENT_ID
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
client.start(process.env.DISCORD_TOKEN);
|
|
92
|
-
`,
|
|
93
|
-
ping: `export const command = {
|
|
94
|
-
description: 'Replies with Pong!',
|
|
95
|
-
execute: async (interaction) => {
|
|
96
|
-
await interaction.reply('Pong!');
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
`,
|
|
100
|
-
ready: `import { Events } from 'djs-next';
|
|
101
|
-
|
|
102
|
-
export const event = {
|
|
103
|
-
name: Events.ClientReady,
|
|
104
|
-
once: true,
|
|
105
|
-
execute: (client) => {
|
|
106
|
-
console.log('Ready! Logged in as ' + client.user?.tag);
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
`,
|
|
110
|
-
healthcheck: `export const task = {
|
|
111
|
-
interval: 60000,
|
|
112
|
-
execute: async (client) => {
|
|
113
|
-
console.log('[Task] Healthcheck completed.');
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
`
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
// src/templates/cjs.ts
|
|
120
|
-
var cjsTemplates = {
|
|
121
|
-
index: `const { DJSNextClient, GatewayIntentBits } = require('djs-next');
|
|
122
|
-
require('dotenv/config');
|
|
123
|
-
|
|
124
|
-
const client = new DJSNextClient({
|
|
125
|
-
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
|
|
126
|
-
commandsDir: './src/commands',
|
|
127
|
-
eventsDir: './src/events',
|
|
128
|
-
componentsDir: './src/components',
|
|
129
|
-
tasksDir: './src/tasks',
|
|
130
|
-
clientId: process.env.CLIENT_ID
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
client.start(process.env.DISCORD_TOKEN);
|
|
134
|
-
`,
|
|
135
|
-
ping: `module.exports = {
|
|
136
|
-
command: {
|
|
137
|
-
description: 'Replies with Pong!',
|
|
138
|
-
execute: async (interaction) => {
|
|
139
|
-
await interaction.reply('Pong!');
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
`,
|
|
144
|
-
ready: `const { Events } = require('djs-next');
|
|
145
|
-
|
|
146
|
-
module.exports = {
|
|
147
|
-
event: {
|
|
148
|
-
name: Events.ClientReady,
|
|
149
|
-
once: true,
|
|
150
|
-
execute: (client) => {
|
|
151
|
-
console.log('Ready! Logged in as ' + client.user?.tag);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
`,
|
|
156
|
-
healthcheck: `module.exports = {
|
|
157
|
-
task: {
|
|
158
|
-
interval: 60000,
|
|
159
|
-
execute: async (client) => {
|
|
160
|
-
console.log('[Task] Healthcheck completed.');
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
`
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
// src/cli.ts
|
|
168
|
-
var import_picocolors = __toESM(require("picocolors"));
|
|
169
|
-
var import_child_process = require("child_process");
|
|
170
|
-
async function main() {
|
|
171
|
-
console.log(import_picocolors.default.bold(import_picocolors.default.blue("\n\u{1F680} Welcome to djs-next!\n")));
|
|
172
|
-
const userAgent = process.env.npm_config_user_agent || "";
|
|
173
|
-
let pm = "npm";
|
|
174
|
-
if (userAgent.startsWith("yarn")) pm = "yarn";
|
|
175
|
-
else if (userAgent.startsWith("pnpm")) pm = "pnpm";
|
|
176
|
-
else if (userAgent.startsWith("bun")) pm = "bun";
|
|
177
|
-
const args = process.argv.slice(2);
|
|
178
|
-
let projectName = args[0] || "";
|
|
179
|
-
if (!projectName || projectName === "init") {
|
|
180
|
-
projectName = await (0, import_prompts.input)({
|
|
181
|
-
message: "What is your project named?",
|
|
182
|
-
default: "my-bot",
|
|
183
|
-
validate: (value) => value.trim().length > 0 || "Project name is required"
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
const language = await (0, import_prompts.select)({
|
|
187
|
-
message: "Would you like to use TypeScript or JavaScript?",
|
|
188
|
-
choices: [
|
|
189
|
-
{ name: "TypeScript", value: "ts" },
|
|
190
|
-
{ name: "JavaScript", value: "js" }
|
|
191
|
-
],
|
|
192
|
-
default: "ts"
|
|
193
|
-
});
|
|
194
|
-
const moduleSystem = await (0, import_prompts.select)({
|
|
195
|
-
message: "Would you like to use ES Modules or CommonJS?",
|
|
196
|
-
choices: [
|
|
197
|
-
{ name: "ES Modules (import/export)", value: "esm" },
|
|
198
|
-
{ name: "CommonJS (require/module.exports)", value: "cjs" }
|
|
199
|
-
],
|
|
200
|
-
default: "esm"
|
|
201
|
-
});
|
|
202
|
-
const botToken = await (0, import_prompts.password)({
|
|
203
|
-
message: "What is your Discord Bot Token? (Leave empty to skip)",
|
|
204
|
-
mask: true
|
|
205
|
-
});
|
|
206
|
-
const clientId = await (0, import_prompts.input)({
|
|
207
|
-
message: "What is your Discord Client ID? (Leave empty to skip)"
|
|
208
|
-
});
|
|
209
|
-
const targetPath = import_path.default.resolve(process.cwd(), projectName);
|
|
210
|
-
if (import_fs.default.existsSync(targetPath)) {
|
|
211
|
-
console.error(import_picocolors.default.red(`
|
|
212
|
-
Directory "${projectName}" already exists.`));
|
|
213
|
-
process.exit(1);
|
|
214
|
-
}
|
|
215
|
-
console.log(import_picocolors.default.cyan(`
|
|
216
|
-
Scaffolding project in ${targetPath}...`));
|
|
217
|
-
import_fs.default.mkdirSync(targetPath, { recursive: true });
|
|
218
|
-
const isTS = language === "ts";
|
|
219
|
-
const isESM = moduleSystem === "esm";
|
|
220
|
-
const ext = isTS ? "ts" : "js";
|
|
221
|
-
let devScript = isTS ? "tsx watch src/index.ts" : "node --watch src/index.js";
|
|
222
|
-
let startScript = isTS ? "node dist/index.js" : "node src/index.js";
|
|
223
|
-
if (pm === "bun") {
|
|
224
|
-
devScript = `bun run --watch src/index.${ext}`;
|
|
225
|
-
startScript = `bun src/index.${ext}`;
|
|
226
|
-
}
|
|
227
|
-
const packageJson = {
|
|
228
|
-
name: projectName.toLowerCase().replace(/\\s+/g, "-"),
|
|
229
|
-
version: "1.0.0",
|
|
230
|
-
main: isTS ? "dist/index.js" : "src/index.js",
|
|
231
|
-
type: isESM ? "module" : "commonjs",
|
|
232
|
-
scripts: {
|
|
233
|
-
"dev": devScript,
|
|
234
|
-
"start": startScript
|
|
235
|
-
},
|
|
236
|
-
dependencies: {
|
|
237
|
-
"discord.js": "latest",
|
|
238
|
-
"djs-next": "latest",
|
|
239
|
-
"dotenv": "latest"
|
|
240
|
-
},
|
|
241
|
-
devDependencies: {}
|
|
242
|
-
};
|
|
243
|
-
if (isTS) {
|
|
244
|
-
packageJson.scripts.build = "tsc";
|
|
245
|
-
packageJson.devDependencies = {
|
|
246
|
-
"typescript": "latest",
|
|
247
|
-
"@types/node": "latest",
|
|
248
|
-
"tsx": "latest"
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
import_fs.default.writeFileSync(import_path.default.join(targetPath, "package.json"), JSON.stringify(packageJson, null, 2));
|
|
252
|
-
if (isTS) {
|
|
253
|
-
const tsconfig = {
|
|
254
|
-
compilerOptions: {
|
|
255
|
-
target: "ES2022",
|
|
256
|
-
module: isESM ? "NodeNext" : "CommonJS",
|
|
257
|
-
moduleResolution: isESM ? "NodeNext" : "Node",
|
|
258
|
-
strict: true,
|
|
259
|
-
esModuleInterop: true,
|
|
260
|
-
outDir: "./dist",
|
|
261
|
-
types: ["node"],
|
|
262
|
-
ignoreDeprecations: "5.0"
|
|
263
|
-
},
|
|
264
|
-
include: ["src/**/*"]
|
|
265
|
-
};
|
|
266
|
-
import_fs.default.writeFileSync(import_path.default.join(targetPath, "tsconfig.json"), JSON.stringify(tsconfig, null, 2));
|
|
267
|
-
}
|
|
268
|
-
import_fs.default.writeFileSync(import_path.default.join(targetPath, ".env"), `DISCORD_TOKEN=${botToken || "your_token_here"}
|
|
269
|
-
CLIENT_ID=${clientId || "your_client_id_here"}
|
|
270
|
-
`);
|
|
271
|
-
import_fs.default.writeFileSync(import_path.default.join(targetPath, ".gitignore"), `node_modules/
|
|
272
|
-
dist/
|
|
273
|
-
.env
|
|
274
|
-
.DS_Store
|
|
275
|
-
`);
|
|
276
|
-
const srcDir = import_path.default.join(targetPath, "src");
|
|
277
|
-
import_fs.default.mkdirSync(srcDir, { recursive: true });
|
|
278
|
-
import_fs.default.mkdirSync(import_path.default.join(srcDir, "commands"), { recursive: true });
|
|
279
|
-
import_fs.default.mkdirSync(import_path.default.join(srcDir, "events"), { recursive: true });
|
|
280
|
-
import_fs.default.mkdirSync(import_path.default.join(srcDir, "components", "buttons"), { recursive: true });
|
|
281
|
-
import_fs.default.mkdirSync(import_path.default.join(srcDir, "tasks"), { recursive: true });
|
|
282
|
-
if (isTS) {
|
|
283
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, `index.${ext}`), tsTemplates.index);
|
|
284
|
-
} else if (isESM) {
|
|
285
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, `index.${ext}`), esmTemplates.index);
|
|
286
|
-
} else {
|
|
287
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, "index.js"), cjsTemplates.index);
|
|
288
|
-
}
|
|
289
|
-
if (isTS) {
|
|
290
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, "commands", "ping.ts"), tsTemplates.ping);
|
|
291
|
-
} else if (isESM) {
|
|
292
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, "commands", "ping.js"), esmTemplates.ping);
|
|
293
|
-
} else {
|
|
294
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, "commands", "ping.js"), cjsTemplates.ping);
|
|
295
|
-
}
|
|
296
|
-
if (isTS) {
|
|
297
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, "events", "ready.ts"), tsTemplates.ready);
|
|
298
|
-
} else if (isESM) {
|
|
299
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, "events", "ready.js"), esmTemplates.ready);
|
|
300
|
-
} else {
|
|
301
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, "events", "ready.js"), cjsTemplates.ready);
|
|
302
|
-
}
|
|
303
|
-
if (isTS) {
|
|
304
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, "tasks", "healthcheck.ts"), tsTemplates.healthcheck);
|
|
305
|
-
} else if (isESM) {
|
|
306
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, "tasks", "healthcheck.js"), esmTemplates.healthcheck);
|
|
307
|
-
} else {
|
|
308
|
-
import_fs.default.writeFileSync(import_path.default.join(srcDir, "tasks", "healthcheck.js"), cjsTemplates.healthcheck);
|
|
309
|
-
}
|
|
310
|
-
console.log(import_picocolors.default.cyan(`
|
|
311
|
-
Installing dependencies with ${pm}...`));
|
|
312
|
-
try {
|
|
313
|
-
(0, import_child_process.execSync)(`${pm} install`, { cwd: targetPath, stdio: "inherit" });
|
|
314
|
-
} catch (error) {
|
|
315
|
-
console.error(import_picocolors.default.red(`
|
|
316
|
-
Failed to install dependencies. Please run '${pm} install' manually.`));
|
|
317
|
-
}
|
|
318
|
-
console.log(import_picocolors.default.green(import_picocolors.default.bold(`
|
|
319
|
-
Success! Created ${projectName} at ${targetPath}`)));
|
|
320
|
-
console.log(`
|
|
321
|
-
Inside that directory, you can run several commands:`);
|
|
322
|
-
console.log(import_picocolors.default.cyan(`
|
|
323
|
-
${pm} run dev`));
|
|
324
|
-
console.log(` Starts the development server with hot-reloading.`);
|
|
325
|
-
if (isTS) {
|
|
326
|
-
console.log(import_picocolors.default.cyan(`
|
|
327
|
-
${pm} run build`));
|
|
328
|
-
console.log(` Compiles the TypeScript app into JavaScript.`);
|
|
329
|
-
}
|
|
330
|
-
console.log(import_picocolors.default.cyan(`
|
|
331
|
-
${pm} start`));
|
|
332
|
-
console.log(` Starts the production server.`);
|
|
333
|
-
console.log(`
|
|
334
|
-
We suggest that you begin by typing:
|
|
335
|
-
`);
|
|
336
|
-
console.log(import_picocolors.default.cyan(` cd ${projectName}`));
|
|
337
|
-
console.log(import_picocolors.default.cyan(` ${pm} run dev
|
|
338
|
-
`));
|
|
339
|
-
}
|
|
340
|
-
main().catch((err) => {
|
|
341
|
-
console.error(import_picocolors.default.red("An unexpected error occurred:"), err);
|
|
342
|
-
process.exit(1);
|
|
343
|
-
});
|
|
344
|
-
//# sourceMappingURL=cli.js.map
|