Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4.0.1
- name: Use Node.js 18.x
uses: actions/setup-node@v4
with:
node-version: 16
node-version: "18.x"

- run: yarn install

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: akhileshns/heroku-deploy@v3.12.14
- uses: akhileshns/heroku-deploy@v3.13.15
with:
heroku_api_key: ${{secrets.HEROKU_API_KEY}}
heroku_app_name: ${{secrets.HEROKU_APP_NAME}}
Expand Down
9 changes: 9 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"node-option": [
"experimental-specifier-resolution=node",
"loader=ts-node/esm"
],
"extension": ["ts"],
"spec": "tests/**/*.test.ts",
"require": "ts-node/register"
}
66 changes: 36 additions & 30 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,26 @@
"main": "index.js",
"license": "BSD-2-Clause",
"engines": {
"node": ">=16 <=18.17.1"
"node": ">18.18.0 && <20.0.0"
},
"type": "module",
"scripts": {
"lint": "eslint . --ext .ts",
"lint-and-fix": "eslint . --ext .ts --fix",
"start:dev": "nodemon --watch './src/**' --ext 'ts,js,json' --exec \"ts-node --files ./src/index.ts\"",
"start:dev": "nodemon --watch './src/**' --ext 'ts,js,json' --exec \"node --no-warnings=ExperimentalWarning --loader ts-node/esm src/index.ts\"",
"prebuild": "rimraf ./build",
"build": "tsc",
"prestart": "npm run build",
"start": "node build/index.js",
"test": "mocha -r ts-node/register tests/**/*.test.ts"
"test": "mocha --esm tests/**/*.test.ts"
},
"nodemonConfig": {
"watch": [
"src"
],
"ext": ".ts,.js",
"ignore": [],
"exec": "ts-node --files ./src/index.ts"
"exec": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./src/index.ts"
},
"repository": {
"type": "git",
Expand All @@ -40,34 +41,39 @@
},
"homepage": "https://github.com/SerenityOS/discord-bot#readme",
"devDependencies": {
"@octokit/types": "^9.1.2",
"@types/chai": "^4.3.4",
"@types/mocha": "^10.0.1",
"@typescript-eslint/eslint-plugin": "^5.59.9",
"@typescript-eslint/parser": "^5.59.1",
"chai": "^4.3.7",
"eslint": "^8.39.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-unused-imports": "^2.0.0",
"mocha": "^10.2.0",
"nodemon": "^2.0.22",
"prettier": "^2.8.8",
"ts-node": "^10.9.1"
"@octokit/types": "^13.5.0",
"@types/chai": "^4.3.16",
"@types/mocha": "^10.0.6",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"chai": "^5.1.1",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unused-imports": "^3.2.0",
"mocha": "^10.4.0",
"nodemon": "^3.1.0",
"prettier": "^3.2.5",
"ts-node": "^10.9.2"
},
"dependencies": {
"@octokit/plugin-throttling": "^5.1.1",
"@octokit/rest": "^19.0.7",
"@types/node": "^18.16.3",
"axios": "^1.4.0",
"bufferutil": "^4.0.7",
"discord.js": "^14.7.1",
"dotenv": "^16.0.3",
"@octokit/core": "^5.2.0",
"@octokit/plugin-throttling": "^8.2.0",
"@octokit/rest": "^20.1.1",
"@types/node": "^20.12.11",
"axios": "^1.6.8",
"bufferutil": "^4.0.8",
"discord.js": "^14.15.2",
"dotenv": "^16.4.5",
"mastodon": "^1.2.2",
"octokit-plugin-create-pull-request": "^4.1.1",
"rimraf": "^5.0.0",
"typescript": "^5.0.4",
"utf-8-validate": "^6.0.3",
"zlib-sync": "^0.1.8"
"octokit-plugin-create-pull-request": "^5.1.1",
"rimraf": "^5.0.7",
"typescript": "^5.4.5",
"utf-8-validate": "^6.0.4",
"zlib-sync": "^0.1.9"
},
"resolutions": {
"strip-ansi": "^6.0.1",
"cliui": "^7.0.4"
}
}
8 changes: 5 additions & 3 deletions src/apis/githubAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
*/

/* eslint camelcase: [2, { "properties": "never" }] */
import { GITHUB_TOKEN } from "../config/secrets";
import { GITHUB_TOKEN } from "../config/secrets.js";
import { Octokit } from "@octokit/rest";
import { throttling as OctokitThrottling } from "@octokit/plugin-throttling";
import { composeCreatePullRequest } from "octokit-plugin-create-pull-request";
import config from "../config/botConfig";
import config from "../config/botConfig.js";
import { throttling as OctokitThrottling } from "@octokit/plugin-throttling";

export interface ManPage {
url: string;
Expand Down Expand Up @@ -134,6 +134,7 @@ class GithubAPI {
});

return results.data;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
if (e.status === 404) return null;

Expand All @@ -157,6 +158,7 @@ class GithubAPI {
});

return results.data?.total_count;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
console.trace(e);
throw e;
Expand Down
21 changes: 11 additions & 10 deletions src/commandHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@
* SPDX-License-Identifier: BSD-2-Clause
*/

import * as Commands from "./commands";
import * as Commands from "./commands/index.js";

import {
ApplicationCommandType,
ButtonInteraction,
Client,
CommandInteraction,
Interaction,
SelectMenuInteraction,
} from "discord.js";

import Command from "./commands/command";
import { GUILD_ID } from "./config/secrets";
import config from "./config/botConfig";
import Command from "./commands/command.js";
import { GUILD_ID } from "./config/secrets.js";
import config from "./config/botConfig.js";

export default class CommandHandler {
private readonly commands: Map<string[], Command>;
Expand All @@ -32,8 +31,9 @@ export default class CommandHandler {
const command = new commandClass();
const data = command.data();

// FIXME: Surely there's a better way to check this?
for (const entry of data)
if (!entry.type || entry.type === ApplicationCommandType.ChatInput)
if ("description" in entry)
availableCommands.push(`**${entry.name}** - ${entry.description}`);

return [data.map(entry => entry.name), command];
Expand All @@ -57,7 +57,7 @@ export default class CommandHandler {
if (!config.production && GUILD_ID) {
const guild = await client.guilds.fetch(GUILD_ID);

guild.commands.set(commands);
await guild.commands.set(commands);
}

if (!client.application) return;
Expand All @@ -74,7 +74,7 @@ export default class CommandHandler {
4
)} from '${interaction.user.tag}`;
await interaction.channel?.send(msg);
await console.log(msg);
console.log(msg);
}

if (!interaction.isCommand()) throw new Error("Invalid command interaction");
Expand Down Expand Up @@ -191,10 +191,11 @@ export default class CommandHandler {
console.trace("matchedCommand.handle{Select|Context}Menu failed", error);

const content = `⚠️ Something went extremely wrong!\n \`\`\`\n${
(error as any)?.stack ?? error ?? ""
(error as any)?.stack ?? error ?? "" // eslint-disable-line @typescript-eslint/no-explicit-any
}\n\`\`\``;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((interaction as any).deferred || (interaction as any).replied)
return (interaction as any).editReply({ content });
return (interaction as any).editReply({ content }); // eslint-disable-line @typescript-eslint/no-explicit-any

interaction.reply({ ephemeral: true, content });
});
Expand Down
4 changes: 2 additions & 2 deletions src/commands/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import {
ApplicationCommandData,
RESTPostAPIApplicationCommandsJSONBody,
ButtonInteraction,
ChatInputCommandInteraction,
ContextMenuCommandInteraction,
Expand All @@ -22,7 +22,7 @@ export default abstract class Command {

handleButton?(interaction: ButtonInteraction): Promise<void>;

abstract data(): ApplicationCommandData[];
abstract data(): RESTPostAPIApplicationCommandsJSONBody[];

buttonData?(): Array<string>;
}
10 changes: 5 additions & 5 deletions src/commands/commitStatsCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import {
EmbedBuilder,
SlashCommandBuilder,
} from "discord.js";
import githubAPI, { Commit, Repository } from "../apis/githubAPI";
import { CommitClubColor, GitHubColor } from "../util/color";
import { toMedal } from "../util/emoji";
import { extractCopy, trimString } from "../util/text";
import Command from "./command";
import githubAPI, { Commit, Repository } from "../apis/githubAPI.js";
import { CommitClubColor, GitHubColor } from "../util/color.js";
import { toMedal } from "../util/emoji.js";
import { extractCopy, trimString } from "../util/text.js";
import Command from "./command.js";

export class CommitStatsCommand extends Command {
override data() {
Expand Down
4 changes: 2 additions & 2 deletions src/commands/emojiCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
*/

import { ChatInputCommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js";
import { getEmoji } from "../util/emoji";
import Command from "./command";
import { getEmoji } from "../util/emoji.js";
import Command from "./command.js";

export class EmojiCommand extends Command {
override data() {
Expand Down
11 changes: 5 additions & 6 deletions src/commands/githubCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@
*/

import {
ApplicationCommandData,
ChatInputCommandInteraction,
SlashCommandBuilder,
TextChannel,
TextBasedChannel,
SlashCommandStringOption,
} from "discord.js";
import githubAPI, { Repository, SERENITY_REPOSITORY } from "../apis/githubAPI";
import { embedFromIssueOrPull } from "../util/embedFromIssueOrPull";
import { getSadCaret } from "../util/emoji";
import Command from "./command";
import githubAPI, { Repository, SERENITY_REPOSITORY } from "../apis/githubAPI.js";
import { embedFromIssueOrPull } from "../util/embedFromIssueOrPull.js";
import { getSadCaret } from "../util/emoji.js";
import Command from "./command.js";

const repositories: Array<{
name: string;
Expand Down Expand Up @@ -190,7 +189,7 @@ export class GithubCommand extends Command {
}

export class ReviewList extends Command {
override data(): ApplicationCommandData[] {
override data() {
const aliases = ["reviewlist", "prlist"];

const baseCommand = new SlashCommandBuilder()
Expand Down
19 changes: 10 additions & 9 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
* DO NOT export command classes using default
*/

export * from "./commitStatsCommand";
export * from "./emojiCommand";
export * from "./githubCommand";
export * from "./manCommand";
export * from "./planCommand";
export * from "./quickLinksCommand";
export * from "./quoteCommand";
export * from "./testCommand";
export * from "./userCommand";
export * from "./commitStatsCommand.js";
export * from "./emojiCommand.js";
export * from "./githubCommand.js";
export * from "./manCommand.js";
export * from "./planCommand.js";
export * from "./quickLinksCommand.js";
export * from "./quoteCommand.js";
export * from "./testCommand.js";
export * from "./userCommand.js";
export * from "./slapCommand.js";
6 changes: 3 additions & 3 deletions src/commands/manCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import {
Interaction,
SlashCommandBuilder,
} from "discord.js";
import githubAPI from "../apis/githubAPI";
import { getMaximize, getMinimize, getSadCaret } from "../util/emoji";
import Command from "./command";
import githubAPI from "../apis/githubAPI.js";
import { getMaximize, getMinimize, getSadCaret } from "../util/emoji.js";
import Command from "./command.js";

interface Paragraph {
title?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/planCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import Command from "./command";
import Command from "./command.js";

export class PlanCommand extends Command {
private readonly baseReply: string = `> Will SerenityOS support \`$THING\`?\nMaybe. Maybe not. There is no plan.\n\nSee: [FAQ](<https://github.com/SerenityOS/serenity/blob/master/Documentation/FAQ.md>)`;
Expand Down
8 changes: 4 additions & 4 deletions src/commands/quickLinksCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-2-Clause
*/

import { ApplicationCommandData, ChatInputCommandInteraction } from "discord.js";
import Command from "./command";
import { ChatInputCommandInteraction } from "discord.js";
import Command from "./command.js";

export class QuickLinksCommand extends Command {
private readonly documentation: string =
Expand Down Expand Up @@ -92,7 +92,7 @@ export class QuickLinksCommand extends Command {
},
];

override data(): ApplicationCommandData[] {
override data() {
return this.links.map(link => ({
name: link.name,
description: link.help,
Expand All @@ -102,7 +102,7 @@ export class QuickLinksCommand extends Command {
override async handleCommand(interaction: ChatInputCommandInteraction) {
for (const link of this.links)
if (link.name === interaction.commandName) {
interaction.reply({ content: link.response });
await interaction.reply({ content: link.response });
return;
}

Expand Down
8 changes: 4 additions & 4 deletions src/commands/quoteCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import {
ContextMenuCommandInteraction,
ChannelType,
} from "discord.js";
import githubAPI, { SERENITY_REPOSITORY } from "../apis/githubAPI";
import { QUOTE_ROLE_ID } from "../config/secrets";
import { getSadCaret } from "../util/emoji";
import Command from "./command";
import githubAPI, { SERENITY_REPOSITORY } from "../apis/githubAPI.js";
import { QUOTE_ROLE_ID } from "../config/secrets.js";
import { getSadCaret } from "../util/emoji.js";
import Command from "./command.js";

export class QuoteCommand extends Command {
private readonly messageLinkRegex: RegExp =
Expand Down
Loading