Skip to content

Commit 7a89fcf

Browse files
authored
Merge pull request #1 from DiscordFactory/cli-next
Cli next
2 parents a6d2dd5 + f8baeba commit 7a89fcf

File tree

9 files changed

+287
-57
lines changed

9 files changed

+287
-57
lines changed

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@discord-factory/core-commands",
3-
"version": "1.2.0",
3+
"version": "2.0.1",
44
"description": "",
55
"main": "build/index.js",
66
"author": "Baptiste Parmantier <[email protected]>",
@@ -35,10 +35,11 @@
3535
"verbose": true
3636
},
3737
"dependencies": {
38-
"@discord-factory/core-next": "^1.3.0",
38+
"@discord-factory/core-next": "2.0.0",
3939
"@leadcodedev/logger": "^1.0.0",
4040
"@typescript-eslint/eslint-plugin": "^4.31.1",
4141
"@typescript-eslint/parser": "^4.31.1",
42-
"discord.js": "^13.1.0"
42+
"discord.js": "^13.1.0",
43+
"enquirer": "^2.3.6"
4344
}
4445
}

src/commands/MakeCommand.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
import { CLICommand, BaseAddonCommand } from '@discord-factory/core-next'
1+
import { CLI, BaseCli, CliContextRuntime } from '@discord-factory/core-next'
22
import Addon from '../index'
33
import path from 'path'
44
import fs from 'fs'
55
import Logger from '@leadcodedev/logger'
66

7-
@CLICommand({
8-
name: 'Create command file',
7+
@CLI({
98
prefix: 'make:command',
10-
usages: ['filename']
9+
description: 'Generate a new command file at the given location',
10+
args: ['filename'],
11+
config: {
12+
allowUnknownOptions: false,
13+
ignoreOptionDefaultValue: false
14+
}
1115
})
12-
export default class MakeCommand extends BaseAddonCommand<Addon> {
13-
public async run (filename: string): Promise<void> {
14-
const location = path.parse(filename)
16+
export default class MakeCommand extends BaseCli<Addon> {
17+
public async run ({ args }: CliContextRuntime): Promise<void> {
18+
const location = path.parse(args.filename as string)
1519
const targetFile = path.join(process.cwd(), 'src', location.dir, `${location.name}.ts`)
1620

1721
const templateFile = await fs.promises.readFile(
@@ -29,7 +33,7 @@ export default class MakeCommand extends BaseAddonCommand<Addon> {
2933
await fs.promises.writeFile(targetFile, fileData)
3034
Logger.send('info', `File was created in ${targetFile.replace(/\\/g, '\\\\')}`)
3135
} catch (e) {
32-
console.log(e)
36+
Logger.send('error', 'An error has occurred')
3337
}
3438
}
3539
}

src/commands/MakeContextMenu.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
import { CLICommand, BaseAddonCommand } from '@discord-factory/core-next'
1+
import { CLI, BaseCli, CliContextRuntime } from '@discord-factory/core-next'
22
import Addon from '../index'
33
import path from 'path'
44
import fs from 'fs'
55
import Logger from '@leadcodedev/logger'
66

7-
@CLICommand({
8-
name: 'Create context menu file',
7+
@CLI({
98
prefix: 'make:context-menu',
10-
usages: ['filename']
9+
description: 'Generate a new context-menu file at the given location',
10+
args: ['filename'],
11+
config: {
12+
allowUnknownOptions: false,
13+
ignoreOptionDefaultValue: false
14+
}
1115
})
12-
export default class MakeContextMenu extends BaseAddonCommand<Addon> {
13-
public async run (filename: string): Promise<void> {
14-
const location = path.parse(filename)
16+
export default class MakeContextMenu extends BaseCli<Addon> {
17+
public async run ({ args }: CliContextRuntime): Promise<void> {
18+
const location = path.parse(args.filename as string)
1519
const targetFile = path.join(process.cwd(), 'src', location.dir, `${location.name}.ts`)
1620

1721
const templateFile = await fs.promises.readFile(
@@ -29,7 +33,7 @@ export default class MakeContextMenu extends BaseAddonCommand<Addon> {
2933
await fs.promises.writeFile(targetFile, fileData)
3034
Logger.send('info', `File was created in ${targetFile.replace(/\\/g, '\\\\')}`)
3135
} catch (e) {
32-
console.log(e)
36+
Logger.send('error', 'An error has occurred')
3337
}
3438
}
3539
}

src/commands/MakeEcosystem.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
import { CLICommand, BaseAddonCommand } from '@discord-factory/core-next'
1+
import { CLI, BaseCli } from '@discord-factory/core-next'
22
import Addon from '../index'
33
import path from 'path'
44
import fs from 'fs'
55
import Logger from '@leadcodedev/logger'
66

7-
@CLICommand({
8-
name: 'Create ecosystem file',
7+
@CLI({
98
prefix: 'pm2:ecosystem',
10-
usages: []
9+
description: 'Generate a new ecosystem.config.js file at root project',
10+
config: {
11+
allowUnknownOptions: false,
12+
ignoreOptionDefaultValue: false
13+
}
1114
})
12-
export default class MakeEcosystem extends BaseAddonCommand<Addon> {
13-
public async run (filename: string): Promise<void> {
15+
export default class MakeEcosystem extends BaseCli<Addon> {
16+
public async run (): Promise<void> {
1417
const targetFile = path.join(process.cwd(), 'ecosystem.config.js')
1518

1619
const templateFile = await fs.promises.readFile(
@@ -21,7 +24,7 @@ export default class MakeEcosystem extends BaseAddonCommand<Addon> {
2124
await fs.promises.writeFile(targetFile, templateFile)
2225
Logger.send('info', 'Ecosystem file was create in your root project.')
2326
} catch (e) {
24-
console.log(e)
27+
Logger.send('error', 'An error has occurred')
2528
}
2629
}
2730
}

src/commands/MakeEvent.ts

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,85 @@
1-
import { CLICommand, BaseAddonCommand } from '@discord-factory/core-next'
1+
import { CLI, BaseCli, CliContextRuntime } from '@discord-factory/core-next'
22
import Addon from '../index'
33
import path from 'path'
4-
import fs from 'fs'
54
import Logger from '@leadcodedev/logger'
5+
import { prompt } from 'enquirer'
6+
import { eventList, makeFileName } from '../utils'
7+
import fs from 'fs'
68

7-
@CLICommand({
8-
name: 'Create event file',
9+
@CLI({
910
prefix: 'make:event',
10-
usages: ['filename']
11+
description: 'Generate a new event file at the given location',
12+
args: ['filename'],
13+
config: {
14+
allowUnknownOptions: false,
15+
ignoreOptionDefaultValue: false
16+
}
1117
})
12-
export default class MakeEvent extends BaseAddonCommand<Addon> {
13-
public async run (filename: string): Promise<void> {
14-
const location = path.parse(filename)
18+
export default class MakeEvent extends BaseCli<Addon> {
19+
public async run ({ args }: CliContextRuntime): Promise<void> {
20+
const location = path.parse(args.filename as string)
1521
const targetFile = path.join(process.cwd(), 'src', location.dir, `${location.name}.ts`)
1622

23+
const result = await this.choiceEvent() as { event: string }
24+
const eventParams = eventList[result.event] as string
25+
const types = eventParams.includes(',')
26+
? eventParams.split(',')
27+
: [eventParams]
28+
29+
const paramsTypes = this.getUniqueTypes(types
30+
.flatMap((param: string) => param.split(': ')[1])
31+
.filter((a) => a !== 'string' && a !== 'number' && a !== 'null' && a !== 'undefined')
32+
)
33+
34+
const importParamsTypes = paramsTypes
35+
.join(', ')
36+
1737
const templateFile = await fs.promises.readFile(
1838
path.join(__dirname, '..', '..', 'src', 'templates', 'Event.txt'),
1939
{ encoding: 'utf-8' }) as unknown as string
2040

21-
const filenameUpper = location.name.charAt(0).toUpperCase() + location.name.slice(1)
22-
2341
try {
2442
await fs.promises.mkdir(path.join(process.cwd(), 'src', location.dir), { recursive: true })
25-
const fileData = templateFile.replace(/\$fileName/g, filenameUpper)
43+
const fileData = templateFile
44+
.replace(/\$fileName/g, makeFileName(location.name))
45+
.replace(/\$event/g, result.event)
46+
.replace(/\$params/g, eventParams)
47+
.replace(/\$imports/g, `import { ${importParamsTypes} } from 'discord.js'`)
2648

2749
await fs.promises.writeFile(targetFile, fileData)
2850
Logger.send('info', `File was created in ${targetFile.replace(/\\/g, '\\\\')}`)
2951
} catch (e) {
30-
console.log(e)
52+
Logger.send('error', e.message)
3153
}
3254
}
55+
56+
protected async choiceEvent (): Promise<any> {
57+
try {
58+
return prompt({
59+
name: 'event',
60+
message: 'Please choose an event from the list below',
61+
type: 'autocomplete',
62+
choices: Object.keys(eventList),
63+
})
64+
} catch {
65+
Logger.send('error', 'An error has occurred')
66+
}
67+
}
68+
69+
private getUniqueTypes(duplicateTypes) {
70+
const array: string[] = []
71+
duplicateTypes.forEach((type: string) => {
72+
const whitelistedType = type
73+
.replace(/\| null/g, '')
74+
.replace(/\| number/g, '')
75+
.replace(/\| string/g, '')
76+
.replace(/\| undefined/g, '')
77+
.trim()
78+
79+
if (!array.includes(whitelistedType)) {
80+
array.push(whitelistedType)
81+
}
82+
})
83+
return array
84+
}
3385
}

src/commands/MakeHook.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
import { CLICommand, BaseAddonCommand } from '@discord-factory/core-next'
1+
import { CLI, BaseCli, CliContextRuntime } from '@discord-factory/core-next'
22
import Addon from '../index'
33
import path from 'path'
44
import fs from 'fs'
55
import Logger from '@leadcodedev/logger'
66

7-
@CLICommand({
8-
name: 'Create hook file',
7+
@CLI({
98
prefix: 'make:hook',
10-
usages: ['filename']
9+
description: 'Generate a new command file at the given location',
10+
args: ['filename'],
11+
config: {
12+
allowUnknownOptions: false,
13+
ignoreOptionDefaultValue: false
14+
}
1115
})
12-
export default class MakeHook extends BaseAddonCommand<Addon> {
13-
public async run (filename: string): Promise<void> {
14-
const location = path.parse(filename)
16+
export default class MakeHook extends BaseCli<Addon> {
17+
public async run ({ args }: CliContextRuntime): Promise<void> {
18+
const location = path.parse(args.filename as string)
1519
const targetFile = path.join(process.cwd(), 'src', location.dir, `${location.name}.ts`)
1620

1721
const templateFile = await fs.promises.readFile(
@@ -27,7 +31,7 @@ export default class MakeHook extends BaseAddonCommand<Addon> {
2731
await fs.promises.writeFile(targetFile, fileData)
2832
Logger.send('info', `File was created in ${targetFile.replace(/\\/g, '\\\\')}`)
2933
} catch (e) {
30-
console.log(e)
34+
Logger.send('error', 'An error has occurred')
3135
}
3236
}
3337
}

src/templates/Event.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { Event, BaseEvent } from 'ioc:factory/Core/Event'
2+
$imports
23

3-
@Event('myEvent')
4+
@Event('$event')
45
export default class $fileName extends BaseEvent {
5-
public async run (args: string[]): Promise<void> {
6+
public async run ($params): Promise<void> {
67
// Your code here
78
}
89
}

src/utils/index.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
export function makeFileName (name: string) {
2+
return name.charAt(0).toUpperCase() + name.slice(1)
3+
}
4+
5+
export const eventList = {
6+
applicationCommandCreate: 'command: ApplicationCommand',
7+
applicationCommandDelete: 'command: ApplicationCommand',
8+
applicationCommandUpdate: 'before: ApplicationCommand | null, after: ApplicationCommand',
9+
channelCreate: 'channel: GuildChannel',
10+
channelDelete: 'channel: DMChannel | GuildChannel',
11+
channelPinsUpdate: 'channel: TextBasedChannels, date: Date',
12+
channelUpdate: 'before: DMChannel | GuildChannel, after: DMChannel | GuildChannel',
13+
debug: 'message: string',
14+
warn: 'message: string',
15+
emojiCreate: 'emoji: GuildEmoji',
16+
emojiDelete: 'emoji: GuildEmoji',
17+
emojiUpdate: 'before: GuildEmoji, after: GuildEmoji',
18+
error: 'error: Error',
19+
guildBanAdd: 'ban: GuildBan',
20+
guildBanRemove: 'ban: GuildBan',
21+
guildCreate: 'guild: Guild',
22+
guildDelete: 'guild: Guild',
23+
guildUnavailable: 'guild: Guild',
24+
guildIntegrationsUpdate: 'guild: Guild',
25+
guildMemberAdd: 'member: GuildMember',
26+
guildMemberAvailable: 'member: GuildMember | PartialGuildMember',
27+
guildMemberRemove: 'member: GuildMember | PartialGuildMember',
28+
guildMembersChunk: '',
29+
guildMemberUpdate: 'before: GuildMember | PartialGuildMember, after: GuildMember',
30+
guildUpdate: 'before: Guild, after: Guild',
31+
inviteCreate: 'invite: Invite',
32+
inviteDelete: 'invite: Invite',
33+
message: 'message: Message',
34+
messageCreate: 'message: Message',
35+
messageDelete: 'message: Message | PartialMessage',
36+
messageReactionRemoveAll: 'message: Message | PartialMessage',
37+
messageReactionRemoveEmoji: 'reaction: MessageReaction | PartialMessageReaction',
38+
messageDeleteBulk: 'messages: Collection<Snowflake, Message | PartialMessage>',
39+
messageReactionAdd: 'reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser',
40+
messageReactionRemove: 'reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser',
41+
messageUpdate: 'before: Message | PartialMessage, after: Message | PartialMessage',
42+
presenceUpdate: 'before: Presence | null, after: Presence',
43+
rateLimit: 'rateLimitData: RateLimitData',
44+
invalidRequestWarning: 'invalidRequestWarningData: InvalidRequestWarningData',
45+
ready: 'client: Client<true>',
46+
invalidated: '',
47+
roleCreate: 'role: Role',
48+
roleDelete: 'role: Role',
49+
roleUpdate: 'before: Role, after: Role',
50+
threadCreate: 'thread: ThreadChannel',
51+
threadDelete: 'thread: ThreadChannel',
52+
threadListSync: 'threads: Collection<Snowflake, ThreadChannel>',
53+
threadMemberUpdate: 'before: ThreadMember, after: ThreadMember',
54+
threadMembersUpdate: '',
55+
threadUpdate: 'before: ThreadChannel, after: ThreadChannel',
56+
typingStart: 'typing: Typing',
57+
userUpdate: 'before: User | PartialUser, after: User',
58+
voiceJoin: 'state: VoiceState',
59+
voiceLeave: 'state: VoiceState',
60+
voiceStateUpdate: 'before: VoiceState, after: VoiceState',
61+
webhookUpdate: 'channel: TextChannel',
62+
interactionCreate: 'interaction: Interaction',
63+
shardDisconnect: 'closeEvent: CloseEvent, shardId: number',
64+
shardError: 'error: Error, shardId: number',
65+
shardReady: 'shardId: number, unavailableGuilds: Set<Snowflake> | undefined',
66+
shardReconnecting: 'shardId: number',
67+
shardResume: 'shardId: number, replayedEvents: number',
68+
stageInstanceCreate: 'stageInstance: StageInstance',
69+
stageInstanceUpdate: 'before: StageInstance | null, after: StageInstance',
70+
stageInstanceDelete: 'stageInstance: StageInstance',
71+
stickerCreate: 'sticker: Sticker',
72+
stickerDelete: 'sticker: Sticker',
73+
stickerUpdate: 'before: Sticker, after: Sticker',
74+
}

0 commit comments

Comments
 (0)