Skip to content

Commit

Permalink
Add localizable decorator and localize middleware, clean up middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
zajrik committed Jun 20, 2017
1 parent bd4f128 commit 740c028
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 17 deletions.
32 changes: 31 additions & 1 deletion src/command/CommandDecorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Message } from '../types/Message';
*/
export function using(func: MiddlewareFunction): MethodDecorator
{
return function(target: Command<any>, key: string, descriptor: PropertyDescriptor): PropertyDescriptor
return function(target: Command, key: string, descriptor: PropertyDescriptor): PropertyDescriptor
{
if (!target) throw new Error('@using must be used as a method decorator for a Command action method.');
if (key !== 'action') throw new Error(`"${target.constructor.name}#${key}" is not a valid method target for @using.`);
Expand Down Expand Up @@ -55,6 +55,36 @@ export function using(func: MiddlewareFunction): MethodDecorator
};
}

/**
* Get the localization language for command output and insert
* it as the first argument passed to the command call.
* Identical to {@link Middleware#localize} but used as a Command
* method decorator.
*
* Like the `localize` middleware, you will want to use this after
* any other usages of middleware via the `@using()` decorator.
* Middleware used with {@link Command#use} is evaluated before
* middlleware used via `@using()` decorator.
* @returns {MethodDecorator}
*/
export function localizable(target: Command, key: string, descriptor: PropertyDescriptor): PropertyDescriptor
{
if (!target) throw new Error('@localizable must be used as a method decorator for a Command action method.');
if (key !== 'action') throw new Error(
`"${target.constructor.name}#${key}" is not a valid method target for @localizable.`);
if (!descriptor) descriptor = Object.getOwnPropertyDescriptor(target, key);
const original: any = descriptor.value;
descriptor.value = async function(this: Command<any>, message: Message, args: any[]): Promise<any>
{
const dm: boolean = message.channel.type !== 'text';
const lang: string = dm ? this.client.defaultLang
: await message.guild.storage.settings.get('lang');

return await original.apply(this, [message, [lang, ...args]]);
};
return descriptor;
}

/**
* Set `name` metadata
* @param {string} value Value to set
Expand Down
6 changes: 3 additions & 3 deletions src/command/base/Help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Lang } from '../../localization/Lang';
import { Message } from '../../types/Message';
import { Command } from '../Command';
import { Util } from '../../util/Util';
import { localizable } from '../CommandDecorators';

export default class extends Command
{
Expand All @@ -18,13 +19,12 @@ export default class extends Command
});
}

public async action(message: Message, [commandName]: [string]): Promise<void>
@localizable
public async action(message: Message, [lang, commandName]: [string, string]): Promise<void>
{
if (this.client.selfbot) message.delete();
const dm: boolean = message.channel.type !== 'text';
const mentionName: string = `@${this.client.user.tag}`;
const lang: string = dm ? this.client.defaultLang
: await message.guild.storage.settings.get('lang');

const cInfo: (command: Command) => LocalizedCommandInfo =
(command: Command) => Lang.getCommandInfo(command, lang);
Expand Down
4 changes: 2 additions & 2 deletions src/command/middleware/Expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { Message } from '../../types/Message';
import { Command } from '../Command';
import { GuildMember, Role, TextChannel, User } from 'discord.js';

export function expect<T extends Client, U extends Command<T>>(argTypes: { [name: string]: ExpectArgType }): MiddlewareFunction
export function expect<T extends Command>(argTypes: { [name: string]: ExpectArgType }): MiddlewareFunction
{
return async function(this: U, message: Message, args: any[]): Promise<[Message, any[]]>
return async function(this: T, message: Message, args: any[]): Promise<[Message, any[]]>
{
const names: string[] = Object.keys(argTypes);
const types: ExpectArgType[] = names.map(a => argTypes[a]);
Expand Down
11 changes: 11 additions & 0 deletions src/command/middleware/Localize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Client } from '../../client/Client';
import { Message } from '../../types/Message';
import { Command } from '../Command';

export async function localize<T extends Command>(this: T, message: Message, args: any[]): Promise<[Message, any[]]>
{
const dm: boolean = message.channel.type !== 'text';
const lang: string = dm ? this.client.defaultLang
: await message.guild.storage.settings.get('lang');
return [message, [lang, ...args]];
}
24 changes: 18 additions & 6 deletions src/command/middleware/Middleware.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Client } from '../../client/Client';
import { Command } from '../Command';
import { expect } from './Expect';
import { resolve } from './Resolve';
import { MiddlewareFunction } from '../../types/MiddlewareFunction';
import { ResolveArgType } from '../../types/ResolveArgType';
import { ExpectArgType } from '../../types/ExpectArgType';
import { Client } from '../../client/Client';
import { localize } from './Localize';
import { Command } from '../Command';
import { resolve } from './Resolve';
import { expect } from './Expect';

/**
* Contains static command middleware methods
Expand Down Expand Up @@ -36,7 +37,7 @@ export class Middleware
* (message: Message, args: any[]) => [Message, any[]]
* ```
*/
public static resolve: <T extends Client, U extends Command<T>>(argTypes: { [name: string]: ResolveArgType }) =>
public static resolve: (argTypes: { [name: string]: ResolveArgType }) =>
MiddlewareFunction = resolve;

/**
Expand Down Expand Up @@ -66,6 +67,17 @@ export class Middleware
* (message: Message, args: any[]) => [Message, any[]]
* ```
*/
public static expect: <T extends Client, U extends Command<T>>(argTypes: { [name: string]: ExpectArgType }) =>
public static expect: (argTypes: { [name: string]: ExpectArgType }) =>
MiddlewareFunction = expect;

/**
* Middleware function that fetches the language to be used for command output
* and passes it as the first argument to the Command. This should be used
* *after* any other middleware like `expect` or `resolve` because those are
* based around user input whereas this should be handled after user input
* related things
* @method localize
* @returns {MiddlewareFunction}
*/
public static localize: MiddlewareFunction = localize;
}
4 changes: 2 additions & 2 deletions src/command/middleware/Resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { Util } from '../../util/Util';
import { Time } from '../../util/Time';
import { Command } from '../Command';

export function resolve<T extends Client, U extends Command<T>>(argTypes: { [name: string]: ResolveArgType }): MiddlewareFunction
export function resolve<T extends Command>(argTypes: { [name: string]: ResolveArgType }): MiddlewareFunction
{
return async function(this: U, message: Message, args: any[]): Promise<[Message, any[]]>
return async function(this: T, message: Message, args: any[]): Promise<[Message, any[]]>
{
const names: string[] = Object.keys(argTypes);
const types: ResolveArgType[] = names.map(a => argTypes[a]);
Expand Down
5 changes: 2 additions & 3 deletions test/test_client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Lang } from '../bin';
import { Client, LogLevel, Logger, ListenerUtil, Util } from '../bin/';
import { Client, LogLevel, Logger, ListenerUtil, Util, Lang } from '../bin/';
const config: any = require('./config.json');
const logger: Logger = Logger.instance();
const { once } = ListenerUtil;
Expand Down Expand Up @@ -31,7 +30,7 @@ class Test extends Client
owner: config.owner,
commandsDir: './commands',
localeDir: './locale',
// defaultLang: 'al_bhed',
defaultLang: 'al_bhed',
pause: true,
logLevel: LogLevel.DEBUG,
disableBase: Util.baseCommandNames
Expand Down

0 comments on commit 740c028

Please sign in to comment.