Compare commits

..

11 commits

11 changed files with 497 additions and 488 deletions

View file

@ -3,12 +3,13 @@ FROM node:18.20.4
ENV DOCKERIZE_VERSION v0.2.0 ENV DOCKERIZE_VERSION v0.2.0
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
RUN npm i -g pnpm
RUN mkdir app RUN mkdir app
WORKDIR /app WORKDIR /app
COPY . . COPY . .
RUN pnpm install RUN pnpm install
RUN pnpm db:push RUN pnpm db:generate
RUN pnpm build RUN pnpm build

View file

@ -17,14 +17,7 @@ const compat = new FlatCompat({
export default [ export default [
{ {
ignores: [ ignores: ['**/dist/', '**/.vscode/', '**/.idea/', '**/node_modules/'],
'**/.yarn/',
'**/.pnp.*',
'**/dist/',
'**/.vscode/',
'**/.idea/',
'**/tsup.config.ts',
],
}, },
...compat.extends('plugin:@typescript-eslint/recommended', 'prettier'), ...compat.extends('plugin:@typescript-eslint/recommended', 'prettier'),
{ {

View file

@ -1,5 +1,5 @@
{ {
"ext": "ts,json", "ext": "ts,json",
"exec": "pnpm build --sourcemap && node dist/src", "exec": "tsc --sourcemap && cross-env NODE_ENV=development node --enable-source-maps dist/src",
"ignore": ["dist/**/*.*"] "ignore": ["dist/**/*.*"]
} }

View file

@ -1,38 +1,39 @@
{ {
"name": "muffinbot", "name": "muffinbot",
"version": "4.0.0-pudding.p241027a", "version": "4.1.1-pudding.r250227a",
"main": "dist/src/index.js", "main": "dist/src/index.js",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@prisma/client": "^5.20.0", "@prisma/client": "^5.22.0",
"@sapphire/decorators": "^6.1.0", "@sapphire/decorators": "^6.1.1",
"@sapphire/discord.js-utilities": "^7.3.0", "@sapphire/discord.js-utilities": "^7.3.2",
"@sapphire/framework": "^5.2.1", "@sapphire/framework": "^5.3.2",
"@sapphire/pieces": "^4.3.1", "@sapphire/pieces": "^4.3.1",
"@sapphire/utilities": "^3.17.0", "@sapphire/utilities": "^3.18.2",
"discord-api-types": "^0.37.101", "discord-api-types": "^0.37.119",
"discord.js": "^14.16.3", "discord.js": "^14.18.0",
"dokdo": "^1.0.1", "dokdo": "^1.0.1",
"dotenv": "^16.4.5", "dotenv": "^16.4.7",
"semver": "^7.6.3" "es-hangul": "^2.3.1",
"semver": "^7.7.1"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3.1.0", "@eslint/eslintrc": "^3.3.0",
"@eslint/js": "^9.11.1", "@eslint/js": "^9.21.0",
"@migan/prettier-config": "^1.2.0", "@migan/prettier-config": "^1.2.0",
"@types/node": "^22.7.4", "@types/node": "^22.13.5",
"@types/semver": "^7.5.8", "@types/semver": "^7.5.8",
"@typescript-eslint/eslint-plugin": "^8.7.0", "@typescript-eslint/eslint-plugin": "^8.25.0",
"@typescript-eslint/parser": "^8.7.0", "@typescript-eslint/parser": "^8.25.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"eslint": "^9.11.1", "eslint": "^9.21.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.3",
"globals": "^15.9.0", "globals": "^15.15.0",
"nodemon": "^3.1.7", "nodemon": "^3.1.9",
"prettier": "^3.3.3", "prettier": "^3.5.2",
"prisma": "^5.20.0", "prisma": "^5.22.0",
"typescript": "^5.6.2" "typescript": "^5.7.3"
}, },
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",

File diff suppressed because it is too large Load diff

View file

@ -6,6 +6,7 @@ import {
ComponentType, ComponentType,
codeBlock, codeBlock,
Message, Message,
ButtonStyle,
} from 'discord.js' } from 'discord.js'
import { import {
DetailedDescriptionCommandObject, DetailedDescriptionCommandObject,
@ -100,15 +101,19 @@ export default class DeleteLearnCommand extends Command {
type: ComponentType.StringSelect, type: ComponentType.StringSelect,
customId: `${CUSTOM_ID}@${user.id}`, customId: `${CUSTOM_ID}@${user.id}`,
placeholder: '지울 데이터를 선택해ㅈ주세요', placeholder: '지울 데이터를 선택해ㅈ주세요',
options: [ options,
...options,
{
label: '❌ 취소',
description: '아무것도 삭제하지 않아요.',
value: `${CUSTOM_ID}-cancel`,
}, },
], ],
}, },
{
type: ComponentType.ActionRow,
components: [
{
type: ComponentType.Button,
customId: `${CUSTOM_ID}-cancel`,
label: '취소',
style: ButtonStyle.Danger,
},
], ],
}, },
], ],

View file

@ -1,6 +1,7 @@
import { ChatInputCommandInteraction, codeBlock, Message } from 'discord.js' import { ChatInputCommandInteraction, codeBlock, Message } from 'discord.js'
import { type Args, Command } from '@sapphire/framework' import { type Args, Command } from '@sapphire/framework'
import { ApplyOptions } from '@sapphire/decorators' import { ApplyOptions } from '@sapphire/decorators'
import { josa } from 'es-hangul'
@ApplyOptions<Command.Options>({ @ApplyOptions<Command.Options>({
name: '배워', name: '배워',
@ -43,7 +44,7 @@ export default class LearnCommand extends Command {
const config = this.container.config const config = this.container.config
const IG_MSG = '해ㄷ당 단어는 배울ㄹ 수 없어요.' const IG_MSG = '해ㄷ당 단어는 배울ㄹ 수 없어요.'
const DI_MSG = '해당 단ㅇ어는 개발자님이 특별히 금지하였ㅇ어요.' const DI_MSG = '해당 단ㅇ어는 개발자님이 특별히 금지하였ㅇ어요.'
const SUCCESS_MSG = '을/를 배웠ㅇ어요.' const SUCCESS_MSG = ' 배웠ㅇ어요.'
let command: string | undefined let command: string | undefined
let result: string | undefined let result: string | undefined
@ -114,8 +115,8 @@ export default class LearnCommand extends Command {
}) })
return ctx instanceof Message return ctx instanceof Message
? await ctx.reply(command + SUCCESS_MSG) ? await ctx.reply(josa(command, '을/를') + SUCCESS_MSG)
: await ctx.editReply(command + SUCCESS_MSG) : await ctx.editReply(josa(command, '을/를') + SUCCESS_MSG)
} }
public async messageRun(msg: Message, args: Args) { public async messageRun(msg: Message, args: Args) {

View file

@ -27,7 +27,10 @@ export default class ListCommand extends Command {
user_id: user.id, user_id: user.id,
}, },
}) })
const list: string[] = [] const list: {
command: string
result: string
}[] = []
if (!data[0]) { if (!data[0]) {
return await ctx.reply({ return await ctx.reply({
@ -36,8 +39,11 @@ export default class ListCommand extends Command {
}) })
} }
for (const listData of data) { for (const { command, result } of data) {
list.push(listData.command) list.push({
command,
result,
})
} }
await ctx.reply({ await ctx.reply({
@ -46,7 +52,7 @@ export default class ListCommand extends Command {
title: `${user.username}님의 지식`, title: `${user.username}님의 지식`,
description: `총합: ${data.length}\n${codeBlock( description: `총합: ${data.length}\n${codeBlock(
'md', 'md',
list.map(item => `- ${item}`).join('\n'), list.map(item => `- ${item.command}: ${item.result}`).join('\n'),
)}`, )}`,
color: this.container.embedColors.default, color: this.container.embedColors.default,
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),

View file

@ -31,18 +31,6 @@ export default class DeleteLearnHandler extends InteractionHandler {
const db = this.container.database const db = this.container.database
const decimalRegexp = /^[0-9]/g const decimalRegexp = /^[0-9]/g
if (id === 'cancel')
return await interaction.editReply({
embeds: [
{
title: '삭제',
description: '아무것도 삭제하지 않았어요.',
color: this.container.embedColors.fail,
},
],
components: [],
})
const itemId = interaction.component.options.map(item => const itemId = interaction.component.options.map(item =>
item.value.endsWith(`${id}`) ? item.label.match(decimalRegexp)![0] : null, item.value.endsWith(`${id}`) ? item.label.match(decimalRegexp)![0] : null,
) )

View file

@ -0,0 +1,31 @@
import { ApplyOptions } from '@sapphire/decorators'
import {
InteractionHandler,
InteractionHandlerTypes,
} from '@sapphire/framework'
import { ButtonInteraction } from 'discord.js'
@ApplyOptions<InteractionHandler.Options>({
interactionHandlerType: InteractionHandlerTypes.Button,
})
export default class DeleteLearnCancelHandler extends InteractionHandler {
private _CUSTOM_ID = 'maa$deleteLearn'
public async parse(interaction: ButtonInteraction) {
if (interaction.customId !== `${this._CUSTOM_ID}-cancel`) return this.none()
return this.some()
}
public async run(interaction: ButtonInteraction) {
return await interaction.update({
embeds: [
{
title: '삭제',
description: '아무것도 삭제하지 않았어요.',
color: this.container.embedColors.fail,
},
],
components: [],
})
}
}

View file

@ -10,6 +10,7 @@ export default class MessageCreateListener extends Listener {
aliases: this.container.dokdoAliases, aliases: this.container.dokdoAliases,
owners: [this.container.config.bot.owner_ID], owners: [this.container.config.bot.owner_ID],
prefix: prefix, prefix: prefix,
secrets: [process.env.DATABASE_URL!],
noPerm, noPerm,
}) })
if (msg.author.bot) return if (msg.author.bot) return