Skip to content

Commit 54168ba

Browse files
committed
feat: i18n wip
1 parent d8c9bee commit 54168ba

24 files changed

+772
-88
lines changed

apps/test-bot/commandkit.config.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { defineConfig } from 'commandkit';
22
import { legacy } from '@commandkit/legacy';
3+
import { i18n } from '@commandkit/i18n';
34

45
export default defineConfig({
5-
plugins: [legacy({ skipBuiltInValidations: true })],
6+
plugins: [i18n(), legacy({ skipBuiltInValidations: true })],
67
});

apps/test-bot/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"dependencies": {
1212
"commandkit": "workspace:*",
1313
"@commandkit/devtools": "workspace:*",
14+
"@commandkit/i18n": "workspace:*",
1415
"@commandkit/legacy": "workspace:*",
1516
"discord.js": "^14.17.3",
1617
"dotenv": "^16.4.7"

apps/test-bot/src/app/commands/(general)/avatar.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ export const command = {
2020
export async function userContextMenu(ctx: UserContextMenuCommandContext) {
2121
const target = ctx.interaction.targetUser;
2222

23+
const { t } = ctx.locale();
24+
2325
await ctx.interaction.reply({
2426
embeds: [
2527
{
26-
title: `${target.username}'s Avatar`,
28+
title: t('avatar', {
29+
user: target.username,
30+
}),
2731
image: {
2832
url: target.displayAvatarURL({ size: 2048 }),
2933
},
@@ -35,11 +39,14 @@ export async function userContextMenu(ctx: UserContextMenuCommandContext) {
3539

3640
export async function chatInput(ctx: SlashCommandContext) {
3741
const user = ctx.options.getUser('user') ?? ctx.interaction.user;
42+
const { t } = ctx.locale();
3843

3944
await ctx.interaction.reply({
4045
embeds: [
4146
{
42-
title: `${user.username}'s Avatar`,
47+
title: t('avatar', {
48+
user: user.username,
49+
}),
4350
image: {
4451
url: user.displayAvatarURL({ size: 2048 }),
4552
},
@@ -51,11 +58,14 @@ export async function chatInput(ctx: SlashCommandContext) {
5158

5259
export async function message(ctx: MessageCommandContext) {
5360
const user = ctx.options.getUser('user') ?? ctx.message.author;
61+
const { t } = ctx.locale();
5462

5563
await ctx.message.reply({
5664
embeds: [
5765
{
58-
title: `${user.username}'s Avatar`,
66+
title: t('avatar', {
67+
user: user.username,
68+
}),
5969
image: {
6070
url: user.displayAvatarURL({ size: 2048 }),
6171
},

apps/test-bot/src/app/locales/en-US/avatar.json

-15
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default {
2+
$command: {
3+
name: 'avatar',
4+
description: 'This is an avatar command.',
5+
options: [
6+
{
7+
name: 'user',
8+
description: 'The user to get the avatar for.',
9+
},
10+
],
11+
},
12+
avatar: "{{user}}'s avatar",
13+
};

apps/test-bot/src/app/locales/en-US/cat.json

-7
This file was deleted.

apps/test-bot/src/app/locales/en-US/legacy.json

-9
This file was deleted.

apps/test-bot/src/app/locales/en-US/prompt.json

-11
This file was deleted.

apps/test-bot/src/app/locales/fr/avatar.json

-15
This file was deleted.
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default {
2+
$command: {
3+
name: 'avatar',
4+
description: "C'est une commande pour afficher l'avatar.",
5+
options: [
6+
{
7+
name: 'user',
8+
description: "L'utilisateur dont vous souhaitez voir l'avatar.",
9+
},
10+
],
11+
},
12+
avatar: 'Avatar de {{user}}',
13+
};

apps/test-bot/src/app/locales/fr/prompt.json

-11
This file was deleted.

apps/test-bot/tsconfig.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
"skipDefaultLibCheck": true,
1414
"allowJs": true,
1515
"alwaysStrict": false,
16-
"checkJs": false
16+
"checkJs": false,
17+
"strict": true,
18+
"strictNullChecks": true
1719
},
1820
"include": ["src", "commandkit.config.ts", "commandkit-env.d.ts"]
1921
}

packages/commandkit/src/CommandKit.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,10 @@ export class CommandKit extends EventEmitter {
137137
});
138138

139139
await this.options.client.login(
140-
token ?? process.env.TOKEN ?? process.env.DISCORD_TOKEN,
140+
token ??
141+
this.options.client.token ??
142+
process.env.TOKEN ??
143+
process.env.DISCORD_TOKEN,
141144
);
142145

143146
await this.plugins.execute((ctx, plugin) => {
@@ -155,7 +158,7 @@ export class CommandKit extends EventEmitter {
155158
*/
156159
async loadPlugins() {
157160
const config = await loadConfigFile();
158-
const plugins = config.plugins.filter((p) => isRuntimePlugin(p));
161+
const plugins = config.plugins.flat(2).filter((p) => isRuntimePlugin(p));
159162

160163
if (!plugins.length) return;
161164

packages/commandkit/src/app/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export * from './handlers/AppCommandHandler';
22
export * from './commands/Context';
33
export * from './commands/MessageCommandParser';
44
export * from './middleware/signals';
5+
export * from './register/CommandRegistrar';
56

67
export {
78
type CommandSource,

packages/commandkit/src/app/register/CommandRegistrar.ts

+72-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
import {
2-
ApplicationCommandType,
3-
REST,
4-
Routes,
5-
ApplicationCommandOptionType,
6-
APIApplicationCommandSubcommandGroupOption,
7-
APIApplicationCommandSubcommandOption,
8-
} from 'discord.js';
1+
import { ApplicationCommandType, REST, Routes } from 'discord.js';
92
import { CommandKit } from '../../CommandKit';
103
import { CommandData } from '../../types';
114
import { Logger } from '../../logger/Logger';
12-
import { Command } from '../router/CommandsRouter';
5+
6+
export interface PreRegisterCommandsEvent {
7+
preventDefault(): void;
8+
commands: CommandData[];
9+
}
1310

1411
export class CommandRegistrar {
1512
private api = new REST();
@@ -80,11 +77,30 @@ export class CommandRegistrar {
8077
* Registers loaded commands.
8178
*/
8279
public async register() {
80+
const commands = this.getCommandsData();
81+
82+
let preRegistrationPrevented = false;
83+
const preRegisterEvent: PreRegisterCommandsEvent = {
84+
preventDefault() {
85+
preRegistrationPrevented = true;
86+
},
87+
commands,
88+
};
89+
90+
await this.commandkit.plugins.execute(async (ctx, plugin) => {
91+
if (preRegistrationPrevented) return;
92+
return plugin.onBeforeRegisterCommands(ctx, preRegisterEvent);
93+
});
94+
95+
if (preRegistrationPrevented) return;
96+
97+
// we check this after the plugin event
98+
// because plugins may be able to register commands
99+
// before the client is ready
83100
if (!this.commandkit.client.isReady()) {
84101
throw new Error('Cannot register commands before the client is ready');
85102
}
86103

87-
const commands = this.getCommandsData();
88104
const guildCommands = commands
89105
.filter((command) => command.guilds?.filter(Boolean).length)
90106
.map((c) => ({
@@ -105,6 +121,19 @@ export class CommandRegistrar {
105121
public async updateGlobalCommands(commands: CommandData[]) {
106122
if (!commands.length) return;
107123

124+
let prevented = false;
125+
const preRegisterEvent: PreRegisterCommandsEvent = {
126+
preventDefault() {
127+
prevented = true;
128+
},
129+
commands,
130+
};
131+
132+
await this.commandkit.plugins.execute(async (ctx, plugin) => {
133+
if (prevented) return;
134+
return plugin.onBeforeRegisterGlobalCommands(ctx, preRegisterEvent);
135+
});
136+
108137
try {
109138
const data = (await this.api.put(
110139
Routes.applicationCommands(this.commandkit.client.user!.id),
@@ -128,6 +157,24 @@ export class CommandRegistrar {
128157
* Updates the guild commands.
129158
*/
130159
public async updateGuildCommands(commands: CommandData[]) {
160+
if (!commands.length) return;
161+
162+
let prevented = false;
163+
const preRegisterEvent: PreRegisterCommandsEvent = {
164+
preventDefault() {
165+
prevented = true;
166+
},
167+
commands,
168+
};
169+
await this.commandkit.plugins.execute(async (ctx, plugin) => {
170+
if (prevented) return;
171+
return plugin.onBeforePrepareGuildCommandsRegistration(
172+
ctx,
173+
preRegisterEvent,
174+
);
175+
});
176+
if (prevented) return;
177+
131178
try {
132179
const guildCommandsMap = new Map<string, CommandData[]>();
133180

@@ -148,6 +195,21 @@ export class CommandRegistrar {
148195
let count = 0;
149196

150197
for (const [guild, guildCommands] of guildCommandsMap) {
198+
let prevented = false;
199+
const preRegisterEvent: PreRegisterCommandsEvent = {
200+
preventDefault() {
201+
prevented = true;
202+
},
203+
commands: guildCommands,
204+
};
205+
206+
await this.commandkit.plugins.execute(async (ctx, plugin) => {
207+
if (prevented) return;
208+
return plugin.onBeforeRegisterGuildCommands(ctx, preRegisterEvent);
209+
});
210+
211+
if (prevented) continue;
212+
151213
const data = (await this.api.put(
152214
Routes.applicationGuildCommands(
153215
this.commandkit.client.user!.id,

packages/commandkit/src/cli/development.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ async function buildAndStart(configPath: string, skipStart = false) {
1818
await buildApplication({
1919
configPath,
2020
isDev: true,
21-
plugins: config.plugins.filter((p) => isCompilerPlugin(p)),
21+
plugins: config.plugins.flat(2).filter((p) => isCompilerPlugin(p)),
2222
esbuildPlugins: config.esbuildPlugins,
2323
});
2424

packages/commandkit/src/config/config.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { MaybeArray } from '../components';
2+
import { CommandKitPlugin } from '../plugins';
13
import { defaultConfig } from './default';
24
import { CommandKitConfig } from './types';
35
import { ResolvedCommandKitConfig } from './utils';
@@ -43,7 +45,10 @@ export function defineConfig(
4345
...(config.esbuildPlugins ?? []),
4446
...(defaultConfig.esbuildPlugins ?? []),
4547
],
46-
plugins: [...(config.plugins ?? []), ...(defaultConfig.plugins ?? [])],
48+
plugins: [
49+
...(config.plugins ?? []),
50+
...(defaultConfig.plugins ?? []),
51+
] as MaybeArray<CommandKitPlugin[]>,
4752
sourceMap: {
4853
...defaultConfig.sourceMap,
4954
...config.sourceMap,

packages/commandkit/src/config/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
import { MaybeArray } from '../components';
12
import { CommandKitPlugin } from '../plugins';
23

34
export interface CommandKitConfig {
45
/**
56
* The plugins to use with CommandKit.
67
*/
7-
plugins?: CommandKitPlugin[];
8+
plugins?: MaybeArray<CommandKitPlugin[]>;
89
/**
910
* The esbuild plugins to use with CommandKit.
1011
*/

0 commit comments

Comments
 (0)