Skip to content

Commit 9571ff6

Browse files
committed
feat: locale cli template
1 parent cdd4c5a commit 9571ff6

File tree

7 files changed

+120
-18
lines changed

7 files changed

+120
-18
lines changed

packages/commandkit/src/cli/env.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,7 @@ export const ProdEnvFiles = ['.env.production', '.env.production.local'];
2727
export const devEnvFileArgs = [...CommonEnvFiles, ...DevEnvFiles];
2828

2929
export const prodEnvFileArgs = [...CommonEnvFiles, ...ProdEnvFiles];
30+
31+
export function setCLIEnv() {
32+
process.env.COMMANDKIT_IS_CLI = 'true';
33+
}

packages/commandkit/src/cli/init.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export async function bootstrapCommandkitCLI(
3030
const { generateCommand, generateEvent } = await import('./generators');
3131
const { version } = await import('../version');
3232
const { showInformation } = await import('./information');
33+
const { setCLIEnv } = await import('./env');
3334

3435
const program = new Command('commandkit');
3536

@@ -72,6 +73,7 @@ export async function bootstrapCommandkitCLI(
7273
.description('Build your project for production usage.')
7374
.option('-c, --config [path]', 'Path to your commandkit config file.')
7475
.action(() => {
76+
setCLIEnv();
7577
const options = program.opts();
7678
return createProductionBuild(options.config);
7779
});
@@ -87,6 +89,8 @@ export async function bootstrapCommandkitCLI(
8789
)
8890
.argument('[args...]', 'Additional arguments for the template')
8991
.action(async (template, args) => {
92+
setCLIEnv();
93+
9094
// Handle custom plugin templates
9195
const { plugins } = await loadConfigFile();
9296
const runtime = new CompilerPluginRuntime(

packages/commandkit/src/utils/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export const COMMANDKIT_CACHE_TAG = Symbol('kCommandKitCacheTag');
22

33
export const COMMANDKIT_IS_DEV = process.env.COMMANDKIT_IS_DEV === 'true';
4-
4+
export const COMMANDKIT_IS_CLI = process.env.COMMANDKIT_IS_CLI === 'true';
55
export const COMMANDKIT_IS_TEST = process.env.COMMANDKIT_IS_TEST === 'true';
66

77
export const COMMANDKIT_BOOTSTRAP_MODE = (process.env

packages/commandkit/src/utils/utilities.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
import { existsSync } from 'node:fs';
22
import { join } from 'node:path';
3-
import { COMMANDKIT_IS_DEV } from './constants';
3+
import { COMMANDKIT_IS_CLI, COMMANDKIT_IS_DEV } from './constants';
44
import { getConfig } from '../config/config';
55
import { eventWorkerContext } from '../app/events/EventWorkerContext';
66

77
let appDir: string | null = null;
88
let currentDir: string | null = null;
99

10+
function getSrcDir() {
11+
if (COMMANDKIT_IS_CLI) {
12+
return 'src';
13+
}
14+
15+
if (COMMANDKIT_IS_DEV) {
16+
return '.commandkit';
17+
}
18+
19+
return getConfig().distDir;
20+
}
21+
1022
export function getCurrentDirectory(): string {
1123
if (currentDir) return currentDir;
12-
13-
let root = join(
14-
process.cwd(),
15-
COMMANDKIT_IS_DEV ? '.commandkit' : getConfig().distDir,
16-
);
24+
const src = getSrcDir();
25+
let root = join(process.cwd(), src);
1726

1827
if (!existsSync(root)) root = process.cwd();
1928

@@ -38,10 +47,7 @@ export function getSourceDirectories(): string[] {
3847
export function findAppDirectory(): string | null {
3948
if (appDir) return appDir;
4049

41-
let root = join(
42-
process.cwd(),
43-
COMMANDKIT_IS_DEV ? '.commandkit' : getConfig().distDir,
44-
);
50+
let root = join(process.cwd(), getSrcDir());
4551

4652
if (!existsSync(root)) root = process.cwd();
4753

packages/i18n/src/cli.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { CompilerPlugin, CompilerPluginRuntime, Logger } from 'commandkit';
2+
import { DISCORD_LOCALES } from './constants';
3+
import { Locale } from 'discord.js';
4+
import { I18nPlugin } from './i18n';
5+
import { existsSync, mkdirSync, writeFileSync } from 'fs';
6+
import { join } from 'path';
7+
8+
export class I18nCliTemplatePlugin extends CompilerPlugin {
9+
public readonly name = 'I18nCliTemplatePlugin';
10+
11+
public async activate(ctx: CompilerPluginRuntime): Promise<void> {
12+
try {
13+
ctx.registerTemplate('locale', this.handleTemplate.bind(this));
14+
} catch (e) {
15+
Logger.error(`Failed to register CLI template "locale": ${e}`);
16+
}
17+
}
18+
19+
public async deactivate(ctx: CompilerPluginRuntime): Promise<void> {
20+
ctx.unregisterTemplate('locale');
21+
}
22+
23+
private panic(message: string): never {
24+
Logger.error(message);
25+
process.exit(1);
26+
}
27+
28+
private async handleTemplate(args: string[]): Promise<void> {
29+
if (args.length < 2) {
30+
this.panic(
31+
`Invalid arguments for locale template. Expected: <locale> <commandName>`,
32+
);
33+
}
34+
35+
const [locale, commandName] = args;
36+
37+
if (!DISCORD_LOCALES.has(locale as Locale)) {
38+
this.panic(
39+
`Invalid locale ${locale}. Please use one of the followings:\n${Array.from(
40+
DISCORD_LOCALES,
41+
)
42+
.map((l) => `- ${l}`)
43+
.join('\n')}`,
44+
);
45+
}
46+
47+
const localePath = I18nPlugin.getLoadPath('src', locale, commandName);
48+
49+
if (existsSync(localePath)) {
50+
this.panic(`Locale file for "${locale}:${commandName}" already exists.`);
51+
}
52+
53+
const localeDirSrc = join(localePath, '..', '..');
54+
55+
if (!existsSync(localeDirSrc)) {
56+
this.panic(
57+
`Could not locate source directory. Please make sure you are running this command from the location of your commandkit config file.`,
58+
);
59+
}
60+
61+
const localeDir = join(localePath, '..');
62+
63+
if (!existsSync(localeDir)) {
64+
mkdirSync(localeDir, { recursive: true });
65+
}
66+
67+
const data = {
68+
$command: {
69+
name: commandName,
70+
description: `${commandName} command`,
71+
},
72+
};
73+
74+
writeFileSync(localePath, JSON.stringify(data, null, 2));
75+
76+
Logger.info(
77+
`Locale file for ${locale} and ${commandName} created at ${localePath}`,
78+
);
79+
}
80+
}

packages/i18n/src/i18n.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,17 @@ export class I18nPlugin extends RuntimePlugin<LocalizationPluginOptions> {
183183
Logger.info('I18nPlugin has been activated');
184184
}
185185

186-
private getLoadPath() {
187-
return join(getCurrentDirectory(), '/app/locales/{{lng}}/{{ns}}.json');
186+
public static getLoadPath(
187+
cwd = getCurrentDirectory(),
188+
lng = '{{lng}}',
189+
ns = '{{ns}}',
190+
) {
191+
return join(cwd, `/app/locales/${lng}/${ns}.json`);
188192
}
189193

190194
private async scanLocaleDirectory() {
191195
const endPattern = /{{lng}}(\/|\\){{ns}}.json$/;
192-
const localesPath = this.getLoadPath();
196+
const localesPath = I18nPlugin.getLoadPath();
193197
const scanDirTarget = localesPath.replace(endPattern, '');
194198

195199
if (!existsSync(scanDirTarget)) {
@@ -301,7 +305,7 @@ export class I18nPlugin extends RuntimePlugin<LocalizationPluginOptions> {
301305
}
302306

303307
private getBackendOptions() {
304-
const loadPath = this.getLoadPath();
308+
const loadPath = I18nPlugin.getLoadPath();
305309

306310
return {
307311
loadPath: function (lng: string, namespace: string) {

packages/i18n/src/index.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import { I18nCliTemplatePlugin } from './cli';
12
import { I18nPlugin, LocalizationPluginOptions } from './i18n';
23

3-
export function i18n(options?: LocalizationPluginOptions) {
4+
export function i18n(
5+
options?: LocalizationPluginOptions,
6+
): [I18nPlugin, I18nCliTemplatePlugin] {
47
const opt = {
58
...options,
69
i18nOptions: {
@@ -15,8 +18,9 @@ export function i18n(options?: LocalizationPluginOptions) {
1518

1619
const localization = new I18nPlugin(opt);
1720

18-
return localization;
21+
return [localization, new I18nCliTemplatePlugin({})];
1922
}
2023

24+
export { I18nCliTemplatePlugin };
2125
export { locale } from './hooks';
22-
export { getI18n, type CommandLocalizationContext } from './i18n';
26+
export { getI18n, I18nPlugin, type CommandLocalizationContext } from './i18n';

0 commit comments

Comments
 (0)