Skip to content

Commit b979bbf

Browse files
feat: add alias of App.getServiceByName() to App.service()
1 parent 1566bae commit b979bbf

30 files changed

+214
-131
lines changed

.vscode/command.code-snippets

Lines changed: 0 additions & 41 deletions
This file was deleted.

.vscode/service.code-snippets

Lines changed: 0 additions & 24 deletions
This file was deleted.

.vscode/sudobot.code-snippets

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"SudoBot Command Class": {
3+
"scope": "typescript",
4+
"prefix": "command",
5+
"body": [
6+
"import { TakesArgument } from \"@framework/arguments/ArgumentTypes\";",
7+
"import type { Buildable } from \"@framework/commands/Command\";",
8+
"import { Command } from \"@framework/commands/Command\";",
9+
"import type Context from \"@framework/commands/Context\";",
10+
"",
11+
"type ${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}}Args = {",
12+
"\targ: string;",
13+
"};",
14+
"",
15+
"@TakesArgument<${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}}Args>({",
16+
"\tnames: [],",
17+
"\ttypes: [],",
18+
"\toptional: false,",
19+
"\terrorMessages: [],",
20+
"})",
21+
"class ${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}} extends Command {",
22+
"\tpublic override readonly name = \"custom\";",
23+
"\tpublic override readonly description: string = \"Custom command.\";",
24+
"\tpublic override readonly detailedDescription: string = \"Custom command.\";",
25+
"\tpublic override readonly defer = true;",
26+
"\tpublic override readonly usage = [\"\"];",
27+
"\tpublic override readonly systemPermissions = [];",
28+
"",
29+
"\tpublic override build(): Buildable[] {",
30+
"\t\treturn [this.buildChatInput()];",
31+
"\t}",
32+
"",
33+
"\tpublic override async execute(context: Context, args: ${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}}Args): Promise<void> {",
34+
"\t\t// Add your custom command logic here",
35+
"\t}",
36+
"}",
37+
"",
38+
"export default ${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}};"
39+
]
40+
},
41+
"SudoBot Service Class": {
42+
"scope": "typescript",
43+
"prefix": "service",
44+
"body": [
45+
"import { Name } from \"@framework/services/Name\";",
46+
"import { Service } from \"@framework/services/Service\";",
47+
"",
48+
"@Name(\"${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}}\")",
49+
"class ${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}} extends Service {",
50+
"\t// TODO: Implement service",
51+
"}",
52+
"",
53+
"export default ${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}};"
54+
]
55+
},
56+
"SudoBot Queue Class": {
57+
"scope": "typescript",
58+
"prefix": "queue",
59+
"body": [
60+
"import Queue from \"@framework/queues/Queue\";",
61+
"",
62+
"type ${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}}Payload = {",
63+
"\t// TODO: Add payload properties",
64+
"};",
65+
"",
66+
"class ${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}} extends Queue<${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}}Payload> {",
67+
"\tpublic static override readonly uniqueName = \"${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}}\";",
68+
"",
69+
"\tpublic async execute(payload: ${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}}Payload) {",
70+
"\t\t// TODO: Implement queue logic",
71+
"\t}",
72+
"}",
73+
"",
74+
"export default ${1:${TM_FILENAME_BASE/(.*?)\\..*/$1/}};"
75+
]
76+
}
77+
}

src/framework/typescript/api/APIServer.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,8 @@ export default class APIServer extends Service {
6666

6767
public async onReady() {
6868
if (
69-
(
70-
this.application.getServiceByName(
71-
"configManager"
72-
) as ConfigurationManagerServiceInterface
73-
).systemConfig.api.enabled
69+
(this.application.service("configManager") as ConfigurationManagerServiceInterface)
70+
.systemConfig.api.enabled
7471
) {
7572
await this.boot();
7673
await this.start();
@@ -81,7 +78,7 @@ export default class APIServer extends Service {
8178
this.expressApp.use(this.onError);
8279
this.expressApp.use(cors());
8380

84-
const configManager = this.application.getServiceByName(
81+
const configManager = this.application.service(
8582
"configManager"
8683
) as ConfigurationManagerServiceInterface;
8784

src/framework/typescript/app/Application.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ class Application {
182182
}
183183

184184
public getServiceByName<N extends ServiceName>(name: N, error = true): ServiceRecord[N] {
185+
return this.service(name, error);
186+
}
187+
188+
/**
189+
* An alias of Application#getServiceByName.
190+
*/
191+
public service<N extends ServiceName>(name: N, error = true): ServiceRecord[N] {
185192
const service = this.serviceManager.getServiceByName(name);
186193

187194
if (!service && error) {

src/framework/typescript/arguments/ArgumentParser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class ArgumentParser extends HasClient {
5858
[];
5959
let payload: ArgumentPayload;
6060
const { args, argv } = context;
61-
const commandManager = Application.current().getServiceByName("commandManager");
61+
const commandManager = Application.current().service("commandManager");
6262

6363
if (isDynamic && !subcommand) {
6464
const paramTypes = Reflect.getMetadata(
@@ -178,7 +178,7 @@ class ArgumentParser extends HasClient {
178178
}
179179

180180
if (subcommand) {
181-
const commandManager = Application.current().getServiceByName("commandManager");
181+
const commandManager = Application.current().service("commandManager");
182182
const canonicalName = commandManager.getCommand(argv[0])?.name ?? argv[0];
183183
const baseCommand = commandManager.commands.get(canonicalName);
184184

src/framework/typescript/commands/Command.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ abstract class Command<T extends ContextType = ContextType.ChatInput | ContextTy
233233
*/
234234
public constructor(protected readonly application: Application) {
235235
this.argumentParser = new ArgumentParser(application.getClient());
236-
this.internalPermissionManager = application.getServiceByName(
236+
this.internalPermissionManager = application.service(
237237
"permissionManager"
238238
) satisfies PermissionManagerServiceInterface;
239239
}
@@ -292,7 +292,7 @@ abstract class Command<T extends ContextType = ContextType.ChatInput | ContextTy
292292
}
293293

294294
public isDisabled(guildId?: Snowflake): boolean {
295-
const configManager = this.application.getServiceByName(
295+
const configManager = this.application.service(
296296
"configManager"
297297
) as ConfigurationManagerServiceInterface;
298298
const name = this.name.replace("::", " ");
@@ -422,9 +422,7 @@ abstract class Command<T extends ContextType = ContextType.ChatInput | ContextTy
422422

423423
if (!state.isSystemAdmin) {
424424
const ratelimiter = (
425-
this.application.getServiceByName(
426-
"commandManager"
427-
) as CommandManagerServiceInterface
425+
this.application.service("commandManager") as CommandManagerServiceInterface
428426
).getRateLimiter();
429427

430428
if (
@@ -482,7 +480,7 @@ abstract class Command<T extends ContextType = ContextType.ChatInput | ContextTy
482480
}
483481

484482
private isInDisabledChannel(guildId: Snowflake, channelId: Snowflake) {
485-
const configManager = this.application.getServiceByName(
483+
const configManager = this.application.service(
486484
"configManager"
487485
) satisfies ConfigurationManagerServiceInterface;
488486

@@ -643,14 +641,14 @@ abstract class Command<T extends ContextType = ContextType.ChatInput | ContextTy
643641
}
644642
}
645643

646-
const configManager = this.application.getServiceByName(
644+
const configManager = this.application.service(
647645
"configManager"
648646
) satisfies ConfigurationManagerServiceInterface;
649647
const mode =
650648
configManager.config[context.guildId]?.permissions.command_permission_mode ??
651649
configManager.systemConfig.command_permission_mode;
652650

653-
const commandManager = this.application.getServiceByName(
651+
const commandManager = this.application.service(
654652
"commandManager"
655653
) satisfies CommandManagerServiceInterface;
656654

src/framework/typescript/commands/Context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ abstract class Context<T extends CommandMessage = CommandMessage> {
106106
}
107107

108108
public get config(): GuildConfig | undefined {
109-
return Application.current().getServiceByName("configManager").config[this.guildId];
109+
return Application.current().service("configManager").config[this.guildId];
110110
}
111111

112112
public abstract get userId(): Snowflake;

src/framework/typescript/datetime/Duration.ts

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import DurationParseError from "@framework/datetime/DurationParseError";
44
import { Override } from "@framework/decorators/Override";
55
import { isAlpha, isDigit } from "@framework/utils/string";
66
import { formatDuration } from "date-fns";
7+
import { TimestampStylesString, time } from "discord.js";
78

89
type DurationOptions = {
910
years?: number;
@@ -159,7 +160,9 @@ class Duration implements BehavesLikePrimitive, JSONSerializable<number> {
159160
}
160161

161162
if (value < 0) {
162-
throw new DurationParseError("Negative numbers are not allowed in duration expressions");
163+
throw new DurationParseError(
164+
"Negative numbers are not allowed in duration expressions"
165+
);
163166
}
164167

165168
let unit = "";
@@ -275,12 +278,11 @@ class Duration implements BehavesLikePrimitive, JSONSerializable<number> {
275278
}
276279

277280
/**
278-
* Returns a string representation of the duration.
281+
* Formats the duration into a human-readable string.
279282
*
280283
* @returns The formatted duration.
281284
*/
282-
@Override
283-
public toString() {
285+
public format(): string {
284286
let formatted = formatDuration(this);
285287

286288
if (this.milliseconds) {
@@ -290,6 +292,39 @@ class Duration implements BehavesLikePrimitive, JSONSerializable<number> {
290292
return formatted;
291293
}
292294

295+
/**
296+
* Formats the duration for Discord.
297+
*
298+
* @returns The formatted duration.
299+
*/
300+
public formatForDiscord(): `<t:${bigint}>`;
301+
302+
/**
303+
* Formats the duration for Discord with a style.
304+
*
305+
* @param style The style to format the duration with.
306+
* @returns The formatted duration.
307+
*/
308+
public formatForDiscord<S extends TimestampStylesString>(style: S): `<t:${bigint}:${S}>`;
309+
310+
public formatForDiscord<S extends TimestampStylesString>(style?: S) {
311+
if (!style) {
312+
return time(this.fromNow());
313+
}
314+
315+
return time(this.fromNow(), style);
316+
}
317+
318+
/**
319+
* Returns a string representation of the duration.
320+
*
321+
* @returns The formatted duration.
322+
*/
323+
@Override
324+
public toString() {
325+
return this.format();
326+
}
327+
293328
/**
294329
* Returns the JSON representation of the duration.
295330
*

src/framework/typescript/import/ClassLoader.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -263,15 +263,11 @@ class ClassLoader {
263263
}
264264

265265
private get configManager() {
266-
return this.application.getServiceByName(
267-
"configManager"
268-
) as ConfigurationManagerServiceInterface;
266+
return this.application.service("configManager") as ConfigurationManagerServiceInterface;
269267
}
270268

271269
private get commandManager() {
272-
return this.application.getServiceByName(
273-
"commandManager"
274-
) as CommandManagerServiceInterface;
270+
return this.application.service("commandManager") as CommandManagerServiceInterface;
275271
}
276272

277273
public flattenCommandGroups() {
@@ -338,7 +334,7 @@ class ClassLoader {
338334
}
339335

340336
public async loadQueueClasses(directory = path.resolve(__dirname, "../../queues")) {
341-
this.application.getServiceByName("queueService").onBeforeQueueRegister();
337+
this.application.service("queueService").onBeforeQueueRegister();
342338
const queueFiles = await this.iterateDirectoryRecursively(directory);
343339

344340
for (const file of queueFiles) {
@@ -352,7 +348,7 @@ class ClassLoader {
352348

353349
public async loadQueueClass(filepath: string) {
354350
const { default: QueueClass }: DefaultExport<typeof Queue> = await import(filepath);
355-
this.application.getServiceByName("queueService").register(QueueClass);
351+
this.application.service("queueService").register(QueueClass);
356352
this.application.logger.info("Loaded Queue: ", QueueClass.uniqueName);
357353
}
358354

src/framework/typescript/permissions/Permission.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ abstract class Permission extends Singleton {
5656
}
5757

5858
public static fromString(permission: string): Permission | undefined {
59-
const permissionManager = Application.current().getServiceByName(
59+
const permissionManager = Application.current().service(
6060
"permissionManager"
6161
) satisfies PermissionManagerServiceInterface;
6262
return permissionManager.getPermissionByName(permission);
@@ -90,7 +90,7 @@ abstract class Permission extends Singleton {
9090

9191
public static async of(member: GuildMember, exclude?: Permission[]) {
9292
const permissions = new FluentSet<Permission>();
93-
const permissionManager = Application.current().getServiceByName(
93+
const permissionManager = Application.current().service(
9494
"permissionManager"
9595
) satisfies PermissionManagerServiceInterface;
9696
const allPermissions = permissionManager.getAllPermissions().values();

0 commit comments

Comments
 (0)