Skip to content

Commit

Permalink
Merge pull request #72 from slash-create/feat/debug-guild
Browse files Browse the repository at this point in the history
feat: `/debug guild`
  • Loading branch information
sudojunior authored Aug 25, 2024
2 parents 9785cc2 + 55d7f29 commit ce03e5f
Show file tree
Hide file tree
Showing 11 changed files with 409 additions and 381 deletions.
18 changes: 9 additions & 9 deletions src/commands/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,21 +389,21 @@ export default class CodeCommand extends BaseCommand {
}

interface CodeBaseOptions {
query: string;
library: string;
share?: boolean;
version?: string;
line_numbers?: boolean;
query: string;
library: string;
share?: boolean;
version?: string;
line_numbers?: boolean;
}

interface CodeEntityOptions extends CodeBaseOptions {
around?: number;
offset?: number;
around?: number;
offset?: number;
}

interface CodeLinesOptions extends CodeBaseOptions {
start: number;
end: number;
start: number;
end: number;
}

type AnyCodeOptions = CodeEntityOptions | CodeLinesOptions;
43 changes: 28 additions & 15 deletions src/commands/debug/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ export default class ChatDebugCommand extends BaseCommand {
},
],
},
{
name: "guild",
type: CommandOptionType.SUB_COMMAND,
description: "Print the payload for the target guild.",
},
],
deferEphemeral: true,
});
Expand All @@ -95,12 +100,21 @@ export default class ChatDebugCommand extends BaseCommand {
};
}

async run(ctx: CommandContext): Promise<MessageOptions> {
async run(ctx: CommandContext): Promise<MessageOptions | string> {
const [subCommand] = ctx.subcommands;
const { target } = ctx.options[subCommand];

let rawPayload: ResolvedDebugUser | CommandChannel | ResolvedRole;
let error: string;
let rawPayload:
| ResolvedDebugUser
| CommandChannel
| ResolvedRole
| { id: string };

if (!ctx.guildID && ["role","guild"].includes(subCommand)) {
return `</${this.commandName} ${subCommand}:${this.ids.get(
"global",
)}> is not in a guild context, you should not be here.`;
}

switch (subCommand) {
case "user": {
Expand All @@ -110,11 +124,6 @@ export default class ChatDebugCommand extends BaseCommand {

case "channel":
case "role": {
if (!ctx.guildID && subCommand === "role") {
error = "This is not a guild context, you should not be here.";
break;
}

const field = `${subCommand}s` as const;

// eslint-disable-next-line prettier/prettier
Expand All @@ -125,13 +134,12 @@ export default class ChatDebugCommand extends BaseCommand {

break;
}
}

if (error) {
return {
content: error,
ephemeral: true,
};
case "guild": {
// @ts-ignore
rawPayload = ctx.data.guild as { id: string };
break;
}
}

const targetID = "user" in rawPayload ? rawPayload.user.id : rawPayload.id;
Expand All @@ -145,7 +153,12 @@ export default class ChatDebugCommand extends BaseCommand {

// rework `header` to use `type` instead and construct the header in this method
static resolveFinalPayload(
payload: ResolvedDebugUser | CommandChannel | ResolvedRole | MessageData,
payload:
| ResolvedDebugUser
| CommandChannel
| ResolvedRole
| MessageData
| { id: string },
type: string,
target: string,
): MessageOptions {
Expand Down
4 changes: 2 additions & 2 deletions src/commands/temporal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ export default class TemporalCommand extends BaseCommand {

const dateInstant = new Date(instant ?? ctx.invokedAt);
const adjustedTimezone =
!isEmpty(timezone) && timezone.includes("(")
!isEmpty(timezone) && timezone.includes("(")
? timezone.split(" ").at(0)
: timezone;
const offsetHours = adjustedTimezone
Expand Down Expand Up @@ -629,7 +629,7 @@ export default class TemporalCommand extends BaseCommand {
return `\`${day}/${months[month]}\` is not possible, please try again.`;

const adjustedTimezone =
!isEmpty(timezone) && timezone.includes("(")
!isEmpty(timezone) && timezone.includes("(")
? timezone.split(" ").at(0)
: timezone;
const exactUTC = new Date(
Expand Down
178 changes: 93 additions & 85 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {
SlashCreator,
CommandOptionType,
type ApplicationCommandOption,
BunServer,
ChannelType,
BaseInteractionContext,
SlashCreator,
CommandOptionType,
type ApplicationCommandOption,
BunServer,
ChannelType,
BaseInteractionContext,
} from "slash-create";
import path from "node:path";

Expand All @@ -21,11 +21,11 @@ import { Provider } from "&docs/source";
console.time("Startup");

const creator = new SlashCreator({
applicationID: process.env.DISCORD_APP_ID,
publicKey: process.env.DISCORD_PUBLIC_KEY,
token: process.env.DISCORD_BOT_TOKEN,
serverPort: Number.parseInt(process.env.PORT, 10) || 8020,
serverHost: "0.0.0.0",
applicationID: process.env.DISCORD_APP_ID,
publicKey: process.env.DISCORD_PUBLIC_KEY,
token: process.env.DISCORD_BOT_TOKEN,
serverPort: Number.parseInt(process.env.PORT, 10) || 8020,
serverHost: "0.0.0.0",
});

// creator.on('debug', (message) => console.debug(message));
Expand All @@ -34,95 +34,101 @@ const creator = new SlashCreator({
// creator.on('synced', () => console.info('Commands synced!'));

creator.on("commandRun", async (command, promise, ctx) => {
const options = ctx.subcommands.reduce(
(target, command) => target[command],
ctx.options,
);

const commandString = `/${command.commandName} ${ctx.subcommands.join(
" ",
)} { ${hashMapToString(options, " = ", ", ", (value) => stringResolver(ctx, value))} }`;

const wrappedTimer = duration();
await promise;
console.info(`${logPrefix(ctx)} ran ${commandString} in ${wrappedTimer()}`);
const options = ctx.subcommands.reduce(
(target, command) => target[command],
ctx.options,
);

const commandString = `/${command.commandName} ${ctx.subcommands.join(
" ",
)} { ${hashMapToString(options, " = ", ", ", (value) =>
stringResolver(ctx, value),
)} }`;

const wrappedTimer = duration();
await promise;
console.info(`${logPrefix(ctx)} ran ${commandString} in ${wrappedTimer()}`);
});

creator.on('autocompleteInteraction', (ctx, command) => {
const { options, focused, subCommands } = getCommandInfo<object>(ctx);
creator.on("autocompleteInteraction", (ctx, command) => {
const { options, focused, subCommands } = getCommandInfo<object>(ctx);

const commandString = `/${command.commandName} ${subCommands.join(" ")} { ${hashMapToString(options, " = ", ", ", (value) => stringResolver(ctx, value))} } [${focused}]`;
const commandString = `/${command.commandName} ${subCommands.join(
" ",
)} { ${hashMapToString(options, " = ", ", ", (value) =>
stringResolver(ctx, value),
)} } [${focused}]`;

console.info(`${logPrefix(ctx)} queried ${commandString}`);
})
console.info(`${logPrefix(ctx)} queried ${commandString}`);
});

creator.on("commandRegister", async (command) => {
const [typeString, typeSymbol] = commandTypeStrings[command.type];

console.info(`$ /${command.commandName} (${typeString} [${typeSymbol}])`);
const commandPaths: Record<string, Record<string, string>> = {};

function searchOptions(
subCommand: ApplicationCommandOption,
commandPath: string[] = [],
) {
switch (subCommand.type) {
case CommandOptionType.SUB_COMMAND:
case CommandOptionType.SUB_COMMAND_GROUP: {
if (
!Array.isArray(subCommand.options) &&
subCommand.type === CommandOptionType.SUB_COMMAND
) {
commandPaths[commandPath.concat(subCommand.name).join(" ")] = {};
break;
}

if (subCommand.options) {
for (const childOption of subCommand.options)
searchOptions(childOption, commandPath.concat(subCommand.name));
}
break;
}

default: {
const pathTarget =
subCommand.name +
(!subCommand.required ? "?" : "") +
("autocomplete" in subCommand && subCommand.autocomplete ? "*" : "");

commandPaths[commandPath.join(" ")] ??= {};
commandPaths[commandPath.join(" ")][pathTarget] = titleCase(
CommandOptionType[subCommand.type].toLowerCase(),
);
if ("choices" in subCommand)
commandPaths[commandPath.join(" ")][pathTarget] +=
`[${subCommand.choices.length}]`;
}
}
}

if (command.options)
for (const option of command.options) searchOptions(option);

for (const key in commandPaths)
console.info(
`^ ${`/${command.commandName} ${key}`.trim()} { ${hashMapToString(
commandPaths[key],
)} }`,
);
const [typeString, typeSymbol] = commandTypeStrings[command.type];

console.info(`$ /${command.commandName} (${typeString} [${typeSymbol}])`);
const commandPaths: Record<string, Record<string, string>> = {};

function searchOptions(
subCommand: ApplicationCommandOption,
commandPath: string[] = [],
) {
switch (subCommand.type) {
case CommandOptionType.SUB_COMMAND:
case CommandOptionType.SUB_COMMAND_GROUP: {
if (
!Array.isArray(subCommand.options) &&
subCommand.type === CommandOptionType.SUB_COMMAND
) {
commandPaths[commandPath.concat(subCommand.name).join(" ")] = {};
break;
}

if (subCommand.options) {
for (const childOption of subCommand.options)
searchOptions(childOption, commandPath.concat(subCommand.name));
}
break;
}

default: {
const pathTarget =
subCommand.name +
(!subCommand.required ? "?" : "") +
("autocomplete" in subCommand && subCommand.autocomplete ? "*" : "");

commandPaths[commandPath.join(" ")] ??= {};
commandPaths[commandPath.join(" ")][pathTarget] = titleCase(
CommandOptionType[subCommand.type].toLowerCase(),
);
if ("choices" in subCommand)
commandPaths[commandPath.join(" ")][pathTarget] +=
`[${subCommand.choices.length}]`;
}
}
}

if (command.options)
for (const option of command.options) searchOptions(option);

for (const key in commandPaths)
console.info(
`^ ${`/${command.commandName} ${key}`.trim()} { ${hashMapToString(
commandPaths[key],
)} }`,
);
});

creator.on("commandError", (command, error) =>
console.error(`Command ${command.commandName}:`, error),
console.error(`Command ${command.commandName}:`, error),
);

creator.on("componentInteraction", (ctx) => {
console.info(`${logPrefix(ctx)} = $${ctx.customID}`);
console.info(`${logPrefix(ctx)} = $${ctx.customID}`);
});

registerComponents(creator);
await creator.registerCommandsIn(path.resolve(import.meta.dir, "./commands"), [
".ts",
".ts",
]);
console.timeLog("Startup", "Commands & Components Loaded");

Expand All @@ -135,5 +141,7 @@ console.timeEnd("Startup");

// Expect 2n requests to be used
// docs manifest list + latest docs manfiest for each provider
await Promise.allSettled(Provider.all.map((provider) => provider.aggregator.onReady));
await Promise.allSettled(
Provider.all.map((provider) => provider.aggregator.onReady),
);
RequestQuota.debug();
4 changes: 2 additions & 2 deletions src/modules/common/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function groupBy<Key extends PropertyKey, Value>(
}

export function isEmpty(val: unknown) {
const empties: unknown[] = [null, undefined, "", Number.NaN] as const;
const empties: unknown[] = [null, undefined, "", Number.NaN] as const;

return empties.includes(val);
return empties.includes(val);
}
Loading

0 comments on commit ce03e5f

Please sign in to comment.