mirror of
https://github.com/kirameki-cafe/Yumi.git
synced 2026-09-13 10:49:20 +00:00
Merge pull request #140 from kirameki-cafe/purge
Early access opt-in, purge commands, bug fixes
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@ NODE_ENV=development
|
|||||||
#development
|
#development
|
||||||
#production
|
#production
|
||||||
|
|
||||||
DATABASE_URL=postgresql://user:password@host:port/dbName?schema=public
|
DATABASE_URL=postgresql://user:password@host:port/dbName?schema=public?schema=public&sslmode=disable&pgbouncer=true
|
||||||
|
|
||||||
DISCORD_TOKEN=SuperSecretDiscordToken
|
DISCORD_TOKEN=SuperSecretDiscordToken
|
||||||
DEVELOPER_IDS=DEV1_ID,DEV2_ID
|
DEVELOPER_IDS=DEV1_ID,DEV2_ID
|
||||||
|
|||||||
+32
-2
@@ -6,7 +6,13 @@
|
|||||||
"bot_no_permissions": "I don't have permission (O_O;)",
|
"bot_no_permissions": "I don't have permission (O_O;)",
|
||||||
"bot_no_permissions_description": "I need ``{{PERMISSIONS}}`` permissions",
|
"bot_no_permissions_description": "I need ``{{PERMISSIONS}}`` permissions",
|
||||||
"processing": "Please wait a moment~",
|
"processing": "Please wait a moment~",
|
||||||
"processing_description": "Getting it done right now! (งᓀ‸ᓂ)ง"
|
"processing_description": "Getting it done right now! (งᓀ‸ᓂ)ง",
|
||||||
|
"early_access_features": "Early access features",
|
||||||
|
"early_access_features_description": "Hey there! So, this new feature we've got is still in its early access phase. We're working hard to test and make it even better. But, just a heads up, early access means there might be some surprises like unexpected stuff, security things, or features that are still a work in progress.\n\nIf you're up for it, guild administrators can jump in and try it out by opting in through the settings"
|
||||||
|
},
|
||||||
|
"early_access_warning": {
|
||||||
|
"title": "Early access warning",
|
||||||
|
"description": "Experience the newest features first with early access! Things might not be perfect yet, but your feedback helps us make it amazing. Contact us with the support command if you find anything\n\n You can disable early access features anytime in the settings"
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"title": "Stats",
|
"title": "Stats",
|
||||||
@@ -48,6 +54,22 @@
|
|||||||
"success": "Done~, I posted a message with your content!",
|
"success": "Done~, I posted a message with your content!",
|
||||||
"error": "An error occurred while trying to post the message with your content!"
|
"error": "An error occurred while trying to post the message with your content!"
|
||||||
},
|
},
|
||||||
|
"purge": {
|
||||||
|
"title": "Purge",
|
||||||
|
"info": "Delete a certain amount of messages",
|
||||||
|
"valid_args": "``(Number of messages)``",
|
||||||
|
"nothing_purged": "Nothing to purge",
|
||||||
|
"nan_error_title": "Invalid argument",
|
||||||
|
"nan_error_description": "The argument is not a number",
|
||||||
|
"error_over_limit": "The number of messages to delete is over the limit, the maximum is {{MAX}}",
|
||||||
|
"purging_progress": "Purging in progress ({{CURRENT}}/{{TOTAL}})",
|
||||||
|
"purge_progress": "Purged {{COUNT}}/{{TOTAL}} messages",
|
||||||
|
"purging_step_bulk_delete": "Bulk deleting messages... ({{CURRENT}} deleted)",
|
||||||
|
"purging_step_bulk_delete_done": "Bulk deleted {{COUNT}} messages",
|
||||||
|
"purging_step_normal_delete": "Deleting messages... ({{CURRENT}} deleted)",
|
||||||
|
"purging_step_normal_delete_done": "Deleted {{COUNT}} messages",
|
||||||
|
"error": "An error occurred while purging messages"
|
||||||
|
},
|
||||||
"invite": {
|
"invite": {
|
||||||
"title": "Invite",
|
"title": "Invite",
|
||||||
"info": "[Invite {{BOT_NAME}} to your server!]({{{LINK}}})",
|
"info": "[Invite {{BOT_NAME}} to your server!]({{{LINK}}})",
|
||||||
@@ -138,7 +160,7 @@
|
|||||||
"settings": {
|
"settings": {
|
||||||
"title": "Settings",
|
"title": "Settings",
|
||||||
"description": "Change how {{BOT_NAME}} behave on **{{{GUILD_NAME}}}**",
|
"description": "Change how {{BOT_NAME}} behave on **{{{GUILD_NAME}}}**",
|
||||||
"valid_args": "``Prefix`` ``Language`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel``"
|
"valid_args": "``Prefix`` ``Language`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel`` ``PurgeLimit``"
|
||||||
},
|
},
|
||||||
"settings_prefix": {
|
"settings_prefix": {
|
||||||
"info": "Current prefix is {{{PREFIX}}}",
|
"info": "Current prefix is {{{PREFIX}}}",
|
||||||
@@ -150,6 +172,14 @@
|
|||||||
"prefix_updated": "Prefix updated",
|
"prefix_updated": "Prefix updated",
|
||||||
"prefix_updated_description": "From now onwards, I shall be called by using ``{{{PREFIX}}}``"
|
"prefix_updated_description": "From now onwards, I shall be called by using ``{{{PREFIX}}}``"
|
||||||
},
|
},
|
||||||
|
"settings_purge_limit": {
|
||||||
|
"info": "Current purge limit is {{LIMIT}}",
|
||||||
|
"info_description": "Provide a new purge limit to change",
|
||||||
|
"purge_limit_too_big": "Purge limit too big, maximum is {{LIMIT}}",
|
||||||
|
"purge_limit_zero": "Purge limit can't be zero",
|
||||||
|
"purge_limit_nan": "Purge limit is not a number",
|
||||||
|
"purge_limit_updated": "Purge limit updated to {{LIMIT}}"
|
||||||
|
},
|
||||||
"settings_language": {
|
"settings_language": {
|
||||||
"info": "Current language is {{LANGUAGE}}",
|
"info": "Current language is {{LANGUAGE}}",
|
||||||
"info_description": "Provide a new language to change\n**Available languages**: ``{{LANGUAGES}}``",
|
"info_description": "Provide a new language to change\n**Available languages**: ``{{LANGUAGES}}``",
|
||||||
|
|||||||
+32
-2
@@ -6,7 +6,13 @@
|
|||||||
"bot_no_permissions": "許可がない (O_O;)",
|
"bot_no_permissions": "許可がない (O_O;)",
|
||||||
"bot_no_permissions_description": "そのためには、あたしの``{{PERMISSIONS}}``の権限が必要です",
|
"bot_no_permissions_description": "そのためには、あたしの``{{PERMISSIONS}}``の権限が必要です",
|
||||||
"processing": "アクションの実行",
|
"processing": "アクションの実行",
|
||||||
"processing_description": "今これを成し遂げています (งᓀ‸ᓂ)ง"
|
"processing_description": "今これを成し遂げています (งᓀ‸ᓂ)ง",
|
||||||
|
"early_access_features": "早期アクセス機能",
|
||||||
|
"early_access_features_description": "こんにちは!新しいこの機能はまだ早期アクセスフェーズにあります。私たちはテストを進め、さらに良くしている最中です。ただし、早期アクセスということは、予期せぬこと、セキュリティの問題、または作業中の機能のような驚きがあるかもしれないことを意味します。\n\nお試しいただけるなら、ギルド管理者は設定からオプトインして試してみることができます。"
|
||||||
|
},
|
||||||
|
"early_access_warning": {
|
||||||
|
"title": "アーリーアクセス注意報",
|
||||||
|
"description": "アーリーアクセスで最新の機能を先取りしよう! まだ完璧じゃないかもしれないけど、あなたのフィードバックが素晴らしいものに変えてくれるんだよ。何か見つけたら、サポートコマンドで連絡してね\n\n設定でいつでもアーリーアクセス機能を無効にできるよ"
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"title": "統計情報",
|
"title": "統計情報",
|
||||||
@@ -48,6 +54,22 @@
|
|||||||
"success": "メッセージの送信に成功しました",
|
"success": "メッセージの送信に成功しました",
|
||||||
"error": "メッセージを送信できない"
|
"error": "メッセージを送信できない"
|
||||||
},
|
},
|
||||||
|
"purge": {
|
||||||
|
"title": "削除",
|
||||||
|
"info": "特定のメッセージ数を削除します",
|
||||||
|
"valid_args": "``(メッセージ数)``",
|
||||||
|
"nothing_purged": "削除するメッセージはありません",
|
||||||
|
"nan_error_title": "無効な引数",
|
||||||
|
"nan_error_description": "引数が数値ではありません",
|
||||||
|
"error_over_limit": "削除するメッセージ数が上限を超えています。最大は {{MAX}} です",
|
||||||
|
"purging_progress": "削除中 ({{CURRENT}}/{{TOTAL}})",
|
||||||
|
"purge_progress": "{{COUNT}}/{{TOTAL}} メッセージ削除済み",
|
||||||
|
"purging_step_bulk_delete": "メッセージを一括で削除中... ({{CURRENT}} 削除済み)",
|
||||||
|
"purging_step_bulk_delete_done": "一括で {{COUNT}} メッセージ削除済み",
|
||||||
|
"purging_step_normal_delete": "メッセージを削除中... ({{CURRENT}} 削除済み)",
|
||||||
|
"purging_step_normal_delete_done": "{{COUNT}} メッセージ削除済み",
|
||||||
|
"error": "メッセージ削除中にエラーが発生しました"
|
||||||
|
},
|
||||||
"invite": {
|
"invite": {
|
||||||
"title": "招待状リンク",
|
"title": "招待状リンク",
|
||||||
"info": "[あなたのサーバに{{BOT_NAME}}を招待してください]({{{LINK}}})",
|
"info": "[あなたのサーバに{{BOT_NAME}}を招待してください]({{{LINK}}})",
|
||||||
@@ -138,7 +160,7 @@
|
|||||||
"settings": {
|
"settings": {
|
||||||
"title": "設定",
|
"title": "設定",
|
||||||
"description": "**{{{GUILD_NAME}}}**サーバでの{{BOT_NAME}}の動作変更",
|
"description": "**{{{GUILD_NAME}}}**サーバでの{{BOT_NAME}}の動作変更",
|
||||||
"valid_args": "``Prefix`` ``Language`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel``"
|
"valid_args": "``Prefix`` ``Language`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel`` ``PurgeLimit``"
|
||||||
},
|
},
|
||||||
"settings_prefix": {
|
"settings_prefix": {
|
||||||
"info": "現在の接頭辞は「{{{PREFIX}}}」です。",
|
"info": "現在の接頭辞は「{{{PREFIX}}}」です。",
|
||||||
@@ -150,6 +172,14 @@
|
|||||||
"prefix_updated": "プレフィックスを更新",
|
"prefix_updated": "プレフィックスを更新",
|
||||||
"prefix_updated_description": "これ以降、私は 「``{{{PREFIX}}}``」 を使って呼び出されることになります。"
|
"prefix_updated_description": "これ以降、私は 「``{{{PREFIX}}}``」 を使って呼び出されることになります。"
|
||||||
},
|
},
|
||||||
|
"settings_purge_limit": {
|
||||||
|
"info": "現在の削除上限は {{LIMIT}} です",
|
||||||
|
"info_description": "変更する新しい削除上限を指定してください",
|
||||||
|
"purge_limit_too_big": "削除上限が大きすぎます。最大は {{LIMIT}} です",
|
||||||
|
"purge_limit_zero": "削除上限はゼロにできません",
|
||||||
|
"purge_limit_nan": "削除上限が数値ではありません",
|
||||||
|
"purge_limit_updated": "削除上限が {{LIMIT}} に更新されました"
|
||||||
|
},
|
||||||
"settings_language": {
|
"settings_language": {
|
||||||
"info": "現在の言語は{{LANGUAGE}}です",
|
"info": "現在の言語は{{LANGUAGE}}です",
|
||||||
"info_description": "変更する新しい言語を提供する\n**利用可能な言語**: ``{{LANGUAGES}}``",
|
"info_description": "変更する新しい言語を提供する\n**利用可能な言語**: ``{{LANGUAGES}}``",
|
||||||
|
|||||||
+32
-2
@@ -6,7 +6,13 @@
|
|||||||
"bot_no_permissions": "ฉันไม่มีสิทธิ์เข้าถึง (O_O;)",
|
"bot_no_permissions": "ฉันไม่มีสิทธิ์เข้าถึง (O_O;)",
|
||||||
"bot_no_permissions_description": "ฉันต้องการสิทธิ์เข้าถึง ``{{PERMISSIONS}}``",
|
"bot_no_permissions_description": "ฉันต้องการสิทธิ์เข้าถึง ``{{PERMISSIONS}}``",
|
||||||
"processing": "รอแปปนึงน้า",
|
"processing": "รอแปปนึงน้า",
|
||||||
"processing_description": "ฉันกำลังดำเนินการให้อยู่ (งᓀ‸ᓂ)ง"
|
"processing_description": "ฉันกำลังดำเนินการให้อยู่ (งᓀ‸ᓂ)ง",
|
||||||
|
"early_access_features": "คุณลักษณะการเข้าถึงล่วงหน้า",
|
||||||
|
"early_access_features_description": "สวัสดี! ฟีเจอร์ใหม่ที่เรามีนี้ยังอยู่ในช่วงการเข้าถึงก่อนใคร เรากำลังทำงานอย่างหนักเพื่อทดสอบและทำให้ดียิ่งขึ้น แต่ขอเตือนไว้ก่อน การเข้าถึงก่อนใครหมายความว่าอาจมีสิ่งที่ไม่คาดคิดเกิดขึ้นได้ เช่น ปัญหาด้านความปลอดภัย หรือคุณลักษณะที่ยังอยู่ระหว่างการพัฒนา\n\nหากคุณสนใจ ผู้ดูแลกิลด์สามารถเข้าร่วมทดลองใช้งานได้โดยเลือกใช้ผ่านการตั้งค่า"
|
||||||
|
},
|
||||||
|
"early_access_warning": {
|
||||||
|
"title": "แจ้งเตือน Early Access",
|
||||||
|
"description": "ลองสัมผัสคุณลักษณะใหม่ๆ ก่อนใครได้กับ Early Access นะคะ! บางอย่างอาจจะยังไม่สมบูรณ์ที่สุดนะ แต่คำติชมจากคุณจะช่วยทำให้มันน่านับถือมากขึ้นเลยนะคะ ติดต่อเราผ่านคำสั่ง support ถ้าคุณพบอะไรเจ๊งจะบอกเรานะคะ\n\nแล้วนะคะ, คุณสามารถปิดใช้คุณลักษณะ Early Access ได้ทุกเมื่อในเมนูตั้งค่าค่ะ"
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"title": "สถิติ",
|
"title": "สถิติ",
|
||||||
@@ -48,6 +54,22 @@
|
|||||||
"success": "เรียบร้อย~ ฉันโพสต์ข้อความพร้อมเนื้อหาของคุณแล้วนะ",
|
"success": "เรียบร้อย~ ฉันโพสต์ข้อความพร้อมเนื้อหาของคุณแล้วนะ",
|
||||||
"error": "เกิดข้อผิดพลาดขณะพยายามโพสต์ข้อความพร้อมเนื้อหาของคุณ!"
|
"error": "เกิดข้อผิดพลาดขณะพยายามโพสต์ข้อความพร้อมเนื้อหาของคุณ!"
|
||||||
},
|
},
|
||||||
|
"purge": {
|
||||||
|
"title": "ล้าง",
|
||||||
|
"info": "ลบจำนวนข้อความที่กำหนด",
|
||||||
|
"valid_args": "``(จำนวนข้อความ)``",
|
||||||
|
"nothing_purged": "ไม่มีข้อความที่จะลบ",
|
||||||
|
"nan_error_title": "อาร์กิวเมนต์ไม่ถูกต้อง",
|
||||||
|
"nan_error_description": "อาร์กิวเมนต์ไม่ใช่ตัวเลข",
|
||||||
|
"error_over_limit": "จำนวนข้อความที่ต้องการลบเกินขีด จำกัด มีได้สูงสุด {{MAX}}",
|
||||||
|
"purging_progress": "กำลังทำการล้าง ({{CURRENT}}/{{TOTAL}})",
|
||||||
|
"purge_progress": "ล้าง {{COUNT}}/{{TOTAL}} ข้อความ",
|
||||||
|
"purging_step_bulk_delete": "กำลังลบข้อความโดยกลุ่ม... (ลบทั้งหมด {{CURRENT}})",
|
||||||
|
"purging_step_bulk_delete_done": "ลบทั้งหมด {{COUNT}} ข้อความ",
|
||||||
|
"purging_step_normal_delete": "กำลังลบข้อความ... (ลบทั้งหมด {{CURRENT}})",
|
||||||
|
"purging_step_normal_delete_done": "ลบทั้งหมด {{COUNT}} ข้อความ",
|
||||||
|
"error": "เกิดข้อผิดพลาดขณะทำการล้างข้อความ"
|
||||||
|
},
|
||||||
"invite": {
|
"invite": {
|
||||||
"title": "เชิญชวน",
|
"title": "เชิญชวน",
|
||||||
"info": "[เชิญ {{BOT_NAME}} เข้าสู่เซิร์ฟเวอร์ของคุณ!]({{{LINK}}})",
|
"info": "[เชิญ {{BOT_NAME}} เข้าสู่เซิร์ฟเวอร์ของคุณ!]({{{LINK}}})",
|
||||||
@@ -138,7 +160,7 @@
|
|||||||
"settings": {
|
"settings": {
|
||||||
"title": "การตั้งค่า",
|
"title": "การตั้งค่า",
|
||||||
"description": "เปลี่ยนพฤติกรรมของ {{BOT_NAME}} บน **{{{GUILD_NAME}}}**",
|
"description": "เปลี่ยนพฤติกรรมของ {{BOT_NAME}} บน **{{{GUILD_NAME}}}**",
|
||||||
"valid_args": "``Prefix`` ``Language`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel``"
|
"valid_args": "``Prefix`` ``Language`` ``EnableServiceAnnouncement`` ``ServiceAnnouncementChannel`` ``PurgeLimit``"
|
||||||
},
|
},
|
||||||
"settings_prefix": {
|
"settings_prefix": {
|
||||||
"info": "คำนำหน้าปัจจุบันคือ {{{PREFIX}}}",
|
"info": "คำนำหน้าปัจจุบันคือ {{{PREFIX}}}",
|
||||||
@@ -150,6 +172,14 @@
|
|||||||
"prefix_updated": "อัปเดตคำนำหน้าแล้ว",
|
"prefix_updated": "อัปเดตคำนำหน้าแล้ว",
|
||||||
"prefix_updated_description": "จากนี้ไป คุณสามารถเรียกฉันโดยใช้ ``{{{PREFIX}}}`` นะ"
|
"prefix_updated_description": "จากนี้ไป คุณสามารถเรียกฉันโดยใช้ ``{{{PREFIX}}}`` นะ"
|
||||||
},
|
},
|
||||||
|
"settings_purge_limit": {
|
||||||
|
"info": "ขณะนี้ขีดจำกัดการล้างคือ {{LIMIT}}",
|
||||||
|
"info_description": "ระบุขีดจำกัดการล้างใหม่เพื่อเปลี่ยนแปลง",
|
||||||
|
"purge_limit_too_big": "ขีดจำกัดการล้างใหญ่เกินไป สูงสุดคือ {{LIMIT}}",
|
||||||
|
"purge_limit_zero": "ไม่สามารถตั้งค่าขีดจำกัดการล้างเป็นศูนย์ได้",
|
||||||
|
"purge_limit_nan": "ขีดจำกัดการล้างไม่ใช่ตัวเลข",
|
||||||
|
"purge_limit_updated": "ปรับปรุงขีดจำกัดการล้างเป็น {{LIMIT}} แล้ว"
|
||||||
|
},
|
||||||
"settings_language": {
|
"settings_language": {
|
||||||
"info": "ภาษาปัจจุบันตอนนี้คือ {{LANGUAGE}}",
|
"info": "ภาษาปัจจุบันตอนนี้คือ {{LANGUAGE}}",
|
||||||
"info_description": "ระบุภาษาใหม่เพื่อเปลี่ยน\n**ภาษาที่ใช้ได้**: ``{{LANGUAGES}}``",
|
"info_description": "ระบุภาษาใหม่เพื่อเปลี่ยน\n**ภาษาที่ใช้ได้**: ``{{LANGUAGES}}``",
|
||||||
|
|||||||
+8
-8
@@ -13,10 +13,10 @@
|
|||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"country-code-emoji": "^2.3.0",
|
"country-code-emoji": "^2.3.0",
|
||||||
"country-code-lookup": "^0.1.1",
|
"country-code-lookup": "^0.1.1",
|
||||||
"discord-api-types": "^0.37.67",
|
"discord-api-types": "^0.37.71",
|
||||||
"discord.js": "^14.14.1",
|
"discord.js": "^14.14.1",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.4.5",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.3",
|
||||||
"i18n": "^0.15.1",
|
"i18n": "^0.15.1",
|
||||||
"libsodium-wrappers": "^0.7.13",
|
"libsodium-wrappers": "^0.7.13",
|
||||||
"node-osu": "^2.2.1",
|
"node-osu": "^2.2.1",
|
||||||
@@ -27,19 +27,19 @@
|
|||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"utf-8-validate": "^6.0.3",
|
"utf-8-validate": "^6.0.3",
|
||||||
"validator": "^13.11.0",
|
"validator": "^13.11.0",
|
||||||
"vrchat": "^1.16.2",
|
"vrchat": "^1.16.6",
|
||||||
"winston": "^3.11.0",
|
"winston": "^3.11.0",
|
||||||
"zlib-sync": "^0.1.9"
|
"zlib-sync": "^0.1.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@prisma/client": "^5.8.0",
|
"@prisma/client": "^5.10.2",
|
||||||
"@types/bluebird": "^3.5.42",
|
"@types/bluebird": "^3.5.42",
|
||||||
"@types/i18n": "^0.13.10",
|
"@types/i18n": "^0.13.10",
|
||||||
"@types/node": "^20.10.8",
|
"@types/node": "^20.11.24",
|
||||||
"@types/ping": "^0.4.4",
|
"@types/ping": "^0.4.4",
|
||||||
"@types/validator": "^13.11.8",
|
"@types/validator": "^13.11.9",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"prisma": "^5.8.0",
|
"prisma": "^5.10.2",
|
||||||
"ts-node-dev": "^2.0.0"
|
"ts-node-dev": "^2.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ model Guild {
|
|||||||
|
|
||||||
ServiceAnnouncement_Enabled Boolean @default(false)
|
ServiceAnnouncement_Enabled Boolean @default(false)
|
||||||
ServiceAnnouncement_Channel String?
|
ServiceAnnouncement_Channel String?
|
||||||
|
|
||||||
|
Purge_Limit Int @default(300)
|
||||||
|
|
||||||
|
EarlyAccess_Enabled Boolean @default(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
model User {
|
model User {
|
||||||
|
|||||||
@@ -0,0 +1,419 @@
|
|||||||
|
import {
|
||||||
|
Message,
|
||||||
|
CommandInteraction,
|
||||||
|
PermissionsBitField,
|
||||||
|
GuildBasedChannel,
|
||||||
|
BaseGuildTextChannel,
|
||||||
|
BaseInteraction,
|
||||||
|
GuildTextBasedChannel
|
||||||
|
} from 'discord.js';
|
||||||
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
|
import DiscordModule, { HybridInteractionMessage } from '../utils/DiscordModule';
|
||||||
|
import {
|
||||||
|
makeSuccessEmbed,
|
||||||
|
sendHybridInteractionMessageResponse,
|
||||||
|
makeErrorEmbed,
|
||||||
|
makeInfoEmbed,
|
||||||
|
sendMessage
|
||||||
|
} from '../utils/DiscordMessage';
|
||||||
|
import Locale from '../services/Locale';
|
||||||
|
import Logger from '../libs/Logger';
|
||||||
|
import Prisma from '../providers/Prisma';
|
||||||
|
import Environment from '../providers/Environment';
|
||||||
|
import {
|
||||||
|
checkBotPermissionsInChannel,
|
||||||
|
checkMemberPermissionsInChannel,
|
||||||
|
checkMemberPermissionsInGuild
|
||||||
|
} from '../utils/DiscordPermission';
|
||||||
|
import Cache from '../providers/Cache';
|
||||||
|
import { COMMON_EMBEDS } from './Settings';
|
||||||
|
|
||||||
|
const EMBEDS = {
|
||||||
|
PURGE_INFO: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeInfoEmbed({
|
||||||
|
title: locale.__('purge.title'),
|
||||||
|
description: locale.__('purge.info'),
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: locale.__('common.available_args'),
|
||||||
|
value: locale.__('purge.valid_args')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGING_STAGE_1: (data: HybridInteractionMessage, locale: I18n, current: number, total: number) => {
|
||||||
|
return makeInfoEmbed({
|
||||||
|
title: locale.__('purge.title'),
|
||||||
|
description:
|
||||||
|
locale.__('purge.purging_progress', { CURRENT: current.toString(), TOTAL: total.toString() }) +
|
||||||
|
'\n\n' +
|
||||||
|
locale.__('purge.purging_step_bulk_delete_done', { COUNT: current.toString() }),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGING_STAGE_2: (
|
||||||
|
data: HybridInteractionMessage,
|
||||||
|
locale: I18n,
|
||||||
|
current: number,
|
||||||
|
current_normal: number,
|
||||||
|
total: number
|
||||||
|
) => {
|
||||||
|
return makeInfoEmbed({
|
||||||
|
title: locale.__('purge.title'),
|
||||||
|
description:
|
||||||
|
locale.__('purge.purging_progress', {
|
||||||
|
CURRENT: (current + current_normal).toString(),
|
||||||
|
TOTAL: total.toString()
|
||||||
|
}) +
|
||||||
|
'\n\n' +
|
||||||
|
locale.__('purge.purging_step_bulk_delete_done', { COUNT: current.toString() }) +
|
||||||
|
'\n' +
|
||||||
|
locale.__('purge.purging_step_normal_delete', { CURRENT: current_normal.toString() }),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGING_DONE_EARLY: (data: HybridInteractionMessage, locale: I18n, current: number, total: number) => {
|
||||||
|
return makeSuccessEmbed({
|
||||||
|
title: locale.__('purge.title'),
|
||||||
|
description:
|
||||||
|
locale.__('purge.purge_progress', { COUNT: current.toString(), TOTAL: total.toString() }) +
|
||||||
|
'\n\n' +
|
||||||
|
locale.__('purge.purging_step_bulk_delete_done', { COUNT: current.toString() }),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGING_DONE: (
|
||||||
|
data: HybridInteractionMessage,
|
||||||
|
locale: I18n,
|
||||||
|
current: number,
|
||||||
|
current_normal: number,
|
||||||
|
total: number
|
||||||
|
) => {
|
||||||
|
return makeSuccessEmbed({
|
||||||
|
title: locale.__('purge.title'),
|
||||||
|
description:
|
||||||
|
locale.__('purge.purge_progress', {
|
||||||
|
COUNT: (current + current_normal).toString(),
|
||||||
|
TOTAL: total.toString()
|
||||||
|
}) +
|
||||||
|
'\n\n' +
|
||||||
|
locale.__('purge.purging_step_bulk_delete_done', { COUNT: current.toString() }) +
|
||||||
|
'\n' +
|
||||||
|
locale.__('purge.purging_step_normal_delete_done', { COUNT: current_normal.toString() }),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGE_ERROR: (data: HybridInteractionMessage, locale: I18n, error: Error) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('purge.error'),
|
||||||
|
description: error.message ? error.message : undefined,
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGE_NAN_ERROR: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('purge.nan_error_title'),
|
||||||
|
description: locale.__('purge.nan_error_description'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGE_OVER_LIMIT: (data: HybridInteractionMessage, locale: I18n, limit: number) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('common.member_no_permissions'),
|
||||||
|
description: locale.__('purge.error_over_limit', { MAX: limit.toString() }),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
NOTHING_PURGED: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeSuccessEmbed({
|
||||||
|
title: locale.__('purge.nothing_purged'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class Purge extends DiscordModule {
|
||||||
|
public id = 'Discord_Purge';
|
||||||
|
public commands = ['purge'];
|
||||||
|
public commandInteractionName = 'purge';
|
||||||
|
|
||||||
|
async GuildOnModuleCommand(args: any, message: Message) {
|
||||||
|
await this.run(new HybridInteractionMessage(message), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async GuildModuleCommandInteractionCreate(interaction: CommandInteraction) {
|
||||||
|
await this.run(new HybridInteractionMessage(interaction), interaction.options);
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(data: HybridInteractionMessage, args: any) {
|
||||||
|
const guild = data.getGuild();
|
||||||
|
if (!guild) return;
|
||||||
|
|
||||||
|
const member = data.getMember();
|
||||||
|
if (!member) return;
|
||||||
|
|
||||||
|
const channel = data.getGuildChannel() as GuildTextBasedChannel;
|
||||||
|
if (!channel) return;
|
||||||
|
|
||||||
|
const cachedGuild = await Cache.getCachedGuild(guild.id);
|
||||||
|
if (!cachedGuild) return;
|
||||||
|
|
||||||
|
const locale = await Locale.getGuildLocale(guild.id);
|
||||||
|
|
||||||
|
// TODO: Remove this feature when ready from early access
|
||||||
|
if (!cachedGuild.EarlyAccess_Enabled)
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [COMMON_EMBEDS.EARLY_ACCESS_WARNING(data, locale)]
|
||||||
|
});
|
||||||
|
|
||||||
|
let query;
|
||||||
|
|
||||||
|
if (data.isMessage()) {
|
||||||
|
const message = data.getMessage();
|
||||||
|
|
||||||
|
if (!message.member) return;
|
||||||
|
|
||||||
|
if (args.length === 0)
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.PURGE_INFO(data, locale)]
|
||||||
|
});
|
||||||
|
|
||||||
|
query = args.join(' ');
|
||||||
|
} else if (data.isApplicationCommand()) {
|
||||||
|
const interaction = data.getSlashCommand();
|
||||||
|
query = interaction.options.get('amount', true).value?.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const purgeMessages = async (query: any, data: HybridInteractionMessage) => {
|
||||||
|
if (isNaN(query)) {
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.PURGE_NAN_ERROR(data, locale)]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(await checkMemberPermissionsInChannel({
|
||||||
|
member,
|
||||||
|
channel,
|
||||||
|
data,
|
||||||
|
locale,
|
||||||
|
permissions: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.ManageMessages]
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(await checkBotPermissionsInChannel({
|
||||||
|
guild,
|
||||||
|
data,
|
||||||
|
locale,
|
||||||
|
channel,
|
||||||
|
permissions: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.ManageMessages]
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const PrismaGuild = await Prisma.client.guild.findFirst({ where: { id: guild.id } });
|
||||||
|
if (!PrismaGuild) return;
|
||||||
|
|
||||||
|
const guildLimit = PrismaGuild.Purge_Limit;
|
||||||
|
try {
|
||||||
|
let totalMessagesToDelete = parseInt(query);
|
||||||
|
|
||||||
|
if (totalMessagesToDelete > guildLimit) {
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.PURGE_OVER_LIMIT(data, locale, guildLimit)]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let totalMessageDeleted = 0;
|
||||||
|
let totalBulkDeletedMessages = 0;
|
||||||
|
|
||||||
|
let messages;
|
||||||
|
let statusMessage;
|
||||||
|
if (data.isMessage()) {
|
||||||
|
if (data.getMessage().deletable)
|
||||||
|
await data
|
||||||
|
.getMessage()
|
||||||
|
.delete()
|
||||||
|
.catch(() => {});
|
||||||
|
|
||||||
|
statusMessage = await sendMessage(channel, data.getUser()!, {
|
||||||
|
embeds: [EMBEDS.PURGING_STAGE_1(data, locale, totalBulkDeletedMessages, totalMessagesToDelete)]
|
||||||
|
});
|
||||||
|
} else if (data.isApplicationCommand()) {
|
||||||
|
statusMessage = await data.getMessageComponentInteraction().reply({
|
||||||
|
embeds: [EMBEDS.PURGING_STAGE_1(data, locale, totalBulkDeletedMessages, totalMessagesToDelete)],
|
||||||
|
fetchReply: true
|
||||||
|
});
|
||||||
|
statusMessage = statusMessage as unknown as BaseInteraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
statusMessage = new HybridInteractionMessage(statusMessage!);
|
||||||
|
|
||||||
|
let amountToDelete = totalMessagesToDelete > 100 ? 100 : totalMessagesToDelete;
|
||||||
|
messages = await channel.messages.fetch({
|
||||||
|
limit: amountToDelete,
|
||||||
|
before: statusMessage.getMessage().id
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filter out statusMessage
|
||||||
|
// messages = messages.filter((msg) => msg.id !== statusMessage!.getMessage().id);
|
||||||
|
|
||||||
|
// Filter out message sent after the status message
|
||||||
|
// messages = messages.filter(
|
||||||
|
// (msg) => msg.createdTimestamp < statusMessage!.getMessage().createdTimestamp
|
||||||
|
//);
|
||||||
|
|
||||||
|
// Edit the message
|
||||||
|
if (messages.size === 0) {
|
||||||
|
let embed = EMBEDS.NOTHING_PURGED(data, locale);
|
||||||
|
if (data.isMessage()) {
|
||||||
|
return await statusMessage.getMessage().edit({ embeds: [embed] });
|
||||||
|
} else if (data.isApplicationCommand()) {
|
||||||
|
return await statusMessage.getMessageComponentInteraction().editReply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (totalMessageDeleted < totalMessagesToDelete) {
|
||||||
|
amountToDelete =
|
||||||
|
totalMessagesToDelete - totalMessageDeleted > 100
|
||||||
|
? 100
|
||||||
|
: totalMessagesToDelete - totalMessageDeleted;
|
||||||
|
|
||||||
|
Logger.debug(
|
||||||
|
'[DiscordPurge]',
|
||||||
|
`Attempting to delete ${amountToDelete} messages. Total deleted: ${totalBulkDeletedMessages}/${totalMessagesToDelete}`
|
||||||
|
);
|
||||||
|
|
||||||
|
messages = await channel.messages.fetch({
|
||||||
|
limit: amountToDelete,
|
||||||
|
before: statusMessage.getMessage().id
|
||||||
|
});
|
||||||
|
|
||||||
|
messages = messages.filter((msg) => msg.deletable);
|
||||||
|
|
||||||
|
if (messages.size === 0) {
|
||||||
|
let embed = EMBEDS.PURGING_DONE_EARLY(data, locale, totalBulkDeletedMessages, amountToDelete);
|
||||||
|
if (data.isMessage()) {
|
||||||
|
return await statusMessage.getMessage().edit({ embeds: [embed] });
|
||||||
|
} else if (data.isApplicationCommand()) {
|
||||||
|
return await statusMessage.getMessageComponentInteraction().editReply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.debug(
|
||||||
|
'[DiscordPurge]',
|
||||||
|
`Bulk deleting: ${messages.size}. Total deleted: ${totalBulkDeletedMessages}/${totalMessagesToDelete}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const deletedMessages = await (channel as BaseGuildTextChannel).bulkDelete(messages, true);
|
||||||
|
totalMessageDeleted += deletedMessages.size;
|
||||||
|
totalBulkDeletedMessages += deletedMessages.size;
|
||||||
|
|
||||||
|
let embed = EMBEDS.PURGING_STAGE_1(data, locale, totalBulkDeletedMessages, totalMessagesToDelete);
|
||||||
|
|
||||||
|
if (data.isMessage()) {
|
||||||
|
await statusMessage.getMessage().edit({ embeds: [embed] });
|
||||||
|
} else if (data.isApplicationCommand()) {
|
||||||
|
await statusMessage.getMessageComponentInteraction().editReply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unable to delete all the messages? Break the loop and start normal deletion
|
||||||
|
if (deletedMessages.size !== messages.size) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//let embed = EMBEDS.PURGING_DONE_EARLY(data, locale, totalBulkDeletedMessages, amountToDelete);
|
||||||
|
Logger.debug(
|
||||||
|
'[DiscordPurge]',
|
||||||
|
`Bulk deleted ${totalBulkDeletedMessages} messages. Total deleted: ${totalBulkDeletedMessages}/${totalMessagesToDelete}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (totalMessageDeleted !== totalMessagesToDelete) {
|
||||||
|
const remainingMessages = totalMessagesToDelete - totalMessageDeleted;
|
||||||
|
const fetchLimit = 100;
|
||||||
|
const fetchIterations = Math.ceil(remainingMessages / fetchLimit);
|
||||||
|
|
||||||
|
for (let i = 0; i < fetchIterations; i++) {
|
||||||
|
const fetchAmount = Math.min(fetchLimit, remainingMessages - i * fetchLimit);
|
||||||
|
let fetchedMessages = await channel.messages.fetch({
|
||||||
|
limit: fetchAmount,
|
||||||
|
before: statusMessage!.getMessage().id
|
||||||
|
});
|
||||||
|
|
||||||
|
fetchedMessages = fetchedMessages.filter((msg) => msg.id !== statusMessage!.getMessage().id);
|
||||||
|
fetchedMessages = fetchedMessages.filter((msg) => msg.deletable);
|
||||||
|
|
||||||
|
let messageCounter = 0; // Counter for tracking every 5 messages
|
||||||
|
|
||||||
|
for (const msg of fetchedMessages.values()) {
|
||||||
|
await msg.delete().catch(() => {});
|
||||||
|
totalMessageDeleted += 1;
|
||||||
|
messageCounter += 1;
|
||||||
|
|
||||||
|
if (messageCounter === 1 || messageCounter % 5 === 0) {
|
||||||
|
let embed = EMBEDS.PURGING_STAGE_2(
|
||||||
|
data,
|
||||||
|
locale,
|
||||||
|
totalBulkDeletedMessages,
|
||||||
|
totalMessageDeleted,
|
||||||
|
totalMessagesToDelete
|
||||||
|
);
|
||||||
|
|
||||||
|
if (data.isMessage()) {
|
||||||
|
await statusMessage.getMessage().edit({ embeds: [embed] });
|
||||||
|
} else if (data.isApplicationCommand()) {
|
||||||
|
await statusMessage.getMessageComponentInteraction().editReply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.debug(
|
||||||
|
'[DiscordPurge]',
|
||||||
|
`Total deleted: ${totalMessageDeleted}/${totalMessagesToDelete}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// One second delay to prevent rate limit
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.debug('[DiscordPurge]', `Total deleted: ${totalMessageDeleted}/${totalMessagesToDelete}`);
|
||||||
|
|
||||||
|
let embed = EMBEDS.PURGING_DONE(
|
||||||
|
data,
|
||||||
|
locale,
|
||||||
|
totalBulkDeletedMessages,
|
||||||
|
totalMessageDeleted - totalBulkDeletedMessages,
|
||||||
|
amountToDelete
|
||||||
|
);
|
||||||
|
if (data.isMessage()) {
|
||||||
|
return await statusMessage.getMessage().edit({ embeds: [embed] });
|
||||||
|
} else if (data.isApplicationCommand()) {
|
||||||
|
return await statusMessage.getMessageComponentInteraction().editReply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger.debug('[DiscordPurge]', `Total deleted: ${totalMessageDeleted}/${totalMessagesToDelete}`);
|
||||||
|
|
||||||
|
let embed = EMBEDS.PURGING_DONE_EARLY(data, locale, totalBulkDeletedMessages, amountToDelete);
|
||||||
|
if (data.isMessage()) {
|
||||||
|
return await statusMessage.getMessage().edit({ embeds: [embed] });
|
||||||
|
} else if (data.isApplicationCommand()) {
|
||||||
|
return await statusMessage.getMessageComponentInteraction().editReply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.PURGE_ERROR(data, locale, err)]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (data.isApplicationCommand() && data.getChannel()) {
|
||||||
|
await purgeMessages(query, data);
|
||||||
|
} else if (data.isMessage()) {
|
||||||
|
await purgeMessages(query, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
import { Guild, GuildChannel, ThreadChannel, Message, PermissionsBitField } from 'discord.js';
|
||||||
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
|
import Prisma from '../../providers/Prisma';
|
||||||
|
import Cache from '../../providers/Cache';
|
||||||
|
|
||||||
|
import { HybridInteractionMessage } from '../../utils/DiscordModule';
|
||||||
|
import {
|
||||||
|
makeInfoEmbed,
|
||||||
|
makeErrorEmbed,
|
||||||
|
makeSuccessEmbed,
|
||||||
|
sendHybridInteractionMessageResponse,
|
||||||
|
makeWarningEmbed
|
||||||
|
} from '../../utils/DiscordMessage';
|
||||||
|
|
||||||
|
import { COMMON_EMBEDS } from '.';
|
||||||
|
import { checkMemberPermissionsInGuild } from '../../utils/DiscordPermission';
|
||||||
|
|
||||||
|
const EMBEDS = {
|
||||||
|
EARLY_ACCESS_INVALID_STATUS: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: 'Invalid status, Use ``true`` or ``false``',
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
NO_EARLY_ACCESS_STATUS_PROVIDED: async (
|
||||||
|
data: HybridInteractionMessage,
|
||||||
|
locale: I18n,
|
||||||
|
isServiceAnnouncementEnabled: boolean
|
||||||
|
) => {
|
||||||
|
return makeInfoEmbed({
|
||||||
|
title: 'Early Access Opt-in Status',
|
||||||
|
description: `Early Access features are ${
|
||||||
|
isServiceAnnouncementEnabled ? '**enabled**' : '**disabled**'
|
||||||
|
} on this server`,
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
EARLY_ACCESS_STATUS_UPDATED: (data: HybridInteractionMessage, locale: I18n, newStatus: boolean) => {
|
||||||
|
return makeSuccessEmbed({
|
||||||
|
title: `Early Access features are now ${newStatus ? 'enabled' : 'disabled'}`,
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
EARLY_ACCESS_STATUS_ALREADY_SET: (data: HybridInteractionMessage, locale: I18n, status: boolean) => {
|
||||||
|
return makeInfoEmbed({
|
||||||
|
title: `Early Access features are already ${status ? 'enabled' : 'disabled'}`,
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
EARLY_ACCESS_ENABLED_WARNING: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeWarningEmbed({
|
||||||
|
title: locale.__('early_access_warning.title'),
|
||||||
|
description: locale.__('early_access_warning.description'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setEnableEarlyAccess = async (data: HybridInteractionMessage, args: any, guild: Guild, locale: I18n) => {
|
||||||
|
let member = data.getMember();
|
||||||
|
if (!member) return;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(await checkMemberPermissionsInGuild({
|
||||||
|
member,
|
||||||
|
data,
|
||||||
|
locale,
|
||||||
|
permissions: [PermissionsBitField.Flags.Administrator]
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let GuildCache = await Cache.getCachedGuild(guild.id);
|
||||||
|
if (!GuildCache) return;
|
||||||
|
|
||||||
|
let newStatus: string | null | undefined;
|
||||||
|
if (data.isMessage()) {
|
||||||
|
let _name: string;
|
||||||
|
if (typeof args[1] === 'undefined')
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [await EMBEDS.NO_EARLY_ACCESS_STATUS_PROVIDED(data, locale, GuildCache.EarlyAccess_Enabled)]
|
||||||
|
});
|
||||||
|
|
||||||
|
let __name = args;
|
||||||
|
__name.shift();
|
||||||
|
_name = __name.join(' ');
|
||||||
|
newStatus = _name;
|
||||||
|
} else if (data.isApplicationCommand())
|
||||||
|
newStatus = data.getSlashCommand().options.get('status', true).value?.toString();
|
||||||
|
|
||||||
|
if (!newStatus)
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [await EMBEDS.NO_EARLY_ACCESS_STATUS_PROVIDED(data, locale, GuildCache.EarlyAccess_Enabled)]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!['true', 'false', 'yes', 'no', 'y', 'n', 'enable', 'disable', 'on', 'off'].includes(newStatus.toLowerCase()))
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.EARLY_ACCESS_INVALID_STATUS(data, locale)]
|
||||||
|
});
|
||||||
|
|
||||||
|
const newStatusBool = ['true', 'yes', 'y', 'enable', 'on'].includes(newStatus.toLowerCase()) ? true : false;
|
||||||
|
|
||||||
|
if (GuildCache?.EarlyAccess_Enabled === newStatusBool)
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.EARLY_ACCESS_STATUS_ALREADY_SET(data, locale, newStatusBool)]
|
||||||
|
});
|
||||||
|
|
||||||
|
let placeholder = await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [COMMON_EMBEDS.PROCESSING(data, locale)]
|
||||||
|
});
|
||||||
|
|
||||||
|
await Prisma.client.guild.update({
|
||||||
|
where: { id: guild.id },
|
||||||
|
data: {
|
||||||
|
EarlyAccess_Enabled: newStatusBool
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await Cache.updateGuildCache(guild.id);
|
||||||
|
|
||||||
|
let toSend = [EMBEDS.EARLY_ACCESS_STATUS_UPDATED(data, locale, newStatusBool)];
|
||||||
|
|
||||||
|
if (newStatusBool) toSend.push(EMBEDS.EARLY_ACCESS_ENABLED_WARNING(data, locale));
|
||||||
|
|
||||||
|
if (data.isMessage())
|
||||||
|
return await (placeholder as Message).edit({
|
||||||
|
embeds: toSend
|
||||||
|
});
|
||||||
|
else if (data.isApplicationCommand())
|
||||||
|
return await sendHybridInteractionMessageResponse(
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
embeds: toSend
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
import { Guild, PermissionsBitField } from 'discord.js';
|
||||||
|
import { I18n } from 'i18n';
|
||||||
|
|
||||||
|
import DiscordProvider from '../../providers/Discord';
|
||||||
|
import Prisma from '../../providers/Prisma';
|
||||||
|
import Cache from '../../providers/Cache';
|
||||||
|
|
||||||
|
import { HybridInteractionMessage } from '../../utils/DiscordModule';
|
||||||
|
import {
|
||||||
|
makeInfoEmbed,
|
||||||
|
makeErrorEmbed,
|
||||||
|
makeSuccessEmbed,
|
||||||
|
sendHybridInteractionMessageResponse
|
||||||
|
} from '../../utils/DiscordMessage';
|
||||||
|
|
||||||
|
import { COMMON_EMBEDS } from '.';
|
||||||
|
import { checkMemberPermissionsInGuild } from '../../utils/DiscordPermission';
|
||||||
|
|
||||||
|
const MAX_GLOBAL_PURGE_LIMIT = 1000;
|
||||||
|
|
||||||
|
const EMBEDS = {
|
||||||
|
PURGE_INFO: (data: HybridInteractionMessage, locale: I18n, currentLimit: string) => {
|
||||||
|
return makeInfoEmbed({
|
||||||
|
title: locale.__('settings_purge_limit.info', { LIMIT: currentLimit }),
|
||||||
|
description: locale.__('settings_purge_limit.info_description'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGE_TOO_BIG: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('settings_purge_limit.purge_limit_too_big', { LIMIT: MAX_GLOBAL_PURGE_LIMIT.toString() }),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGE_NAN: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('settings_purge_limit.purge_limit_nan'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGE_ZERO: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeErrorEmbed({
|
||||||
|
title: locale.__('settings_purge_limit.purge_limit_zero'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
PURGE_UPDATED: (data: HybridInteractionMessage, locale: I18n, newLimit: string) => {
|
||||||
|
return makeSuccessEmbed({
|
||||||
|
title: locale.__('settings_purge_limit.purge_limit_updated', { LIMIT: newLimit }),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async (data: HybridInteractionMessage, args: any, guild: Guild, locale: I18n) => {
|
||||||
|
let member = data.getMember();
|
||||||
|
if (!member) return;
|
||||||
|
|
||||||
|
const GuildCache = await Cache.getCachedGuild(guild.id);
|
||||||
|
if (!GuildCache) return;
|
||||||
|
const limit = GuildCache.Purge_Limit;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(await checkMemberPermissionsInGuild({
|
||||||
|
member,
|
||||||
|
data,
|
||||||
|
locale,
|
||||||
|
permissions: [PermissionsBitField.Flags.ManageGuild]
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let newLimit: string | null | undefined;
|
||||||
|
if (data.isMessage()) {
|
||||||
|
let _name: string;
|
||||||
|
if (typeof args[1] === 'undefined')
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.PURGE_INFO(data, locale, limit.toString())]
|
||||||
|
});
|
||||||
|
|
||||||
|
let __name = args;
|
||||||
|
__name.shift();
|
||||||
|
_name = __name.join(' ');
|
||||||
|
newLimit = _name;
|
||||||
|
} else if (data.isApplicationCommand())
|
||||||
|
newLimit = data.getSlashCommand().options.get('limit', true).value?.toString();
|
||||||
|
|
||||||
|
if (typeof newLimit === 'undefined' || newLimit === null)
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.PURGE_INFO(data, locale, limit.toString())]
|
||||||
|
});
|
||||||
|
|
||||||
|
let parsedLimit = parseInt(newLimit);
|
||||||
|
if (isNaN(parsedLimit))
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.PURGE_NAN(data, locale)]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (parsedLimit > MAX_GLOBAL_PURGE_LIMIT)
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.PURGE_TOO_BIG(data, locale)]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (parsedLimit === 0)
|
||||||
|
return await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [EMBEDS.PURGE_ZERO(data, locale)]
|
||||||
|
});
|
||||||
|
|
||||||
|
let placeholder: HybridInteractionMessage | undefined;
|
||||||
|
|
||||||
|
let _placeholder = await sendHybridInteractionMessageResponse(data, {
|
||||||
|
embeds: [COMMON_EMBEDS.PROCESSING(data, locale)]
|
||||||
|
});
|
||||||
|
if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder);
|
||||||
|
|
||||||
|
await Prisma.client.guild.update({
|
||||||
|
where: { id: guild.id },
|
||||||
|
data: { Purge_Limit: parsedLimit }
|
||||||
|
});
|
||||||
|
Cache.updateGuildCache(guild.id);
|
||||||
|
|
||||||
|
if (data && data.isMessage() && placeholder && placeholder.isMessage())
|
||||||
|
return placeholder.getMessage().edit({ embeds: [EMBEDS.PURGE_UPDATED(data, locale, newLimit)] });
|
||||||
|
else if (data.isApplicationCommand())
|
||||||
|
return await sendHybridInteractionMessageResponse(
|
||||||
|
data,
|
||||||
|
{ embeds: [EMBEDS.PURGE_UPDATED(data, locale, newLimit)] },
|
||||||
|
true
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -258,6 +258,8 @@ export const setServiceAnnouncementChannel = async (
|
|||||||
data: { ServiceAnnouncement_Channel: channel.id }
|
data: { ServiceAnnouncement_Channel: channel.id }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await Cache.updateGuildCache(guild.id);
|
||||||
|
|
||||||
if (data.isMessage())
|
if (data.isMessage())
|
||||||
return await (placeholder as Message).edit({
|
return await (placeholder as Message).edit({
|
||||||
embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_CONFIGURED_CHANNEL(data, locale, TargetChannel)]
|
embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_CONFIGURED_CHANNEL(data, locale, TargetChannel)]
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import {
|
|||||||
import * as PrefixModule from './Prefix';
|
import * as PrefixModule from './Prefix';
|
||||||
import * as LanguageModule from './Language';
|
import * as LanguageModule from './Language';
|
||||||
import * as ServiceAnnouncementModule from './ServiceAnnouncement';
|
import * as ServiceAnnouncementModule from './ServiceAnnouncement';
|
||||||
|
import * as EarlyAccessModule from './EarlyAccess';
|
||||||
|
import * as PurgeLimitModule from './PurgeLimit';
|
||||||
|
|
||||||
export const COMMON_EMBEDS = {
|
export const COMMON_EMBEDS = {
|
||||||
MEMBER_NO_PERMISSION: (data: HybridInteractionMessage, locale: I18n, permissions: PermissionResolvable[]) => {
|
MEMBER_NO_PERMISSION: (data: HybridInteractionMessage, locale: I18n, permissions: PermissionResolvable[]) => {
|
||||||
@@ -48,6 +50,14 @@ export const COMMON_EMBEDS = {
|
|||||||
description: locale.__('common.processing_description'),
|
description: locale.__('common.processing_description'),
|
||||||
user: data.getUser()
|
user: data.getUser()
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
EARLY_ACCESS_WARNING: (data: HybridInteractionMessage, locale: I18n) => {
|
||||||
|
return makeInfoEmbed({
|
||||||
|
icon: '🧪',
|
||||||
|
title: locale.__('common.early_access_features'),
|
||||||
|
description: locale.__('common.early_access_features_description'),
|
||||||
|
user: data.getUser()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,10 +121,14 @@ export default class Settings extends DiscordModule {
|
|||||||
return await PrefixModule.default(data, args, guild, locale);
|
return await PrefixModule.default(data, args, guild, locale);
|
||||||
case 'language':
|
case 'language':
|
||||||
return await LanguageModule.default(data, args, guild, locale);
|
return await LanguageModule.default(data, args, guild, locale);
|
||||||
|
case 'purgelimit':
|
||||||
|
return await PurgeLimitModule.default(data, args, guild, locale);
|
||||||
case 'enableserviceannouncement':
|
case 'enableserviceannouncement':
|
||||||
return await ServiceAnnouncementModule.setEnableServiceAnnouncement(data, args, guild, locale);
|
return await ServiceAnnouncementModule.setEnableServiceAnnouncement(data, args, guild, locale);
|
||||||
case 'serviceannouncementchannel':
|
case 'serviceannouncementchannel':
|
||||||
return await ServiceAnnouncementModule.setServiceAnnouncementChannel(data, args, guild, locale);
|
return await ServiceAnnouncementModule.setServiceAnnouncementChannel(data, args, guild, locale);
|
||||||
|
case 'earlyaccess':
|
||||||
|
return await EarlyAccessModule.setEnableEarlyAccess(data, args, guild, locale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import {
|
|||||||
TextBasedChannelMixin,
|
TextBasedChannelMixin,
|
||||||
ChannelType,
|
ChannelType,
|
||||||
BaseGuildVoiceChannel,
|
BaseGuildVoiceChannel,
|
||||||
InteractionType
|
InteractionType,
|
||||||
|
ThreadChannel
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
|
|
||||||
import Logger from '../libs/Logger';
|
import Logger from '../libs/Logger';
|
||||||
@@ -30,6 +31,7 @@ import Discord_VRChatLogin from '../discord/Developer/VRChatLogin';
|
|||||||
import Discord_UserInfo from '../discord/UserInfo';
|
import Discord_UserInfo from '../discord/UserInfo';
|
||||||
import Discord_Stats from '../discord/Stats';
|
import Discord_Stats from '../discord/Stats';
|
||||||
import Discord_Support from '../discord/Support';
|
import Discord_Support from '../discord/Support';
|
||||||
|
import Discord_Purge from '../discord/Purge';
|
||||||
|
|
||||||
import Discord_MusicPlayer_Play from '../discord/MusicPlayer/Play';
|
import Discord_MusicPlayer_Play from '../discord/MusicPlayer/Play';
|
||||||
import Discord_MusicPlayer_PlayMy from '../discord/MusicPlayer/PlayMy';
|
import Discord_MusicPlayer_PlayMy from '../discord/MusicPlayer/PlayMy';
|
||||||
@@ -86,6 +88,7 @@ class Discord {
|
|||||||
new Discord_VRChatLogin(),
|
new Discord_VRChatLogin(),
|
||||||
new Discord_Settings(),
|
new Discord_Settings(),
|
||||||
new Discord_Support(),
|
new Discord_Support(),
|
||||||
|
new Discord_Purge(),
|
||||||
|
|
||||||
new Discord_MusicPlayer_Play(),
|
new Discord_MusicPlayer_Play(),
|
||||||
new Discord_MusicPlayer_PlayMy(),
|
new Discord_MusicPlayer_PlayMy(),
|
||||||
@@ -215,7 +218,13 @@ class Discord {
|
|||||||
|
|
||||||
// Handling guild commands
|
// Handling guild commands
|
||||||
this.client.on('messageCreate', async (message: Message) => {
|
this.client.on('messageCreate', async (message: Message) => {
|
||||||
if (!(message.channel instanceof BaseGuildTextChannel || message.channel instanceof BaseGuildVoiceChannel))
|
if (
|
||||||
|
!(
|
||||||
|
message.channel instanceof BaseGuildTextChannel ||
|
||||||
|
message.channel instanceof BaseGuildVoiceChannel ||
|
||||||
|
message.channel instanceof ThreadChannel
|
||||||
|
)
|
||||||
|
)
|
||||||
return;
|
return;
|
||||||
if (message.author.bot) return;
|
if (message.author.bot) return;
|
||||||
if (typeof message.guild?.id === 'undefined') return;
|
if (typeof message.guild?.id === 'undefined') return;
|
||||||
@@ -322,7 +331,13 @@ class Discord {
|
|||||||
// Handling mentions
|
// Handling mentions
|
||||||
this.client.on('messageCreate', async (message: Message) => {
|
this.client.on('messageCreate', async (message: Message) => {
|
||||||
// TODO: Handle DMs commands soon
|
// TODO: Handle DMs commands soon
|
||||||
if (!(message.channel instanceof BaseGuildTextChannel || message.channel instanceof BaseGuildVoiceChannel))
|
if (
|
||||||
|
!(
|
||||||
|
message.channel instanceof BaseGuildTextChannel ||
|
||||||
|
message.channel instanceof BaseGuildVoiceChannel ||
|
||||||
|
message.channel instanceof ThreadChannel
|
||||||
|
)
|
||||||
|
)
|
||||||
return;
|
return;
|
||||||
if (message.author.bot) return;
|
if (message.author.bot) return;
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ export const GLOBAL_COMMANDS: Object[] = [
|
|||||||
option.setName('message').setDescription('Message you want me to say').setRequired(true)
|
option.setName('message').setDescription('Message you want me to say').setRequired(true)
|
||||||
),
|
),
|
||||||
|
|
||||||
|
new SlashCommandBuilder()
|
||||||
|
.setName('purge')
|
||||||
|
.setDescription('Purge messages')
|
||||||
|
.addStringOption((option) => option.setName('amount').setDescription('Amount to purge').setRequired(true)),
|
||||||
|
|
||||||
new SlashCommandBuilder()
|
new SlashCommandBuilder()
|
||||||
.setName('osu')
|
.setName('osu')
|
||||||
.setDescription('Interact with the game osu!')
|
.setDescription('Interact with the game osu!')
|
||||||
|
|||||||
@@ -152,9 +152,8 @@ export async function sendMessage(
|
|||||||
else message = await channel.send(options);
|
else message = await channel.send(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (typeof user === 'undefined') {
|
if (typeof user === 'undefined') {
|
||||||
return Logger.error(
|
Logger.error(`Cannot find available destinations to send the message CID: ${channel.id} C_ERR: ${error}`);
|
||||||
`Cannot find available destinations to send the message CID: ${channel.id} C_ERR: ${error}`
|
return;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
message = await user.send(options);
|
message = await user.send(options);
|
||||||
|
|||||||
@@ -196,46 +196,46 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
make-plural "^7.0.0"
|
make-plural "^7.0.0"
|
||||||
|
|
||||||
"@prisma/client@^5.8.0":
|
"@prisma/client@^5.10.2":
|
||||||
version "5.8.0"
|
version "5.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.8.0.tgz#5f4c8c1c7cb60b1f4d39082bb214d048ffeb3730"
|
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.10.2.tgz#e087b40a4de8e3171eb9cbf0a873465cd2068e17"
|
||||||
integrity sha512-QxO6C4MaA/ysTIbC+EcAH1aX/YkpymhXtO6zPdk+FvA7+59tNibIYpd+7koPdViLg2iKES4ojsxWNUGNJaEcbA==
|
integrity sha512-ef49hzB2yJZCvM5gFHMxSFL9KYrIP9udpT5rYo0CsHD4P9IKj473MbhU1gjKKftiwWBTIyrt9jukprzZXazyag==
|
||||||
|
|
||||||
"@prisma/debug@5.8.0":
|
"@prisma/debug@5.10.2":
|
||||||
version "5.8.0"
|
version "5.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.8.0.tgz#e49b9d8fd4ef79d177ac4b9f5242e857e8d5a044"
|
resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.10.2.tgz#74be81d8969978f4d53c1b4e76d61f04bfbc3951"
|
||||||
integrity sha512-ZqPpkvbovu/kQJ1bvy57NO4dw97fpQGcbQSCtsqlwSE1UNKJP75R3BKxdznk8ZPMY+GJdMRetWNv4oAvSbWn8Q==
|
integrity sha512-bkBOmH9dpEBbMKFJj8V+Zp8IZHIBjy3fSyhLhxj4FmKGb/UBSt9doyfA6k1UeUREsMJft7xgPYBbHSOYBr8XCA==
|
||||||
|
|
||||||
"@prisma/engines-version@5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848":
|
"@prisma/engines-version@5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9":
|
||||||
version "5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848"
|
version "5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848.tgz#072d9fb98d9454aeb3549ae8c922446313312145"
|
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9.tgz#1502335d4d72d2014cb25b8ad8a740a3a13400ea"
|
||||||
integrity sha512-cXcoVweYbnv8xRfkWq9oj8BECOdzHUazrSpYCa0ehp5TNz4l5Spa8jbq/VROCTzj3ZncH5D9Q2TmySYTOUeKlw==
|
integrity sha512-uCy/++3Jx/O3ufM+qv2H1L4tOemTNqcP/gyEVOlZqTpBvYJUe0tWtW0y3o2Ueq04mll4aM5X3f6ugQftOSLdFQ==
|
||||||
|
|
||||||
"@prisma/engines@5.8.0":
|
"@prisma/engines@5.10.2":
|
||||||
version "5.8.0"
|
version "5.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.8.0.tgz#610560705a8753089ceb93cee8102679ba7eed51"
|
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.10.2.tgz#a4851d90f76ad6d22e783d5fd2e2e8c0640f1e81"
|
||||||
integrity sha512-Qhqm9WWLujNEC13AuZlUO14SQ15tNLe5puaz+tOk7UqINqJ3PtqMmuSuzomiw2diGVqZ+HYiSQzlR3+pPucVHA==
|
integrity sha512-HkSJvix6PW8YqEEt3zHfCYYJY69CXsNdhU+wna+4Y7EZ+AwzeupMnUThmvaDA7uqswiHkgm5/SZ6/4CStjaGmw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@prisma/debug" "5.8.0"
|
"@prisma/debug" "5.10.2"
|
||||||
"@prisma/engines-version" "5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848"
|
"@prisma/engines-version" "5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9"
|
||||||
"@prisma/fetch-engine" "5.8.0"
|
"@prisma/fetch-engine" "5.10.2"
|
||||||
"@prisma/get-platform" "5.8.0"
|
"@prisma/get-platform" "5.10.2"
|
||||||
|
|
||||||
"@prisma/fetch-engine@5.8.0":
|
"@prisma/fetch-engine@5.10.2":
|
||||||
version "5.8.0"
|
version "5.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.8.0.tgz#ebba3f0fdf6b9c757502f5dd34fcfa80690e4e7b"
|
resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.10.2.tgz#a061f6727d395c7033b55f9c6e92f8741a70d5c5"
|
||||||
integrity sha512-1CAuE+JoYsPNggMEn6qk0zos06Uc9bYZBJ0VBPHD6R7REL05614koAbOCmn52IaYz3nobb7f25hqW6AY7rLkIw==
|
integrity sha512-dSmXcqSt6DpTmMaLQ9K8ZKzVAMH3qwGCmYEZr/uVnzVhxRJ1EbT/w2MMwIdBNq1zT69Rvh0h75WMIi0mrIw7Hg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@prisma/debug" "5.8.0"
|
"@prisma/debug" "5.10.2"
|
||||||
"@prisma/engines-version" "5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848"
|
"@prisma/engines-version" "5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9"
|
||||||
"@prisma/get-platform" "5.8.0"
|
"@prisma/get-platform" "5.10.2"
|
||||||
|
|
||||||
"@prisma/get-platform@5.8.0":
|
"@prisma/get-platform@5.10.2":
|
||||||
version "5.8.0"
|
version "5.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.8.0.tgz#a1057322f0cb5dd0d2f59b4120659621e5e24526"
|
resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.10.2.tgz#7af97b1d82e5574a474e3fbf6eaf04f4156bc535"
|
||||||
integrity sha512-Nk3rhTFZ1LYkFZJnpSvQcLPCaBWgJQfteHII6UEENOOkYlmP0k3FuswND54tzzEr4qs39wOdV9pbXKX9U2lv7A==
|
integrity sha512-nqXP6vHiY2PIsebBAuDeWiUYg8h8mfjBckHh6Jezuwej0QJNnjDiOq30uesmg+JXxGk99nqyG3B7wpcOODzXvg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@prisma/debug" "5.8.0"
|
"@prisma/debug" "5.10.2"
|
||||||
|
|
||||||
"@sapphire/async-queue@^1.5.0":
|
"@sapphire/async-queue@^1.5.0":
|
||||||
version "1.5.1"
|
version "1.5.1"
|
||||||
@@ -352,13 +352,20 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690"
|
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690"
|
||||||
integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==
|
integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==
|
||||||
|
|
||||||
"@types/node@*", "@types/node@^20.10.8":
|
"@types/node@*":
|
||||||
version "20.10.8"
|
version "20.10.8"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.8.tgz#f1e223cbde9e25696661d167a5b93a9b2a5d57c7"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.8.tgz#f1e223cbde9e25696661d167a5b93a9b2a5d57c7"
|
||||||
integrity sha512-f8nQs3cLxbAFc00vEU59yf9UyGUftkPaLGfvbVOIDdx2i1b8epBqj2aNGyP19fiyXWvlmZ7qC1XLjAzw/OKIeA==
|
integrity sha512-f8nQs3cLxbAFc00vEU59yf9UyGUftkPaLGfvbVOIDdx2i1b8epBqj2aNGyP19fiyXWvlmZ7qC1XLjAzw/OKIeA==
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types "~5.26.4"
|
undici-types "~5.26.4"
|
||||||
|
|
||||||
|
"@types/node@^20.11.24":
|
||||||
|
version "20.11.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.24.tgz#cc207511104694e84e9fb17f9a0c4c42d4517792"
|
||||||
|
integrity sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==
|
||||||
|
dependencies:
|
||||||
|
undici-types "~5.26.4"
|
||||||
|
|
||||||
"@types/os-utils@^0.0.4":
|
"@types/os-utils@^0.0.4":
|
||||||
version "0.0.4"
|
version "0.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/os-utils/-/os-utils-0.0.4.tgz#d26863ed7de0a52fc0566131e2b61615ed00595e"
|
resolved "https://registry.yarnpkg.com/@types/os-utils/-/os-utils-0.0.4.tgz#d26863ed7de0a52fc0566131e2b61615ed00595e"
|
||||||
@@ -416,10 +423,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c"
|
resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c"
|
||||||
integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==
|
integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==
|
||||||
|
|
||||||
"@types/validator@^13.11.8":
|
"@types/validator@^13.11.9":
|
||||||
version "13.11.8"
|
version "13.11.9"
|
||||||
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.11.8.tgz#bb1162ec0fe6f87c95ca812f15b996fcc5e1e2dc"
|
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.11.9.tgz#adfe96520b437a0eaa798a475877bf2f75ee402d"
|
||||||
integrity sha512-c/hzNDBh7eRF+KbCf+OoZxKbnkpaK/cKp9iLQWqB7muXtM+MtL9SUUH8vCFcLn6dH1Qm05jiexK0ofWY7TfOhQ==
|
integrity sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==
|
||||||
|
|
||||||
"@types/ws@8.5.9":
|
"@types/ws@8.5.9":
|
||||||
version "8.5.9"
|
version "8.5.9"
|
||||||
@@ -553,13 +560,13 @@ bluebird@^3.7.2:
|
|||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
||||||
|
|
||||||
body-parser@1.20.1:
|
body-parser@1.20.2:
|
||||||
version "1.20.1"
|
version "1.20.2"
|
||||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
|
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd"
|
||||||
integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==
|
integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==
|
||||||
dependencies:
|
dependencies:
|
||||||
bytes "3.1.2"
|
bytes "3.1.2"
|
||||||
content-type "~1.0.4"
|
content-type "~1.0.5"
|
||||||
debug "2.6.9"
|
debug "2.6.9"
|
||||||
depd "2.0.0"
|
depd "2.0.0"
|
||||||
destroy "1.2.0"
|
destroy "1.2.0"
|
||||||
@@ -567,7 +574,7 @@ body-parser@1.20.1:
|
|||||||
iconv-lite "0.4.24"
|
iconv-lite "0.4.24"
|
||||||
on-finished "2.4.1"
|
on-finished "2.4.1"
|
||||||
qs "6.11.0"
|
qs "6.11.0"
|
||||||
raw-body "2.5.1"
|
raw-body "2.5.2"
|
||||||
type-is "~1.6.18"
|
type-is "~1.6.18"
|
||||||
unpipe "1.0.0"
|
unpipe "1.0.0"
|
||||||
|
|
||||||
@@ -744,7 +751,7 @@ content-disposition@0.5.4:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "5.2.1"
|
safe-buffer "5.2.1"
|
||||||
|
|
||||||
content-type@~1.0.4:
|
content-type@~1.0.4, content-type@~1.0.5:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
|
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
|
||||||
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
|
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
|
||||||
@@ -870,10 +877,10 @@ discord-api-types@0.37.61:
|
|||||||
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.61.tgz#9dd8e58c624237e6f1b23be2d29579af268b8c5b"
|
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.61.tgz#9dd8e58c624237e6f1b23be2d29579af268b8c5b"
|
||||||
integrity sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==
|
integrity sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==
|
||||||
|
|
||||||
discord-api-types@^0.37.67:
|
discord-api-types@^0.37.71:
|
||||||
version "0.37.67"
|
version "0.37.71"
|
||||||
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.67.tgz#c4280aa122104ea74e103884ba27e8218210bef8"
|
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.71.tgz#43b0855a4bf78d00bdca5b8d56e460b5985e9655"
|
||||||
integrity sha512-4HEzUEmwGPXWJdVhGZ/K+9eWs8kurdn5r/I8qD3/0hb14I0MZvx8K/JOyLhKLgcR4/8/jcr6Xej820BNgNXN7A==
|
integrity sha512-oYDVWoiQdblr9DpwOgpi5d78dVhPcoN9YZCCqYZf2T0v9+iICs7k2bYGumoHuYMtaIitpp5aQNs+2guVkgjbOA==
|
||||||
|
|
||||||
discord.js@^14.14.1:
|
discord.js@^14.14.1:
|
||||||
version "14.14.1"
|
version "14.14.1"
|
||||||
@@ -895,10 +902,10 @@ discord.js@^14.14.1:
|
|||||||
undici "5.27.2"
|
undici "5.27.2"
|
||||||
ws "8.14.2"
|
ws "8.14.2"
|
||||||
|
|
||||||
dotenv@^16.3.1:
|
dotenv@^16.4.5:
|
||||||
version "16.3.1"
|
version "16.4.5"
|
||||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e"
|
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
|
||||||
integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==
|
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
|
||||||
|
|
||||||
dynamic-dedupe@^0.3.0:
|
dynamic-dedupe@^0.3.0:
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
@@ -942,14 +949,14 @@ etag@~1.8.1:
|
|||||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||||
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
|
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
|
||||||
|
|
||||||
express@^4.18.2:
|
express@^4.18.3:
|
||||||
version "4.18.2"
|
version "4.18.3"
|
||||||
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
|
resolved "https://registry.yarnpkg.com/express/-/express-4.18.3.tgz#6870746f3ff904dee1819b82e4b51509afffb0d4"
|
||||||
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
|
integrity sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==
|
||||||
dependencies:
|
dependencies:
|
||||||
accepts "~1.3.8"
|
accepts "~1.3.8"
|
||||||
array-flatten "1.1.1"
|
array-flatten "1.1.1"
|
||||||
body-parser "1.20.1"
|
body-parser "1.20.2"
|
||||||
content-disposition "0.5.4"
|
content-disposition "0.5.4"
|
||||||
content-type "~1.0.4"
|
content-type "~1.0.4"
|
||||||
cookie "0.5.0"
|
cookie "0.5.0"
|
||||||
@@ -1608,12 +1615,12 @@ prism-media@^1.3.5:
|
|||||||
resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.3.5.tgz#ea1533229f304a1b774b158de40e98c765db0aa6"
|
resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.3.5.tgz#ea1533229f304a1b774b158de40e98c765db0aa6"
|
||||||
integrity sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==
|
integrity sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==
|
||||||
|
|
||||||
prisma@^5.8.0:
|
prisma@^5.10.2:
|
||||||
version "5.8.0"
|
version "5.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.8.0.tgz#4efef66c1e8aee98bbc1d41b32bf629f5f7275b2"
|
resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.10.2.tgz#aa63085c49dc74cdb5c3816e8dd1fb4d74a2aadd"
|
||||||
integrity sha512-hDKoEqPt2qEUTH5yGO3l27CBnPtwvte0CGMKrpCr9+/A919JghfqJ3qgCGgMbOwdkXUOzdho0RH9tyUF3UhpMw==
|
integrity sha512-hqb/JMz9/kymRE25pMWCxkdyhbnIWrq+h7S6WysJpdnCvhstbJSNP/S6mScEcqiB8Qv2F+0R3yG+osRaWqZacQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@prisma/engines" "5.8.0"
|
"@prisma/engines" "5.10.2"
|
||||||
|
|
||||||
process-nextick-args@~2.0.0:
|
process-nextick-args@~2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
@@ -1662,10 +1669,10 @@ range-parser@~1.2.1:
|
|||||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
||||||
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
|
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
|
||||||
|
|
||||||
raw-body@2.5.1:
|
raw-body@2.5.2:
|
||||||
version "2.5.1"
|
version "2.5.2"
|
||||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
|
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a"
|
||||||
integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
|
integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==
|
||||||
dependencies:
|
dependencies:
|
||||||
bytes "3.1.2"
|
bytes "3.1.2"
|
||||||
http-errors "2.0.0"
|
http-errors "2.0.0"
|
||||||
@@ -2157,10 +2164,10 @@ vary@^1, vary@~1.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||||
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
|
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
|
||||||
|
|
||||||
vrchat@^1.16.2:
|
vrchat@^1.16.6:
|
||||||
version "1.16.2"
|
version "1.16.6"
|
||||||
resolved "https://registry.yarnpkg.com/vrchat/-/vrchat-1.16.2.tgz#f408e999962bb3331342ea0b2f9dcd2c011d1b9a"
|
resolved "https://registry.yarnpkg.com/vrchat/-/vrchat-1.16.6.tgz#28e0885400a2470a76e0ff5061371cd2dcd901c0"
|
||||||
integrity sha512-bUuvM2hUHRMyb4fRjPA+abjCTdG1n0N3aBrBIPbPGPDAqvNNnPhHEOnjNTKh5twMVbHiYjS7BuO7ufc5XlrdcQ==
|
integrity sha512-PtLaZX1PN5eakSIGduLrMhwA5oK3m7yynsJ5hYSAwSLKeh2pgpcUoAUF7ahCMilI5egzwtX0SwZiNjwRHmoqIQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/tough-cookie" "^4.0.1"
|
"@types/tough-cookie" "^4.0.1"
|
||||||
axios "^0.26.1"
|
axios "^0.26.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user