diff --git a/COPYING b/COPYING index 5abc3e989..13c13bf93 100644 --- a/COPYING +++ b/COPYING @@ -6,10 +6,6 @@ And is distributed under The GNU Affero General Public License Version 3, you sh Misskey includes several third-party Open-Source softwares. -Unicode emoji regular expressions by Twitter, Inc. -License: MIT -https://github.com/twitter/twemoji-parser/blob/master/LICENSE.md - Emoji keywords for Unicode 11 and below by Mu-An Chiou License: MIT https://github.com/muan/emojilib/blob/master/LICENSE diff --git a/README.md b/README.md index 5cff3619f..816765af6 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,11 @@ Please see the [Contribution Guide](./CONTRIBUTING.md). To receive updates of this repo, follow [@repo@misskey.io](https://misskey.io/@repo) on fediverse. +Related projects +---------------------------------------------------------------- +- [misskey.js](https://github.com/misskey-dev/misskey.js) - Misskey SDK for JavaScript +- [mfm.js](https://github.com/misskey-dev/mfm.js) - MFM parser + :heart: Backers ---------------------------------------------------------------- diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..2c026a5f3 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,9 @@ +# Reporting Security Issues + +If you discover a security issue in Misskey, please report it by sending an +email to [syuilotan@yahoo.co.jp](mailto:syuilotan@yahoo.co.jp). + +This will allow us to assess the risk, and make a fix available before we add a +bug report to the GitHub repository. + +Thanks for helping make Misskey safe for everyone. diff --git a/assets/about/banner.svg b/assets/about/banner.svg index 586cc034e..a6e56c2a0 100644 --- a/assets/about/banner.svg +++ b/assets/about/banner.svg @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62d9285a05f04db45533bbad9dca576ce23f934fdc8755c98796700f69c408d3 -size 35817 +oid sha256:9b9f133f6fb4be1ffa25a8282e59d20347f5c10f070707f3846445c26ddec405 +size 39137 diff --git a/assets/banner.afdesign b/assets/banner.afdesign index e3e9e81f4..be5220595 100644 --- a/assets/banner.afdesign +++ b/assets/banner.afdesign @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9cd303e731d0b45bf3a79ed6c2647952d738feca261b4217d4d5b37f7692ae38 -size 65435 +oid sha256:1d23de60c4797976ea380109cd3b578724e356060d23de04ed774f037d98b393 +size 73201 diff --git a/gulpfile.ts b/gulpfile.ts index 660dfb013..2cdcbdb6f 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -4,7 +4,7 @@ import * as fs from 'fs'; import * as gulp from 'gulp'; -import * as rimraf from 'rimraf'; +import rimraf from 'rimraf'; const replace = require('gulp-replace'); const terser = require('gulp-terser'); const cssnano = require('gulp-cssnano'); diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index 631027cb7..9c20ea752 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -259,8 +259,6 @@ monthX: "{month}" yearX: "{year}" pages: "الصفحات" integration: "دمج" -connectSerice: "أوصل" -disconnectSerice: "قطع الاتصال" enableLocalTimeline: "تفعيل الخيط المحلي" enableGlobalTimeline: "تفعيل الخيط الزمني الشامل" disablingTimelinesInfo: "سيتمكن المسؤولون ومن تعديل دائمًا و من الوصول إلى جميع المخططات الزمنية ، حتى إذا لم يتم تمكينها." diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index 6d62b5345..995d8eccd 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -269,8 +269,6 @@ monthX: "{month}" yearX: "{year}" pages: "Stránky" integration: "Integrace" -connectSerice: "Připojit" -disconnectSerice: "Odpojit" enableLocalTimeline: "Povolit lokální čas" enableGlobalTimeline: "Povolit globální čas" registration: "Registrace" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 1f35b9de7..e3edcf5f4 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -279,6 +279,7 @@ emptyDrive: "Drive ist leer" emptyFolder: "Der Ordner ist leer" unableToDelete: "Nicht löschbar" inputNewFileName: "Gib einen neuen Dateinamen ein" +inputNewDescription: "Gib eine neue Beschreibung ein" inputNewFolderName: "Gib einen neuen Ordnernamen ein" circularReferenceFolder: "Der Zielordner ist ein Unterorder des Ordners, den du verschieben möchtest." hasChildFilesOrFolders: "Dieser Ordner kann nicht gelöscht werden, da er nicht leer ist." @@ -310,8 +311,8 @@ monthX: "{month}" yearX: "{year}" pages: "Seiten" integration: "Integration" -connectSerice: "Verbinden" -disconnectSerice: "Trennen" +connectService: "Verbinden" +disconnectService: "Trennen" enableLocalTimeline: "Lokale Chronik aktivieren" enableGlobalTimeline: "Globale Chronik aktivieren" disablingTimelinesInfo: "Administratoren und Moderatoren haben immer Zugriff auf alle Chroniken, auch wenn diese deaktiviert sind." @@ -546,6 +547,8 @@ disablePlayer: "Video-Player schließen" expandTweet: "Tweet ausklappen" themeEditor: "Farbthemen-Editor" description: "Beschreibung" +describeFile: "Beschreibung hinzufügen" +enterFileDescription: "Beschreibung eingeben" author: "Autor" leaveConfirm: "Es gibt unspeicherte Änderungen. Möchtest du diese verwerfen?" manage: "Verwaltung" diff --git a/locales/en-US.yml b/locales/en-US.yml index 4cf417d21..3dd581c8a 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -279,6 +279,7 @@ emptyDrive: "The drive is empty" emptyFolder: "This folder is empty" unableToDelete: "Unable to delete" inputNewFileName: "Enter a new filename" +inputNewDescription: "Enter new caption" inputNewFolderName: "Enter a new folder name" circularReferenceFolder: "The destination folder is a subfolder of the folder you wish to move." hasChildFilesOrFolders: "Since this folder is not empty, it can not be deleted." @@ -310,8 +311,8 @@ monthX: "{month}" yearX: "{year} /" pages: "Pages" integration: "Integration" -connectSerice: "Connect" -disconnectSerice: "Disconnect" +connectService: "Connect" +disconnectService: "Disconnect" enableLocalTimeline: "Enable local timeline" enableGlobalTimeline: "Enable global timeline" disablingTimelinesInfo: "Admins and Mods will always have access to all timelines, even if they are not enabled." @@ -546,6 +547,8 @@ disablePlayer: "Close video player" expandTweet: "Expand tweet" themeEditor: "Theme editor" description: "Description" +describeFile: "Add caption" +enterFileDescription: "Enter caption" author: "Author" leaveConfirm: "There are unsaved changes. Do you want to discard them?" manage: "Management" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index ae7fba897..89e170678 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -309,8 +309,6 @@ monthX: "Mes {month}" yearX: "Año {year}" pages: "Páginas" integration: "Integración" -connectSerice: "Conectarse" -disconnectSerice: "Desconectarse" enableLocalTimeline: "Habilitar linea de tiempo local" enableGlobalTimeline: "Habilitar linea de tiempo global" disablingTimelinesInfo: "Aunque se desactiven estas lineas de tiempo, por conveniencia el administrador y los moderadores pueden seguir usándolos" diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index c62b1c3b6..174a3a8f5 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -310,8 +310,6 @@ monthX: "{month}" yearX: "{year}" pages: "Pages" integration: "Intégrations" -connectSerice: "Connecter" -disconnectSerice: "Déconnecter" enableLocalTimeline: "Activer le fil local" enableGlobalTimeline: "Activer le fil global" disablingTimelinesInfo: "Même si vous désactivez ces fils, les administrateur·rice·s et les modérateur·rice·s pourront toujours y accéder." diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 5f401bc4b..ed1ac1412 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -1,5 +1,5 @@ --- -_lang_: "Bahasa Jepang" +_lang_: "Bahasa Indonesia" headlineMisskey: "Jaringan terhubung melalui note" introMisskey: "Selamat datang! Misskey adalah perangkat mikroblog tercatu bersifat sumber terbuka.\nMulailah menuliskan catatan, bagikan peristiwa terkini, serta ceritakan segala tentangmu.📡\nTunjukkan juga reaksimu pada catatan pengguna lain.👍\nMari jelajahi dunia baru🚀" monthAndDay: "{day} {month}" @@ -310,8 +310,6 @@ monthX: "{month}" yearX: "{year}" pages: "Halaman" integration: "Integrasi" -connectSerice: "Sambungkan" -disconnectSerice: "Putuskan" enableLocalTimeline: "Nyalakan linimasa lokal" enableGlobalTimeline: "Nyalakan linimasa global" disablingTimelinesInfo: "Admin dan Moderator akan selalu memiliki akses ke semua linimasa meskipun linimasa tersebut tidak diaktifkan." @@ -977,9 +975,9 @@ _theme: infoFg: "Teks informasi" infoWarnBg: "Latar belakang peringatan" infoWarnFg: "Teks peringatan" - cwBg: "Latar belakang tombol CW" - cwFg: "Teks tombol CW" - cwHoverBg: "Latar belakang tombol CW (Mengambang)" + cwBg: "Latar belakang tombol Sembunyikan Konten" + cwFg: "Teks tombol Sembunyikan Konten" + cwHoverBg: "Latar belakang tombol Sembunyikan Konten (Mengambang)" toastBg: "Latar belakang pemberitahuan" toastFg: "Teks pemberitahuan" buttonBg: "Latar belakang tombol" @@ -1122,7 +1120,7 @@ _widgets: aiscript: "Konsol AiScript" _cw: hide: "Sembunyikan" - show: "Selebihnya" + show: "Lihat konten" chars: "{count} karakter" files: "{count} berkas" _poll: @@ -1551,7 +1549,7 @@ _pages: fn: "Fungsi" _fn: slots: "Slot" - slots-info: "Pisahkan setiap slow dengan baris baru" + slots-info: "Pisahkan setiap slot dengan baris baru" arg1: "Keluaran" for: "Ulangi" _for: diff --git a/locales/index.js b/locales/index.js index 727e0e384..35f9972ff 100644 --- a/locales/index.js +++ b/locales/index.js @@ -21,6 +21,7 @@ const languages = [ 'en-US', 'es-ES', 'fr-FR', + 'id-ID', 'ja-JP', 'ja-KS', 'kab-KAB', diff --git a/locales/it-IT.yml b/locales/it-IT.yml index 69c8152d7..0fdf78c79 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -305,8 +305,6 @@ monthX: "{month}" yearX: "{year}" pages: "Pagine" integration: "App collegate" -connectSerice: "Connetti" -disconnectSerice: "Disconnetti" enableLocalTimeline: "Abilita Timeline locale" enableGlobalTimeline: "Abilita Timeline federata" disablingTimelinesInfo: "Anche se disabiliti queste timeline, gli amministratori e i moderatori potranno sempre accederci." diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index e869f5b01..13f7e331a 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -279,6 +279,7 @@ emptyDrive: "ドライブは空です" emptyFolder: "フォルダーは空です" unableToDelete: "削除できません" inputNewFileName: "新しいファイル名を入力してください" +inputNewDescription: "新しいキャプションを入力してください" inputNewFolderName: "新しいフォルダ名を入力してください" circularReferenceFolder: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。" hasChildFilesOrFolders: "このフォルダは空でないため、削除できません。" @@ -310,8 +311,8 @@ monthX: "{month}月" yearX: "{year}年" pages: "ページ" integration: "連携" -connectSerice: "接続する" -disconnectSerice: "切断する" +connectService: "接続する" +disconnectService: "切断する" enableLocalTimeline: "ローカルタイムラインを有効にする" enableGlobalTimeline: "グローバルタイムラインを有効にする" disablingTimelinesInfo: "これらのタイムラインを無効化しても、利便性のため管理者およびモデレーターは引き続き利用することができます。" @@ -546,6 +547,8 @@ disablePlayer: "プレイヤーを閉じる" expandTweet: "ツイートを展開する" themeEditor: "テーマエディター" description: "説明" +describeFile: "キャプションを付ける" +enterFileDescription: "キャプションを入力" author: "作者" leaveConfirm: "未保存の変更があります。破棄しますか?" manage: "管理" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 6435b5835..060c7b142 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -308,8 +308,6 @@ monthX: "{month}月" yearX: "{year}年" pages: "ページ" integration: "連携" -connectSerice: "つなぐ" -disconnectSerice: "切ってまう" enableLocalTimeline: "ローカルタイムラインを使えるようにする" enableGlobalTimeline: "グローバルタイムラインを使えるようにする" disablingTimelinesInfo: "ここらへんのタイムラインを使えんようにしてしもても、管理者とモデレーターは使えるままになってるで、そうやなかったら不便やからな。" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 49069d258..3d313b8c7 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -279,6 +279,7 @@ emptyDrive: "드라이브가 비어 있습니다" emptyFolder: "폴더가 비어 있습니다" unableToDelete: "삭제할 수 없습니다" inputNewFileName: "바꿀 파일명을 입력해 주세요" +inputNewDescription: "새 캡션을 입력해 주세요" inputNewFolderName: "바꿀 폴더명을 입력해 주세요" circularReferenceFolder: "지정한 폴더가 이동할 폴더의 하위 폴더입니다." hasChildFilesOrFolders: "이 폴더는 비어있지 않기 때문에 삭제할 수 없습니다." @@ -310,8 +311,8 @@ monthX: "{month}월" yearX: "{year}년" pages: "페이지" integration: "연동" -connectSerice: "접속" -disconnectSerice: "연결 끊기" +connectService: "계정 연동" +disconnectService: "계정 연동 해제" enableLocalTimeline: "로컬 타임라인 활성화" enableGlobalTimeline: "글로벌 타임라인 활성화" disablingTimelinesInfo: "특정 타임라인을 비활성화하더라도 관리자 및 모더레이터는 계속 사용할 수 있습니다." @@ -546,6 +547,8 @@ disablePlayer: "플레이어 닫기" expandTweet: "트윗 확장하기" themeEditor: "테마 에디터" description: "설명" +describeFile: "캡션 추가" +enterFileDescription: "캡션 입력" author: "작성자" leaveConfirm: "저장하지 않은 변경사항이 있습니다. 취소하시겠습니까?" manage: "관리" diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index 4b4c80f7f..550bda78b 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -135,6 +135,7 @@ settingGuide: "Proponowana konfiguracja" cacheRemoteFiles: "Przechowuj zdalne pliki w pamięci podręcznej" cacheRemoteFilesDescription: "Gdy ta opcja jest wyłączona, zdalne pliki są ładowane bezpośrednio ze zdalnych instancji. Wyłączenie the opcji zmniejszy użycie powierzchni dyskowej, ale zwiększy transfer, ponieważ miniaturki nie będą generowane." flagAsBot: "To konto jest botem" +flagAsBotDescription: "Jeżeli ten kanał jest kontrolowany przez jakiś program, ustaw tę opcję. Jeżeli włączona, będzie działać jako flaga informująca innych programistów, aby zapobiegać nieskończonej interakcji z różnymi botami i dostosowywać wewnętrzne systemy Misskey, traktując konto jako bota." flagAsCat: "To konto jest kotem" flagAsCatDescription: "Przełącz tę opcję, aby konto było oznaczone jako kot." autoAcceptFollowed: "Automatycznie przyjmuj prośby o możliwość obserwacji od użytkowników, których obserwujesz" @@ -182,6 +183,7 @@ clearQueueConfirmTitle: "Czy na pewno chcesz wyczyścić kolejkę?" clearCachedFiles: "Wyczyść pamięć podręczną" clearCachedFilesConfirm: "Czy na pewno chcesz usunąć wszystkie zdalne pliki z pamięci podręcznej?" blockedInstances: "Zablokowane instancje" +blockedInstancesDescription: "Wypisz nazwy hostów instancji, które powinny zostać zablokowane. Wypisane instancje nie będą mogły dłużej komunikować się z tą instancją." muteAndBlock: "Wycisz / Zablokuj" mutedUsers: "Wyciszeni użytkownicy" blockedUsers: "Zablokowani użytkownicy" @@ -274,6 +276,7 @@ emptyDrive: "Dysk jest pusty" emptyFolder: "Ten katalog jest pusty" unableToDelete: "Nie można usunąć" inputNewFileName: "Wprowadź nową nazwę pliku" +inputNewDescription: "Proszę wpisać nowy napis" inputNewFolderName: "Wprowadź nową nazwę katalogu" circularReferenceFolder: "Katalog docelowy jest podkatalogiem katalogu, który chcesz przenieść." hasChildFilesOrFolders: "Ponieważ ten katalog nie jest pusty, nie może być usunięty." @@ -305,8 +308,6 @@ monthX: "{month}" yearX: "{year}" pages: "Strony" integration: "Integracja" -connectSerice: "Połącz" -disconnectSerice: "Rozłącz" enableLocalTimeline: "Włącz lokalną oś czasu" enableGlobalTimeline: "Włącz globalną oś czasu" disablingTimelinesInfo: "Administratorzy i moderatorzy będą zawsze mieć dostęp do wszystkich osi czasu, nawet gdy są one wyłączone." @@ -532,6 +533,8 @@ disablePlayer: "Zamknij odtwarzacz wideo" expandTweet: "Rozwiń tweet" themeEditor: "Edytor motywu" description: "Opis" +describeFile: "dodaj podpis" +enterFileDescription: "Wprowadź napis" author: "Autor" leaveConfirm: "Są niezapisane zmiany. Czy chcesz je odrzucić?" manage: "Zarządzanie" diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 2610403a7..c9700f4c9 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -309,8 +309,6 @@ monthX: "{month} месяц" yearX: "{year} год" pages: "Страницы" integration: "Интеграция" -connectSerice: "Соединение" -disconnectSerice: "Отключение" enableLocalTimeline: "Включить локальную ленту" enableGlobalTimeline: "Включить глобальную ленту" disablingTimelinesInfo: "У администраторов и модераторов есть доступ ко всем лентам, даже если они отключены." diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index bb010ed5f..3b8e6461c 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -307,8 +307,6 @@ monthX: "{month}" yearX: "{year}" pages: "Сторінки" integration: "Інтеграція" -connectSerice: "Під’єднати" -disconnectSerice: "Відключитися" enableLocalTimeline: "Увімкнути локальну стрічку" enableGlobalTimeline: "Увімкнути глобальну стрічку" disablingTimelinesInfo: "Адміністратори та модератори завжди мають доступ до всіх стрічок, навіть якщо вони вимкнуті." diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 4754fec4a..905c84575 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -279,6 +279,7 @@ emptyDrive: "驱动器为空" emptyFolder: "空文件夹" unableToDelete: "无法删除" inputNewFileName: "请输入新文件名" +inputNewDescription: "请输入新标题" inputNewFolderName: "请输入新文件名" circularReferenceFolder: "目标文件夹是您要移动的文件夹的子文件夹。" hasChildFilesOrFolders: "此文件夹不为空,无法删除。" @@ -310,8 +311,8 @@ monthX: "{month}月" yearX: "{year}年" pages: "页面" integration: "关联" -connectSerice: "连接" -disconnectSerice: "断开连接" +connectService: "连接" +disconnectService: "断开连接" enableLocalTimeline: "启用本地时间线功能" enableGlobalTimeline: "启用全局时间线" disablingTimelinesInfo: "即使时间线功能被禁用,出于便利性的原因,管理员和数据图表也可以继续使用。" @@ -546,6 +547,8 @@ disablePlayer: "关闭播放器" expandTweet: "展开贴文" themeEditor: "主题编辑器" description: "描述" +describeFile: "添加标题" +enterFileDescription: "输入标题" author: "作者" leaveConfirm: "存在未保存的更改。要放弃更改吗?" manage: "管理" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index e8c7e5553..dd9552a87 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1,18 +1,19 @@ --- _lang_: "繁體中文" -headlineMisskey: "貼文連繫網絡" -introMisskey: "歡迎! Misskey是一個開源且去中心化的社群網絡。\n通過「貼文」分享周邊新鮮事,並告訴其他人您的想法!📡\n透過「情感」功能,對大家的貼文表達情感!👍\n一起來探索這個新的世界吧!🚀" +headlineMisskey: "貼文連繫網路" +introMisskey: "歡迎! Misskey是一個開放原始碼且去中心化的社群網路。\n透過「貼文」分享周邊新鮮事,並告訴其他人您的想法!📡\n透過「情感」功能,對大家的貼文表達情感!👍\n一起來探索這個新的世界吧!🚀" monthAndDay: "{month}月 {day}日" search: "搜尋" notifications: "通知" username: "使用者名稱" password: "密碼" +forgotPassword: "忘記密碼" fetchingAsApObject: "從聯邦宇宙取得中..." ok: "OK" gotIt: "知道了" cancel: "取消" enterUsername: "輸入使用者名稱" -renotedBy: "{user} 轉發了" +renotedBy: "{user} 轉傳了" noNotes: "貼文不可用。" noNotifications: "沒有通知" instance: "實例" @@ -92,9 +93,9 @@ followRequestPending: "追隨許可批准中" enterEmoji: "輸入表情符號" renote: "轉發" unrenote: "取消轉發" -renoted: "轉發成功" +renoted: "轉傳成功" cantRenote: "無法轉發此貼文。" -cantReRenote: "無法轉發之前已經轉發過的內容。" +cantReRenote: "無法轉傳之前已經轉傳過的內容。" quote: "引用" pinnedNote: "已置頂的貼文" pinned: "置頂" @@ -309,8 +310,6 @@ monthX: "{month}月" yearX: "{year}年" pages: "頁面" integration: "整合" -connectSerice: "連線" -disconnectSerice: "中斷連線" enableLocalTimeline: "開啟本地時間軸" enableGlobalTimeline: "啟用公開時間軸" disablingTimelinesInfo: "即使您關閉了時間線功能,管理員和協調人仍可以繼續使用,以方便您。" @@ -733,6 +732,7 @@ noBotProtectionWarning: "尚未設定Bot防護。" configure: "設定" expiration: "期限" middle: "中" +emailNotConfiguredWarning: "沒有設定電子郵件地址" _ad: back: "返回" _gallery: diff --git a/package.json b/package.json index 4f01c7881..68f9bd75b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "misskey", "author": "syuilo ", - "version": "12.81.2", + "version": "12.82.0", "codename": "indigo", "repository": { "type": "git", @@ -30,6 +30,7 @@ "format": "gulp format" }, "resolutions": { + "mfm-js/twemoji-parser": "13.1.x", "chokidar": "^3.3.1", "constantinople": "^4.0.1", "jsonld/rdf-canonize/node-forge": "0.10.0", @@ -43,7 +44,7 @@ "@koa/router": "9.0.1", "@sentry/browser": "5.29.2", "@sentry/tracing": "5.29.2", - "@sinonjs/fake-timers": "7.0.5", + "@sinonjs/fake-timers": "7.1.2", "@syuilo/aiscript": "0.11.1", "@types/bcryptjs": "2.4.2", "@types/bull": "3.15.1", @@ -58,23 +59,23 @@ "@types/jsdom": "16.2.10", "@types/jsonld": "1.5.5", "@types/katex": "0.11.0", - "@types/koa": "2.13.1", + "@types/koa": "2.13.3", "@types/koa-bodyparser": "4.3.0", "@types/koa-cors": "0.0.0", "@types/koa-favicon": "2.0.19", "@types/koa-logger": "3.1.1", "@types/koa-mount": "4.0.0", "@types/koa-send": "4.1.2", - "@types/koa-views": "2.0.4", + "@types/koa-views": "7.0.0", "@types/koa__cors": "3.0.2", "@types/koa__multer": "2.0.2", "@types/koa__router": "8.0.4", "@types/markdown-it": "12.0.1", "@types/matter-js": "0.14.12", "@types/mocha": "8.2.2", - "@types/node": "15.3.1", + "@types/node": "15.6.1", "@types/node-fetch": "2.5.10", - "@types/nodemailer": "6.4.1", + "@types/nodemailer": "6.4.2", "@types/nprogress": "0.2.0", "@types/oauth": "0.9.1", "@types/parse5": "6.0.0", @@ -85,12 +86,12 @@ "@types/qrcode": "1.4.0", "@types/random-seed": "0.3.3", "@types/ratelimiter": "3.4.1", - "@types/redis": "2.8.28", + "@types/redis": "2.8.29", "@types/rename": "1.0.3", "@types/request-stats": "3.0.0", "@types/rimraf": "3.0.0", "@types/seedrandom": "2.4.28", - "@types/sharp": "0.28.1", + "@types/sharp": "0.28.2", "@types/sinonjs__fake-timers": "6.0.2", "@types/speakeasy": "2.0.5", "@types/throttle-debounce": "2.1.0", @@ -102,14 +103,14 @@ "@types/webpack-stream": "3.2.12", "@types/websocket": "1.0.2", "@types/ws": "7.4.4", - "@typescript-eslint/parser": "4.24.0", + "@typescript-eslint/parser": "4.25.0", "@vue/compiler-sfc": "3.0.11", "abort-controller": "3.0.0", "apexcharts": "3.26.3", "autobind-decorator": "2.4.0", "autosize": "4.0.4", "autwh": "0.1.0", - "aws-sdk": "2.910.0", + "aws-sdk": "2.918.0", "bcryptjs": "2.4.3", "blurhash": "1.1.3", "broadcast-channel": "3.6.0", @@ -120,20 +121,20 @@ "chart.js": "2.9.4", "cli-highlight": "2.1.11", "commander": "7.2.0", - "concurrently": "6.1.0", + "concurrently": "6.2.0", "content-disposition": "0.5.3", - "core-js": "3.12.1", + "core-js": "3.13.1", "crc-32": "1.2.0", - "css-loader": "5.2.4", - "cssnano": "5.0.3", + "css-loader": "5.2.6", + "cssnano": "5.0.5", "dateformat": "4.5.1", "diskusage": "1.1.3", "escape-regexp": "0.0.1", - "eslint": "7.26.0", - "eslint-plugin-vue": "7.9.0", + "eslint": "7.27.0", + "eslint-plugin-vue": "7.10.0", "eventemitter3": "4.0.7", "feed": "4.2.2", - "file-type": "16.4.0", + "file-type": "16.5.0", "fluent-ffmpeg": "2.1.2", "glob": "7.1.7", "got": "11.8.2", @@ -148,12 +149,12 @@ "http-proxy-agent": "4.0.1", "http-signature": "1.3.5", "https-proxy-agent": "5.0.0", - "idb-keyval": "5.0.5", + "idb-keyval": "5.0.6", "insert-text-at-cursor": "0.3.0", "is-root": "2.1.0", "is-svg": "4.3.1", "js-yaml": "4.1.0", - "jsdom": "16.5.3", + "jsdom": "16.6.0", "json5": "2.2.0", "json5-loader": "4.0.1", "jsonld": "4.0.1", @@ -174,22 +175,23 @@ "markdown-it-anchor": "7.1.0", "matter-js": "0.17.1", "mfm-js": "0.16.4", + "misskey-js": "0.0.2", "mocha": "8.4.0", "moji": "0.5.1", "ms": "2.1.3", "multer": "1.4.2", "nested-property": "4.0.0", "node-fetch": "2.6.1", - "nodemailer": "6.6.0", + "nodemailer": "6.6.1", "object-assign-deep": "0.4.0", "os-utils": "0.0.14", "parse5": "6.0.1", "pg": "8.6.0", "portscanner": "2.2.0", - "postcss": "8.2.15", + "postcss": "8.3.0", "postcss-loader": "5.3.0", "prismjs": "1.23.0", - "probe-image-size": "7.1.0", + "probe-image-size": "7.1.1", "promise-limit": "2.7.0", "promise-sequential": "1.1.1", "pug": "3.0.2", @@ -210,30 +212,31 @@ "rimraf": "3.0.2", "rndstr": "1.0.0", "s-age": "1.1.2", - "sass": "1.32.13", + "sass": "1.34.0", "sass-loader": "11.1.1", "seedrandom": "3.0.5", - "sharp": "0.28.2", + "sharp": "0.28.3", "speakeasy": "2.0.0", "stringz": "2.1.0", "style-loader": "2.0.0", "summaly": "2.4.0", "syslog-pro": "1.0.0", - "systeminformation": "5.6.22", + "systeminformation": "5.7.4", "syuilo-password-strength": "0.0.1", "textarea-caret": "3.1.0", "three": "0.117.1", "throttle-debounce": "3.0.1", "tinycolor2": "1.4.2", "tmp": "0.2.1", - "ts-loader": "9.2.1", - "ts-node": "9.1.1", + "ts-loader": "9.2.2", + "ts-node": "10.0.0", "tsc-alias": "1.2.11", "tsconfig-paths": "3.9.0", "tslint": "6.1.3", "tslint-sonarts": "1.9.0", + "twemoji-parser": "13.1.0", "typeorm": "0.2.32", - "typescript": "4.2.4", + "typescript": "4.3.2", "ulid": "2.3.0", "uuid": "8.3.2", "v-debounce": "0.1.2", @@ -248,10 +251,10 @@ "vue-svg-loader": "0.17.0-beta.2", "vuedraggable": "4.0.1", "web-push": "3.4.4", - "webpack": "5.37.1", + "webpack": "5.38.1", "webpack-cli": "4.7.0", "websocket": "1.0.34", - "ws": "7.4.5", + "ws": "7.4.6", "xev": "2.0.1" }, "devDependencies": { diff --git a/src/client/components/date-separated-list.vue b/src/client/components/date-separated-list.vue index 34085cc07..6a0c7f29f 100644 --- a/src/client/components/date-separated-list.vue +++ b/src/client/components/date-separated-list.vue @@ -1,11 +1,11 @@ + + diff --git a/src/client/components/media-image.vue b/src/client/components/media-image.vue index 267e4debd..863eb1027 100644 --- a/src/client/components/media-image.vue +++ b/src/client/components/media-image.vue @@ -1,6 +1,6 @@ @@ -28,12 +28,14 @@ import XList from './date-separated-list.vue'; import XNote from './note.vue'; import { notificationTypes } from '../../types'; import * as os from '@client/os'; +import MkButton from '@client/components/ui/button.vue'; export default defineComponent({ components: { XNotification, XList, XNote, + MkButton, }, mixins: [ @@ -87,7 +89,7 @@ export default defineComponent({ }, mounted() { - this.connection = os.stream.useSharedConnection('main'); + this.connection = os.stream.useChannel('main'); this.connection.on('notification', this.onNotification); }, diff --git a/src/client/components/post-form-attaches.vue b/src/client/components/post-form-attaches.vue index f832ea87b..27e20fdfa 100644 --- a/src/client/components/post-form-attaches.vue +++ b/src/client/components/post-form-attaches.vue @@ -89,6 +89,27 @@ export default defineComponent({ file.name = result; }); }, + + async describe(file) { + os.popup(import("@client/components/media-caption.vue"), { + title: this.$ts.describeFile, + input: { + placeholder: this.$ts.inputNewDescription, + default: file.comment !== null ? file.comment : "", + }, + image: file + }, { + done: result => { + if (!result || result.canceled) return; + let comment = result.result; + os.api('drive/files/update', { + fileId: file.id, + comment: comment.length == 0 ? null : comment + }); + } + }, 'closed'); + }, + showFileMenu(file, ev: MouseEvent) { if (this.menu) return; this.menu = os.modalMenu([{ @@ -99,6 +120,10 @@ export default defineComponent({ text: file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive, icon: file.isSensitive ? 'fas fa-eye-slash' : 'fas fa-eye', action: () => { this.toggleSensitive(file) } + }, { + text: this.$ts.describeFile, + icon: 'fas fa-i-cursor', + action: () => { this.describe(file) } }, { text: this.$ts.attachCancel, icon: 'fas fa-times-circle', diff --git a/src/client/components/timeline.vue b/src/client/components/timeline.vue index 753eba2ba..c21e1ec2a 100644 --- a/src/client/components/timeline.vue +++ b/src/client/components/timeline.vue @@ -92,33 +92,33 @@ export default defineComponent({ this.query = { antennaId: this.antenna }; - this.connection = os.stream.connectToChannel('antenna', { + this.connection = os.stream.useChannel('antenna', { antennaId: this.antenna }); this.connection.on('note', prepend); } else if (this.src == 'home') { endpoint = 'notes/timeline'; - this.connection = os.stream.useSharedConnection('homeTimeline'); + this.connection = os.stream.useChannel('homeTimeline'); this.connection.on('note', prepend); - this.connection2 = os.stream.useSharedConnection('main'); + this.connection2 = os.stream.useChannel('main'); this.connection2.on('follow', onChangeFollowing); this.connection2.on('unfollow', onChangeFollowing); } else if (this.src == 'local') { endpoint = 'notes/local-timeline'; - this.connection = os.stream.useSharedConnection('localTimeline'); + this.connection = os.stream.useChannel('localTimeline'); this.connection.on('note', prepend); } else if (this.src == 'social') { endpoint = 'notes/hybrid-timeline'; - this.connection = os.stream.useSharedConnection('hybridTimeline'); + this.connection = os.stream.useChannel('hybridTimeline'); this.connection.on('note', prepend); } else if (this.src == 'global') { endpoint = 'notes/global-timeline'; - this.connection = os.stream.useSharedConnection('globalTimeline'); + this.connection = os.stream.useChannel('globalTimeline'); this.connection.on('note', prepend); } else if (this.src == 'mentions') { endpoint = 'notes/mentions'; - this.connection = os.stream.useSharedConnection('main'); + this.connection = os.stream.useChannel('main'); this.connection.on('mention', prepend); } else if (this.src == 'directs') { endpoint = 'notes/mentions'; @@ -130,14 +130,14 @@ export default defineComponent({ prepend(note); } }; - this.connection = os.stream.useSharedConnection('main'); + this.connection = os.stream.useChannel('main'); this.connection.on('mention', onNote); } else if (this.src == 'list') { endpoint = 'notes/user-list-timeline'; this.query = { listId: this.list }; - this.connection = os.stream.connectToChannel('userList', { + this.connection = os.stream.useChannel('userList', { listId: this.list }); this.connection.on('note', prepend); @@ -148,7 +148,7 @@ export default defineComponent({ this.query = { channelId: this.channel }; - this.connection = os.stream.connectToChannel('channel', { + this.connection = os.stream.useChannel('channel', { channelId: this.channel }); this.connection.on('note', prepend); diff --git a/src/client/init.ts b/src/client/init.ts index a4465d75c..12bb0d58c 100644 --- a/src/client/init.ts +++ b/src/client/init.ts @@ -163,8 +163,6 @@ fetchInstance().then(() => { initializeSw(); }); -stream.init($i); - const app = createApp(await ( window.location.search === '?zen' ? import('@client/ui/zen.vue') : !$i ? import('@client/ui/visitor.vue') : @@ -296,7 +294,7 @@ if ($i) { } } - const main = stream.useSharedConnection('main', 'System'); + const main = stream.useChannel('main', null, 'System'); // 自分の情報が更新されたとき main.on('meUpdated', i => { @@ -358,10 +356,6 @@ if ($i) { sound.play('channel'); }); - main.on('readAllAnnouncements', () => { - updateAccount({ hasUnreadAnnouncement: false }); - }); - // トークンが再生成されたとき // このままではMisskeyが利用できないので強制的にサインアウトさせる main.on('myTokenRegenerated', () => { diff --git a/src/client/instance.ts b/src/client/instance.ts index 024ff1acb..04d335320 100644 --- a/src/client/instance.ts +++ b/src/client/instance.ts @@ -1,26 +1,14 @@ import { computed, reactive } from 'vue'; +import * as Misskey from 'misskey-js'; import { api } from './os'; // TODO: 他のタブと永続化されたstateを同期 -export type Instance = { - emojis: { - category: string; - }[]; - ads: { - id: string; - ratio: number; - place: string; - url: string; - imageUrl: string; - }[]; -}; - const data = localStorage.getItem('instance'); // TODO: instanceをリアクティブにするかは再考の余地あり -export const instance: Instance = reactive(data ? JSON.parse(data) : { +export const instance: Misskey.entities.InstanceMetadata = reactive(data ? JSON.parse(data) : { // TODO: set default values }); diff --git a/src/client/os.ts b/src/client/os.ts index b159cf509..987844b2d 100644 --- a/src/client/os.ts +++ b/src/client/os.ts @@ -3,16 +3,16 @@ import { Component, defineAsyncComponent, markRaw, reactive, Ref, ref } from 'vue'; import { EventEmitter } from 'eventemitter3'; import insertTextAtCursor from 'insert-text-at-cursor'; +import * as Misskey from 'misskey-js'; import * as Sentry from '@sentry/browser'; -import Stream from '@client/scripts/stream'; -import { apiUrl, debug } from '@client/config'; +import { apiUrl, debug, url } from '@client/config'; import MkPostFormDialog from '@client/components/post-form-dialog.vue'; import MkWaitingDialog from '@client/components/waiting-dialog.vue'; import { resolve } from '@client/router'; import { $i } from '@client/account'; import { defaultStore } from '@client/store'; -export const stream = markRaw(new Stream()); +export const stream = markRaw(new Misskey.Stream(url, $i)); export const pendingApiRequestsCount = ref(0); let apiRequestsCount = 0; // for debug @@ -20,7 +20,11 @@ export const apiRequests = ref([]); // for debug export const windows = new Map(); -export function api(endpoint: string, data: Record = {}, token?: string | null | undefined) { +const apiClient = new Misskey.api.APIClient({ + origin: url, +}); + +export const api = ((endpoint: string, data: Record = {}, token?: string | null | undefined) => { pendingApiRequestsCount.value++; const onFinally = () => { @@ -56,7 +60,7 @@ export function api(endpoint: string, data: Record = {}, token?: st if (res.status === 200) { resolve(body); if (debug) { - log!.res = markRaw(body); + log!.res = markRaw(JSON.parse(JSON.stringify(body))); log!.state = 'success'; } } else if (res.status === 204) { @@ -90,17 +94,15 @@ export function api(endpoint: string, data: Record = {}, token?: st promise.then(onFinally, onFinally); return promise; -} +}) as typeof apiClient.request; -export function apiWithDialog( +export const apiWithDialog = (( endpoint: string, data: Record = {}, token?: string | null | undefined, - onSuccess?: (res: any) => void, - onFailure?: (e: Error) => void, -) { +) => { const promise = api(endpoint, data, token); - promiseDialog(promise, onSuccess, onFailure ? onFailure : (e) => { + promiseDialog(promise, null, (e) => { dialog({ type: 'error', text: e.message + '\n' + (e as any).id, @@ -108,7 +110,7 @@ export function apiWithDialog( }); return promise; -} +}) as typeof api; export function promiseDialog>( promise: T, diff --git a/src/client/pages/instance/metrics.vue b/src/client/pages/instance/metrics.vue index 18cfe5eee..407cce9e7 100644 --- a/src/client/pages/instance/metrics.vue +++ b/src/client/pages/instance/metrics.vue @@ -90,7 +90,7 @@ export default defineComponent({ stats: null, serverInfo: null, connection: null, - queueConnection: os.stream.useSharedConnection('queueStats'), + queueConnection: os.stream.useChannel('queueStats'), memUsage: 0, chartCpuMem: null, chartNet: null, @@ -121,7 +121,7 @@ export default defineComponent({ os.api('admin/server-info', {}).then(res => { this.serverInfo = res; - this.connection = os.stream.useSharedConnection('serverStats'); + this.connection = os.stream.useChannel('serverStats'); this.connection.on('stats', this.onStats); this.connection.on('statsLog', this.onStatsLog); this.connection.send('requestLog', { diff --git a/src/client/pages/instance/overview.vue b/src/client/pages/instance/overview.vue index dca2529e1..cb9cff9fc 100644 --- a/src/client/pages/instance/overview.vue +++ b/src/client/pages/instance/overview.vue @@ -92,6 +92,7 @@ export default defineComponent({ version, url, stats: null, + meta: null, fetchStats: () => os.api('stats', {}), fetchServerInfo: () => os.api('admin/server-info', {}), fetchJobs: () => os.api('admin/queue/deliver-delayed', {}), diff --git a/src/client/pages/instance/queue.vue b/src/client/pages/instance/queue.vue index 2dccf48d3..8f56fd74b 100644 --- a/src/client/pages/instance/queue.vue +++ b/src/client/pages/instance/queue.vue @@ -35,7 +35,7 @@ export default defineComponent({ title: this.$ts.jobQueue, icon: 'fas fa-clipboard-list', }, - connection: os.stream.useSharedConnection('queueStats'), + connection: os.stream.useChannel('queueStats'), } }, diff --git a/src/client/pages/messaging/index.vue b/src/client/pages/messaging/index.vue index 9f3323f62..832cce5ab 100644 --- a/src/client/pages/messaging/index.vue +++ b/src/client/pages/messaging/index.vue @@ -63,7 +63,7 @@ export default defineComponent({ }, mounted() { - this.connection = os.stream.useSharedConnection('messagingIndex'); + this.connection = os.stream.useChannel('messagingIndex'); this.connection.on('message', this.onMessage); this.connection.on('read', this.onRead); diff --git a/src/client/pages/messaging/messaging-room.vue b/src/client/pages/messaging/messaging-room.vue index 44bfd6c51..f1d55ee28 100644 --- a/src/client/pages/messaging/messaging-room.vue +++ b/src/client/pages/messaging/messaging-room.vue @@ -141,7 +141,7 @@ const Component = defineComponent({ this.group = group; } - this.connection = os.stream.connectToChannel('messaging', { + this.connection = os.stream.useChannel('messaging', { otherparty: this.user ? this.user.id : undefined, group: this.group ? this.group.id : undefined, }); diff --git a/src/client/pages/reversi/game.vue b/src/client/pages/reversi/game.vue index 62c99d775..dc4d11ca4 100644 --- a/src/client/pages/reversi/game.vue +++ b/src/client/pages/reversi/game.vue @@ -61,7 +61,7 @@ export default defineComponent({ if (this.connection) { this.connection.dispose(); } - this.connection = os.stream.connectToChannel('gamesReversiGame', { + this.connection = os.stream.useChannel('gamesReversiGame', { gameId: this.game.id }); this.connection.on('started', this.onStarted); diff --git a/src/client/pages/reversi/index.vue b/src/client/pages/reversi/index.vue index 37126fca1..dd329084a 100644 --- a/src/client/pages/reversi/index.vue +++ b/src/client/pages/reversi/index.vue @@ -92,7 +92,7 @@ export default defineComponent({ mounted() { if (this.$i) { - this.connection = os.stream.useSharedConnection('gamesReversi'); + this.connection = os.stream.useChannel('gamesReversi'); this.connection.on('invited', this.onInvited); diff --git a/src/client/pages/settings/integration.vue b/src/client/pages/settings/integration.vue index 2d2be0405..f1c0a88af 100644 --- a/src/client/pages/settings/integration.vue +++ b/src/client/pages/settings/integration.vue @@ -4,8 +4,8 @@
Twitter

{{ $ts.connectedTo }}: @{{ integrations.twitter.screenName }}

- {{ $ts.disconnectSerice }} - {{ $ts.connectSerice }} + {{ $ts.disconnectService }} + {{ $ts.connectService }}
@@ -13,8 +13,8 @@
Discord

{{ $ts.connectedTo }}: @{{ integrations.discord.username }}#{{ integrations.discord.discriminator }}

- {{ $ts.disconnectSerice }} - {{ $ts.connectSerice }} + {{ $ts.disconnectService }} + {{ $ts.connectService }}
@@ -22,8 +22,8 @@
GitHub

{{ $ts.connectedTo }}: @{{ integrations.github.login }}

- {{ $ts.disconnectSerice }} - {{ $ts.connectSerice }} + {{ $ts.disconnectService }} + {{ $ts.connectService }}
diff --git a/src/client/scripts/get-static-image-url.ts b/src/client/scripts/get-static-image-url.ts index e2728d73f..92c31914c 100644 --- a/src/client/scripts/get-static-image-url.ts +++ b/src/client/scripts/get-static-image-url.ts @@ -3,6 +3,11 @@ import * as url from '../../prelude/url'; export function getStaticImageUrl(baseUrl: string): string { const u = new URL(baseUrl); + if (u.href.startsWith(`${instanceUrl}/proxy/`)) { + // もう既にproxyっぽそうだったらsearchParams付けるだけ + u.searchParams.set('static', '1'); + return u.href; + } const dummy = `${u.host}${u.pathname}`; // 拡張子がないとキャッシュしてくれないCDNがあるので return `${instanceUrl}/proxy/${dummy}?${url.query({ url: u.href, diff --git a/src/client/scripts/select-file.ts b/src/client/scripts/select-file.ts index c193e7dc7..b8039fb67 100644 --- a/src/client/scripts/select-file.ts +++ b/src/client/scripts/select-file.ts @@ -47,7 +47,7 @@ export function selectFile(src: any, label: string | null, multiple = false) { const marker = Math.random().toString(); // TODO: UUIDとか使う - const connection = os.stream.useSharedConnection('main'); + const connection = os.stream.useChannel('main'); connection.on('urlUploadFinished', data => { if (data.marker === marker) { res(multiple ? [data.file] : data.file); @@ -55,7 +55,7 @@ export function selectFile(src: any, label: string | null, multiple = false) { } }); - os.api('drive/files/upload_from_url', { + os.api('drive/files/upload-from-url', { url: url, marker }); diff --git a/src/client/scripts/stream.ts b/src/client/scripts/stream.ts deleted file mode 100644 index 065059221..000000000 --- a/src/client/scripts/stream.ts +++ /dev/null @@ -1,312 +0,0 @@ -import autobind from 'autobind-decorator'; -import { EventEmitter } from 'eventemitter3'; -import ReconnectingWebsocket from 'reconnecting-websocket'; -import { markRaw } from 'vue'; -import { debug, wsUrl } from '@client/config'; -import { query as urlQuery } from '../../prelude/url'; - -/** - * Misskey stream connection - */ -export default class Stream extends EventEmitter { - private stream: ReconnectingWebsocket; - public state: 'initializing' | 'reconnecting' | 'connected' = 'initializing'; - private sharedConnectionPools: Pool[] = []; - private sharedConnections: SharedConnection[] = []; - private nonSharedConnections: NonSharedConnection[] = []; - - @autobind - public init(user): void { - const query = urlQuery({ - i: user?.token, - _t: Date.now(), - }); - - this.stream = new ReconnectingWebsocket(`${wsUrl}?${query}`, '', { minReconnectionDelay: 1 }); // https://github.com/pladaria/reconnecting-websocket/issues/91 - this.stream.addEventListener('open', this.onOpen); - this.stream.addEventListener('close', this.onClose); - this.stream.addEventListener('message', this.onMessage); - } - - @autobind - public useSharedConnection(channel: string, name?: string): SharedConnection { - let pool = this.sharedConnectionPools.find(p => p.channel === channel); - - if (pool == null) { - pool = new Pool(this, channel); - this.sharedConnectionPools.push(pool); - } - - const connection = markRaw(new SharedConnection(this, channel, pool, name)); - this.sharedConnections.push(connection); - return connection; - } - - @autobind - public removeSharedConnection(connection: SharedConnection) { - this.sharedConnections = this.sharedConnections.filter(c => c !== connection); - } - - @autobind - public removeSharedConnectionPool(pool: Pool) { - this.sharedConnectionPools = this.sharedConnectionPools.filter(p => p !== pool); - } - - @autobind - public connectToChannel(channel: string, params?: any): NonSharedConnection { - const connection = markRaw(new NonSharedConnection(this, channel, params)); - this.nonSharedConnections.push(connection); - return connection; - } - - @autobind - public disconnectToChannel(connection: NonSharedConnection) { - this.nonSharedConnections = this.nonSharedConnections.filter(c => c !== connection); - } - - /** - * Callback of when open connection - */ - @autobind - private onOpen() { - const isReconnect = this.state === 'reconnecting'; - - this.state = 'connected'; - this.emit('_connected_'); - - // チャンネル再接続 - if (isReconnect) { - for (const p of this.sharedConnectionPools) - p.connect(); - for (const c of this.nonSharedConnections) - c.connect(); - } - } - - /** - * Callback of when close connection - */ - @autobind - private onClose() { - if (this.state === 'connected') { - this.state = 'reconnecting'; - this.emit('_disconnected_'); - } - } - - /** - * Callback of when received a message from connection - */ - @autobind - private onMessage(message) { - const { type, body } = JSON.parse(message.data); - - if (type === 'channel') { - const id = body.id; - - let connections: Connection[]; - - connections = this.sharedConnections.filter(c => c.id === id); - - if (connections.length === 0) { - connections = [this.nonSharedConnections.find(c => c.id === id)]; - } - - for (const c of connections.filter(c => c != null)) { - c.emit(body.type, Object.freeze(body.body)); - if (debug) c.inCount++; - } - } else { - this.emit(type, Object.freeze(body)); - } - } - - /** - * Send a message to connection - */ - @autobind - public send(typeOrPayload, payload?) { - const data = payload === undefined ? typeOrPayload : { - type: typeOrPayload, - body: payload - }; - - this.stream.send(JSON.stringify(data)); - } - - /** - * Close this connection - */ - @autobind - public close() { - this.stream.removeEventListener('open', this.onOpen); - this.stream.removeEventListener('message', this.onMessage); - } -} - -let idCounter = 0; - -class Pool { - public channel: string; - public id: string; - protected stream: Stream; - public users = 0; - private disposeTimerId: any; - private isConnected = false; - - constructor(stream: Stream, channel: string) { - this.channel = channel; - this.stream = stream; - - this.id = (++idCounter).toString(); - - this.stream.on('_disconnected_', this.onStreamDisconnected); - } - - @autobind - private onStreamDisconnected() { - this.isConnected = false; - } - - @autobind - public inc() { - if (this.users === 0 && !this.isConnected) { - this.connect(); - } - - this.users++; - - // タイマー解除 - if (this.disposeTimerId) { - clearTimeout(this.disposeTimerId); - this.disposeTimerId = null; - } - } - - @autobind - public dec() { - this.users--; - - // そのコネクションの利用者が誰もいなくなったら - if (this.users === 0) { - // また直ぐに再利用される可能性があるので、一定時間待ち、 - // 新たな利用者が現れなければコネクションを切断する - this.disposeTimerId = setTimeout(() => { - this.disconnect(); - }, 3000); - } - } - - @autobind - public connect() { - if (this.isConnected) return; - this.isConnected = true; - this.stream.send('connect', { - channel: this.channel, - id: this.id - }); - } - - @autobind - private disconnect() { - this.stream.off('_disconnected_', this.onStreamDisconnected); - this.stream.send('disconnect', { id: this.id }); - this.stream.removeSharedConnectionPool(this); - } -} - -abstract class Connection extends EventEmitter { - public channel: string; - protected stream: Stream; - public abstract id: string; - - public name?: string; // for debug - public inCount: number = 0; // for debug - public outCount: number = 0; // for debug - - constructor(stream: Stream, channel: string, name?: string) { - super(); - - this.stream = stream; - this.channel = channel; - this.name = name; - } - - @autobind - public send(id: string, typeOrPayload, payload?) { - const type = payload === undefined ? typeOrPayload.type : typeOrPayload; - const body = payload === undefined ? typeOrPayload.body : payload; - - this.stream.send('ch', { - id: id, - type: type, - body: body - }); - - if (debug) this.outCount++; - } - - public abstract dispose(): void; -} - -class SharedConnection extends Connection { - private pool: Pool; - - public get id(): string { - return this.pool.id; - } - - constructor(stream: Stream, channel: string, pool: Pool, name?: string) { - super(stream, channel, name); - - this.pool = pool; - this.pool.inc(); - } - - @autobind - public send(typeOrPayload, payload?) { - super.send(this.pool.id, typeOrPayload, payload); - } - - @autobind - public dispose() { - this.pool.dec(); - this.removeAllListeners(); - this.stream.removeSharedConnection(this); - } -} - -class NonSharedConnection extends Connection { - public id: string; - protected params: any; - - constructor(stream: Stream, channel: string, params?: any) { - super(stream, channel); - - this.params = params; - this.id = (++idCounter).toString(); - - this.connect(); - } - - @autobind - public connect() { - this.stream.send('connect', { - channel: this.channel, - id: this.id, - params: this.params - }); - } - - @autobind - public send(typeOrPayload, payload?) { - super.send(this.id, typeOrPayload, payload); - } - - @autobind - public dispose() { - this.removeAllListeners(); - this.stream.send('disconnect', { id: this.id }); - this.stream.disconnectToChannel(this); - } -} diff --git a/src/client/style.scss b/src/client/style.scss index 39bf6ef2d..dc419bd87 100644 --- a/src/client/style.scss +++ b/src/client/style.scss @@ -146,6 +146,7 @@ hr { width: 100%; height: 100%; background: var(--modalBg); + -webkit-backdrop-filter: var(--modalBgFilter); backdrop-filter: var(--modalBgFilter); } diff --git a/src/client/ui/_common_/common.vue b/src/client/ui/_common_/common.vue index 785b1631d..8da19a098 100644 --- a/src/client/ui/_common_/common.vue +++ b/src/client/ui/_common_/common.vue @@ -43,7 +43,7 @@ export default defineComponent({ }; if ($i) { - const connection = stream.useSharedConnection('main', 'UI'); + const connection = stream.useChannel('main', null, 'UI'); connection.on('notification', onNotification); } diff --git a/src/client/ui/chat/timeline.vue b/src/client/ui/chat/timeline.vue index 13032cce0..2245a9d8a 100644 --- a/src/client/ui/chat/timeline.vue +++ b/src/client/ui/chat/timeline.vue @@ -121,33 +121,33 @@ export default defineComponent({ this.query = { antennaId: this.antenna }; - this.connection = os.stream.connectToChannel('antenna', { + this.connection = os.stream.useChannel('antenna', { antennaId: this.antenna }); this.connection.on('note', prepend); } else if (this.src == 'home') { endpoint = 'notes/timeline'; - this.connection = os.stream.useSharedConnection('homeTimeline'); + this.connection = os.stream.useChannel('homeTimeline'); this.connection.on('note', prepend); - this.connection2 = os.stream.useSharedConnection('main'); + this.connection2 = os.stream.useChannel('main'); this.connection2.on('follow', onChangeFollowing); this.connection2.on('unfollow', onChangeFollowing); } else if (this.src == 'local') { endpoint = 'notes/local-timeline'; - this.connection = os.stream.useSharedConnection('localTimeline'); + this.connection = os.stream.useChannel('localTimeline'); this.connection.on('note', prepend); } else if (this.src == 'social') { endpoint = 'notes/hybrid-timeline'; - this.connection = os.stream.useSharedConnection('hybridTimeline'); + this.connection = os.stream.useChannel('hybridTimeline'); this.connection.on('note', prepend); } else if (this.src == 'global') { endpoint = 'notes/global-timeline'; - this.connection = os.stream.useSharedConnection('globalTimeline'); + this.connection = os.stream.useChannel('globalTimeline'); this.connection.on('note', prepend); } else if (this.src == 'mentions') { endpoint = 'notes/mentions'; - this.connection = os.stream.useSharedConnection('main'); + this.connection = os.stream.useChannel('main'); this.connection.on('mention', prepend); } else if (this.src == 'directs') { endpoint = 'notes/mentions'; @@ -159,14 +159,14 @@ export default defineComponent({ prepend(note); } }; - this.connection = os.stream.useSharedConnection('main'); + this.connection = os.stream.useChannel('main'); this.connection.on('mention', onNote); } else if (this.src == 'list') { endpoint = 'notes/user-list-timeline'; this.query = { listId: this.list }; - this.connection = os.stream.connectToChannel('userList', { + this.connection = os.stream.useChannel('userList', { listId: this.list }); this.connection.on('note', prepend); @@ -178,7 +178,7 @@ export default defineComponent({ this.query = { channelId: this.channel }; - this.connection = os.stream.connectToChannel('channel', { + this.connection = os.stream.useChannel('channel', { channelId: this.channel }); this.connection.on('note', prepend); diff --git a/src/client/ui/default.sidebar.vue b/src/client/ui/default.sidebar.vue index 725fd844d..c7e2d30c7 100644 --- a/src/client/ui/default.sidebar.vue +++ b/src/client/ui/default.sidebar.vue @@ -241,7 +241,6 @@ export default defineComponent({ > .text { display: none; } - } } @@ -309,7 +308,7 @@ export default defineComponent({ > .indicator { position: absolute; top: 0; - left: 20px; + left: 0; color: var(--navIndicator); font-size: 8px; animation: blink 1s infinite; diff --git a/src/client/widgets/job-queue.vue b/src/client/widgets/job-queue.vue index 31a322e6e..162ffe9c8 100644 --- a/src/client/widgets/job-queue.vue +++ b/src/client/widgets/job-queue.vue @@ -65,7 +65,7 @@ export default defineComponent({ extends: widget, data() { return { - connection: os.stream.useSharedConnection('queueStats'), + connection: os.stream.useChannel('queueStats'), inbox: { activeSincePrevTick: 0, active: 0, diff --git a/src/client/widgets/photos.vue b/src/client/widgets/photos.vue index 65843385b..7f6fa8272 100644 --- a/src/client/widgets/photos.vue +++ b/src/client/widgets/photos.vue @@ -48,7 +48,7 @@ export default defineComponent({ }; }, mounted() { - this.connection = os.stream.useSharedConnection('main'); + this.connection = os.stream.useChannel('main'); this.connection.on('driveFileCreated', this.onDriveFileCreated); diff --git a/src/client/widgets/server-metric/index.vue b/src/client/widgets/server-metric/index.vue index 6331b5bdf..2398e9920 100644 --- a/src/client/widgets/server-metric/index.vue +++ b/src/client/widgets/server-metric/index.vue @@ -63,7 +63,7 @@ export default defineComponent({ os.api('server-info', {}).then(res => { this.meta = res; }); - this.connection = os.stream.useSharedConnection('serverStats'); + this.connection = os.stream.useChannel('serverStats'); }, unmounted() { this.connection.dispose(); diff --git a/src/emojilist.json b/src/emojilist.json index 30cf6dd73..75c424ab4 100644 --- a/src/emojilist.json +++ b/src/emojilist.json @@ -93,6 +93,9 @@ { "category": "face", "char": "🥱", "name": "yawning", "keywords": ["face", "tired", "yawning"] }, { "category": "face", "char": "😴", "name": "sleeping", "keywords": ["face", "tired", "sleepy", "night", "zzz"] }, { "category": "face", "char": "💤", "name": "zzz", "keywords": ["sleepy", "tired", "dream"] }, + { "category": "face", "char": "\uD83D\uDE36\u200D\uD83C\uDF2B\uFE0F", "name": "face_in_clouds", "keywords": [] }, + { "category": "face", "char": "\uD83D\uDE2E\u200D\uD83D\uDCA8", "name": "face_exhaling", "keywords": [] }, + { "category": "face", "char": "\uD83D\uDE35\u200D\uD83D\uDCAB", "name": "face_with_spiral_eyes", "keywords": [] }, { "category": "face", "char": "💩", "name": "poop", "keywords": ["hankey", "shitface", "fail", "turd", "shit"] }, { "category": "face", "char": "😈", "name": "smiling_imp", "keywords": ["devil", "horns"] }, { "category": "face", "char": "👿", "name": "imp", "keywords": ["devil", "angry", "horns"] }, @@ -1219,6 +1222,8 @@ { "category": "symbols", "char": "💘", "name": "cupid", "keywords": ["love", "like", "heart", "affection", "valentines"] }, { "category": "symbols", "char": "💝", "name": "gift_heart", "keywords": ["love", "valentines"] }, { "category": "symbols", "char": "💟", "name": "heart_decoration", "keywords": ["purple-square", "love", "like"] }, + { "category": "symbols", "char": "\u2764\uFE0F\u200D\uD83D\uDD25", "name": "heart_on_fire", "keywords": [] }, + { "category": "symbols", "char": "\u2764\uFE0F\u200D\uD83E\uDE79", "name": "mending_heart", "keywords": [] }, { "category": "symbols", "char": "☮", "name": "peace_symbol", "keywords": ["hippie"] }, { "category": "symbols", "char": "✝", "name": "latin_cross", "keywords": ["christianity"] }, { "category": "symbols", "char": "☪", "name": "star_and_crescent", "keywords": ["islam"] }, diff --git a/src/misc/emoji-regex.ts b/src/misc/emoji-regex.ts index 9f9c360ff..8b07fbd8f 100644 --- a/src/misc/emoji-regex.ts +++ b/src/misc/emoji-regex.ts @@ -1,4 +1,3 @@ -// https://github.com/twitter/twemoji-parser/blob/master/src/lib/regex.js d1ea6ccfb72735698f4994e7015accc447eeac8e -export const emojiRegex = /((?:\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f)/; +const twemojiRegex = require('twemoji-parser/dist/lib/regex').default; -export const emojiRegexWithCustom = new RegExp(`(${emojiRegex.source}|:[0-9A-Za-z_]+:)`, 'g'); +export const emojiRegex = new RegExp(`(${twemojiRegex.source})`); diff --git a/src/misc/populate-emojis.ts b/src/misc/populate-emojis.ts index 8052c7148..42aaaf070 100644 --- a/src/misc/populate-emojis.ts +++ b/src/misc/populate-emojis.ts @@ -5,6 +5,8 @@ import { Note } from '../models/entities/note'; import { Cache } from './cache'; import { isSelfHost, toPunyNullable } from './convert-host'; import { decodeReaction } from './reaction-lib'; +import config from '@/config'; +import { query } from '@/prelude/url'; const cache = new Cache(1000 * 60 * 60 * 12); @@ -59,9 +61,12 @@ export async function populateEmoji(emojiName: string, noteUserHost: string | nu if (emoji == null) return null; + const isLocal = emoji.host == null; + const url = isLocal ? emoji.url : `${config.url}/proxy/image.png?${query({url: emoji.url})}`; + return { name: emojiName, - url: emoji.url, + url, }; } diff --git a/src/models/repositories/drive-file.ts b/src/models/repositories/drive-file.ts index 590079fe4..92bf12a4e 100644 --- a/src/models/repositories/drive-file.ts +++ b/src/models/repositories/drive-file.ts @@ -59,6 +59,7 @@ export class DriveFileRepository extends Repository { const { sum } = await this .createQueryBuilder('file') .where('file.userId = :id', { id: id }) + .andWhere('file.isLink = FALSE') .select('SUM(file.size)', 'sum') .getRawOne(); @@ -69,6 +70,7 @@ export class DriveFileRepository extends Repository { const { sum } = await this .createQueryBuilder('file') .where('file.userHost = :host', { host: toPuny(host) }) + .andWhere('file.isLink = FALSE') .select('SUM(file.size)', 'sum') .getRawOne(); @@ -79,6 +81,7 @@ export class DriveFileRepository extends Repository { const { sum } = await this .createQueryBuilder('file') .where('file.userHost IS NULL') + .andWhere('file.isLink = FALSE') .select('SUM(file.size)', 'sum') .getRawOne(); @@ -89,6 +92,7 @@ export class DriveFileRepository extends Repository { const { sum } = await this .createQueryBuilder('file') .where('file.userHost IS NOT NULL') + .andWhere('file.isLink = FALSE') .select('SUM(file.size)', 'sum') .getRawOne(); diff --git a/src/remote/activitypub/kernel/accept/index.ts b/src/remote/activitypub/kernel/accept/index.ts index 083e312a6..79cdbb2ef 100644 --- a/src/remote/activitypub/kernel/accept/index.ts +++ b/src/remote/activitypub/kernel/accept/index.ts @@ -1,12 +1,12 @@ import Resolver from '../../resolver'; import { IRemoteUser } from '../../../../models/entities/user'; import acceptFollow from './follow'; -import { IAccept, IFollow } from '../../type'; +import { IAccept, isFollow, getApType } from '../../type'; import { apLogger } from '../../logger'; const logger = apLogger; -export default async (actor: IRemoteUser, activity: IAccept): Promise => { +export default async (actor: IRemoteUser, activity: IAccept): Promise => { const uri = activity.id || activity; logger.info(`Accept: ${uri}`); @@ -18,13 +18,7 @@ export default async (actor: IRemoteUser, activity: IAccept): Promise => { throw e; }); - switch (object.type) { - case 'Follow': - acceptFollow(actor, object as IFollow); - break; + if (isFollow(object)) return await acceptFollow(actor, object); - default: - logger.warn(`Unknown accept type: ${object.type}`); - break; - } + return `skip: Unknown Accept type: ${getApType(object)}`; }; diff --git a/src/remote/activitypub/kernel/create/index.ts b/src/remote/activitypub/kernel/create/index.ts index 108cfedf4..f1a3ebff4 100644 --- a/src/remote/activitypub/kernel/create/index.ts +++ b/src/remote/activitypub/kernel/create/index.ts @@ -1,7 +1,7 @@ import Resolver from '../../resolver'; import { IRemoteUser } from '../../../../models/entities/user'; import createNote from './note'; -import { ICreate, getApId, validPost } from '../../type'; +import { ICreate, getApId, isPost, getApType } from '../../type'; import { apLogger } from '../../logger'; import { toArray, concat, unique } from '../../../../prelude/array'; @@ -35,9 +35,9 @@ export default async (actor: IRemoteUser, activity: ICreate): Promise => { throw e; }); - if (validPost.includes(object.type)) { + if (isPost(object)) { createNote(resolver, actor, object, false, activity); } else { - logger.warn(`Unknown type: ${object.type}`); + logger.warn(`Unknown type: ${getApType(object)}`); } }; diff --git a/src/remote/activitypub/kernel/reject/index.ts b/src/remote/activitypub/kernel/reject/index.ts index 96e9aadf5..d7a80fce7 100644 --- a/src/remote/activitypub/kernel/reject/index.ts +++ b/src/remote/activitypub/kernel/reject/index.ts @@ -1,12 +1,12 @@ import Resolver from '../../resolver'; import { IRemoteUser } from '../../../../models/entities/user'; import rejectFollow from './follow'; -import { IReject, IFollow } from '../../type'; +import { IReject, isFollow, getApType } from '../../type'; import { apLogger } from '../../logger'; const logger = apLogger; -export default async (actor: IRemoteUser, activity: IReject): Promise => { +export default async (actor: IRemoteUser, activity: IReject): Promise => { const uri = activity.id || activity; logger.info(`Reject: ${uri}`); @@ -18,13 +18,7 @@ export default async (actor: IRemoteUser, activity: IReject): Promise => { throw e; }); - switch (object.type) { - case 'Follow': - rejectFollow(actor, object as IFollow); - break; + if (isFollow(object)) return await rejectFollow(actor, object); - default: - logger.warn(`Unknown reject type: ${object.type}`); - break; - } + return `skip: Unknown Reject type: ${getApType(object)}`; }; diff --git a/src/remote/activitypub/kernel/undo/announce.ts b/src/remote/activitypub/kernel/undo/announce.ts index 38ce5b6c5..e08fea188 100644 --- a/src/remote/activitypub/kernel/undo/announce.ts +++ b/src/remote/activitypub/kernel/undo/announce.ts @@ -3,14 +3,15 @@ import { IRemoteUser } from '../../../../models/entities/user'; import { IAnnounce, getApId } from '../../type'; import deleteNote from '../../../../services/note/delete'; -export const undoAnnounce = async (actor: IRemoteUser, activity: IAnnounce): Promise => { +export const undoAnnounce = async (actor: IRemoteUser, activity: IAnnounce): Promise => { const uri = getApId(activity); const note = await Notes.findOne({ uri }); - if (!note) return; + if (!note) return 'skip: no such Announce'; await deleteNote(actor, note); + return 'ok: deleted'; }; diff --git a/src/remote/activitypub/kernel/undo/index.ts b/src/remote/activitypub/kernel/undo/index.ts index 93909352d..0bab3c966 100644 --- a/src/remote/activitypub/kernel/undo/index.ts +++ b/src/remote/activitypub/kernel/undo/index.ts @@ -1,5 +1,5 @@ import { IRemoteUser } from '../../../../models/entities/user'; -import { IUndo, IFollow, IBlock, ILike, IAnnounce } from '../../type'; +import { IUndo, isFollow, isBlock, isLike, isAnnounce, getApType } from '../../type'; import unfollow from './follow'; import unblock from './block'; import undoLike from './like'; @@ -9,7 +9,7 @@ import { apLogger } from '../../logger'; const logger = apLogger; -export default async (actor: IRemoteUser, activity: IUndo): Promise => { +export default async (actor: IRemoteUser, activity: IUndo): Promise => { if ('actor' in activity && actor.uri !== activity.actor) { throw new Error('invalid actor'); } @@ -25,20 +25,10 @@ export default async (actor: IRemoteUser, activity: IUndo): Promise => { throw e; }); - switch (object.type) { - case 'Follow': - unfollow(actor, object as IFollow); - break; - case 'Block': - unblock(actor, object as IBlock); - break; - case 'Like': - case 'EmojiReaction': - case 'EmojiReact': - undoLike(actor, object as ILike); - break; - case 'Announce': - undoAnnounce(actor, object as IAnnounce); - break; - } + if (isFollow(object)) return await unfollow(actor, object); + if (isBlock(object)) return await unblock(actor, object); + if (isLike(object)) return await undoLike(actor, object); + if (isAnnounce(object)) return await undoAnnounce(actor, object); + + return `skip: unknown object type ${getApType(object)}`; }; diff --git a/src/remote/activitypub/kernel/update/index.ts b/src/remote/activitypub/kernel/update/index.ts index ea7e6a063..6dd3e5f29 100644 --- a/src/remote/activitypub/kernel/update/index.ts +++ b/src/remote/activitypub/kernel/update/index.ts @@ -1,5 +1,5 @@ import { IRemoteUser } from '../../../../models/entities/user'; -import { IUpdate, validActor } from '../../type'; +import { getApType, IUpdate, isActor } from '../../type'; import { apLogger } from '../../logger'; import { updateQuestion } from '../../models/question'; import Resolver from '../../resolver'; @@ -22,13 +22,13 @@ export default async (actor: IRemoteUser, activity: IUpdate): Promise => throw e; }); - if (validActor.includes(object.type)) { + if (isActor(object)) { await updatePerson(actor.uri!, resolver, object); return `ok: Person updated`; - } else if (object.type === 'Question') { + } else if (getApType(object) === 'Question') { await updateQuestion(object).catch(e => console.log(e)); return `ok: Question updated`; } else { - return `skip: Unknown type: ${object.type}`; + return `skip: Unknown type: ${getApType(object)}`; } }; diff --git a/src/remote/activitypub/models/image.ts b/src/remote/activitypub/models/image.ts index 79fc2bf4a..7bec1d603 100644 --- a/src/remote/activitypub/models/image.ts +++ b/src/remote/activitypub/models/image.ts @@ -28,7 +28,7 @@ export async function createImage(actor: IRemoteUser, value: any): Promise normalizeForSearch(tag)).splice(0, 32); - const isBot = object.type === 'Service'; + const isBot = getApType(object) === 'Service'; const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/); @@ -337,7 +337,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint emojis: emojiNames, name: person.name, tags, - isBot: object.type === 'Service', + isBot: getApType(object) === 'Service', isCat: (person as any).isCat === true, isLocked: !!person.manuallyApprovesFollowers, isExplorable: !!person.discoverable, @@ -476,7 +476,7 @@ export async function updateFeatured(userId: User['id']) { // Resolve and regist Notes const limit = promiseLimit(2); const featuredNotes = await Promise.all(items - .filter(item => item.type === 'Note') + .filter(item => getApType(item) === 'Note') // TODO: Noteでなくてもいいかも .slice(0, 5) .map(item => limit(() => resolveNote(item, resolver)))); diff --git a/src/remote/activitypub/renderer/document.ts b/src/remote/activitypub/renderer/document.ts index 4f6ea8c4e..f6e9dca45 100644 --- a/src/remote/activitypub/renderer/document.ts +++ b/src/remote/activitypub/renderer/document.ts @@ -4,5 +4,6 @@ import { DriveFiles } from '../../../models'; export default (file: DriveFile) => ({ type: 'Document', mediaType: file.type, - url: DriveFiles.getPublicUrl(file) + url: DriveFiles.getPublicUrl(file), + name: file.comment, }); diff --git a/src/remote/activitypub/renderer/image.ts b/src/remote/activitypub/renderer/image.ts index ce98f98c6..cbd4fbbe6 100644 --- a/src/remote/activitypub/renderer/image.ts +++ b/src/remote/activitypub/renderer/image.ts @@ -4,5 +4,6 @@ import { DriveFiles } from '../../../models'; export default (file: DriveFile) => ({ type: 'Image', url: DriveFiles.getPublicUrl(file), - sensitive: file.isSensitive + sensitive: file.isSensitive, + name: file.comment }); diff --git a/src/remote/activitypub/type.ts b/src/remote/activitypub/type.ts index db866ae67..98025da90 100644 --- a/src/remote/activitypub/type.ts +++ b/src/remote/activitypub/type.ts @@ -3,7 +3,7 @@ export type ApObject = IObject | string | (IObject | string)[]; export interface IObject { '@context': string | obj | obj[]; - type: string; + type: string | unknown[]; id?: string; summary?: string; published?: string; @@ -51,6 +51,15 @@ export function getApId(value: string | IObject): string { throw new Error(`cannot detemine id`); } +/** + * Get ActivityStreams Object type + */ +export function getApType(value: IObject): string { + if (typeof value.type === 'string') return value.type; + if (Array.isArray(value.type) && typeof value.type[0] === 'string') return value.type[0]; + throw new Error(`cannot detect type`); +} + export function getOneApHrefNullable(value: ApObject | undefined): string | undefined { const firstOne = Array.isArray(value) ? value[0] : value; return getApHrefNullable(firstOne); @@ -92,6 +101,9 @@ export interface IOrderedCollection extends IObject { export const validPost = ['Note', 'Question', 'Article', 'Audio', 'Document', 'Image', 'Page', 'Video', 'Event']; +export const isPost = (object: IObject): object is IPost => + validPost.includes(getApType(object)); + export interface IPost extends IObject { type: 'Note' | 'Question' | 'Article' | 'Audio' | 'Document' | 'Image' | 'Page' | 'Video' | 'Event'; _misskey_content?: string; @@ -112,7 +124,7 @@ export interface IQuestion extends IObject { } export const isQuestion = (object: IObject): object is IQuestion => - object.type === 'Note' || object.type === 'Question'; + getApType(object) === 'Note' || getApType(object) === 'Question'; interface IQuestionChoice { name?: string; @@ -126,10 +138,13 @@ export interface ITombstone extends IObject { } export const isTombstone = (object: IObject): object is ITombstone => - object.type === 'Tombstone'; + getApType(object) === 'Tombstone'; export const validActor = ['Person', 'Service', 'Group', 'Organization', 'Application']; +export const isActor = (object: IObject): object is IPerson => + validActor.includes(getApType(object)); + export interface IPerson extends IObject { type: 'Person' | 'Service' | 'Organization' | 'Group' | 'Application'; name?: string; @@ -154,10 +169,10 @@ export interface IPerson extends IObject { } export const isCollection = (object: IObject): object is ICollection => - object.type === 'Collection'; + getApType(object) === 'Collection'; export const isOrderedCollection = (object: IObject): object is IOrderedCollection => - object.type === 'OrderedCollection'; + getApType(object) === 'OrderedCollection'; export const isCollectionOrOrderedCollection = (object: IObject): object is ICollection | IOrderedCollection => isCollection(object) || isOrderedCollection(object); @@ -171,7 +186,7 @@ export interface IApPropertyValue extends IObject { export const isPropertyValue = (object: IObject): object is IApPropertyValue => object && - object.type === 'PropertyValue' && + getApType(object) === 'PropertyValue' && typeof object.name === 'string' && typeof (object as any).value === 'string'; @@ -181,7 +196,7 @@ export interface IApMention extends IObject { } export const isMention = (object: IObject): object is IApMention=> - object.type === 'Mention' && + getApType(object) === 'Mention' && typeof object.href === 'string'; export interface IApHashtag extends IObject { @@ -190,7 +205,7 @@ export interface IApHashtag extends IObject { } export const isHashtag = (object: IObject): object is IApHashtag => - object.type === 'Hashtag' && + getApType(object) === 'Hashtag' && typeof object.name === 'string'; export interface IApEmoji extends IObject { @@ -199,7 +214,7 @@ export interface IApEmoji extends IObject { } export const isEmoji = (object: IObject): object is IApEmoji => - object.type === 'Emoji' && !Array.isArray(object.icon) && object.icon.url != null; + getApType(object) === 'Emoji' && !Array.isArray(object.icon) && object.icon.url != null; export interface ICreate extends IActivity { type: 'Create'; @@ -258,17 +273,17 @@ export interface IFlag extends IActivity { type: 'Flag'; } -export const isCreate = (object: IObject): object is ICreate => object.type === 'Create'; -export const isDelete = (object: IObject): object is IDelete => object.type === 'Delete'; -export const isUpdate = (object: IObject): object is IUpdate => object.type === 'Update'; -export const isRead = (object: IObject): object is IRead => object.type === 'Read'; -export const isUndo = (object: IObject): object is IUndo => object.type === 'Undo'; -export const isFollow = (object: IObject): object is IFollow => object.type === 'Follow'; -export const isAccept = (object: IObject): object is IAccept => object.type === 'Accept'; -export const isReject = (object: IObject): object is IReject => object.type === 'Reject'; -export const isAdd = (object: IObject): object is IAdd => object.type === 'Add'; -export const isRemove = (object: IObject): object is IRemove => object.type === 'Remove'; -export const isLike = (object: IObject): object is ILike => object.type === 'Like' || object.type === 'EmojiReaction' || object.type === 'EmojiReact'; -export const isAnnounce = (object: IObject): object is IAnnounce => object.type === 'Announce'; -export const isBlock = (object: IObject): object is IBlock => object.type === 'Block'; -export const isFlag = (object: IObject): object is IFlag => object.type === 'Flag'; +export const isCreate = (object: IObject): object is ICreate => getApType(object) === 'Create'; +export const isDelete = (object: IObject): object is IDelete => getApType(object) === 'Delete'; +export const isUpdate = (object: IObject): object is IUpdate => getApType(object) === 'Update'; +export const isRead = (object: IObject): object is IRead => getApType(object) === 'Read'; +export const isUndo = (object: IObject): object is IUndo => getApType(object) === 'Undo'; +export const isFollow = (object: IObject): object is IFollow => getApType(object) === 'Follow'; +export const isAccept = (object: IObject): object is IAccept => getApType(object) === 'Accept'; +export const isReject = (object: IObject): object is IReject => getApType(object) === 'Reject'; +export const isAdd = (object: IObject): object is IAdd => getApType(object) === 'Add'; +export const isRemove = (object: IObject): object is IRemove => getApType(object) === 'Remove'; +export const isLike = (object: IObject): object is ILike => getApType(object) === 'Like' || getApType(object) === 'EmojiReaction' || getApType(object) === 'EmojiReact'; +export const isAnnounce = (object: IObject): object is IAnnounce => getApType(object) === 'Announce'; +export const isBlock = (object: IObject): object is IBlock => getApType(object) === 'Block'; +export const isFlag = (object: IObject): object is IFlag => getApType(object) === 'Flag'; diff --git a/src/server/api/define.ts b/src/server/api/define.ts index 432d5017e..cba69cfdc 100644 --- a/src/server/api/define.ts +++ b/src/server/api/define.ts @@ -5,6 +5,8 @@ import { ApiError } from './error'; import { SchemaType } from '@/misc/schema'; import { AccessToken } from '../../models/entities/access-token'; +type NonOptional = T extends undefined ? never : T; + type SimpleUserInfo = { id: ILocalUser['id']; host: ILocalUser['host']; @@ -17,11 +19,12 @@ type SimpleUserInfo = { isSilenced: ILocalUser['isSilenced']; }; -// TODO: defaultが設定されている場合はその型も考慮する type Params = { [P in keyof T['params']]: NonNullable[P]['transform'] extends Function ? ReturnType[P]['transform']> - : ReturnType[P]['validator']['get']>[0]; + : NonNullable[P]['default'] extends null | number | string + ? NonOptional[P]['validator']['get']>[0]> + : ReturnType[P]['validator']['get']>[0]; }; export type Response = Record | void; diff --git a/src/server/api/endpoints/ap/show.ts b/src/server/api/endpoints/ap/show.ts index 2ce11160e..b4df1ad4d 100644 --- a/src/server/api/endpoints/ap/show.ts +++ b/src/server/api/endpoints/ap/show.ts @@ -10,7 +10,7 @@ import { Users, Notes } from '../../../../models'; import { Note } from '../../../../models/entities/note'; import { User } from '../../../../models/entities/user'; import { fetchMeta } from '@/misc/fetch-meta'; -import { validActor, validPost } from '../../../../remote/activitypub/type'; +import { isActor, isPost, getApId } from '../../../../remote/activitypub/type'; export const meta = { tags: ['federation'], @@ -154,16 +154,16 @@ async function fetchAny(uri: string) { } // それでもみつからなければ新規であるため登録 - if (validActor.includes(object.type)) { - const user = await createPerson(object.id); + if (isActor(object)) { + const user = await createPerson(getApId(object)); return { type: 'User', object: await Users.pack(user, null, { detail: true }) }; } - if (validPost.includes(object.type)) { - const note = await createNote(object.id, undefined, true); + if (isPost(object)) { + const note = await createNote(getApId(object), undefined, true); return { type: 'Note', object: await Notes.pack(note!, null, { detail: true }) diff --git a/src/server/api/endpoints/drive/files/update.ts b/src/server/api/endpoints/drive/files/update.ts index 6eda83967..f740fea67 100644 --- a/src/server/api/endpoints/drive/files/update.ts +++ b/src/server/api/endpoints/drive/files/update.ts @@ -49,6 +49,14 @@ export const meta = { 'ja-JP': 'このメディアが「閲覧注意」(NSFW)かどうか', 'en-US': 'Whether this media is NSFW' } + }, + + comment: { + validator: $.optional.nullable.str, + default: undefined as any, + desc: { + 'ja-JP': 'コメント' + } } }, @@ -92,6 +100,8 @@ export default define(meta, async (ps, user) => { if (ps.name) file.name = ps.name; + if (ps.comment !== undefined) file.comment = ps.comment; + if (ps.isSensitive !== undefined) file.isSensitive = ps.isSensitive; if (ps.folderId !== undefined) { @@ -113,6 +123,7 @@ export default define(meta, async (ps, user) => { await DriveFiles.update(file.id, { name: file.name, + comment: file.comment, folderId: file.folderId, isSensitive: file.isSensitive }); diff --git a/src/server/api/endpoints/gallery/posts/create.ts b/src/server/api/endpoints/gallery/posts/create.ts index d1ae68b12..ed24a45f8 100644 --- a/src/server/api/endpoints/gallery/posts/create.ts +++ b/src/server/api/endpoints/gallery/posts/create.ts @@ -6,6 +6,7 @@ import { DriveFiles, GalleryPosts } from '../../../../../models'; import { genId } from '../../../../../misc/gen-id'; import { GalleryPost } from '../../../../../models/entities/gallery-post'; import { ApiError } from '../../../error'; +import { DriveFile } from '@/models/entities/drive-file'; export const meta = { tags: ['gallery'], @@ -55,7 +56,7 @@ export default define(meta, async (ps, user) => { id: fileId, userId: user.id }) - ))).filter(file => file != null); + ))).filter((file): file is DriveFile => file != null); if (files.length === 0) { throw new Error(); diff --git a/src/server/api/endpoints/gallery/posts/update.ts b/src/server/api/endpoints/gallery/posts/update.ts index c8bb8d48c..d9176ea40 100644 --- a/src/server/api/endpoints/gallery/posts/update.ts +++ b/src/server/api/endpoints/gallery/posts/update.ts @@ -5,6 +5,7 @@ import { ID } from '../../../../../misc/cafy-id'; import { DriveFiles, GalleryPosts } from '../../../../../models'; import { GalleryPost } from '../../../../../models/entities/gallery-post'; import { ApiError } from '../../../error'; +import { DriveFile } from '@/models/entities/drive-file'; export const meta = { tags: ['gallery'], @@ -58,7 +59,7 @@ export default define(meta, async (ps, user) => { id: fileId, userId: user.id }) - ))).filter(file => file != null); + ))).filter((file): file is DriveFile => file != null); if (files.length === 0) { throw new Error(); diff --git a/src/server/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts index b481fdba8..a10dc09df 100644 --- a/src/server/api/endpoints/i/notifications.ts +++ b/src/server/api/endpoints/i/notifications.ts @@ -5,6 +5,7 @@ import define from '../../define'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { Notifications, Followings, Mutings, Users } from '../../../../models'; import { notificationTypes } from '../../../../types'; +import read from '@/services/note/read'; export const meta = { desc: { @@ -103,9 +104,9 @@ export default define(meta, async (ps, user) => { query.setParameters(followingQuery.getParameters()); } - if (ps.includeTypes?.length > 0) { + if (ps.includeTypes && ps.includeTypes.length > 0) { query.andWhere(`notification.type IN (:...includeTypes)`, { includeTypes: ps.includeTypes }); - } else if (ps.excludeTypes?.length > 0) { + } else if (ps.excludeTypes && ps.excludeTypes.length > 0) { query.andWhere(`notification.type NOT IN (:...excludeTypes)`, { excludeTypes: ps.excludeTypes }); } @@ -116,5 +117,11 @@ export default define(meta, async (ps, user) => { readNotification(user.id, notifications.map(x => x.id)); } + const notes = notifications.filter(notification => ['mention', 'reply', 'quote'].includes(notification.type)).map(notification => notification.note!); + + if (notes.length > 0) { + read(user.id, notes); + } + return await Notifications.packMany(notifications, user.id); }); diff --git a/src/server/api/endpoints/notes/search-by-tag.ts b/src/server/api/endpoints/notes/search-by-tag.ts index 61f62dd5a..463c5fff5 100644 --- a/src/server/api/endpoints/notes/search-by-tag.ts +++ b/src/server/api/endpoints/notes/search-by-tag.ts @@ -104,22 +104,25 @@ export default define(meta, async (ps, me) => { generateVisibilityQuery(query, me); if (me) generateMutedUserQuery(query, me); - if (ps.tag) { - if (!safeForSql(ps.tag)) return; - query.andWhere(`'{"${normalizeForSearch(ps.tag)}"}' <@ note.tags`); - } else { - let i = 0; - query.andWhere(new Brackets(qb => { - for (const tags of ps.query!) { - qb.orWhere(new Brackets(qb => { - for (const tag of tags) { - if (!safeForSql(tag)) return; - qb.andWhere(`'{"${normalizeForSearch(ps.tag)}"}' <@ note.tags`); - i++; - } - })); - } - })); + try { + if (ps.tag) { + if (!safeForSql(ps.tag)) throw 'Injection'; + query.andWhere(`'{"${normalizeForSearch(ps.tag)}"}' <@ note.tags`); + } else { + query.andWhere(new Brackets(qb => { + for (const tags of ps.query!) { + qb.orWhere(new Brackets(qb => { + for (const tag of tags) { + if (!safeForSql(tag)) throw 'Injection'; + qb.andWhere(`'{"${normalizeForSearch(tag)}"}' <@ note.tags`); + } + })); + } + })); + } + } catch (e) { + if (e === 'Injection') return []; + throw e; } if (ps.reply != null) { diff --git a/src/services/chart/core.ts b/src/services/chart/core.ts index d956d33bd..4a554daa7 100644 --- a/src/services/chart/core.ts +++ b/src/services/chart/core.ts @@ -93,7 +93,7 @@ export default abstract class Chart> { } @autobind - private static convertFlattenColumnsToObject(x: Record) { + private static convertFlattenColumnsToObject(x: Record): Record { const obj = {} as any; for (const k of Object.keys(x).filter(k => k.startsWith(Chart.columnPrefix))) { // now k is ___x_y_z @@ -285,8 +285,7 @@ export default abstract class Chart> { const latest = await this.getLatestLog(group); if (latest != null) { - const obj = Chart.convertFlattenColumnsToObject( - latest as Record); + const obj = Chart.convertFlattenColumnsToObject(latest) as T; // 空ログデータを作成 data = this.getNewLog(obj); @@ -474,13 +473,13 @@ export default abstract class Chart> { const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current)); if (log) { - const data = Chart.convertFlattenColumnsToObject(log as Record); - chart.unshift(Chart.countUniqueFields(data)); + const data = Chart.convertFlattenColumnsToObject(log); + chart.unshift(Chart.countUniqueFields(data) as T); } else { // 隙間埋め const latest = logs.find(l => isTimeBefore(new Date(l.date * 1000), current)); - const data = latest ? Chart.convertFlattenColumnsToObject(latest as Record) : null; - chart.unshift(Chart.countUniqueFields(this.getNewLog(data))); + const data = latest ? Chart.convertFlattenColumnsToObject(latest) as T : null; + chart.unshift(Chart.countUniqueFields(this.getNewLog(data)) as T); } } } else if (span === 'day') { @@ -497,14 +496,14 @@ export default abstract class Chart> { if (log) { if (logsForEachDays[currentDayIndex]) { - logsForEachDays[currentDayIndex].unshift(Chart.convertFlattenColumnsToObject(log)); + logsForEachDays[currentDayIndex].unshift(Chart.convertFlattenColumnsToObject(log) as T); } else { - logsForEachDays[currentDayIndex] = [Chart.convertFlattenColumnsToObject(log)]; + logsForEachDays[currentDayIndex] = [Chart.convertFlattenColumnsToObject(log) as T]; } } else { // 隙間埋め const latest = logs.find(l => isTimeBefore(new Date(l.date * 1000), current)); - const data = latest ? Chart.convertFlattenColumnsToObject(latest as Record) : null; + const data = latest ? Chart.convertFlattenColumnsToObject(latest) as T : null; const newLog = this.getNewLog(data); if (logsForEachDays[currentDayIndex]) { logsForEachDays[currentDayIndex].unshift(newLog); @@ -516,7 +515,7 @@ export default abstract class Chart> { for (const logs of logsForEachDays) { const log = this.aggregate(logs); - chart.unshift(Chart.countUniqueFields(log)); + chart.unshift(Chart.countUniqueFields(log) as T); } } diff --git a/src/services/drive/add-file.ts b/src/services/drive/add-file.ts index ad9f753e7..2356a23cb 100644 --- a/src/services/drive/add-file.ts +++ b/src/services/drive/add-file.ts @@ -267,7 +267,8 @@ async function upload(key: string, stream: fs.ReadStream | Buffer, type: string, async function deleteOldFile(user: IRemoteUser) { const q = DriveFiles.createQueryBuilder('file') - .where('file.userId = :userId', { userId: user.id }); + .where('file.userId = :userId', { userId: user.id }) + .andWhere('file.isLink = FALSE'); if (user.avatarId) { q.andWhere('file.id != :avatarId', { avatarId: user.avatarId }); diff --git a/src/services/drive/delete-file.ts b/src/services/drive/delete-file.ts index bb9c0ae2c..2dd244532 100644 --- a/src/services/drive/delete-file.ts +++ b/src/services/drive/delete-file.ts @@ -79,7 +79,7 @@ async function postProcess(file: DriveFile, isExpired = false) { url: file.uri, thumbnailUrl: null, webpublicUrl: null, - size: 0, + storedInternal: false, // ローカルプロキシ用 accessKey: uuid(), thumbnailAccessKey: 'thumbnail-' + uuid(), diff --git a/src/services/drive/upload-from-url.ts b/src/services/drive/upload-from-url.ts index 2f4c5aeea..2f660d903 100644 --- a/src/services/drive/upload-from-url.ts +++ b/src/services/drive/upload-from-url.ts @@ -25,6 +25,12 @@ export default async ( name = null; } + // If the comment is same as the name, skip comment + // (image.name is passed in when receiving attachment) + if (comment !== null && name == comment) { + comment = null; + } + // Create temp file const [path, cleanup] = await createTemp(); diff --git a/yarn.lock b/yarn.lock index 3d8430564..2d9284c4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -395,10 +395,10 @@ dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@7.0.5": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.0.5.tgz#558a7f8145a01366c44b3dcbdd7172c05c461564" - integrity sha512-fUt6b15bjV/VW93UP5opNXJxdwZSbK1EdiwnhN7XrQrcpaOhMJpZ/CjwFpM3THpxwA+YviBUJKSuEqKlCK5alw== +"@sinonjs/fake-timers@7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" + integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== dependencies: "@sinonjs/commons" "^1.7.0" @@ -440,6 +440,26 @@ resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.1.1.tgz#3348564048e7a2d7398c935d466c0414ebb6a669" integrity sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow== +"@tsconfig/node10@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.7.tgz#1eb1de36c73478a2479cc661ef5af1c16d86d606" + integrity sha512-aBvUmXLQbayM4w3A8TrjwrXs4DZ8iduJnuJLLRGdkWlyakCf1q6uHZJBzXoRA/huAEknG5tcUyQxN3A+In5euQ== + +"@tsconfig/node12@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.7.tgz#677bd9117e8164dc319987dd6ff5fc1ba6fbf18b" + integrity sha512-dgasobK/Y0wVMswcipr3k0HpevxFJLijN03A8mYfEPvWvOs14v0ZlYTR4kIgMx8g4+fTyTFv8/jLCIfRqLDJ4A== + +"@tsconfig/node14@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.0.tgz#5bd046e508b1ee90bc091766758838741fdefd6e" + integrity sha512-RKkL8eTdPv6t5EHgFKIVQgsDapugbuOptNd9OOunN/HAkzmmTnZELx1kNCK0rSdUYGmiFMM3rRQMAWiyp023LQ== + +"@tsconfig/node16@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.1.tgz#a6ca6a9a0ff366af433f42f5f0e124794ff6b8f1" + integrity sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA== + "@types/accepts@*": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" @@ -783,14 +803,14 @@ dependencies: "@types/koa" "*" -"@types/koa-views@2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/koa-views/-/koa-views-2.0.4.tgz#3fa87ba13174f9816c6f7701fbf129dfe9855e39" - integrity sha512-aGFBVLiPC7FkXTqHLhnmjKhx3COV+GeJHO9OkLX/p/iAQTgDB5bbnsddx3XgrS6aACWyxR3BpQJVDdSqCNY1lw== +"@types/koa-views@7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@types/koa-views/-/koa-views-7.0.0.tgz#5613450c77ab69c980c47104378da4b7669c5f2e" + integrity sha512-AB/NB+oFHcLOZJYFv3bG5Af8YbwYCD9/zK0WcKALsbjI/FRKrcXTUTC64RebDrkyOkBm3bpCgpGndhAH/3YQ2Q== dependencies: - "@types/koa" "*" + koa-views "*" -"@types/koa@*", "@types/koa@2.13.1", "@types/koa@^2.13.1": +"@types/koa@*", "@types/koa@^2.13.1": version "2.13.1" resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.1.tgz#e29877a6b5ad3744ab1024f6ec75b8cbf6ec45db" integrity sha512-Qbno7FWom9nNqu0yHZ6A0+RWt4mrYBhw3wpBAQ3+IuzGcLlfeYkzZrnMq5wsxulN2np8M4KKeUpTodsOsSad5Q== @@ -804,6 +824,20 @@ "@types/koa-compose" "*" "@types/node" "*" +"@types/koa@2.13.3": + version "2.13.3" + resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.3.tgz#5b44c0956d7f7bf41f74ccfb530fec60fbed45ca" + integrity sha512-TaujBV+Dhe/FvmSMZJtCFBms+bqQacgUebk/M2C2tq8iGmHE/DDf4DcW2Hc7NqusVZmy5xzrWOjtdPKNP+fTfw== + dependencies: + "@types/accepts" "*" + "@types/content-disposition" "*" + "@types/cookies" "*" + "@types/http-assert" "*" + "@types/http-errors" "*" + "@types/keygrip" "*" + "@types/koa-compose" "*" + "@types/node" "*" + "@types/koa__cors@3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@types/koa__cors/-/koa__cors-3.0.2.tgz#578917ffca964e98f5e9849996ae1eeda7c15704" @@ -877,10 +911,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055" integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g== -"@types/node@15.3.1": - version "15.3.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-15.3.1.tgz#23a06b87eedb524016616e886b116b8fdcb180af" - integrity sha512-weaeiP4UF4XgF++3rpQhpIJWsCTS4QJw5gvBhQu6cFIxTwyxWIe3xbnrY/o2lTCQ0lsdb8YIUDUvLR4Vuz5rbw== +"@types/node@15.6.1": + version "15.6.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.1.tgz#32d43390d5c62c5b6ec486a9bc9c59544de39a08" + integrity sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA== "@types/node@^14.11.8": version "14.14.44" @@ -892,10 +926,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.0.tgz#3ba770047723b3eeb8dc9fca02cce8a7fb6378da" integrity sha512-w8VZUN/f7SSbvVReb9SWp6cJFevxb4/nkG65yLAya//98WgocKm5PLDAtSs5CtJJJM+kHmJjO/6mmYW4MHShZA== -"@types/nodemailer@6.4.1": - version "6.4.1" - resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.1.tgz#31f96f4410632f781d3613bd1f4293649e423f75" - integrity sha512-8081UY/0XTTDpuGqCnDc8IY+Q3DSg604wB3dBH0CaZlj4nZWHWuxtZ3NRZ9c9WUrz1Vfm6wioAUnqL3bsh49uQ== +"@types/nodemailer@6.4.2": + version "6.4.2" + resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.2.tgz#d8ee254c969e6ad83fb9a0a0df3a817406a3fa3b" + integrity sha512-yhsqg5Xbr8aWdwjFS3QjkniW5/tLpWXtOYQcJdo9qE3DolBxsKzgRCQrteaMY0hos8MklJNSEsMqDpZynGzMNg== dependencies: "@types/node" "*" @@ -991,10 +1025,10 @@ "@types/node" "*" safe-buffer "*" -"@types/redis@2.8.28": - version "2.8.28" - resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.28.tgz#5862b2b64aa7f7cbc76dafd7e6f06992b52c55e3" - integrity sha512-8l2gr2OQ969ypa7hFOeKqtFoY70XkHxISV0pAwmQ2nm6CSPb1brmTmqJCGGrekCo+pAZyWlNXr+Kvo6L/1wijA== +"@types/redis@2.8.29": + version "2.8.29" + resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.29.tgz#f272dba985156e599e2523afb4f5f7e7586b56b5" + integrity sha512-/pjQ9lwnL/t1bEfRHQFEJB3kHCR65tpB19NEWmbqcgGgqrfeGo/9b4tUtHbClxQoy3+g6Esx2QRtV7fk7kBPYg== dependencies: "@types/node" "*" @@ -1038,10 +1072,10 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" -"@types/sharp@0.28.1": - version "0.28.1" - resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.28.1.tgz#dbd702bd6a8d42576b8faffe1c2ec06fdffaaaff" - integrity sha512-Jn9NHCjT3KXjxTpbtaxBI4iL+st5o9pWhMGVpHF+Cs+t/31lohLNXSW9PT9RSl7Ct7yBT2XFu7R/xfo0Y8HH2Q== +"@types/sharp@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.28.2.tgz#75bb9f60714ed752dc88c477ef55310f17c2f08f" + integrity sha512-xXanJalZA3EVSZ49667lBctyao75JiH5tD5/hKYu9u5C3d9rxEqOHvMOtx/oenJUqKKgIwIZEsL0hjmKo2rjJg== dependencies: "@types/node" "*" @@ -1192,48 +1226,48 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== -"@typescript-eslint/parser@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.24.0.tgz#2e5f1cc78ffefe43bfac7e5659309a92b09a51bd" - integrity sha512-dj1ZIh/4QKeECLb2f/QjRwMmDArcwc2WorWPRlB8UNTZlY1KpTVsbX7e3ZZdphfRw29aTFUSNuGB8w9X5sS97w== +"@typescript-eslint/parser@4.25.0": + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.25.0.tgz#6b2cb6285aa3d55bfb263c650739091b0f19aceb" + integrity sha512-OZFa1SKyEJpAhDx8FcbWyX+vLwh7OEtzoo2iQaeWwxucyfbi0mT4DijbOSsTgPKzGHr6GrF2V5p/CEpUH/VBxg== dependencies: - "@typescript-eslint/scope-manager" "4.24.0" - "@typescript-eslint/types" "4.24.0" - "@typescript-eslint/typescript-estree" "4.24.0" + "@typescript-eslint/scope-manager" "4.25.0" + "@typescript-eslint/types" "4.25.0" + "@typescript-eslint/typescript-estree" "4.25.0" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.24.0.tgz#38088216f0eaf235fa30ed8cabf6948ec734f359" - integrity sha512-9+WYJGDnuC9VtYLqBhcSuM7du75fyCS/ypC8c5g7Sdw7pGL4NDTbeH38eJPfzIydCHZDoOgjloxSAA3+4l/zsA== +"@typescript-eslint/scope-manager@4.25.0": + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.25.0.tgz#9d86a5bcc46ef40acd03d85ad4e908e5aab8d4ca" + integrity sha512-2NElKxMb/0rya+NJG1U71BuNnp1TBd1JgzYsldsdA83h/20Tvnf/HrwhiSlNmuq6Vqa0EzidsvkTArwoq+tH6w== dependencies: - "@typescript-eslint/types" "4.24.0" - "@typescript-eslint/visitor-keys" "4.24.0" + "@typescript-eslint/types" "4.25.0" + "@typescript-eslint/visitor-keys" "4.25.0" -"@typescript-eslint/types@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.24.0.tgz#6d0cca2048cbda4e265e0c4db9c2a62aaad8228c" - integrity sha512-tkZUBgDQKdvfs8L47LaqxojKDE+mIUmOzdz7r+u+U54l3GDkTpEbQ1Jp3cNqqAU9vMUCBA1fitsIhm7yN0vx9Q== +"@typescript-eslint/types@4.25.0": + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.25.0.tgz#0e444a5c5e3c22d7ffa5e16e0e60510b3de5af87" + integrity sha512-+CNINNvl00OkW6wEsi32wU5MhHti2J25TJsJJqgQmJu3B3dYDBcmOxcE5w9cgoM13TrdE/5ND2HoEnBohasxRQ== -"@typescript-eslint/typescript-estree@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.24.0.tgz#b49249679a98014d8b03e8d4b70864b950e3c90f" - integrity sha512-kBDitL/by/HK7g8CYLT7aKpAwlR8doshfWz8d71j97n5kUa5caHWvY0RvEUEanL/EqBJoANev8Xc/mQ6LLwXGA== +"@typescript-eslint/typescript-estree@4.25.0": + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.25.0.tgz#942e4e25888736bff5b360d9b0b61e013d0cfa25" + integrity sha512-1B8U07TGNAFMxZbSpF6jqiDs1cVGO0izVkf18Q/SPcUAc9LhHxzvSowXDTvkHMWUVuPpagupaW63gB6ahTXVlg== dependencies: - "@typescript-eslint/types" "4.24.0" - "@typescript-eslint/visitor-keys" "4.24.0" + "@typescript-eslint/types" "4.25.0" + "@typescript-eslint/visitor-keys" "4.25.0" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/visitor-keys@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.24.0.tgz#a8fafdc76cad4e04a681a945fbbac4e35e98e297" - integrity sha512-4ox1sjmGHIxjEDBnMCtWFFhErXtKA1Ec0sBpuz0fqf3P+g3JFGyTxxbF06byw0FRsPnnbq44cKivH7Ks1/0s6g== +"@typescript-eslint/visitor-keys@4.25.0": + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.25.0.tgz#863e7ed23da4287c5b469b13223255d0fde6aaa7" + integrity sha512-AmkqV9dDJVKP/TcZrbf6s6i1zYXt5Hl8qOLrRDTFfRNae4+LB8A4N3i+FLZPW85zIxRy39BgeWOfMS3HoH5ngg== dependencies: - "@typescript-eslint/types" "4.24.0" + "@typescript-eslint/types" "4.25.0" eslint-visitor-keys "^2.0.0" "@ungap/promise-all-settled@1.1.2": @@ -1290,7 +1324,7 @@ "@vue/compiler-dom" "3.0.11" "@vue/shared" "3.0.11" -"@vue/reactivity@3.0.11": +"@vue/reactivity@3.0.11", "@vue/reactivity@^3.0.11": version "3.0.11" resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.11.tgz#07b588349fd05626b17f3500cbef7d4bdb4dbd0b" integrity sha512-SKM3YKxtXHBPMf7yufXeBhCZ4XZDKP9/iXeQSC8bBO3ivBuzAi4aZi0bNoeE2IF2iGfP/AHEt1OU4ARj4ao/Xw== @@ -1525,20 +1559,15 @@ acorn@^8.0.4: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe" integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA== -acorn@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.1.tgz#fb0026885b9ac9f48bac1e185e4af472971149ff" - integrity sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g== - -acorn@^8.2.1: +acorn@^8.2.1, acorn@^8.2.4: version "8.2.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0" integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg== agent-base@6: - version "6.0.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.0.tgz#5d0101f19bbfaed39980b22ae866de153b93f09a" - integrity sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw== + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" @@ -1574,6 +1603,16 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.1: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b" + integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -1899,7 +1938,7 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autobind-decorator@2.4.0: +autobind-decorator@2.4.0, autobind-decorator@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/autobind-decorator/-/autobind-decorator-2.4.0.tgz#ea9e1c98708cf3b5b356f7cf9f10f265ff18239c" integrity sha512-OGYhWUO72V6DafbF8PM8rm3EPbfuyMZcJhtm5/n26IDwO18pohE4eNazLoCGhPiXOCD0gEGmrbU3849QvM8bbw== @@ -1928,10 +1967,10 @@ autwh@0.1.0: dependencies: oauth "0.9.15" -aws-sdk@2.910.0: - version "2.910.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.910.0.tgz#7b5f448c6af2caae6c3c956eb56feea3d6dd9b1a" - integrity sha512-PC4x3qzxXxZEhd4CbcMdso/WnxeQvsiuYXHL+lb5B5d8zdORcXPaNmyIL/2DByyjJ2Ur4tfXgoQVPDKyYLcWEA== +aws-sdk@2.918.0: + version "2.918.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.918.0.tgz#e4323de000262beb762e9c139f89e07282462f17" + integrity sha512-ZjWanOA1Zo664EyWLCnbUlkwCjoRPmSIMx529W4gk1418qo3oCEcvUy1HeibGGIClYnZZ7J4FMQvVDm2+JtHLQ== dependencies: buffer "4.9.2" events "1.1.1" @@ -2182,6 +2221,17 @@ browserslist@^4.16.0: escalade "^3.1.1" node-releases "^1.1.71" +browserslist@^4.16.6: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== + dependencies: + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" + buffer-alloc-unsafe@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" @@ -2378,7 +2428,7 @@ camelcase@^5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0, camelcase@^6.2.0: +camelcase@^6.0.0: version "6.2.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== @@ -2423,6 +2473,11 @@ caniuse-lite@^1.0.30001208: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001208.tgz#a999014a35cebd4f98c405930a057a0d75352eb9" integrity sha512-OE5UE4+nBOro8Dyvv0lfx+SRtfVIOM9uhKqFmJeUbGriqhhStgp1A0OyBpgy3OUF8AhYCT+PVwPC1gMl2ZcQMA== +caniuse-lite@^1.0.30001219: + version "1.0.30001230" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71" + integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ== + canonicalize@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.1.tgz#657b4f3fa38a6ecb97a9e5b7b26d7a19cc6e0da9" @@ -2883,10 +2938,10 @@ color@^3.1.3: color-convert "^1.9.1" color-string "^1.5.4" -colord@^1.7.0: - version "1.7.2" - resolved "https://registry.yarnpkg.com/colord/-/colord-1.7.2.tgz#474f0e46333cb5c7a191dbd571edeee19a5f97b6" - integrity sha512-/sQCxy6PEhZbrAn1+NVRRefy3k4jkWQGxk7mo2o0CoNA24jq4ujDc2jXzJ5uXphm/TwfdGOP0w8U+H+9ys4Peg== +colord@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.0.1.tgz#1e7fb1f9fa1cf74f42c58cb9c20320bab8435aa0" + integrity sha512-vm5YpaWamD0Ov6TSG0GGmUIwstrWcfKQV/h2CmbR7PbNu41+qdB5PW9lpzhjedrpm08uuYvcXi0Oel1RLZIJuA== colorette@^1.2.0, colorette@^1.2.1, colorette@^1.2.2: version "1.2.2" @@ -2975,10 +3030,10 @@ concat-stream@^1.5.2, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" -concurrently@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.1.0.tgz#00d22525d3fcdce7f34cc7f3c9753f90a57d6208" - integrity sha512-jy+xj49pvqeKjc2TAVXRIhrgPG51eBKDZti0kZ41kaWk9iLbyWBjH6KMFpW7peOLkEymD+ZM83Lx6UEy3N/M9g== +concurrently@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.2.0.tgz#587e2cb8afca7234172d8ea55176088632c4c56d" + integrity sha512-v9I4Y3wFoXCSY2L73yYgwA9ESrQMpRn80jMcqMgHx720Hecz2GZAvTI6bREVST6lkddNypDKRN22qhK0X8Y00g== dependencies: chalk "^4.1.0" date-fns "^2.16.1" @@ -3088,10 +3143,10 @@ core-js-compat@^3.9.1: browserslist "^4.16.3" semver "7.0.0" -core-js@3.12.1: - version "3.12.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112" - integrity sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw== +core-js@3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.13.1.tgz#30303fabd53638892062d8b4e802cac7599e9fb7" + integrity sha512-JqveUc4igkqwStL2RTRn/EPFGBOfEZHxJl/8ej1mXJR75V3go2mFF4bmUYkEIT1rveHKnkUlcJX/c+f1TyIovQ== core-util-is@1.0.2, core-util-is@^1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -3174,15 +3229,14 @@ css-declaration-sorter@^6.0.3: dependencies: timsort "^0.3.0" -css-loader@5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.4.tgz#e985dcbce339812cb6104ef3670f08f9893a1536" - integrity sha512-OFYGyINCKkdQsTrSYxzGSFnGS4gNjcXkKkQgWxK138jgnPt+lepxdjSZNc8sHAl5vP3DhsJUxufWIjOwI8PMMw== +css-loader@5.2.6: + version "5.2.6" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.6.tgz#c3c82ab77fea1f360e587d871a6811f4450cc8d1" + integrity sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w== dependencies: - camelcase "^6.2.0" icss-utils "^5.1.0" loader-utils "^2.0.0" - postcss "^8.2.10" + postcss "^8.2.15" postcss-modules-extract-imports "^3.0.0" postcss-modules-local-by-default "^4.0.0" postcss-modules-scope "^3.0.0" @@ -3271,22 +3325,22 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.0.tgz#3ff4a1c102f72c7976580ce7f1c52325dc4628ed" - integrity sha512-VTO0WAlrEsU0u+A4RwALRs5zSVnD23WgYO8Np3HowBMZTqWIP1GvIWWzs9zZmjNgeL8U+70megRZymb+1yGg/w== +cssnano-preset-default@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.2.tgz#5d4877a91769823c5da6bcebd54996ecdf8aca12" + integrity sha512-spilp8LRw0sacuxiN9A/dyyPr6G/WISKMBKcBD4NMoPV0ENx4DeuWvIIrSx9PII2nJIDCO3kywkqTPreECBVOg== dependencies: css-declaration-sorter "^6.0.3" cssnano-utils "^2.0.1" postcss-calc "^8.0.0" - postcss-colormin "^5.1.0" + postcss-colormin "^5.2.0" postcss-convert-values "^5.0.1" postcss-discard-comments "^5.0.1" postcss-discard-duplicates "^5.0.1" postcss-discard-empty "^5.0.1" postcss-discard-overridden "^5.0.1" postcss-merge-longhand "^5.0.2" - postcss-merge-rules "^5.0.1" + postcss-merge-rules "^5.0.2" postcss-minify-font-values "^5.0.1" postcss-minify-gradients "^5.0.1" postcss-minify-params "^5.0.1" @@ -3303,7 +3357,7 @@ cssnano-preset-default@^5.1.0: postcss-ordered-values "^5.0.1" postcss-reduce-initial "^5.0.1" postcss-reduce-transforms "^5.0.1" - postcss-svgo "^5.0.1" + postcss-svgo "^5.0.2" postcss-unique-selectors "^5.0.1" cssnano-utils@^2.0.1: @@ -3311,13 +3365,13 @@ cssnano-utils@^2.0.1: resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2" integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ== -cssnano@5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.3.tgz#3ae26411a176168e7a0ef425f4691579e1aed12a" - integrity sha512-Ga/a+IA6U0F9+MNmqrXgwn1A3btY5jFkla2iurL7i9PTmQmMu2Kc99W9a8KSxT8iLV0aoI+Q5Q9i3SpVAVNnrQ== +cssnano@5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.5.tgz#6b8787123bf4cd5a220a2fa6cb5bc036b0854b48" + integrity sha512-L2VtPXnq6rmcMC9vkBOP131sZu3ccRQI27ejKZdmQiPDpUlFkUbpXHgKN+cibeO1U4PItxVZp1zTIn5dHsXoyg== dependencies: cosmiconfig "^7.0.0" - cssnano-preset-default "^5.1.0" + cssnano-preset-default "^5.1.2" is-resolvable "^1.1.0" cssnano@^3.0.0: @@ -3845,6 +3899,11 @@ electron-to-chromium@^1.3.712: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz#78d4c857070755fb58ab64bcc173db1d51cbc25f" integrity sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ== +electron-to-chromium@^1.3.723: + version "1.3.742" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz#7223215acbbd3a5284962ebcb6df85d88b95f200" + integrity sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q== + emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -4031,7 +4090,7 @@ escape-regexp@0.0.1: resolved "https://registry.yarnpkg.com/escape-regexp/-/escape-regexp-0.0.1.tgz#f44bda12d45bbdf9cb7f862ee7e4827b3dd32254" integrity sha1-9EvaEtRbvfnLf4Yu5+SCez3TIlQ= -escape-string-regexp@4.0.0: +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== @@ -4053,17 +4112,17 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-plugin-vue@7.9.0: - version "7.9.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-7.9.0.tgz#f8e83a2a908f4c43fc8304f5401d4ff671f3d560" - integrity sha512-2Q0qQp5+5h+pZvJKCbG1/jCRUYrdgAz5BYKGyTlp2NU8mx09u3Hp7PsH6d5qef6ojuPoCXMnrbbDxeoplihrSw== +eslint-plugin-vue@7.10.0: + version "7.10.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-7.10.0.tgz#251749aa99e089e085275f011042c6e74189f89a" + integrity sha512-xdr6e4t/L2moRAeEQ9HKgge/hFq+w9v5Dj+BA54nTAzSFdUyKLiSOdZaRQjCHMY0Pk2WaQBFH9QiWG60xiC+6A== dependencies: eslint-utils "^2.1.0" natural-compare "^1.4.0" semver "^7.3.2" vue-eslint-parser "^7.6.0" -eslint-scope@^5.0.0, eslint-scope@^5.1.1: +eslint-scope@5.1.1, eslint-scope@^5.0.0, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -4088,10 +4147,10 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@7.26.0: - version "7.26.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.26.0.tgz#d416fdcdcb3236cd8f282065312813f8c13982f6" - integrity sha512-4R1ieRf52/izcZE7AlLy56uIHHDLT74Yzz2Iv2l6kDaYvEu9x+wMB5dZArVL8SYGXSYV2YAg70FcW5Y5nGGNIg== +eslint@7.27.0: + version "7.27.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.27.0.tgz#665a1506d8f95655c9274d84bd78f7166b07e9c7" + integrity sha512-JZuR6La2ZF0UD384lcbnd0Cgg6QJjiCwhMD6eU4h/VGPcVGwawNNzKU41tgokGXnfjOOyI6QIffthhJTPzzuRA== dependencies: "@babel/code-frame" "7.12.11" "@eslint/eslintrc" "^0.4.1" @@ -4101,12 +4160,14 @@ eslint@7.26.0: debug "^4.0.1" doctrine "^3.0.0" enquirer "^2.3.5" + escape-string-regexp "^4.0.0" eslint-scope "^5.1.1" eslint-utils "^2.1.0" eslint-visitor-keys "^2.0.0" espree "^7.3.1" esquery "^1.4.0" esutils "^2.0.2" + fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" @@ -4118,7 +4179,7 @@ eslint@7.26.0: js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" - lodash "^4.17.21" + lodash.merge "^4.6.2" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" @@ -4127,7 +4188,7 @@ eslint@7.26.0: semver "^7.2.1" strip-ansi "^6.0.0" strip-json-comments "^3.1.0" - table "^6.0.4" + table "^6.0.9" text-table "^0.2.0" v8-compile-cache "^2.0.3" @@ -4203,7 +4264,7 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@4.0.7: +eventemitter3@4.0.7, eventemitter3@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -4342,6 +4403,11 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== +fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + fast-glob@^3.1.1: version "3.2.4" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" @@ -4400,15 +4466,14 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-type@16.4.0: - version "16.4.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.4.0.tgz#464197e44bd94a452d77b09085d977ae0dad2df4" - integrity sha512-MDAkwha3wHg11Lp++2T3Gu347eC/DB4r7nYj6iZaf1l7UhGBh2746QKxg0BWC8w2dJsxUEmH8KvLueX+GthN2w== +file-type@16.5.0: + version "16.5.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.0.tgz#16a2626f3b33bac612f6e81e52216f3a7c8e12a2" + integrity sha512-OxgWA9tbL8N/WP00GD1z8O0MiwQKFyWRs1q+3FhjdvcGgKqwxcejyGWso3n4/IMU6DdwV+ARZ4A7TTnPkDcSiw== dependencies: readable-web-to-node-stream "^3.0.0" strtok3 "^6.0.3" token-types "^2.0.0" - typedarray-to-buffer "^3.1.5" fill-range@^4.0.0: version "4.0.0" @@ -5345,10 +5410,10 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -idb-keyval@5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-5.0.5.tgz#1b02984dcf42ad4aa290bf9f10935b485419df34" - integrity sha512-cqi65rrjhgPExI9vmSU7VcYEbHCUfIBY+9YUWxyr0PyGizptFgGFnvZQ0w+tqOXk1lUcGCZGVLfabf7QnR2S0g== +idb-keyval@5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-5.0.6.tgz#62fe4a6703fb5ec86661f41330c94fda65e6d0e6" + integrity sha512-6lJuVbwyo82mKSH6Wq2eHkt9LcbwHAelMIcMe0tP4p20Pod7tTxq9zf0ge2n/YDfMOpDryerfmmYyuQiaFaKOg== ieee754@1.1.13, ieee754@^1.1.13, ieee754@^1.1.4: version "1.1.13" @@ -5736,10 +5801,10 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-potential-custom-element-name@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" - integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== is-promise@^2.0.0: version "2.2.2" @@ -5981,13 +6046,13 @@ jschardet@^2.1.0: resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.1.1.tgz#af6f8fd0b3b0f5d46a8fd9614a4fce490575c184" integrity sha512-pA5qG9Zwm8CBpGlK/lo2GE9jPxwqRgMV7Lzc/1iaPccw6v4Rhj8Zg2BTyrdmHmxlJojnbLupLeRnaPLsq03x6Q== -jsdom@16.5.3: - version "16.5.3" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.3.tgz#13a755b3950eb938b4482c407238ddf16f0d2136" - integrity sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA== +jsdom@16.6.0: + version "16.6.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.6.0.tgz#f79b3786682065492a3da6a60a4695da983805ac" + integrity sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg== dependencies: abab "^2.0.5" - acorn "^8.1.0" + acorn "^8.2.4" acorn-globals "^6.0.0" cssom "^0.4.4" cssstyle "^2.3.0" @@ -5995,12 +6060,13 @@ jsdom@16.5.3: decimal.js "^10.2.1" domexception "^2.0.1" escodegen "^2.0.0" + form-data "^3.0.0" html-encoding-sniffer "^2.0.1" - is-potential-custom-element-name "^1.0.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" nwsapi "^2.2.0" parse5 "6.0.1" - request "^2.88.2" - request-promise-native "^1.0.9" saxes "^5.0.1" symbol-tree "^3.2.4" tough-cookie "^4.0.0" @@ -6010,7 +6076,7 @@ jsdom@16.5.3: whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" whatwg-url "^8.5.0" - ws "^7.4.4" + ws "^7.4.5" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -6038,6 +6104,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -6277,7 +6348,7 @@ koa-slow@2.1.0: lodash.isregexp "3.0.5" q "1.4.1" -koa-views@7.0.1: +koa-views@*, koa-views@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/koa-views/-/koa-views-7.0.1.tgz#0c8f8e65d5cd2e08249430cb83dc361e49a17a5a" integrity sha512-yS8751DXHXXDbdl/oUZd0PsgnxR0MLiguu77Eqrgu6yawE9Hi99wNKiVENb0Kfgsmvq/8px7YCI+USgxaTB1LA== @@ -6504,6 +6575,11 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -6589,6 +6665,11 @@ lodash.throttle@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" @@ -6977,6 +7058,16 @@ minizlib@^2.0.0, minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" +misskey-js@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/misskey-js/-/misskey-js-0.0.2.tgz#233d62e5a326a00dd72f36d63436e6584c8076f2" + integrity sha512-gsq3E9lUepNapK4i/3mmqjobQV6gYlgO1O1rQt401ot3LCYlcaLhlUrwBOFtI+ALMGKgwRgkLlDQhcWgAfHHuQ== + dependencies: + "@vue/reactivity" "^3.0.11" + autobind-decorator "^2.4.0" + eventemitter3 "^4.0.7" + reconnecting-websocket "^4.4.0" + mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -7117,11 +7208,6 @@ nanoid@3.1.20, nanoid@^3.1.20: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== -nanoid@^3.1.22: - version "3.1.22" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" - integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== - nanoid@^3.1.23: version "3.1.23" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" @@ -7207,10 +7293,10 @@ node-abi@^2.21.0: dependencies: semver "^5.4.1" -node-addon-api@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239" - integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== +node-addon-api@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" + integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== node-fetch@2.6.1, node-fetch@^2.6.1: version "2.6.1" @@ -7253,10 +7339,10 @@ node-releases@^1.1.70, node-releases@^1.1.71: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== -nodemailer@6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.6.0.tgz#ed47bb572b48d9d0dca3913fdc156203f438f427" - integrity sha512-ikSMDU1nZqpo2WUPE0wTTw/NGGImTkwpJKDIFPZT+YvvR9Sj+ze5wzu95JHkBMglQLoG2ITxU21WukCC/XsFkg== +nodemailer@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.6.1.tgz#2a05fbf205b897d71bf43884167b5d4d3bd01b99" + integrity sha512-1xzFN3gqv+/qJ6YRyxBxfTYstLNt0FCtZaFRvf4Sg9wxNGWbwFmGXVpfSi6ThGK6aRxAo+KjHtYSW8NvCsNSAg== nofilter@^2.0.3: version "2.0.3" @@ -8035,13 +8121,14 @@ postcss-colormin@^2.1.8: postcss "^5.0.13" postcss-value-parser "^3.2.3" -postcss-colormin@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.1.0.tgz#686da694e5e638eac141364e150eb936b3a8e79f" - integrity sha512-5s+VNfQ5CsR6yvBc6Tc8NK9cxb/c8sA547zy+8ofL04gs/GygmOcVZt2s6jJn7TvntAw0Bp6MDpq4bd51EPwdw== +postcss-colormin@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.0.tgz#2b620b88c0ff19683f3349f4cf9e24ebdafb2c88" + integrity sha512-+HC6GfWU3upe5/mqmxuqYZ9B2Wl4lcoUUNkoaX59nEWV4EtADCMiBqui111Bu8R8IvaZTmqmxrqOAqjbHIwXPw== dependencies: - browserslist "^4.16.0" - colord "^1.7.0" + browserslist "^4.16.6" + caniuse-api "^3.0.0" + colord "^2.0.1" postcss-value-parser "^4.1.0" postcss-convert-values@^2.3.4: @@ -8167,12 +8254,12 @@ postcss-merge-rules@^2.0.3: postcss-selector-parser "^2.2.2" vendors "^1.0.0" -postcss-merge-rules@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.1.tgz#4ff61c5089d86845184a0f149e88d687028bef7e" - integrity sha512-UR6R5Ph0c96QB9TMBH3ml8/kvPCThPHepdhRqAbvMRDRHQACPC8iM5NpfIC03+VRMZTGXy4L/BvFzcDFCgb+fA== +postcss-merge-rules@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.2.tgz#d6e4d65018badbdb7dcc789c4f39b941305d410a" + integrity sha512-5K+Md7S3GwBewfB4rjDeol6V/RZ8S+v4B66Zk2gChRqLTCC8yjnHQ601omj9TKftS19OPGqZ/XzoqpzNQQLwbg== dependencies: - browserslist "^4.16.0" + browserslist "^4.16.6" caniuse-api "^3.0.0" cssnano-utils "^2.0.1" postcss-selector-parser "^6.0.5" @@ -8474,10 +8561,10 @@ postcss-svgo@^2.1.1: postcss-value-parser "^3.2.3" svgo "^0.7.0" -postcss-svgo@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.1.tgz#6ed5e01e164e59204978994d844c653a331a8100" - integrity sha512-cD7DFo6tF9i5eWvwtI4irKOHCpmASFS0xvZ5EQIgEdA1AWfM/XiHHY/iss0gcKHhkqwgYmuo2M0KhJLd5Us6mg== +postcss-svgo@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.2.tgz#bc73c4ea4c5a80fbd4b45e29042c34ceffb9257f" + integrity sha512-YzQuFLZu3U3aheizD+B1joQ94vzPfE6BNUcSYuceNxlVnKKsOtdo6hL9/zyC168Q8EwfLSgaDSalsUGa9f2C0A== dependencies: postcss-value-parser "^4.1.0" svgo "^2.3.0" @@ -8519,14 +8606,14 @@ postcss-zindex@^2.0.1: postcss "^5.0.4" uniqs "^2.0.0" -postcss@8.2.15: - version "8.2.15" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65" - integrity sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q== +postcss@8.3.0, postcss@^8.2.15: + version "8.3.0" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f" + integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ== dependencies: colorette "^1.2.2" nanoid "^3.1.23" - source-map "^0.6.1" + source-map-js "^0.6.2" postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.8, postcss@^5.2.16: version "5.2.18" @@ -8547,15 +8634,6 @@ postcss@^8.1.10: nanoid "^3.1.20" source-map "^0.6.1" -postcss@^8.2.10: - version "8.2.12" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.12.tgz#81248a1a87e0f575cc594a99a08207fd1c4addc4" - integrity sha512-BJnGT5+0q2tzvs6oQfnY2NpEJ7rIXNfBnZtQOKCIsweeWXBXeDd5k31UgTdS3d/c02ouspufn37mTaHWkJyzMQ== - dependencies: - colorette "^1.2.2" - nanoid "^3.1.22" - source-map "^0.6.1" - postgres-array@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" @@ -8647,10 +8725,10 @@ prismjs@1.23.0: optionalDependencies: clipboard "^2.0.0" -probe-image-size@7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/probe-image-size/-/probe-image-size-7.1.0.tgz#2b0f8474c9c0c68f3b640e353fe64127585f0f6b" - integrity sha512-T7F4ZF4iWQJWhj/ijPyh88fHen9UtaUwtV+QMZ1NkmpUSDHmfYlZgRUTOcFKnqi95I6kpGBQ+3pF1dCtVmDeIg== +probe-image-size@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/probe-image-size/-/probe-image-size-7.1.1.tgz#ea3dc7acd69fb041212de12bb390be58c1025917" + integrity sha512-lvpHKqtino5SSrFEKxFncco8raLywljcLbjcE35VIRl5O+u1qLXenNaEfnopYdJgN4PPvvBxdr8b7sEUTvfY/w== dependencies: lodash.merge "^4.6.2" needle "^2.5.2" @@ -9072,7 +9150,7 @@ rechoir@^0.7.0: dependencies: resolve "^1.9.0" -reconnecting-websocket@4.4.0: +reconnecting-websocket@4.4.0, reconnecting-websocket@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz#3b0e5b96ef119e78a03135865b8bb0af1b948783" integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng== @@ -9222,13 +9300,6 @@ request-promise-core@1.1.2: dependencies: lodash "^4.17.11" -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - request-promise-native@1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.7.tgz#a49868a624bdea5069f1251d0a836e0d89aa2c59" @@ -9238,15 +9309,6 @@ request-promise-native@1.0.7: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request-promise-native@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - request-stats@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/request-stats/-/request-stats-3.0.0.tgz#769155dc8974d78d4a1cb87bbf14eaab985afe25" @@ -9281,7 +9343,7 @@ request@2.88.0: tunnel-agent "^0.6.0" uuid "^3.3.2" -request@^2.88.0, request@^2.88.2: +request@^2.88.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -9322,6 +9384,11 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" @@ -9514,10 +9581,10 @@ sass-loader@11.1.1: klona "^2.0.4" neo-async "^2.6.2" -sass@1.32.13: - version "1.32.13" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.13.tgz#8d29c849e625a415bce71609c7cf95e15f74ed00" - integrity sha512-dEgI9nShraqP7cXQH+lEXVf73WOPCse0QlFzSD8k+1TcOxCMwVXfQlr0jtoluZysQOyJGnfr21dLvYKDJq8HkA== +sass@1.34.0: + version "1.34.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.34.0.tgz#e46d5932d8b0ecc4feb846d861f26a578f7f7172" + integrity sha512-rHEN0BscqjUYuomUEaqq3BMgsXqQfkcMVR7UhscsAVub0/spUrZGBMxQXFS2kfiDsPLZw5yuU9iJEFNC2x38Qw== dependencies: chokidar ">=3.0.0 <4.0.0" @@ -9655,14 +9722,14 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" -sharp@0.28.2: - version "0.28.2" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.28.2.tgz#31c6ebdf8ddb9b4ca3e30179e3f4a73f0c7474e4" - integrity sha512-CdmySbsQVe/+ZM2j9zzvUfWumM0L0iHj1kpxJMFuyWvSuBULebvGCdOLb1f5vbbBrIGroX714Fx1wiWaKniz4A== +sharp@0.28.3: + version "0.28.3" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.28.3.tgz#ecd74cefd020bee4891bb137c9850ee2ce277a8b" + integrity sha512-21GEP45Rmr7q2qcmdnjDkNP04Ooh5v0laGS5FDpojOO84D1DJwUijLiSq8XNNM6e8aGXYtoYRh3sVNdm8NodMA== dependencies: color "^3.1.3" detect-libc "^1.0.3" - node-addon-api "^3.1.0" + node-addon-api "^3.2.0" prebuild-install "^6.1.2" semver "^7.3.5" simple-get "^3.1.0" @@ -9814,6 +9881,11 @@ source-list-map@^2.0.0, source-list-map@^2.0.1: resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" @@ -10361,25 +10433,27 @@ syslog-pro@1.0.0: dependencies: moment "^2.22.2" -systeminformation@5.6.22: - version "5.6.22" - resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.6.22.tgz#7751340e2835bd3d0b28694ae273e168b235f1df" - integrity sha512-GJYkEUn2rKKsRG8ieUhnOXkowSTno2s8CD/jkeyi3KErxSq0HCYu+7YYbxirL3/bh7zE3yjy/S52rEnrBjjf7Q== +systeminformation@5.7.4: + version "5.7.4" + resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.7.4.tgz#13fcc29bd3836cf5043802f0f2532d0c4961a4ea" + integrity sha512-m6oziAu2zP8IMnNZpVWptzpcaXG6x59c2sQB8BI7DTcfBOTLXj5jGgjWxCVP65c5k7Fwhn35yVTCIZEypc1n9A== syuilo-password-strength@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/syuilo-password-strength/-/syuilo-password-strength-0.0.1.tgz#08f71a8f0ecb77db649f3d9a6424510d9d945f52" integrity sha1-CPcajw7Ld9tknz2aZCRRDZ2UX1I= -table@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/table/-/table-6.0.4.tgz#c523dd182177e926c723eb20e1b341238188aa0d" - integrity sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw== +table@^6.0.9: + version "6.7.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" + integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== dependencies: - ajv "^6.12.4" - lodash "^4.17.20" + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" slice-ansi "^4.0.0" string-width "^4.2.0" + strip-ansi "^6.0.0" tapable@^1.0.0-beta.5: version "1.1.3" @@ -10702,21 +10776,25 @@ tree-kill@^1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -ts-loader@9.2.1: - version "9.2.1" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.1.tgz#5699af8d10aa3a763aadfced1d4b275a432b76eb" - integrity sha512-BLfLa4paMQyf819haKxxbZqA1aLDqsk8XEZLmd7E1eBa0NsEHYFcTWlUlPmYMGhvD/IMi0NcIW3A/G7vzr3oiA== +ts-loader@9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.2.tgz#416333900621c82d5eb1b1f6dea4114111f096bf" + integrity sha512-hNIhGTQHtNKjOzR2ZtQ2OSVbXPykOae+zostf1IlHCf61Mt41GMJurKNqrYUbzHgpmj6UWRu8eBfb7q0XliV0g== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" micromatch "^4.0.0" semver "^7.3.4" -ts-node@9.1.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" - integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== +ts-node@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.0.0.tgz#05f10b9a716b0b624129ad44f0ea05dac84ba3be" + integrity sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg== dependencies: + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.1" arg "^4.1.0" create-require "^1.1.0" diff "^4.0.1" @@ -10824,10 +10902,10 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= -twemoji-parser@13.0.x: - version "13.0.0" - resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-13.0.0.tgz#bd9d1b98474f1651dc174696b45cabefdfa405af" - integrity sha512-zMaGdskpH8yKjT2RSE/HwE340R4Fm+fbie4AaqjDa4H/l07YUmAvxkSfNl6awVWNRRQ0zdzLQ8SAJZuY5MgstQ== +twemoji-parser@13.0.x, twemoji-parser@13.1.0, twemoji-parser@13.1.x: + version "13.1.0" + resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-13.1.0.tgz#65e7e449c59258791b22ac0b37077349127e3ea4" + integrity sha512-AQOzLJpYlpWMy8n+0ATyKKZzWlZBJN+G0C+5lhX7Ftc2PeEVdUU/7ns2Pn2vVje26AIZ/OHwFoUbdv6YYD/wGg== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -10921,10 +10999,10 @@ typeorm@0.2.32: yargs "^16.2.0" zen-observable-ts "^1.0.0" -typescript@4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" - integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== +typescript@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" + integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" @@ -11338,6 +11416,14 @@ watchpack@^2.0.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +watchpack@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce" + integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + web-push@3.4.4: version "3.4.4" resolved "https://registry.yarnpkg.com/web-push/-/web-push-3.4.4.tgz#b11523ada0f4b8c2481f65d1d059acd45ba27ca0" @@ -11403,10 +11489,18 @@ webpack-sources@^2.1.1: source-list-map "^2.0.1" source-map "^0.6.1" -webpack@5.37.1: - version "5.37.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.37.1.tgz#2deb5acd350583c1ab9338471f323381b0b0c14b" - integrity sha512-btZjGy/hSjCAAVHw+cKG+L0M+rstlyxbO2C+BOTaQ5/XAnxkDrP5sVbqWhXgo4pL3X2dcOib6rqCP20Zr9PLow== +webpack-sources@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.0.tgz#9ed2de69b25143a4c18847586ad9eccb19278cfa" + integrity sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ== + dependencies: + source-list-map "^2.0.1" + source-map "^0.6.1" + +webpack@5.38.1: + version "5.38.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.38.1.tgz#5224c7f24c18e729268d3e3bc97240d6e880258e" + integrity sha512-OqRmYD1OJbHZph6RUMD93GcCZy4Z4wC0ele4FXyYF0J6AxO1vOSuIlU1hkS/lDlR9CDYBz64MZRmdbdnFFoT2g== dependencies: "@types/eslint-scope" "^3.7.0" "@types/estree" "^0.0.47" @@ -11418,7 +11512,7 @@ webpack@5.37.1: chrome-trace-event "^1.0.2" enhanced-resolve "^5.8.0" es-module-lexer "^0.4.0" - eslint-scope "^5.1.1" + eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" graceful-fs "^4.2.4" @@ -11429,8 +11523,8 @@ webpack@5.37.1: schema-utils "^3.0.0" tapable "^2.1.1" terser-webpack-plugin "^5.1.1" - watchpack "^2.0.0" - webpack-sources "^2.1.1" + watchpack "^2.2.0" + webpack-sources "^2.3.0" webpack@^5: version "5.33.2" @@ -11616,15 +11710,10 @@ write-json-file@^2.3.0: sort-keys "^2.0.0" write-file-atomic "^2.0.0" -ws@7.4.5: - version "7.4.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1" - integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g== - -ws@^7.4.4: - version "7.4.4" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" - integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== +ws@7.4.6, ws@^7.4.5: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== xev@2.0.1: version "2.0.1"