style: prettier formatter

This commit is contained in:
Jozef Steinhübl 2024-07-19 23:17:50 +02:00
parent b0438f26c0
commit 3ff1b06150
No known key found for this signature in database
GPG key ID: E6BC90C91973B08F
15 changed files with 131 additions and 109 deletions

BIN
bun.lockb

Binary file not shown.

View file

@ -5,10 +5,13 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"start": "NODE_ENV=production bun src/index.ts", "start": "NODE_ENV=production bun src/index.ts",
"validate:tags": "bun scripts/validate_tags/index.ts" "validate:tags": "bun scripts/validate_tags/index.ts",
"format:check": "prettier . --check",
"format:apply": "prettier . --write"
}, },
"devDependencies": { "devDependencies": {
"bun-types": "^1.1.6" "bun-types": "^1.1.6",
"prettier": "3.3.3"
}, },
"dependencies": { "dependencies": {
"@lilybird/handlers": "^0.6.0-beta.9", "@lilybird/handlers": "^0.6.0-beta.9",

View file

@ -6,7 +6,7 @@ import { safeSlice } from "src/util.ts";
// @ts-expect-error It is callable, but algolia for some reason has a namespace with the same name // @ts-expect-error It is callable, but algolia for some reason has a namespace with the same name
const algoliaClient = algoliasearch( const algoliaClient = algoliasearch(
"2527C13E0N", "2527C13E0N",
"4efc87205e1fce4a1f267cadcab42cb2" "4efc87205e1fce4a1f267cadcab42cb2",
); );
const algoliaIndex = algoliaClient.initIndex("bun"); const algoliaIndex = algoliaClient.initIndex("bun");
@ -20,11 +20,12 @@ $applicationCommand({
description: "Select query", description: "Select query",
required: true, required: true,
autocomplete: true, autocomplete: true,
}, { },
{
type: ApplicationCommandOptionType.USER, type: ApplicationCommandOptionType.USER,
name: "target", name: "target",
description: "User to mention" description: "User to mention",
} },
], ],
autocomplete: async (interaction) => { autocomplete: async (interaction) => {
const query = interaction.data.getFocused<string>().value; const query = interaction.data.getFocused<string>().value;
@ -40,7 +41,7 @@ $applicationCommand({
name: safeSlice(name.full, 100), name: safeSlice(name.full, 100),
value: safeSlice(name.name, 100), value: safeSlice(name.name, 100),
}; };
}) }),
); );
}, },
handle: async (interaction) => { handle: async (interaction) => {
@ -58,7 +59,7 @@ $applicationCommand({
const name = getHitName(hit); const name = getHitName(hit);
const snippetContent = hit._snippetResult?.content?.value?.replace( const snippetContent = hit._snippetResult?.content?.value?.replace(
/<[^>]+>/g, /<[^>]+>/g,
"" "",
); );
const notice = hit.content?.replace(/\r/g, ""); const notice = hit.content?.replace(/\r/g, "");
@ -68,9 +69,9 @@ $applicationCommand({
snippetContent ? snippetContent : "", snippetContent ? snippetContent : "",
notice notice
? notice ? notice
.split("\n") .split("\n")
.map((s: any) => `> ${s}`) .map((s: any) => `> ${s}`)
.join("\n") .join("\n")
: "", : "",
].join("\n"); ].join("\n");

View file

@ -1,4 +1,3 @@
import { $applicationCommand } from "@lilybird/handlers/advanced"; import { $applicationCommand } from "@lilybird/handlers/advanced";
import { ApplicationCommandOptionType } from "lilybird"; import { ApplicationCommandOptionType } from "lilybird";
import { safeSlice, silently } from "../util.ts"; import { safeSlice, silently } from "../util.ts";
@ -35,7 +34,8 @@ interface Item {
$applicationCommand({ $applicationCommand({
name: "github", name: "github",
description: "Query an issue, pull request or direct link to issue, pull request", description:
"Query an issue, pull request or direct link to issue, pull request",
options: [ options: [
{ {
type: ApplicationCommandOptionType.STRING, type: ApplicationCommandOptionType.STRING,
@ -43,8 +43,9 @@ $applicationCommand({
description: "Issue/Pull request number or name", description: "Issue/Pull request number or name",
autocomplete: true, autocomplete: true,
required: true, required: true,
max_length: 100 max_length: 100,
}, { },
{
type: ApplicationCommandOptionType.STRING, type: ApplicationCommandOptionType.STRING,
name: "state", name: "state",
description: "Issue or Pull request state", description: "Issue or Pull request state",
@ -55,23 +56,24 @@ $applicationCommand({
{ name: "⚫️ Closed", value: "closed" }, { name: "⚫️ Closed", value: "closed" },
{ name: "🟣 Merged", value: "merged" }, { name: "🟣 Merged", value: "merged" },
{ name: "📝 Draft", value: "draft" }, { name: "📝 Draft", value: "draft" },
{ name: "🌍 All", value: "all" } { name: "🌍 All", value: "all" },
] ],
}, { },
{
type: ApplicationCommandOptionType.STRING, type: ApplicationCommandOptionType.STRING,
name: "type", name: "type",
description: "Issue/Pull request number or name", description: "Issue/Pull request number or name",
choices: [ choices: [
{ name: "🐛 Issues", value: "issues" }, { name: "🐛 Issues", value: "issues" },
{ name: "🔨 Pull Requests", value: "pull_requests" }, { name: "🔨 Pull Requests", value: "pull_requests" },
{ name: "🌍 Both", value: "both" } { name: "🌍 Both", value: "both" },
], ],
}, },
{ {
type: ApplicationCommandOptionType.BOOLEAN, type: ApplicationCommandOptionType.BOOLEAN,
name: "hide", name: "hide",
description: "Show this message only for you" description: "Show this message only for you",
} },
], ],
handle: async (interaction) => { handle: async (interaction) => {
const hide = interaction.data.getBoolean("hide") ?? false; const hide = interaction.data.getBoolean("hide") ?? false;
@ -79,7 +81,8 @@ $applicationCommand({
await interaction.deferReply(hide); await interaction.deferReply(hide);
const query = interaction.data.getString("query", true); const query = interaction.data.getString("query", true);
const state: State = (interaction.data.getString("state") as State) || "all"; const state: State =
(interaction.data.getString("state") as State) || "all";
const type: Type = (interaction.data.getString("type") as Type) || "both"; const type: Type = (interaction.data.getString("type") as Type) || "both";
const result = (await search(query, state, type))[0]; const result = (await search(query, state, type))[0];
@ -95,8 +98,10 @@ $applicationCommand({
interaction.editReply({ interaction.editReply({
content: [ content: [
`${result.emoji.type} ${result.emoji.state} [#${result.number `${result.emoji.type} ${result.emoji.state} [#${
} in oven-sh/bun](<${result.html_url}>) by [${result.user.login}](<${result.user.html_url result.number
} in oven-sh/bun](<${result.html_url}>) by [${result.user.login}](<${
result.user.html_url
}>) ${stateToText(result)} ${stateToTimestamp(result)}`, }>) ${stateToText(result)} ${stateToTimestamp(result)}`,
result.title, result.title,
].join("\n"), ].join("\n"),
@ -118,11 +123,11 @@ $applicationCommand({
response.map((r) => ({ response.map((r) => ({
name: safeSlice<string>( name: safeSlice<string>(
`${r.emoji.type} ${r.emoji.state} #${r.number} | ${r.title}`, `${r.emoji.type} ${r.emoji.state} #${r.number} | ${r.title}`,
100 100,
), ),
value: r.number.toString(), value: r.number.toString(),
})) })),
) ),
); );
}, },
}); });
@ -178,7 +183,7 @@ async function search(
query: string, query: string,
state: State, state: State,
type: Type, type: Type,
length = 1 length = 1,
): Promise<Item[]> { ): Promise<Item[]> {
let actualQuery = "repo:oven-sh/bun "; let actualQuery = "repo:oven-sh/bun ";
@ -225,14 +230,14 @@ async function search(
const response = await fetch( const response = await fetch(
`https://api.github.com/search/issues?q=${encodeURIComponent( `https://api.github.com/search/issues?q=${encodeURIComponent(
actualQuery actualQuery,
)}&per_page=${length}`, )}&per_page=${length}`,
{ {
headers: { headers: {
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
Accept: "application/vnd.github+json", Accept: "application/vnd.github+json",
}, },
} },
); );
const body = await response.json(); const body = await response.json();

View file

@ -38,7 +38,6 @@ const MDN_DATA = (await (
const cache = new Map<string, Document>(); const cache = new Map<string, Document>();
$applicationCommand({ $applicationCommand({
name: "mdn", name: "mdn",
description: "Search the Mozilla Developer Network documentation", description: "Search the Mozilla Developer Network documentation",
options: [ options: [
@ -48,16 +47,18 @@ $applicationCommand({
description: "Class or method to search for", description: "Class or method to search for",
required: true, required: true,
autocomplete: true, autocomplete: true,
max_length: 100 max_length: 100,
}, { },
{
type: ApplicationCommandOptionType.USER, type: ApplicationCommandOptionType.USER,
name: "target", name: "target",
description: "User to mention" description: "User to mention",
}, { },
{
type: ApplicationCommandOptionType.BOOLEAN, type: ApplicationCommandOptionType.BOOLEAN,
name: "hide", name: "hide",
description: "Show this message only for you" description: "Show this message only for you",
} },
], ],
handle: async (interaction) => { handle: async (interaction) => {
const hide = interaction.data.getBoolean("hide") ?? false; const hide = interaction.data.getBoolean("hide") ?? false;
@ -73,7 +74,7 @@ $applicationCommand({
if (!hit) { if (!hit) {
try { try {
const result = (await fetch(key).then(async (response) => const result = (await fetch(key).then(async (response) =>
response.json() response.json(),
)) as APIResult; )) as APIResult;
hit = result.doc; hit = result.doc;
} catch { } catch {
@ -143,9 +144,9 @@ $applicationCommand({
name: candidate.entry.title, name: candidate.entry.title,
value: candidate.entry.url, value: candidate.entry.url,
})), })),
25 25,
) ),
) ),
); );
}, },
}); });

View file

@ -7,35 +7,38 @@ import { ButtonStyle, ComponentType } from "lilybird";
$applicationCommand({ $applicationCommand({
name: "ping", name: "ping",
description: "pong", description: "pong",
components: [{ components: [
type: ComponentType.Button, {
id: "ping", type: ComponentType.Button,
customMatcher: `custom_id[0] == "0" && custom_id[1] == "-"`, id: "ping",
handle: (interaction) => { customMatcher: `custom_id[0] == "0" && custom_id[1] == "-"`,
const combined = interaction.data.id.split("-")?.[1]; handle: (interaction) => {
if (!combined) return; const combined = interaction.data.id.split("-")?.[1];
if (!combined) return;
const [ws, wsClosedForm, rest, restClosedForm] = S.generic.decodeCustomId(combined); const [ws, wsClosedForm, rest, restClosedForm] =
S.generic.decodeCustomId(combined);
silently( silently(
interaction.reply({ interaction.reply({
content: [ content: [
`🏓`, `🏓`,
"**WebSocket:**", "**WebSocket:**",
`\`${wsClosedForm}\``, `\`${wsClosedForm}\``,
`\`${ws} ms\``, `\`${ws} ms\``,
"", "",
"**Rest:**", "**Rest:**",
`\`${restClosedForm}\``, `\`${restClosedForm}\``,
`\`${rest} ms\``, `\`${rest} ms\``,
"", "",
"Mathematics is the language of the universe, it's truly fascinating! 😄", "Mathematics is the language of the universe, it's truly fascinating! 😄",
].join("\n"), ].join("\n"),
ephemeral: true, ephemeral: true,
}) }),
); );
} },
}], },
],
handle: async (interaction) => { handle: async (interaction) => {
await interaction.deferReply(); await interaction.deferReply();

View file

@ -7,18 +7,17 @@ $applicationCommand({
description: "Get tag", description: "Get tag",
options: [ options: [
{ {
type: ApplicationCommandOptionType.STRING, type: ApplicationCommandOptionType.STRING,
name: "query", name: "query",
description: "Select query", description: "Select query",
required: true, required: true,
autocomplete: true autocomplete: true,
}, },
{ {
type: ApplicationCommandOptionType.USER, type: ApplicationCommandOptionType.USER,
name: "target", name: "target",
description: "User to mention" description: "User to mention",
} },
], ],
handle: async (interaction) => { handle: async (interaction) => {
if (!interaction.inGuild()) return; if (!interaction.inGuild()) return;

View file

@ -14,7 +14,8 @@ $applicationCommand({
handle: (interaction) => { handle: (interaction) => {
interaction.reply({ interaction.reply({
content: [ content: [
`[git-bun-discord-bot-${COMMIT_HASH}](<https://github.com/xHyroM/bun-discord-bot/tree/${COMMIT_HASH}>) ${!PRODUCTION ? "(dev)" : "" `[git-bun-discord-bot-${COMMIT_HASH}](<https://github.com/xHyroM/bun-discord-bot/tree/${COMMIT_HASH}>) ${
!PRODUCTION ? "(dev)" : ""
}`, }`,
`[Bun v${Bun.version} (${Bun.revision})](<https://github.com/oven-sh/bun/releases/tag/bun-v${Bun.version}>)`, `[Bun v${Bun.version} (${Bun.revision})](<https://github.com/oven-sh/bun/releases/tag/bun-v${Bun.version}>)`,
"", "",

View file

@ -10,11 +10,11 @@ export const COMMIT_HASH = spawnSync({
export const LILYBIRD_VERSION = sliceIfStartsWith(dependencies.lilybird, "^"); export const LILYBIRD_VERSION = sliceIfStartsWith(dependencies.lilybird, "^");
export const LILYBIRD_JSX_VERSION = sliceIfStartsWith( export const LILYBIRD_JSX_VERSION = sliceIfStartsWith(
dependencies["@lilybird/jsx"], dependencies["@lilybird/jsx"],
"^" "^",
); );
export const LILYBIRD_HANDLERS_VERSION = sliceIfStartsWith( export const LILYBIRD_HANDLERS_VERSION = sliceIfStartsWith(
dependencies["@lilybird/handlers"], dependencies["@lilybird/handlers"],
"^" "^",
); );
export const PRODUCTION = process.env.NODE_ENV === "production"; export const PRODUCTION = process.env.NODE_ENV === "production";

View file

@ -3,31 +3,39 @@ import "./loaders/tags.ts";
import { SimpleTransformers, transformers, handler } from "./handler.ts"; import { SimpleTransformers, transformers, handler } from "./handler.ts";
import { ClientListeners, Intents, createClient } from "lilybird"; import { ClientListeners, Intents, createClient } from "lilybird";
import { createHandler } from "@lilybird/handlers/simple"; import { createHandler } from "@lilybird/handlers/simple";
import { info } from "@paperdave/logger" import { info } from "@paperdave/logger";
// Make sure bubu will not crash // Make sure bubu will not crash
process.on("unhandledRejection", console.error); process.on("unhandledRejection", console.error);
process.on("uncaughtException", console.error); process.on("uncaughtException", console.error);
handler.cachePath = `${import.meta.dir}/lily-cache/handler`; handler.cachePath = `${import.meta.dir}/lily-cache/handler`;
await handler.scanDir(`${import.meta.dir}/commands`); await handler.scanDir(`${import.meta.dir}/commands`);
await handler.scanDir(`${import.meta.dir}/listeners`); await handler.scanDir(`${import.meta.dir}/listeners`);
const { listeners: { messageCreate } } = await createHandler({ const {
listeners: { messageCreate },
} = await createHandler({
prefix: process.env.MESSAGE_PREFIX, prefix: process.env.MESSAGE_PREFIX,
dirs: { dirs: {
messageCommands: `${import.meta.dir}/message-commands` messageCommands: `${import.meta.dir}/message-commands`,
}, },
}); });
const listeners = handler.getListenersObject() as ClientListeners<SimpleTransformers>; const listeners =
handler.getListenersObject() as ClientListeners<SimpleTransformers>;
if (typeof listeners.messageCreate !== "undefined" && typeof messageCreate !== "undefined") if (
listeners.messageCreate = async (m) => { await listeners.messageCreate!(m); await messageCreate(m) } typeof listeners.messageCreate !== "undefined" &&
else if (typeof messageCreate !== "undefined") listeners.messageCreate = messageCreate; typeof messageCreate !== "undefined"
)
listeners.messageCreate = async (m) => {
await listeners.messageCreate!(m);
await messageCreate(m);
};
else if (typeof messageCreate !== "undefined")
listeners.messageCreate = messageCreate;
await createClient({ await createClient({
token: process.env.DISCORD_BOT_TOKEN, token: process.env.DISCORD_BOT_TOKEN,
@ -42,5 +50,5 @@ await createClient({
await handler.loadGlobalCommands(client); await handler.loadGlobalCommands(client);
}, },
transformers, transformers,
listeners listeners,
}); });

View file

@ -92,17 +92,19 @@ async function handleGithubLink(message: Message): Promise<void> {
if (extension === "zig") extension = "rs"; if (extension === "zig") extension = "rs";
message.reply({ message.reply({
content: `***${basename(path)}*** — *(L${firstLineNumber + 1}${secondLineNumber ? `-L${secondLineNumber}` : "" content: `***${basename(path)}*** — *(L${firstLineNumber + 1}${
})*\n\`\`\`${extension}\n${safeSlice( secondLineNumber ? `-L${secondLineNumber}` : ""
text, })*\n\`\`\`${extension}\n${safeSlice(
2000 - 6 - extension.length text,
)}\n\`\`\``, 2000 - 6 - extension.length,
)}\n\`\`\``,
components: [ components: [
<ActionRow> <ActionRow>
<Button <Button
style={ButtonStyle.Link} style={ButtonStyle.Link}
url={`https://github.com/${repo}/blob/${path}#L${firstLineNumber + 1 url={`https://github.com/${repo}/blob/${path}#L${
}${secondLineNumber ? `-L${secondLineNumber}` : ""}`} firstLineNumber + 1
}${secondLineNumber ? `-L${secondLineNumber}` : ""}`}
label={repo} label={repo}
/> />
</ActionRow>, </ActionRow>,

View file

@ -2,7 +2,6 @@ import { PartialMessage } from "@lilybird/transformers";
import { isBunOnlyLikeMessage } from "src/util.ts"; import { isBunOnlyLikeMessage } from "src/util.ts";
import { $listener } from "../handler.ts"; import { $listener } from "../handler.ts";
$listener({ $listener({
event: "messageUpdate", event: "messageUpdate",
handle: (message) => { handle: (message) => {

View file

@ -48,7 +48,7 @@ function getAvailableTags(channel: PartialGuildTextChannel) {
export function getTags( export function getTags(
channel: PartialGuildTextChannel, channel: PartialGuildTextChannel,
length: number length: number,
): Array<ApplicationCommand.Option.ChoiceStructure> { ): Array<ApplicationCommand.Option.ChoiceStructure> {
const availableTags = getAvailableTags(channel); const availableTags = getAvailableTags(channel);
return safeSlice<Array<ApplicationCommand.Option.ChoiceStructure>>( return safeSlice<Array<ApplicationCommand.Option.ChoiceStructure>>(
@ -56,30 +56,30 @@ export function getTags(
name: `🚀 ${tag.question}`, name: `🚀 ${tag.question}`,
value: tag.question, value: tag.question,
})), })),
length length,
); );
} }
export function searchTag<T extends boolean>( export function searchTag<T extends boolean>(
channel: PartialGuildTextChannel, channel: PartialGuildTextChannel,
providedQuery: string, providedQuery: string,
multiple?: T multiple?: T,
): T extends true ? Array<ApplicationCommand.Option.ChoiceStructure> : Tag { ): T extends true ? Array<ApplicationCommand.Option.ChoiceStructure> : Tag {
const availableTags = getAvailableTags(channel); const availableTags = getAvailableTags(channel);
const query = providedQuery?.toLowerCase()?.replace(/-/g, " "); const query = providedQuery?.toLowerCase()?.replace(/-/g, " ");
if (!multiple) { if (!multiple) {
const exactKeyword = availableTags.find((tag) => const exactKeyword = availableTags.find((tag) =>
tag.keywords.find((k) => k.toLowerCase() === query) tag.keywords.find((k) => k.toLowerCase() === query),
); );
const keywordMatch = availableTags.find((tag) => const keywordMatch = availableTags.find((tag) =>
tag.keywords.find((k) => k.toLowerCase().includes(query)) tag.keywords.find((k) => k.toLowerCase().includes(query)),
); );
const questionMatch = availableTags.find((tag) => const questionMatch = availableTags.find((tag) =>
tag.question.toLowerCase().includes(query) tag.question.toLowerCase().includes(query),
); );
const answerMatch = availableTags.find((tag) => const answerMatch = availableTags.find((tag) =>
tag.answer.toLowerCase().includes(query) tag.answer.toLowerCase().includes(query),
); );
const tag = exactKeyword ?? questionMatch ?? keywordMatch ?? answerMatch; const tag = exactKeyword ?? questionMatch ?? keywordMatch ?? answerMatch;
@ -96,7 +96,7 @@ export function searchTag<T extends boolean>(
for (const tag of availableTags) { for (const tag of availableTags) {
const exactKeyword = tag.keywords.find((t) => t.toLowerCase() === query); const exactKeyword = tag.keywords.find((t) => t.toLowerCase() === query);
const includesKeyword = tag.keywords.find((t) => const includesKeyword = tag.keywords.find((t) =>
t.toLowerCase().includes(query) t.toLowerCase().includes(query),
); );
const questionMatch = tag.question.toLowerCase().includes(query); const questionMatch = tag.question.toLowerCase().includes(query);
const answerMatch = tag.answer.toLowerCase().includes(query); const answerMatch = tag.answer.toLowerCase().includes(query);

View file

@ -6,7 +6,7 @@ const URL_REGEX = /\(\s*(https?:\/\/[^\s\[\]]+)\s*\)/gi;
export function safeSlice<T extends string | Array<any>>( export function safeSlice<T extends string | Array<any>>(
input: T, input: T,
length: number length: number,
): T { ): T {
return <T>(input.length > length ? input.slice(0, length) : input); return <T>(input.length > length ? input.slice(0, length) : input);
} }
@ -14,7 +14,7 @@ export function safeSlice<T extends string | Array<any>>(
export async function silently<T>(value: Promise<T>) { export async function silently<T>(value: Promise<T>) {
try { try {
await value; await value;
} catch { } } catch {}
} }
export async function moderateNick(member: GuildMember) { export async function moderateNick(member: GuildMember) {
@ -27,7 +27,7 @@ export async function moderateNick(member: GuildMember) {
member.modify({ member.modify({
nick: normalizedName, nick: normalizedName,
reason: "lame username", reason: "lame username",
}) }),
); );
} }
@ -38,7 +38,7 @@ export function isBunOnlyLikeMessage(content?: string) {
return BUN_EMOJIS.some((emoji) => return BUN_EMOJIS.some((emoji) =>
emoji.animated emoji.animated
? content.replace(/<a:|>/g, "") == `${emoji.name}:${emoji.id}` ? content.replace(/<a:|>/g, "") == `${emoji.name}:${emoji.id}`
: content.replace(/<:|>/g, "") == `${emoji.name}:${emoji.id}` : content.replace(/<:|>/g, "") == `${emoji.name}:${emoji.id}`,
); );
} }
@ -51,7 +51,7 @@ export function sliceIfStartsWith(input: string, startsWith: string) {
} }
export async function getBunReportDetailsInMarkdown( export async function getBunReportDetailsInMarkdown(
url: string url: string,
): Promise<string | undefined> { ): Promise<string | undefined> {
const remap = await parseAndRemap(url); const remap = await parseAndRemap(url);
if (!remap) return; if (!remap) return;
@ -76,7 +76,7 @@ export async function getBunReportDetailsInMarkdown(
} }
export async function possibleClosedForm( export async function possibleClosedForm(
value: number | string value: number | string,
): Promise<string | number> { ): Promise<string | number> {
try { try {
const res = await wolframApiClient.getFull(value.toString()); const res = await wolframApiClient.getFull(value.toString());