diff --git a/.vscode/extensions.json b/.vscode/extensions.json index fda19cb919..04544f46b9 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,7 +2,6 @@ "recommendations": [ "editorconfig.editorconfig", "eg2.vscode-npm-script", - "ms-vscode.typescript-javascript-grammar", "dbaeumer.vscode-eslint", "johnsoncodehk.volar", "sysoev.language-stylus" diff --git a/CHANGELOG.md b/CHANGELOG.md index b70791d05a..496e9befd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,13 +7,36 @@ --> -## 12.x.x (unreleased) +## 12.100.1 (2021/12/17) + +### Bugfixes +- クライアント: デザインの調整 + +## 12.100.0 (2021/12/17) + +### Improvements +- クライアント: モバイルでの各種メニュー、リアクションピッカーの表示を改善 + +### Bugfixes +- クライアント: 一部のコンポーネントが裏に隠れるのを修正 + +## 12.99.3 (2021/12/14) +### Bugfixes +- クライアント: オートコンプリートがダイアログの裏に隠れる問題を修正 + +## 12.99.2 (2021/12/14) + +## 12.99.1 (2021/12/14) + +## 12.99.0 (2021/12/14) ### Improvements - Added a user-level instance mute in user settings - フォローエクスポートでミュートしているユーザーを含めないオプションを追加 - フォローエクスポートで使われていないアカウントを含めないオプションを追加 - カスタム絵文字エクスポート機能 +- チャートのパフォーマンスの改善 +- グループから抜けられるように ### Bugfixes - クライアント: タッチ機能付きディスプレイを使っていてマウス操作をしている場合に一部機能が動作しない問題を修正 diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index c831fafff1..23f7f48a14 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -752,6 +752,7 @@ muteThread: "اكتم النقاش" unmuteThread: "ارفع الكتم عن النقاش" deleteAccountConfirm: "سيحذف حسابك نهائيًا، أتريد المتابعة؟" incorrectPassword: "كلمة السر خاطئة." +hide: "إخفاء" _emailUnavailable: used: "هذا البريد الإلكتروني مستخدم" format: "صيغة البريد الإلكتروني غير صالحة" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 69d90c7624..c615e6424c 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -592,6 +592,7 @@ smtpSecure: "Für SMTP-Verbindungen implizit SSL/TLS verwenden" smtpSecureInfo: "Schalte dies aus, falls du STARTTLS verwendest" testEmail: "Email-Versand testen" wordMute: "Wort-Stummschaltung" +instanceMute: "Instanzstummschaltungen" userSaysSomething: "{name} hat etwas gesagt" makeActive: "Aktivieren" display: "Anzeigeart" @@ -811,6 +812,7 @@ continueThread: "Weiteren Threadverlauf anzeigen" deleteAccountConfirm: "Dein Benutzerkonto wird unwiderruflich gelöscht. Trotzdem fortfahren?" incorrectPassword: "Falsches Passwort." voteConfirm: "Wirklich für \"{choice}\" abstimmen?" +hide: "Inhalt verbergen" _emailUnavailable: used: "Diese Email-Adresse wird bereits verwendet" format: "Das Format dieser Email-Adresse ist ungültig" @@ -1001,6 +1003,11 @@ _wordMute: soft: "Leicht" hard: "Schwer" mutedNotes: "Stummgeschaltete Notizen" +_instanceMute: + instanceMuteDescription: "Schaltet alle Notizen/Renotes stumm, die von den gelisteten Instanzen stammen, inklusive Antworten von Benutzern an einen Benutzer einer stummgeschalteten Instanz." + instanceMuteDescription2: "Instanzen getrennt durch Zeilenumbrüchen angeben" + title: "Blendet Notizen von stummgeschalteten Instanzen aus." + heading: "Liste der stummzuschaltenden Instanzen" _theme: explore: "Themen erforschen" install: "Thema installieren" @@ -1274,6 +1281,8 @@ _exportOrImport: muteList: "Stummschaltungen" blockingList: "Blockierungen" userLists: "Listen" + excludeMutingUsers: "Stummgeschaltete Benutzer aussortieren" + excludeInactiveUsers: "Inaktive Benutzer aussortieren" _charts: federationInstancesIncDec: "Unterschied in der Anzahl von förderierenden Instanzen" federationInstancesTotal: "Anzahl aller föderierenden Instanzen" diff --git a/locales/en-US.yml b/locales/en-US.yml index 5388a7a636..65d1cc04a1 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -137,7 +137,7 @@ addEmoji: "Add an emoji" settingGuide: "Recommended settings" cacheRemoteFiles: "Cache remote files" cacheRemoteFilesDescription: "When this setting is disabled, remote files are loaded directly from the remote instance. Disabling this will decrease storage usage, but increase traffic, as thumbnails will not be generated." -flagAsBot: "Mark this account as as bot" +flagAsBot: "Mark this account as a bot" flagAsBotDescription: "Enable this option if this account is controlled by a program. If enabled, it will act as a flag for other developers to prevent endless interaction chains with other bots and adjust Misskey's internal systems to treat this account as a bot." flagAsCat: "Mark this account as a cat" flagAsCatDescription: "Enable this option to mark this account as a cat." @@ -592,6 +592,7 @@ smtpSecure: "Use implicit SSL/TLS for SMTP connections" smtpSecureInfo: "Turn this off when using STARTTLS" testEmail: "Test email delivery" wordMute: "Word mute" +instanceMute: "Instance mutes" userSaysSomething: "{name} said something" makeActive: "Activate" display: "Display" @@ -810,6 +811,7 @@ continueThread: "View thread continuation" deleteAccountConfirm: "This will irreversibly delete your account. Proceed?" incorrectPassword: "Incorrect password." voteConfirm: "Confirm your vote for \"{choice}\"?" +hide: "Hide" _emailUnavailable: used: "This email address is already being used" format: "The format of this email address is invalid" @@ -1000,6 +1002,11 @@ _wordMute: soft: "Soft" hard: "Hard" mutedNotes: "Muted notes" +_instanceMute: + instanceMuteDescription: "This will mute any notes/renotes from the listed instances, including those of users replying to a user from a muted instance." + instanceMuteDescription2: "Separate with newlines" + title: "Hides notes from listed instances." + heading: "List of instances to be muted" _theme: explore: "Explore Themes" install: "Install a theme" @@ -1273,6 +1280,8 @@ _exportOrImport: muteList: "Muted users" blockingList: "Blocked users" userLists: "User lists" + excludeMutingUsers: "Exclude muted users" + excludeInactiveUsers: "Exclude inactive users" _charts: federationInstancesIncDec: "Difference in # of federating instances" federationInstancesTotal: "Total # of federating instances" diff --git a/locales/eo-UY.yml b/locales/eo-UY.yml index a57206e090..1128cb20b7 100644 --- a/locales/eo-UY.yml +++ b/locales/eo-UY.yml @@ -1,8 +1,8 @@ --- _lang_: "Esperanto" -headlineMisskey: "Jen la reto konektata de notoj" -introMisskey: "Bonvenon! Misskey estas malfermitkoda malcentraliza etbloga servo.\nKreu \"noto\"n por paroli vian penson al iuj ĉirkaŭ vi. 📡\nLa funkcion \"reago\" ebligas esprimi rapide vian senton pri ies noto en Fediverso. 👍\nBonvole esploru novan mondon. 🚀" -monthAndDay: "la {day}a de la {month}a" +headlineMisskey: "Reto konektita per notoj" +introMisskey: "Bonvenon! Misskey estas malfermitkoda malcentraliza etbloga servo.\nKreu \"noto\"n por diskonigi nunan aferon, aŭ por paroli vian penson al ĉiuj ĉirkaŭ vi. 📡\nLa funkcion \"reago\" ebligas esprimi rapide vian senton pri la noto de la alia en la Fediverso. 👍\nBonvole esploru novan mondon. 🚀" +monthAndDay: "la {day}a de la {month}a monato" search: "Serĉi" notifications: "Sciigoj" username: "Uzantnomo" @@ -20,13 +20,13 @@ instance: "Nodo" settings: "Agordoj" basicSettings: "Ĝeneralaj agordoj" otherSettings: "Aliaj agordoj" -openInWindow: "Malfermi en fenestro" +openInWindow: "Malfermi en nova fenestro" profile: "Profilo" timeline: "Templinio" -noAccountDescription: "Neniu sinprezento" -login: "Ensaluti" -loggingIn: "Ensalutado…" -logout: "Elsaluti" +noAccountDescription: "Neniu priskribo" +login: "Saluti" +loggingIn: "Salutado…" +logout: "Adiaŭi" signup: "Registriĝi" uploading: "Alŝutado…" save: "Konservi" @@ -58,13 +58,13 @@ followRequestAccepted: "La peto de sekvado akceptita" mention: "Mencioj" mentions: "Mencioj" directNotes: "Rekte senditaj" -importAndExport: "Importi/eksporti" -import: "Importi" -export: "Eksporti" +importAndExport: "Enporti kaj elporti" +import: "Enporti" +export: "Elporti" files: "Dosieroj" download: "Elŝuti" -driveFileDeleteConfirm: "Ĉu vi certas, ke vi volas forviŝi la dosieron \"{name}\"? Pro tio forviŝiĝos ankaŭ la notoj kiuj enhavas ĝin." -unfollowConfirm: "Ĉu vi certas, ke vi volas ĉesi sekvi {name}'(o)n?" +driveFileDeleteConfirm: "Ĉu vi certas, ke vi volas forviŝi la dosieron \"{name}\"? Tio ankaŭ forviŝos la notojn kiuj citas ĝin." +unfollowConfirm: "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?" lists: "Listoj" noLists: "Neniu listo" note: "Sendi" @@ -101,7 +101,7 @@ clickToShow: "Klaku por malkaŝu" sensitive: "Enhavo ne estas deca por laborejo (NSFW)" add: "Aldoni" reaction: "Reagoj" -reactionSettingDescription: "Agordi la reagojn kiujn vi volas prefere montrigi ĉe la elektilo de reagoj" +reactionSettingDescription: "Agordi la reagojn kiujn vi volas montrigi prefere ĉe la elektilo de reagoj" rememberNoteVisibility: "Rememori la agordon de videbleco de la laste sendita" attachCancel: "Deigi aldonaĵon" markAsSensitive: "Troviĝi NSFW" @@ -129,8 +129,9 @@ emojiUrl: "URL de la emoĵio" addEmoji: "Aldoni emoĵion" settingGuide: "Agordaj rekomendoj" cacheRemoteFiles: "Stapli forajn dosierojn" -flagAsBot: "Fari la flagon por robota uzanto" -flagAsCat: "Fari la flagon por kat-iĝi" +flagAsBot: "Agordi por robota uzanto" +flagAsCat: "Agordi por kata uzanto" +flagAsCatDescription: "Se vi estas kato, ebligu la agordon." autoAcceptFollowed: "Aŭtomate akcepti la peton de sekvado far uzantoj kiujn vi sekvas" addAccount: "Aldoni konton" showOnRemote: "Vidi ĉe la surloka nodo" @@ -140,15 +141,16 @@ setWallpaper: "Apliki ekranfonon" removeWallpaper: "Forviŝi ekranfonon. " searchWith: "Serĉi: {q}" youHaveNoLists: "Vi ne havas listojn." -followConfirm: "Ĉu vi certas ke vi volas sekvi {name}'(o)n?" +followConfirm: "Ĉu vi certas ke vi volas sekvi {name}?" +proxyAccount: "Retperanta konto" host: "Nodo" selectUser: "Elekti uzanton" -recipient: "Ricevonto" +recipient: "Ricevonton" annotation: "Komentarioj" federation: "Federaĵo" instances: "Nodoj" -latestRequestSentAt: "Lastatempa sendo" -latestRequestReceivedAt: "Lastatempa ricevo" +latestRequestSentAt: "La laste sendita peto" +latestRequestReceivedAt: "La laste ricevita peto " latestStatus: "Laŭstato" charts: "Diagramoj" perHour: "por horo" @@ -157,7 +159,7 @@ blockThisInstance: "Bloki la nodon" operations: "Agoj" software: "Programaro" version: "Versio" -metadata: "Metadatumoj" +metadata: "Pridatumoj" withNFiles: "{n} dosiero(j)" monitor: "Monitoro" network: "Reto" @@ -223,11 +225,11 @@ messageRead: "Legita" noMoreHistory: "Ne plu de la historio" startMessaging: "Komenci babiladon" nUsersRead: "Legita de {n} homoj" -agreeTo: "Mi akceptas {0}'(o)n" +agreeTo: "Mi akceptas {0}" tos: "Kondiĉoj de uzado" start: "Komenciĝi" home: "Hejma" -remoteUserCaution: "Ĉi tiuj infomoj de la uzanto el fora nodo, ne estas tute ekzaktaj." +remoteUserCaution: "Ĉi tiuj infomoj ne estas kompletaj, ĉar ili estas pri uzanto el la fora." activity: "Aktiveco" images: "Bildoj" birthday: "Naskiĝdato" @@ -235,12 +237,13 @@ yearsOld: "{age} jaroj aĝa" registeredDate: "Dato de registriĝo" location: "Kie" theme: "Koloraro" -themeForLightMode: "Luma kolararo en la luma modo" -themeForDarkMode: "Malluma kolararo en la malluma modo" +themeForLightMode: "Koloraro uzita en la luma modo" +themeForDarkMode: "Koloraro uzita en la malluma modo" light: "Luma" dark: "Malluma" lightThemes: "Luma koloraro" darkThemes: "Malluma koloraro" +syncDeviceDarkMode: "Speguli la luman modon de via aparato" drive: "Disko" fileName: "Dosiernomo" selectFile: "Elekti dosieron" @@ -262,7 +265,7 @@ inputNewFolderName: "Entajpu novan nomon de la dosierujo" hasChildFilesOrFolders: "La dosierujo ne estas forviŝebla, ĉar ĝi ne malplenas." copyUrl: "Kopii URL" rename: "Alinomi" -avatar: "Ikono" +avatar: "Bildsimbolo" banner: "Standardo" nsfw: "Enhavo ne estas deca por laborejo (NSFW)" disconnectedFromServer: "Malkonektita de servilo" @@ -277,7 +280,7 @@ normal: "Normala" instanceName: "Nomo de la nodo" instanceDescription: "Priskribo de la nodo " maintainerName: "Nomo de la administranto" -maintainerEmail: "Retpoŝto de la administranto" +maintainerEmail: "Retpoŝtadreso de la administranto" tosUrl: "URL de kondiĉoj de uzado" thisYear: "Ĉi-jare" thisMonth: "Ĉi-monate" @@ -296,9 +299,9 @@ enableRegistration: "Ebligi novan uzanton registriĝon" invite: "Inviti" driveCapacityPerLocalAccount: "Volumo de disko po unu loka uzanto" driveCapacityPerRemoteAccount: "Volumo de disko po unu fora uzanto" -iconUrl: "URL de la ikono (retpaĝsimbolo, ktp)" +iconUrl: "URL de la bildsimbolo (retpaĝsimbolo, ktp.)" bannerUrl: "URL de standardo" -backgroundImageUrl: "URL de fona bildo" +backgroundImageUrl: "URL de la fona bildo" basicInfo: "Baza informo" pinnedUsers: "Alpinglita uzanto" pinnedUsersDescription: "Listigu uzantnomojn apartige en ĉiu linio por alpingli al la paĝoj ekz \"Esplori\"." @@ -338,7 +341,7 @@ userList: "Listoj" about: "Informoj" aboutMisskey: "Pri Misskey" administrator: "Administranto" -token: "Ĵetono" +token: "Peco" twoStepAuthentication: "Dua-faktora aŭtentiko" moderator: "Kontrolisto" nUsersMentioned: "{n} uzanto(j) menciis" @@ -347,12 +350,13 @@ securityKeyName: "Nomo de la ŝlosilo" registerSecurityKey: "Registri ŝlosilon de sekureco" lastUsed: "Plej malnove uzita" unregister: "Malregistriĝi" -passwordLessLogin: "Ensaluti sen pasvorto" +passwordLessLogin: "Saluti sen pasvorto" resetPassword: "Restarigi pasvorton" newPasswordIs: "La nova pasvorto estas {password}." -reduceUiAnimation: "Redukti la animacioj de la fasado" +reduceUiAnimation: "Redukti la animaciojn de la fasado" share: "Kundividi" notFound: "Ne trovita" +uploadFolder: "Dosierujo implicita por alŝuto" cacheClear: "Malplenigi staplon" markAsReadAllNotifications: "Marki ĉiujn sciigojn kiel legita" help: "Manlibro de uzado" @@ -362,7 +366,7 @@ group: "Grupo" groups: "Grupoj" createGroup: "Krei grupon" ownedGroups: "Administrataj grupoj" -joinedGroups: "Al grupoj kiuj vi aliĝis" +joinedGroups: "Grupoj al kiuj vi aliĝis" invites: "Inviti" groupName: "Grupa nomo" members: "Membroj" @@ -381,9 +385,9 @@ quoteQuestion: "Ĉu vi aldonas citaĵon?" noMessagesYet: "Ankoraŭ neniu mesaĝo" newMessageExists: "Vi ricevis novan mesaĝon." onlyOneFileCanBeAttached: "Oni povas aldoni nur unu dosieron po mesaĝo." -signinRequired: "Bonvolu ensaluti" +signinRequired: "Bonvolu saluti" invitations: "Inviti" -invitationCode: "Invita kodo" +invitationCode: "Kodo de invito" available: "Disposabla" unavailable: "Ne disponebla" usernameInvalidFormat: "La uzantnomo povas enhavi minusklajn kaj majusklajn literojn, numerojn, nur kaj '_'." @@ -394,10 +398,11 @@ normalPassword: "Normala pasvorto" strongPassword: "Forta pasvorto" passwordMatched: "Konforma" passwordNotMatched: "Nekonforma" -signinWith: "Ensaluti kun {x}" +signinWith: "Saluti kun {x}" or: "Aŭ" language: "Lingvo" uiLanguage: "Lingvo de fasado" +groupInvited: "Invitita al grupo" aboutX: "Pri {x}" useOsNativeEmojis: "Uzi la emoĵiojn implicitan de la operaciumo" youHaveNoGroups: "Neniuj grupoj" @@ -408,7 +413,7 @@ category: "Kategorio" tags: "Etikedoj" docSource: "Fonto de la dokumento" createAccount: "Krei konton" -existingAccount: "Ekzista konto" +existingAccount: "Ekzistan konton" regenerate: "Regeneri" fontSize: "Tipara grando" noFollowRequests: "Vi ne havas peto de sekvado" @@ -426,9 +431,10 @@ objectStorageBaseUrl: "Baza URL" objectStoragePrefix: "Prefix" objectStorageRegion: "Regiono" objectStorageUseSSL: "Oni uzas SSL" +objectStorageUseProxy: "Uzi retperilon" serverLogs: "Servila protokolo" deleteAll: "Forviŝi ĉiujn" -newNoteRecived: "Jen estas novaj notoj" +newNoteRecived: "Jen novaj notoj" sounds: "Sonoj" listen: "Aŭdi" none: "Neniu" @@ -467,8 +473,8 @@ enableInfiniteScroll: "Ebligi infinitan rulumon" visibility: "Videbleco" poll: "Balotujo" useCw: "Kaŝi enhavo" -enablePlayer: "Vidi videon" -disablePlayer: "Fermi videon" +enablePlayer: "Vidigi la filmeton" +disablePlayer: "Malfermi la filmeton" expandTweet: "Disvolvi pepon" themeEditor: "Redaktilo de koloraroj" description: "Priskribo" @@ -484,15 +490,16 @@ height: "Alteco" large: "Granda" medium: "Meza" small: "Malgranda" -generateAccessToken: "Generi ĵetonon de aliro" +generateAccessToken: "Generi aŭtentikigan pecon" permission: "Permesoj" enableAll: "Ebligi ĉiujn" disableAll: "Malebligi ĉiujn" notificationType: "Tipo de sciigoj" edit: "Redakti" emailServer: "Retpoŝta servilo" +enableEmail: "Ebligi dissendon el retpoŝto" email: "Retpoŝto" -emailAddress: "Retpoŝta adreso" +emailAddress: "Retpoŝtadreso" smtpConfig: "Agordoj de SMTP servilo" smtpHost: "Transa servilo" smtpPort: "Pordo" @@ -513,14 +520,14 @@ create: "Krei" notificationSetting: "Agordoj de sciigoj" useGlobalSetting: "Oni uzas malloka agordo" other: "Aliaj" -regenerateLoginToken: "Regeneri la ĵetonon de aliro" +regenerateLoginToken: "Regeneri la aŭtentikigan pecon" fileIdOrUrl: "Dosiera identigilo aŭ URL" chatOpenBehavior: "Konduto por malfermi la fenestron de babilejo" behavior: "Konduto" sample: "Ekzemplo" abuseReports: "Signaloj" reportAbuse: "Signalo" -reportAbuseOf: "Signali kontraŭ {name}'(o)" +reportAbuseOf: "Signali kontraŭ {name}" send: "Sendi" openInNewTab: "Malfermi en nova langeto" editTheseSettingsMayBreakAccount: "Redakti ĉi tiujn agordojn povas damaĝi vian konton." @@ -528,6 +535,7 @@ instanceTicker: "Nomo de la nodo sendinta notojn" waitingFor: "Atendado pro {x}" random: "Hazarde" system: "Sistemo" +switchUi: "Modifi la aspektigon" desktop: "Labortablo" createNew: "Krei novan" optional: "Opciaj" @@ -563,7 +571,7 @@ wide: "Vasta" narrow: "Malvasta" showTitlebar: "Videbligi titolan stangon" clearCache: "Malplenigi staplon" -onlineUsersCount: "{n} uzanto(j) estas surlinea" +onlineUsersCount: "{n} uzantoj estas surlineaj" nUsers: "{n} uzanto(j)" nNotes: "{n} notoj" myTheme: "Miaj koloraroj" @@ -583,6 +591,7 @@ youAreRunningUpToDateClient: "Vi uzas la plej novan version de via kliento." newVersionOfClientAvailable: "Nova versio de via kliento estas disponebla." inUse: "Uzata" editCode: "Redakti kodon" +receiveAnnouncementFromInstance: "Ricevi informojn sciigintajn de la nodo" emailNotification: "Sciigoj per retpoŝto" inChannelSearch: "Serĉi en kanalo" useReactionPickerForContextMenu: "Dekstre-klaki por malfermi la elektilon de reagoj" @@ -617,6 +626,7 @@ troubleshooting: "Problemsolvi" learnMore: "Lernu pli" translate: "Traduki" translatedFrom: "Tradukita el {x}" +breakFollow: "Ĉesigi la sekvadon al vi" itsOn: "Ŝaltita" unread: "Nelegita" controlPanel: "Ŝaltpodio" @@ -647,7 +657,7 @@ _gallery: like: "Ŝati" _email: _follow: - title: "Vi estas eksekvita" + title: "Eksekvis vin" _receiveFollowRequest: title: "Vi ricevis peton de sekvado" _plugin: @@ -735,12 +745,12 @@ _sfx: notification: "Sciigoj" chat: "Retbabili" chatBg: "Retbabili (BG)" - antenna: "Ricevo de anteno" + antenna: "Ricevo de la anteno" channel: "Sciigoj de kanalo" _ago: future: "Futuro" justNow: "Ĵus" - secondsAgo: "Antaŭ {n} sekundo(j)" + secondsAgo: "Antaŭ {n} sekundoj" minutesAgo: "Antaŭ {n} minutoj" hoursAgo: "Antaŭ {n} horo(j)" daysAgo: "Antaŭ {n} tago(j)" @@ -780,6 +790,7 @@ _permissions: "read:reactions": "Vidi reagojn" "write:reactions": "Redakti viajn reagojn" "read:page-likes": "Vidi ŝatojn de paĝo" + "read:user-groups": "Vidi viajn grupojn de uzantoj" "read:channels": "Vidi kanalojn" _antennaSources: all: "Ĉiuj notoj" @@ -827,23 +838,23 @@ _visibility: _postForm: replyPlaceholder: "Respondi la noton…" quotePlaceholder: "Citi la noton…" - channelPlaceholder: "Mencii en kanalo…" + channelPlaceholder: "Mencii en la kanalo…" _profile: name: "Nomo" username: "Uzantnomo" description: "Sinprezento" metadata: "Kromaj informoj" - metadataEdit: "Redakti kromaj informoj" + metadataEdit: "Redakti kromajn informojn" changeAvatar: "Ŝanĝi profilbildon" changeBanner: "Ŝanĝi standardon" _exportOrImport: allNotes: "Ĉiuj notoj" - followingList: "Sekvataj uzantoj" + followingList: "Sekvatoj" muteList: "Silentigoj" blockingList: "Blokitoj" userLists: "Listoj" _charts: - federationInstancesTotal: "La totala nombro de nodoj kunfederantaj" + federationInstancesTotal: "La totala nombro de nodoj federantaj" usersTotal: "La totala nombro de la uzantoj" activeUsers: "La nombro de la uzantoj aktivaj" notesTotal: "La totala nombro de notoj" @@ -914,6 +925,7 @@ _pages: default: "Implicitaĵa valoro" _canvas: id: "Kanvasa identigilo" + width: "Larĝeco" _note: id: "Identigilo de noto" _switch: @@ -924,8 +936,11 @@ _pages: _button: text: "Titolo" _action: + _dialog: + content: "Enhavo" _pushEvent: event: "Nomo de la evento" + no-variable: "Neniu" _radioButton: title: "Titolo" default: "Implicitaĵa valoro" @@ -991,6 +1006,7 @@ _notification: youWereFollowed: "eksekvis vin" youReceivedFollowRequest: "Vi ricevis peton de sekvado" yourFollowRequestAccepted: "Via peto de sekvado estis akceptita." + youWereInvitedToGroup: "Invitita al grupo" _types: all: "Ĉio" follow: "Novaj sekvatoj" @@ -1001,6 +1017,7 @@ _notification: reaction: "Reagoj" receiveFollowRequest: "Ricevi peton de sekvado" followRequestAccepted: "Akceptita peto por sekvado" + groupInvited: "Invitita al grupo" _deck: profile: "Agordaro" _columns: diff --git a/locales/es-ES.yml b/locales/es-ES.yml index f81c3772aa..f22a104c71 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -738,6 +738,7 @@ lastCommunication: "Última comunicación" resolved: "Resuelto" unresolved: "Sin resolver" controlPanel: "Panel de control" +hide: "Ocultar" _accountDelete: accountDelete: "Eliminar Cuenta" _ad: diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index cf5e2238b1..d1f0236971 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -798,6 +798,7 @@ filter: "Filtre" controlPanel: "Panneau de contrôle" manageAccounts: "Gérer les comptes" classic: "Classique" +hide: "Masquer" _emailUnavailable: format: "Le format de cette adresse de courriel est invalide" mx: "Ce serveur de courriels est invalide" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index d9e6368c3a..ecf7dbffc3 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -810,6 +810,7 @@ continueThread: "Lihat lanjutan thread" deleteAccountConfirm: "Akun akan dihapus. Apakah kamu yakin?" incorrectPassword: "Kata sandi salah." voteConfirm: "Konfirmasi suara kamu untuk ({choice})?" +hide: "Sembunyikan" _emailUnavailable: used: "Alamat surel ini telah digunakan" format: "Format tidak valid." diff --git a/locales/index.js b/locales/index.js index a0181cd7aa..8350b3d9c4 100644 --- a/locales/index.js +++ b/locales/index.js @@ -46,7 +46,10 @@ const primaries = { 'zh': 'CN', }; -const locales = languages.reduce((a, c) => (a[c] = yaml.load(fs.readFileSync(`${__dirname}/${c}.yml`, 'utf-8')) || {}, a), {}); +// 何故か文字列にバックスペース文字が混入することがあり、YAMLが壊れるので取り除く +const clean = (text) => text.replace(new RegExp(String.fromCodePoint(0x08), 'g'), ''); + +const locales = languages.reduce((a, c) => (a[c] = yaml.load(clean(fs.readFileSync(`${__dirname}/${c}.yml`, 'utf-8'))) || {}, a), {}); module.exports = Object.entries(locales) .reduce((a, [k ,v]) => (a[k] = (() => { diff --git a/locales/it-IT.yml b/locales/it-IT.yml index d650f44357..ed198c9928 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -745,6 +745,7 @@ global: "Federata" sent: "Inviare" hashtags: "Hashtag" troubleshooting: "Risoluzione problemi" +hide: "Nascondere" _ffVisibility: public: "Pubblico" _ad: diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index d2278df920..daac05c66c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -106,7 +106,7 @@ clickToShow: "クリックして表示" sensitive: "閲覧注意" add: "追加" reaction: "リアクション" -reactionSettingDescription: "リアクションピッカーに表示するリアクションを設定します。" +reactionSetting: "ピッカーに表示するリアクション" reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押して追加します。" rememberNoteVisibility: "公開範囲を記憶する" attachCancel: "添付取り消し" @@ -813,6 +813,9 @@ deleteAccountConfirm: "アカウントが削除されます。よろしいです incorrectPassword: "パスワードが間違っています。" voteConfirm: "「{choice}」に投票しますか?" hide: "隠す" +leaveGroup: "グループから抜ける" +leaveGroupConfirm: "「{name}」から抜けますか?" +useDrawerReactionPickerForMobile: "モバイルデバイスのときドロワーで表示" _emailUnavailable: used: "既に使用されています" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 49ef286a59..96bc50a4b0 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -653,6 +653,7 @@ low: "低い" global: "グローバル" sent: "送信" hashtags: "ハッシュタグ" +hide: "隠す" _ad: back: "戻る" _gallery: diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index dde60c4c81..080d59fc3a 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -81,6 +81,8 @@ somethingHappened: "오류가 발생했습니다" retry: "다시 시도" pageLoadError: "페이지를 불러오지 못했습니다." pageLoadErrorDescription: "네트워크 연결 또는 브라우저 캐시로 인해 발생했을 가능성이 높습니다. 캐시를 삭제하거나, 잠시 후 다시 시도해 주세요." +serverIsDead: "서버로부터 응답이 없습니다. 잠시 후 다시 시도해주세요." +youShouldUpgradeClient: "이 페이지를 표시하려면 새로고침하여 새로운 버전의 클라이언트를 이용해 주십시오." enterListName: "리스트 이름을 입력" privacy: "프라이버시" makeFollowManuallyApprove: "팔로우를 수동으로 승인" @@ -590,6 +592,7 @@ smtpSecure: "SMTP 연결에 Implicit SSL/TTS 사용" smtpSecureInfo: "STARTTLS 사용 시에는 해제합니다." testEmail: "이메일 전송 테스트" wordMute: "단어 뮤트" +instanceMute: "인스턴스 뮤트" userSaysSomething: "{name}님이 무언가를 말했습니다" makeActive: "활성화" display: "표시" @@ -618,6 +621,8 @@ reportAbuse: "신고" reportAbuseOf: "{name}을 신고하기" fillAbuseReportDescription: "신고하려는 이유를 자세히 알려주세요. 특정 게시물을 신고할 때에는 게시물의 URL도 포함해 주세요." abuseReported: "신고를 보냈습니다. 신고해 주셔서 감사합니다." +reporteeOrigin: "피신고자" +reporterOrigin: "신고자" send: "전송" abuseMarkAsResolved: "해결됨으로 표시" openInNewTab: "새 탭에서 열기" @@ -764,6 +769,7 @@ middle: "보통" low: "낮음" emailNotConfiguredWarning: "메일 주소가 설정되어 있지 않습니다." ratio: "비율" +previewNoteText: "본문 미리보기" customCss: "CSS 사용자화" customCssWarn: "이 설정은 기능을 알고 있는 경우에만 사용해야 합니다. 잘못된 값을 입력하면 클라이언트가 정상적으로 작동하지 않을 수 있습니다." global: "글로벌" @@ -787,9 +793,40 @@ pubSub: "Pub/Sub 계정" lastCommunication: "마지막 통신" resolved: "해결됨" unresolved: "해결되지 않음" +breakFollow: "팔로워 해제" +itsOn: "켜짐" +itsOff: "꺼짐" +emailRequiredForSignup: "가입할 때 이메일 주소 입력을 필수로 하기" +unread: "읽지 않음" +filter: "필터" controlPanel: "제어판" +manageAccounts: "계정 관리" +makeReactionsPublic: "리액션 목록을 공개하기" +makeReactionsPublicDescription: "나의 리액션을 누구나 볼 수 있게 합니다." +classic: "클래식" +muteThread: "이 글타래를 뮤트" +unmuteThread: "글타래 뮤트 해제" +ffVisibility: "내 인맥의 공개 범위" +ffVisibilityDescription: "나의 팔로우와 팔로워 정보에 대한 공개 범위를 설정할 수 있습니다." +continueThread: "이 글타래 이어서 보기" +deleteAccountConfirm: "계정이 삭제되고 되돌릴 수 없게 됩니다. 계속하시겠습니까? " +incorrectPassword: "비밀번호가 올바르지 않습니다." +voteConfirm: "\"{choice}\"에 투표하시겠습니까?" +hide: "숨기기" +_emailUnavailable: + used: "이 메일 주소는 사용중입니다" + format: "형식이 올바르지 않습니다" + disposable: "임시 이메일 주소는 사용할 수 없습니다" + mx: "메일 서버가 올바르지 않습니다" + smtp: "메일 서버가 응답하지 않습니다" _ffVisibility: - public: "게시" + public: "공개" + followers: "팔로워에게만 공개" + private: "비공개" +_signup: + almostThere: "거의 다 끝났습니다" + emailAddressInfo: "당신이 사용하고 있는 이메일 주소를 입력해 주세요. 이메일 주소는 다른 유저에게 공개되지 않습니다." + emailSent: "입력하신 메일 주소({email})로 확인 메일을 보내드렸습니다. 가입을 완료하시려면 보내드린 메일에 있는 링크로 접속해 주세요." _accountDelete: accountDelete: "계정 삭제" mayTakeTime: "계정 삭제는 서버에 부하를 가하기 때문에, 작성한 콘텐츠나 업로드한 파일의 수가 많으면 완료까지 시간이 걸릴 수 있습니다." @@ -900,6 +937,7 @@ _mfm: sparkle: "반짝반짝" sparkleDescription: "반짝이는 파티클 효과를 추가합니다." rotate: "회전" + rotateDescription: "지정한 각도로 회전시킵니다." _reversi: reversi: "리버시" gameSettings: "대국 설정" @@ -965,6 +1003,11 @@ _wordMute: soft: "보통" hard: "보다 높은 수준" mutedNotes: "뮤트된 노트" +_instanceMute: + instanceMuteDescription: "뮤트한 인스턴스에서 오는 답글을 포함한 모든 노트와 Renote를 뮤트합니다." + instanceMuteDescription2: "한 줄에 하나씩 입력해 주세요" + title: "지정한 인스턴스의 노트를 숨깁니다." + heading: "뮤트할 인스턴스" _theme: explore: "테마 찾아보기" install: "테마 설치" @@ -1238,6 +1281,8 @@ _exportOrImport: muteList: "뮤트" blockingList: "차단" userLists: "리스트" + excludeMutingUsers: "뮤트한 유저 제외하기" + excludeInactiveUsers: "휴면 중인 계정 제외하기" _charts: federationInstancesIncDec: "연합 인스턴스 수 증감" federationInstancesTotal: "연합 인스턴스 수 합계" diff --git a/locales/nl-NL.yml b/locales/nl-NL.yml index 0393d94303..364e877c5e 100644 --- a/locales/nl-NL.yml +++ b/locales/nl-NL.yml @@ -120,16 +120,144 @@ unblock: "Deblokkeren" suspend: "Opschorten" unsuspend: "Heractiveren" blockConfirm: "Weet je zeker dat je dit account wil blokkeren?" +searchWith: "Zoeken: {q}" +youHaveNoLists: "Je hebt geen lijsten" +followConfirm: "Weet je zeker dat je {name} wilt volgen?" +proxyAccount: "Proxy account" +proxyAccountDescription: "Een proxy-account is een account dat onder bepaalde voorwaarden fungeert als externe volger voor gebruikers. Als een gebruiker bijvoorbeeld een externe gebruiker aan de lijst toevoegt, wordt de activiteit van de externe gebruiker niet aan de server geleverd als geen lokale gebruiker die gebruiker volgt, dus het proxy-account volgt in plaats daarvan." +host: "Server" +selectUser: "Kies een gebruiker" +recipient: "Ontvanger" +annotation: "Reacties" +federation: "Federatie" instances: "Server" +registeredAt: "Geregistreerd op" +latestRequestSentAt: "Laatste aanvraag verstuurd" +latestRequestReceivedAt: "Laatste aanvraag ontvangen" +latestStatus: "Laatste status" +storageUsage: "Gebruikte opslagruimte" +charts: "Grafieken" +perHour: "Per uur" +perDay: "Per dag" +stopActivityDelivery: "Stop met versturen activiteiten" +blockThisInstance: "Blokkeer deze server" +operations: "Verwerkingen" +software: "Software" +version: "Versie" +metadata: "Metadata" +withNFiles: "{n} bestand(en)" +monitor: "Monitor" +jobQueue: "Job Queue" +cpuAndMemory: "CPU en geheugen" +network: "Netwerk" +disk: "Schijfruimte" +instanceInfo: "Serverinformatie" +statistics: "Statistieken" +clearQueue: "Wachtrij wissen" +clearQueueConfirmTitle: "Weet je zeker dat je de wachtrji leeg wil maken?" +clearQueueConfirmText: "Niet-bezorgde biljetten die nog in de wachtrij staan, worden niet gefedereerd. Meestal is deze operatie niet nodig." +clearCachedFiles: "Cache opschonen" +clearCachedFilesConfirm: "Weet je zeker dat je alle externe bestanden in de cache wilt verwijderen?" +blockedInstances: "Geblokkeerde servers" +blockedInstancesDescription: "Maak een lijst van de servers die moeten worden geblokkeerd, gescheiden door regeleinden. Geblokkeerde servers kunnen niet meer communiceren met deze server." +muteAndBlock: "Gedempt en geblokkeerd" +mutedUsers: "Gedempte gebruikers" +blockedUsers: "Geblokkeerde gebruikers" +noUsers: "Er zijn geen gebruikers." +editProfile: "Bewerk Profiel" +noteDeleteConfirm: "Ben je zeker dat je dit bericht wil verwijderen?" +pinLimitExceeded: "Je kunt geen berichten meer vastprikken" +intro: "Installatie van Misskey geëindigd! Maak nu een beheerder aan." +done: "Klaar" +processing: "Bezig met verwerken" +preview: "Voorbeeld" +default: "Standaard" +noCustomEmojis: "Er zijn geen emojis" +noJobs: "Er zijn geen taken" +federating: "Federeren" +blocked: "Geblokkeerd" +suspended: "Opgeschort" +all: "Alle" +subscribing: "Abonneren" +publishing: "Publiceren" +notResponding: "Reageert niet" +instanceFollowing: "Volgend op server" +instanceFollowers: "Volgers op server" +instanceUsers: "Gebruikers van deze server" +changePassword: "Wachtwoord wijzigen" +security: "Beveiliging" +retypedNotMatch: "Invoer komt niet overeen" +currentPassword: "Huidig wachtwoord" +newPassword: "Nieuwe wachtwoord" +newPasswordRetype: "Nieuw wachtwoord (herhalen)" +attachFile: "Bestanden toevoegen" +more: "Meer!" +featured: "Uitgelicht" +usernameOrUserId: "Gebruikersnaam of id" +noSuchUser: "Gebruiker niet gevonden" +lookup: "Opzoeken" +announcements: "Aankondigingen" +imageUrl: "AfbeeldingsURL" remove: "Verwijderen" +removed: "Succesvol verwijderd" +removeAreYouSure: "Weet je zeker dat je \"{x}\" wil verwijderen?" +deleteAreYouSure: "Weet je zeker dat je \"{x}\" wil verwijderen?" +resetAreYouSure: "Resetten?" +saved: "Opgeslagen" +messaging: "Chat" +upload: "Uploaden" +fromDrive: "Van schijf" +fromUrl: "Van URL" +uploadFromUrl: "Uploaden vanaf een URL" +uploadFromUrlDescription: "URL van het bestand dat je wil uploaden" +uploadFromUrlRequested: "Uploadverzoek" +uploadFromUrlMayTakeTime: "Het kan even duren voordat het uploaden voltooid is." +explore: "Verkennen" +games: "Misskey spellen" +messageRead: "Lezen" +noMoreHistory: "Er is geen verdere geschiedenis" +startMessaging: "Start een gesprek" +nUsersRead: "gelezen door {n}" +agreeTo: "Ik stem in met {0}" +tos: "Gebruiksvoorwaarden" +start: "Aan de slag" +home: "Startpagina" +remoteUserCaution: "Aangezien deze gebruiker van een externe server afkomstig is, kan de weergegeven informatie onvolledig zijn." +activity: "Activiteit" +images: "Afbeeldingen" +birthday: "Geboortedatum" +yearsOld: "{age} jaar" +registeredDate: "Inschrijvingsdatum" +location: "Locatie" +theme: "Thema's" +themeForLightMode: "Thema voor gebruik in de lichte modus" +themeForDarkMode: "Thema voor gebruik in de donkere modus" +light: "Licht" +dark: "Donker" +lightThemes: "Licht thema's" +darkThemes: "Donkere thema's" +syncDeviceDarkMode: "Synchroniseer donkere modus met je apparaatinstellingen" +drive: "Schijf" +fileName: "Bestandsnaam" +selectFile: "Kies een bestand" +selectFiles: "Selecteer bestanden" +selectFolder: "Kies een map" +selectFolders: "Kies mappen" +renameFile: "Wijzig bestandsnaam" +folderName: "Mapnaam" +createFolder: "Map aanmaken" +renameFolder: "Map hernoemen" nsfw: "NSFW" pinnedNotes: "Vastgemaakte notitie" userList: "Lijsten" +smtpHost: "Server" smtpUser: "Gebruikersnaam" smtpPass: "Wachtwoord" +clearCache: "Cache opschonen" user: "Gebruikers" muteThread: "Discussies dempen " unmuteThread: "Dempen van discussie ongedaan maken" +hide: "Verbergen" _email: _follow: title: "volgde jou" @@ -144,12 +272,17 @@ _theme: _sfx: note: "Notities" notification: "Meldingen" + chat: "Chat" _widgets: notifications: "Meldingen" timeline: "Tijdlijn" + activity: "Activiteit" + federation: "Federatie" + jobQueue: "Job Queue" _cw: show: "Laad meer" _visibility: + home: "Startpagina" followers: "Volgers" _profile: username: "Gebruikersnaam" @@ -158,7 +291,18 @@ _exportOrImport: muteList: "Dempen" blockingList: "Blokkeren" userLists: "Lijsten" + excludeMutingUsers: "Negeer gedempte gebruikers" + excludeInactiveUsers: "Negeer inactieve gebruikers" +_timelines: + home: "Startpagina" +_rooms: + _roomType: + default: "Standaard" + _furnitures: + monitor: "Monitor" _pages: + blocks: + image: "Afbeeldingen" script: categories: list: "Lijsten" diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index 1a52f35235..0d744167d3 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -738,6 +738,7 @@ ratio: "Stosunek" global: "Globalna" sent: "Wyślij" hashtags: "Hashtag" +hide: "Ukryj" _ffVisibility: public: "Publikuj" _ad: diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 1d889866db..e0a049b7f3 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -802,6 +802,7 @@ makeReactionsPublicDescription: "Список сделанных вами реа classic: "Классика" unmuteThread: "Отключить звук" ffVisibilityDescription: "Вы можете установить объем вашей следующей/последней информации." +hide: "Спрятать" _emailUnavailable: used: "Уже используется" format: "Неправильный формат" @@ -923,6 +924,7 @@ _mfm: sparkle: "Блеск" sparkleDescription: "Добавьте эффект искрящихся частиц." rotate: "Повернуть" + rotateDescription: "Повернуть на указанный угол." _reversi: reversi: "Реверси" gameSettings: "Настройки игры" diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index 9104b0839d..375f05f735 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -692,6 +692,7 @@ middle: "Середній" global: "Глобальна" sent: "Відправити" hashtags: "Хештеґ" +hide: "Сховати" _ad: back: "Назад" _gallery: diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 829c47e7dc..410d322191 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -592,6 +592,7 @@ smtpSecure: "在 SMTP 连接中使用隐式 SSL / TLS" smtpSecureInfo: "使用STARTTLS时关闭。" testEmail: "邮件发送测试" wordMute: "文字屏蔽" +instanceMute: "实例的屏蔽" userSaysSomething: "{name}说了什么" makeActive: "启用" display: "显示" @@ -811,6 +812,7 @@ continueThread: "查看更多帖子" deleteAccountConfirm: "将要删除账户。是否确认?" incorrectPassword: "密码错误" voteConfirm: "确定投给“{choice}” ?" +hide: "隐藏" _emailUnavailable: used: "已经被使用过" format: "无效的格式" @@ -1001,6 +1003,11 @@ _wordMute: soft: "软屏蔽" hard: "硬屏蔽" mutedNotes: "被屏蔽的帖子" +_instanceMute: + instanceMuteDescription: "屏蔽配置实例中的所有帖子和转帖,包括实例的用户回复。" + instanceMuteDescription2: "设置时用换行符来分隔" + title: "隐藏实例已设置的帖子。" + heading: "屏蔽实例" _theme: explore: "寻找主题" install: "安装主题" @@ -1274,6 +1281,8 @@ _exportOrImport: muteList: "屏蔽" blockingList: "拉黑" userLists: "列表" + excludeMutingUsers: "排除屏蔽用户" + excludeInactiveUsers: "排除不活跃用户" _charts: federationInstancesIncDec: "联合:增加/减少" federationInstancesTotal: "联合总数" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 56eaaa0f0d..bba04170e1 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -754,6 +754,7 @@ ratio: "%" global: "公開" sent: "發送" hashtags: "#tag" +hide: "隱藏" _ffVisibility: public: "發佈" _ad: diff --git a/package.json b/package.json index ef08f2d5e8..3e7e4b9d6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "12.98.0", + "version": "12.100.1", "codename": "indigo", "repository": { "type": "git", diff --git a/packages/backend/migration/1639325650583-chart-v3.js b/packages/backend/migration/1639325650583-chart-v3.js new file mode 100644 index 0000000000..b9d8814c69 --- /dev/null +++ b/packages/backend/migration/1639325650583-chart-v3.js @@ -0,0 +1,189 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV31639325650583 { + name = 'chartV31639325650583' + + async up(queryRunner) { + await queryRunner.query(`DELETE FROM "__chart__per_user_drive" WHERE "group" IS NULL`); + + await queryRunner.query(`DROP INDEX "public"."IDX_dd907becf76104e4b656659e6b"`); + await queryRunner.query(`DROP INDEX "public"."IDX_eddfed8fb40305a04c6f941050"`); + await queryRunner.query(`DROP INDEX "public"."IDX_f09d543e3acb16c5976bdb31fa"`); + await queryRunner.query(`DROP INDEX "public"."IDX_e60c358aaced5aab8900a4af31"`); + await queryRunner.query(`DROP INDEX "public"."IDX_337e9599f278bd7537fe30876f"`); + await queryRunner.query(`DROP INDEX "public"."IDX_66feba81e1795d176d06c0b1e6"`); + await queryRunner.query(`DROP INDEX "public"."IDX_0a905b992fecd2b5c3fb98759e"`); + await queryRunner.query(`DROP INDEX "public"."IDX_2082327b2699ce924fa654afc5"`); + await queryRunner.query(`DROP INDEX "public"."IDX_9a3ed15a30ab7e3a37702e6e08"`); + await queryRunner.query(`DROP INDEX "public"."IDX_60c5c6e7e538c09aa274ecd1cf"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8111b817b9818c04d7eb8475b1"`); + await queryRunner.query(`DROP INDEX "public"."IDX_583a157ed0cf0ed1b5ec2a833f"`); + await queryRunner.query(`DROP INDEX "public"."IDX_3313d7288855ec105b5bbf6c21"`); + await queryRunner.query(`DROP INDEX "public"."IDX_ceab80a6729f8e2e6f5b8a1a3d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_3b7697a96f522d0478972e6d6f"`); + await queryRunner.query(`DROP INDEX "public"."IDX_53a3604b939e2b479eb2cfaac8"`); + await queryRunner.query(`DROP INDEX "public"."IDX_dabbb38a51ab86ee3cab291326"`); + await queryRunner.query(`DROP INDEX "public"."IDX_a9a806d466b314f253a1a611c4"`); + await queryRunner.query(`CREATE TABLE "__chart_day__federation" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "___instance_total" bigint NOT NULL, "___instance_inc" bigint NOT NULL, "___instance_dec" bigint NOT NULL, CONSTRAINT "UQ_617a8fe225a6e701d89e02d2c74" UNIQUE ("date"), CONSTRAINT "PK_7ca721c769f31698e0e1331e8e6" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_617a8fe225a6e701d89e02d2c7" ON "__chart_day__federation" ("date") `); + await queryRunner.query(`CREATE TABLE "__chart_day__notes" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "___local_total" bigint NOT NULL, "___local_inc" bigint NOT NULL, "___local_dec" bigint NOT NULL, "___local_diffs_normal" bigint NOT NULL, "___local_diffs_reply" bigint NOT NULL, "___local_diffs_renote" bigint NOT NULL, "___remote_total" bigint NOT NULL, "___remote_inc" bigint NOT NULL, "___remote_dec" bigint NOT NULL, "___remote_diffs_normal" bigint NOT NULL, "___remote_diffs_reply" bigint NOT NULL, "___remote_diffs_renote" bigint NOT NULL, CONSTRAINT "UQ_1a527b423ad0858a1af5a056d43" UNIQUE ("date"), CONSTRAINT "PK_1fa4139e1f338272b758d05e090" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_1a527b423ad0858a1af5a056d4" ON "__chart_day__notes" ("date") `); + await queryRunner.query(`CREATE TABLE "__chart_day__users" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "___local_total" bigint NOT NULL, "___local_inc" bigint NOT NULL, "___local_dec" bigint NOT NULL, "___remote_total" bigint NOT NULL, "___remote_inc" bigint NOT NULL, "___remote_dec" bigint NOT NULL, CONSTRAINT "UQ_cad6e07c20037f31cdba8a350c3" UNIQUE ("date"), CONSTRAINT "PK_d7f7185abb9851f70c4726c54bd" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_cad6e07c20037f31cdba8a350c" ON "__chart_day__users" ("date") `); + await queryRunner.query(`CREATE TABLE "__chart_day__network" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "___incomingRequests" bigint NOT NULL, "___outgoingRequests" bigint NOT NULL, "___totalTime" bigint NOT NULL, "___incomingBytes" bigint NOT NULL, "___outgoingBytes" bigint NOT NULL, CONSTRAINT "UQ_8bfa548c2b31f9e07db113773ee" UNIQUE ("date"), CONSTRAINT "PK_cac499d6f471042dfed1e7e0132" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_8bfa548c2b31f9e07db113773e" ON "__chart_day__network" ("date") `); + await queryRunner.query(`CREATE TABLE "__chart_day__active_users" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "___local_users" character varying array NOT NULL, "___remote_users" character varying array NOT NULL, CONSTRAINT "UQ_d5954f3df5e5e3bdfc3c03f3906" UNIQUE ("date"), CONSTRAINT "PK_b1790489b14f005ae8f404f5795" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d5954f3df5e5e3bdfc3c03f390" ON "__chart_day__active_users" ("date") `); + await queryRunner.query(`CREATE TABLE "__chart_day__instance" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128) NOT NULL, "___requests_failed" bigint NOT NULL, "___requests_succeeded" bigint NOT NULL, "___requests_received" bigint NOT NULL, "___notes_total" bigint NOT NULL, "___notes_inc" bigint NOT NULL, "___notes_dec" bigint NOT NULL, "___notes_diffs_normal" bigint NOT NULL, "___notes_diffs_reply" bigint NOT NULL, "___notes_diffs_renote" bigint NOT NULL, "___users_total" bigint NOT NULL, "___users_inc" bigint NOT NULL, "___users_dec" bigint NOT NULL, "___following_total" bigint NOT NULL, "___following_inc" bigint NOT NULL, "___following_dec" bigint NOT NULL, "___followers_total" bigint NOT NULL, "___followers_inc" bigint NOT NULL, "___followers_dec" bigint NOT NULL, "___drive_totalFiles" bigint NOT NULL, "___drive_totalUsage" bigint NOT NULL, "___drive_incFiles" bigint NOT NULL, "___drive_incUsage" bigint NOT NULL, "___drive_decFiles" bigint NOT NULL, "___drive_decUsage" bigint NOT NULL, CONSTRAINT "UQ_fea7c0278325a1a2492f2d6acbf" UNIQUE ("date", "group"), CONSTRAINT "PK_479a8ff9d959274981087043023" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_fea7c0278325a1a2492f2d6acb" ON "__chart_day__instance" ("date", "group") `); + await queryRunner.query(`CREATE TABLE "__chart_day__per_user_notes" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128) NOT NULL, "___total" bigint NOT NULL, "___inc" bigint NOT NULL, "___dec" bigint NOT NULL, "___diffs_normal" bigint NOT NULL, "___diffs_reply" bigint NOT NULL, "___diffs_renote" bigint NOT NULL, CONSTRAINT "UQ_c5545d4b31cdc684034e33b81c3" UNIQUE ("date", "group"), CONSTRAINT "PK_58bab6b6d3ad9310cbc7460fd28" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_c5545d4b31cdc684034e33b81c" ON "__chart_day__per_user_notes" ("date", "group") `); + await queryRunner.query(`CREATE TABLE "__chart_day__drive" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "___local_totalCount" bigint NOT NULL, "___local_totalSize" bigint NOT NULL, "___local_incCount" bigint NOT NULL, "___local_incSize" bigint NOT NULL, "___local_decCount" bigint NOT NULL, "___local_decSize" bigint NOT NULL, "___remote_totalCount" bigint NOT NULL, "___remote_totalSize" bigint NOT NULL, "___remote_incCount" bigint NOT NULL, "___remote_incSize" bigint NOT NULL, "___remote_decCount" bigint NOT NULL, "___remote_decSize" bigint NOT NULL, CONSTRAINT "UQ_0b60ebb3aa0065f10b0616c1171" UNIQUE ("date"), CONSTRAINT "PK_e7ec0de057c77c40fc8d8b62151" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0b60ebb3aa0065f10b0616c117" ON "__chart_day__drive" ("date") `); + await queryRunner.query(`CREATE TABLE "__chart_day__per_user_reaction" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128) NOT NULL, "___local_count" bigint NOT NULL, "___remote_count" bigint NOT NULL, CONSTRAINT "UQ_d54b653660d808b118e36c184c0" UNIQUE ("date", "group"), CONSTRAINT "PK_8af24e2d51ff781a354fe595eda" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d54b653660d808b118e36c184c" ON "__chart_day__per_user_reaction" ("date", "group") `); + await queryRunner.query(`CREATE TABLE "__chart_day__hashtag" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128) NOT NULL, "___local_users" character varying array NOT NULL, "___remote_users" character varying array NOT NULL, CONSTRAINT "UQ_8f589cf056ff51f09d6096f6450" UNIQUE ("date", "group"), CONSTRAINT "PK_13d5a3b089344e5557f8e0980b4" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_8f589cf056ff51f09d6096f645" ON "__chart_day__hashtag" ("date", "group") `); + await queryRunner.query(`CREATE TABLE "__chart_day__per_user_following" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128) NOT NULL, "___local_followings_total" bigint NOT NULL, "___local_followings_inc" bigint NOT NULL, "___local_followings_dec" bigint NOT NULL, "___local_followers_total" bigint NOT NULL, "___local_followers_inc" bigint NOT NULL, "___local_followers_dec" bigint NOT NULL, "___remote_followings_total" bigint NOT NULL, "___remote_followings_inc" bigint NOT NULL, "___remote_followings_dec" bigint NOT NULL, "___remote_followers_total" bigint NOT NULL, "___remote_followers_inc" bigint NOT NULL, "___remote_followers_dec" bigint NOT NULL, CONSTRAINT "UQ_e4849a3231f38281280ea4c0eee" UNIQUE ("date", "group"), CONSTRAINT "PK_68ce6b67da57166da66fc8fb27e" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e4849a3231f38281280ea4c0ee" ON "__chart_day__per_user_following" ("date", "group") `); + await queryRunner.query(`CREATE TABLE "__chart_day__per_user_drive" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128) NOT NULL, "___totalCount" bigint NOT NULL, "___totalSize" bigint NOT NULL, "___incCount" bigint NOT NULL, "___incSize" bigint NOT NULL, "___decCount" bigint NOT NULL, "___decSize" bigint NOT NULL, CONSTRAINT "UQ_62aa5047b5aec92524f24c701d7" UNIQUE ("date", "group"), CONSTRAINT "PK_1ae135254c137011645da7f4045" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_62aa5047b5aec92524f24c701d" ON "__chart_day__per_user_drive" ("date", "group") `); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "group"`); + await queryRunner.query(`ALTER TABLE "__chart__notes" DROP COLUMN "group"`); + await queryRunner.query(`ALTER TABLE "__chart__users" DROP COLUMN "group"`); + await queryRunner.query(`ALTER TABLE "__chart__network" DROP COLUMN "group"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "group"`); + await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "group"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD CONSTRAINT "UQ_36cb699c49580d4e6c2e6159f97" UNIQUE ("date")`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ADD CONSTRAINT "UQ_42eb716a37d381cdf566192b2be" UNIQUE ("date")`); + await queryRunner.query(`ALTER TABLE "__chart__users" ADD CONSTRAINT "UQ_845254b3eaf708ae8a6cac30265" UNIQUE ("date")`); + await queryRunner.query(`ALTER TABLE "__chart__network" ADD CONSTRAINT "UQ_a1efd3e0048a5f2793a47360dc6" UNIQUE ("date")`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD CONSTRAINT "UQ_0ad37b7ef50f4ddc84363d7ccca" UNIQUE ("date")`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___local_users" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___remote_users" DROP DEFAULT`); + await queryRunner.query(`DROP INDEX "public"."IDX_39ee857ab2f23493037c6b6631"`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "group" SET NOT NULL`); + await queryRunner.query(`DROP INDEX "public"."IDX_5048e9daccbbbc6d567bb142d3"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "group" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ADD CONSTRAINT "UQ_13565815f618a1ff53886c5b28a" UNIQUE ("date")`); + await queryRunner.query(`DROP INDEX "public"."IDX_229a41ad465f9205f1f5703291"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "group" SET NOT NULL`); + await queryRunner.query(`DROP INDEX "public"."IDX_25a97c02003338124b2b75fdbc"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "group" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___local_users" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___remote_users" DROP DEFAULT`); + await queryRunner.query(`DROP INDEX "public"."IDX_b77d4dd9562c3a899d9a286fcd"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "group" SET NOT NULL`); + await queryRunner.query(`DROP INDEX "public"."IDX_30bf67687f483ace115c5ca642"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "group" SET NOT NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_36cb699c49580d4e6c2e6159f9" ON "__chart__federation" ("date") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_42eb716a37d381cdf566192b2b" ON "__chart__notes" ("date") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_845254b3eaf708ae8a6cac3026" ON "__chart__users" ("date") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a1efd3e0048a5f2793a47360dc" ON "__chart__network" ("date") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc" ON "__chart__active_users" ("date") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_13565815f618a1ff53886c5b28" ON "__chart__drive" ("date") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `); + await queryRunner.query(`ALTER TABLE "__chart__instance" ADD CONSTRAINT "UQ_39ee857ab2f23493037c6b66311" UNIQUE ("date", "group")`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ADD CONSTRAINT "UQ_5048e9daccbbbc6d567bb142d34" UNIQUE ("date", "group")`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ADD CONSTRAINT "UQ_229a41ad465f9205f1f57032910" UNIQUE ("date", "group")`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD CONSTRAINT "UQ_25a97c02003338124b2b75fdbc8" UNIQUE ("date", "group")`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ADD CONSTRAINT "UQ_b77d4dd9562c3a899d9a286fcd7" UNIQUE ("date", "group")`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ADD CONSTRAINT "UQ_30bf67687f483ace115c5ca6429" UNIQUE ("date", "group")`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" DROP CONSTRAINT "UQ_30bf67687f483ace115c5ca6429"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" DROP CONSTRAINT "UQ_b77d4dd9562c3a899d9a286fcd7"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP CONSTRAINT "UQ_25a97c02003338124b2b75fdbc8"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" DROP CONSTRAINT "UQ_229a41ad465f9205f1f57032910"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" DROP CONSTRAINT "UQ_5048e9daccbbbc6d567bb142d34"`); + await queryRunner.query(`ALTER TABLE "__chart__instance" DROP CONSTRAINT "UQ_39ee857ab2f23493037c6b66311"`); + await queryRunner.query(`DROP INDEX "public"."IDX_30bf67687f483ace115c5ca642"`); + await queryRunner.query(`DROP INDEX "public"."IDX_b77d4dd9562c3a899d9a286fcd"`); + await queryRunner.query(`DROP INDEX "public"."IDX_25a97c02003338124b2b75fdbc"`); + await queryRunner.query(`DROP INDEX "public"."IDX_229a41ad465f9205f1f5703291"`); + await queryRunner.query(`DROP INDEX "public"."IDX_13565815f618a1ff53886c5b28"`); + await queryRunner.query(`DROP INDEX "public"."IDX_5048e9daccbbbc6d567bb142d3"`); + await queryRunner.query(`DROP INDEX "public"."IDX_39ee857ab2f23493037c6b6631"`); + await queryRunner.query(`DROP INDEX "public"."IDX_0ad37b7ef50f4ddc84363d7ccc"`); + await queryRunner.query(`DROP INDEX "public"."IDX_a1efd3e0048a5f2793a47360dc"`); + await queryRunner.query(`DROP INDEX "public"."IDX_845254b3eaf708ae8a6cac3026"`); + await queryRunner.query(`DROP INDEX "public"."IDX_42eb716a37d381cdf566192b2b"`); + await queryRunner.query(`DROP INDEX "public"."IDX_36cb699c49580d4e6c2e6159f9"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "group" DROP NOT NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "group" DROP NOT NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___remote_users" SET DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___local_users" SET DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "group" DROP NOT NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "group" DROP NOT NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `); + await queryRunner.query(`ALTER TABLE "__chart__drive" DROP CONSTRAINT "UQ_13565815f618a1ff53886c5b28a"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "group" DROP NOT NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "group" DROP NOT NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___remote_users" SET DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___local_users" SET DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP CONSTRAINT "UQ_0ad37b7ef50f4ddc84363d7ccca"`); + await queryRunner.query(`ALTER TABLE "__chart__network" DROP CONSTRAINT "UQ_a1efd3e0048a5f2793a47360dc6"`); + await queryRunner.query(`ALTER TABLE "__chart__users" DROP CONSTRAINT "UQ_845254b3eaf708ae8a6cac30265"`); + await queryRunner.query(`ALTER TABLE "__chart__notes" DROP CONSTRAINT "UQ_42eb716a37d381cdf566192b2be"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP CONSTRAINT "UQ_36cb699c49580d4e6c2e6159f97"`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "group" character varying(128)`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "group" character varying(128)`); + await queryRunner.query(`ALTER TABLE "__chart__network" ADD "group" character varying(128)`); + await queryRunner.query(`ALTER TABLE "__chart__users" ADD "group" character varying(128)`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ADD "group" character varying(128)`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "group" character varying(128)`); + await queryRunner.query(`DROP INDEX "public"."IDX_62aa5047b5aec92524f24c701d"`); + await queryRunner.query(`DROP TABLE "__chart_day__per_user_drive"`); + await queryRunner.query(`DROP INDEX "public"."IDX_e4849a3231f38281280ea4c0ee"`); + await queryRunner.query(`DROP TABLE "__chart_day__per_user_following"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8f589cf056ff51f09d6096f645"`); + await queryRunner.query(`DROP TABLE "__chart_day__hashtag"`); + await queryRunner.query(`DROP INDEX "public"."IDX_d54b653660d808b118e36c184c"`); + await queryRunner.query(`DROP TABLE "__chart_day__per_user_reaction"`); + await queryRunner.query(`DROP INDEX "public"."IDX_0b60ebb3aa0065f10b0616c117"`); + await queryRunner.query(`DROP TABLE "__chart_day__drive"`); + await queryRunner.query(`DROP INDEX "public"."IDX_c5545d4b31cdc684034e33b81c"`); + await queryRunner.query(`DROP TABLE "__chart_day__per_user_notes"`); + await queryRunner.query(`DROP INDEX "public"."IDX_fea7c0278325a1a2492f2d6acb"`); + await queryRunner.query(`DROP TABLE "__chart_day__instance"`); + await queryRunner.query(`DROP INDEX "public"."IDX_d5954f3df5e5e3bdfc3c03f390"`); + await queryRunner.query(`DROP TABLE "__chart_day__active_users"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8bfa548c2b31f9e07db113773e"`); + await queryRunner.query(`DROP TABLE "__chart_day__network"`); + await queryRunner.query(`DROP INDEX "public"."IDX_cad6e07c20037f31cdba8a350c"`); + await queryRunner.query(`DROP TABLE "__chart_day__users"`); + await queryRunner.query(`DROP INDEX "public"."IDX_1a527b423ad0858a1af5a056d4"`); + await queryRunner.query(`DROP TABLE "__chart_day__notes"`); + await queryRunner.query(`DROP INDEX "public"."IDX_617a8fe225a6e701d89e02d2c7"`); + await queryRunner.query(`DROP TABLE "__chart_day__federation"`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a9a806d466b314f253a1a611c4" ON "__chart__per_user_drive" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dabbb38a51ab86ee3cab291326" ON "__chart__per_user_following" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_53a3604b939e2b479eb2cfaac8" ON "__chart__hashtag" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_3b7697a96f522d0478972e6d6f" ON "__chart__per_user_reaction" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ceab80a6729f8e2e6f5b8a1a3d" ON "__chart__drive" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_3313d7288855ec105b5bbf6c21" ON "__chart__drive" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_583a157ed0cf0ed1b5ec2a833f" ON "__chart__per_user_notes" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_8111b817b9818c04d7eb8475b1" ON "__chart__instance" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_60c5c6e7e538c09aa274ecd1cf" ON "__chart__active_users" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_9a3ed15a30ab7e3a37702e6e08" ON "__chart__active_users" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2082327b2699ce924fa654afc5" ON "__chart__network" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0a905b992fecd2b5c3fb98759e" ON "__chart__network" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_66feba81e1795d176d06c0b1e6" ON "__chart__users" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_337e9599f278bd7537fe30876f" ON "__chart__users" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e60c358aaced5aab8900a4af31" ON "__chart__notes" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_f09d543e3acb16c5976bdb31fa" ON "__chart__notes" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_eddfed8fb40305a04c6f941050" ON "__chart__federation" ("date") WHERE ("group" IS NULL)`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dd907becf76104e4b656659e6b" ON "__chart__federation" ("date", "group") `); + } +} diff --git a/packages/backend/package.json b/packages/backend/package.json index abcde0ab72..ffd179dfa3 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -170,7 +170,7 @@ "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", "style-loader": "3.3.1", - "summaly": "2.4.1", + "summaly": "2.5.0", "syslog-pro": "1.0.0", "systeminformation": "5.9.9", "throttle-debounce": "3.0.1", diff --git a/packages/backend/src/db/postgre.ts b/packages/backend/src/db/postgre.ts index 4daf6b4434..b5f228d919 100644 --- a/packages/backend/src/db/postgre.ts +++ b/packages/backend/src/db/postgre.ts @@ -3,10 +3,10 @@ const types = require('pg').types; types.setTypeParser(20, Number); import { createConnection, Logger, getConnection } from 'typeorm'; -import config from '@/config/index'; -import { entities as charts } from '@/services/chart/entities'; -import { dbLogger } from './logger'; import * as highlight from 'cli-highlight'; +import config from '@/config/index'; + +import { dbLogger } from './logger'; import { User } from '@/models/entities/user'; import { DriveFile } from '@/models/entities/drive-file'; @@ -74,6 +74,8 @@ import { Ad } from '@/models/entities/ad'; import { PasswordResetRequest } from '@/models/entities/password-reset-request'; import { UserPending } from '@/models/entities/user-pending'; +import { entities as charts } from '@/services/chart/entities'; + const sqlLogger = dbLogger.createSubLogger('sql', 'white', false); class MyCustomLogger implements Logger { @@ -175,7 +177,7 @@ export const entities = [ Ad, PasswordResetRequest, UserPending, - ...charts as any, + ...charts, ]; export function initDb(justBorrow = false, sync = false, forceRecreate = false) { diff --git a/packages/backend/src/queue/processors/db/export-custom-emojis.ts b/packages/backend/src/queue/processors/db/export-custom-emojis.ts index ed0ad249a5..925b187970 100644 --- a/packages/backend/src/queue/processors/db/export-custom-emojis.ts +++ b/packages/backend/src/queue/processors/db/export-custom-emojis.ts @@ -39,16 +39,20 @@ export async function exportCustomEmojis(job: Bull.Job, done: () => void): Promi const metaStream = fs.createWriteStream(metaPath, { flags: 'a' }); - await new Promise((res, rej) => { - metaStream.write('[', err => { - if (err) { - logger.error(err); - rej(err); - } else { - res(); - } + const writeMeta = (text: string): Promise => { + return new Promise((res, rej) => { + metaStream.write(text, err => { + if (err) { + logger.error(err); + rej(err); + } else { + res(); + } + }); }); - }); + }; + + await writeMeta(`{"metaVersion":1,"emojis":[`); const customEmojis = await Emojis.find({ where: { @@ -72,34 +76,17 @@ export async function exportCustomEmojis(job: Bull.Job, done: () => void): Promi logger.error(e); } - await new Promise((res, rej) => { - const content = JSON.stringify({ - id: exportId, - downloaded: downloaded, - emoji: emoji, - }); - const isFirst = customEmojis.indexOf(emoji) === 0; - metaStream.write(isFirst ? content : ',\n' + content, err => { - if (err) { - logger.error(err); - rej(err); - } else { - res(); - } - }); + const content = JSON.stringify({ + id: exportId, + downloaded: downloaded, + emoji: emoji, }); + const isFirst = customEmojis.indexOf(emoji) === 0; + + await writeMeta(isFirst ? content : ',\n' + content); } - await new Promise((res, rej) => { - metaStream.write(']', err => { - if (err) { - logger.error(err); - rej(err); - } else { - res(); - } - }); - }); + await writeMeta(']}'); metaStream.end(); diff --git a/packages/backend/src/queue/processors/db/export-notes.ts b/packages/backend/src/queue/processors/db/export-notes.ts index 7220455edc..e64e763513 100644 --- a/packages/backend/src/queue/processors/db/export-notes.ts +++ b/packages/backend/src/queue/processors/db/export-notes.ts @@ -34,16 +34,20 @@ export async function exportNotes(job: Bull.Job, done: any): Prom const stream = fs.createWriteStream(path, { flags: 'a' }); - await new Promise((res, rej) => { - stream.write('[', err => { - if (err) { - logger.error(err); - rej(err); - } else { - res(); - } + const write = (text: string): Promise => { + return new Promise((res, rej) => { + stream.write(text, err => { + if (err) { + logger.error(err); + rej(err); + } else { + res(); + } + }); }); - }); + }; + + await write('['); let exportedNotesCount = 0; let cursor: Note['id'] | null = null; @@ -73,17 +77,8 @@ export async function exportNotes(job: Bull.Job, done: any): Prom poll = await Polls.findOneOrFail({ noteId: note.id }); } const content = JSON.stringify(serialize(note, poll)); - await new Promise((res, rej) => { - const isFirst = exportedNotesCount === 0; - stream.write(isFirst ? content : ',\n' + content, err => { - if (err) { - logger.error(err); - rej(err); - } else { - res(); - } - }); - }); + const isFirst = exportedNotesCount === 0; + await write(isFirst ? content : ',\n' + content); exportedNotesCount++; } @@ -94,16 +89,7 @@ export async function exportNotes(job: Bull.Job, done: any): Prom job.progress(exportedNotesCount / total); } - await new Promise((res, rej) => { - stream.write(']', err => { - if (err) { - logger.error(err); - rej(err); - } else { - res(); - } - }); - }); + await write(']'); stream.end(); logger.succ(`Exported to: ${path}`); diff --git a/packages/backend/src/services/chart/charts/classes/active-users.ts b/packages/backend/src/services/chart/charts/active-users.ts similarity index 81% rename from packages/backend/src/services/chart/charts/classes/active-users.ts rename to packages/backend/src/services/chart/charts/active-users.ts index 029e93a391..9490101e36 100644 --- a/packages/backend/src/services/chart/charts/classes/active-users.ts +++ b/packages/backend/src/services/chart/charts/active-users.ts @@ -1,12 +1,16 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { User } from '@/models/entities/user'; import { SchemaType } from '@/misc/schema'; import { Users } from '@/models/index'; -import { name, schema } from '../schemas/active-users'; +import { name, schema } from './entities/active-users'; type ActiveUsersLog = SchemaType; +/** + * アクティブユーザーに関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class ActiveUsersChart extends Chart { constructor() { super(name, schema); @@ -35,7 +39,7 @@ export default class ActiveUsersChart extends Chart { } @autobind - public async update(user: { id: User['id'], host: User['host'] }) { + public async update(user: { id: User['id'], host: User['host'] }): Promise { const update: Obj = { users: [user.id], }; diff --git a/packages/backend/src/services/chart/charts/classes/drive.ts b/packages/backend/src/services/chart/charts/drive.ts similarity index 89% rename from packages/backend/src/services/chart/charts/classes/drive.ts rename to packages/backend/src/services/chart/charts/drive.ts index 2ed8e7fad1..06cf7ebeeb 100644 --- a/packages/backend/src/services/chart/charts/classes/drive.ts +++ b/packages/backend/src/services/chart/charts/drive.ts @@ -1,13 +1,17 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; import { DriveFiles } from '@/models/index'; import { Not, IsNull } from 'typeorm'; import { DriveFile } from '@/models/entities/drive-file'; -import { name, schema } from '../schemas/drive'; +import { name, schema } from './entities/drive'; type DriveLog = SchemaType; +/** + * ドライブに関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class DriveChart extends Chart { constructor() { super(name, schema); @@ -71,7 +75,7 @@ export default class DriveChart extends Chart { } @autobind - public async update(file: DriveFile, isAdditional: boolean) { + public async update(file: DriveFile, isAdditional: boolean): Promise { const update: Obj = {}; update.totalCount = isAdditional ? 1 : -1; diff --git a/packages/backend/src/services/chart/charts/schemas/active-users.ts b/packages/backend/src/services/chart/charts/entities/active-users.ts similarity index 85% rename from packages/backend/src/services/chart/charts/schemas/active-users.ts rename to packages/backend/src/services/chart/charts/entities/active-users.ts index 322fdb8691..d6b49c86c3 100644 --- a/packages/backend/src/services/chart/charts/schemas/active-users.ts +++ b/packages/backend/src/services/chart/charts/entities/active-users.ts @@ -1,4 +1,8 @@ -export const logSchema = { +import Chart from '../../core'; + +export const name = 'activeUsers'; + +const logSchema = { /** * アクティブユーザー */ @@ -12,9 +16,6 @@ export const logSchema = { }, }; -/** - * アクティブユーザーに関するチャート - */ export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -32,4 +33,4 @@ export const schema = { }, }; -export const name = 'activeUsers'; +export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/schemas/drive.ts b/packages/backend/src/services/chart/charts/entities/drive.ts similarity index 93% rename from packages/backend/src/services/chart/charts/schemas/drive.ts rename to packages/backend/src/services/chart/charts/entities/drive.ts index e7d3267931..3362cbd4cb 100644 --- a/packages/backend/src/services/chart/charts/schemas/drive.ts +++ b/packages/backend/src/services/chart/charts/entities/drive.ts @@ -1,3 +1,7 @@ +import Chart from '../../core'; + +export const name = 'drive'; + const logSchema = { /** * 集計期間時点での、全ドライブファイル数 @@ -65,4 +69,4 @@ export const schema = { }, }; -export const name = 'drive'; +export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/schemas/federation.ts b/packages/backend/src/services/chart/charts/entities/federation.ts similarity index 86% rename from packages/backend/src/services/chart/charts/schemas/federation.ts rename to packages/backend/src/services/chart/charts/entities/federation.ts index 1b8bbce0a8..836116bd06 100644 --- a/packages/backend/src/services/chart/charts/schemas/federation.ts +++ b/packages/backend/src/services/chart/charts/entities/federation.ts @@ -1,6 +1,7 @@ -/** - * フェデレーションに関するチャート - */ +import Chart from '../../core'; + +export const name = 'federation'; + export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -26,4 +27,4 @@ export const schema = { }, }; -export const name = 'federation'; +export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/schemas/hashtag.ts b/packages/backend/src/services/chart/charts/entities/hashtag.ts similarity index 84% rename from packages/backend/src/services/chart/charts/schemas/hashtag.ts rename to packages/backend/src/services/chart/charts/entities/hashtag.ts index 6b4eca2978..43e15456a5 100644 --- a/packages/backend/src/services/chart/charts/schemas/hashtag.ts +++ b/packages/backend/src/services/chart/charts/entities/hashtag.ts @@ -1,4 +1,8 @@ -export const logSchema = { +import Chart from '../../core'; + +export const name = 'hashtag'; + +const logSchema = { /** * 投稿したユーザー */ @@ -12,9 +16,6 @@ export const logSchema = { }, }; -/** - * ハッシュタグに関するチャート - */ export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -32,4 +33,4 @@ export const schema = { }, }; -export const name = 'hashtag'; +export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/schemas/instance.ts b/packages/backend/src/services/chart/charts/entities/instance.ts similarity index 97% rename from packages/backend/src/services/chart/charts/schemas/instance.ts rename to packages/backend/src/services/chart/charts/entities/instance.ts index 5f17ac0d11..9d1f651dbb 100644 --- a/packages/backend/src/services/chart/charts/schemas/instance.ts +++ b/packages/backend/src/services/chart/charts/entities/instance.ts @@ -1,6 +1,7 @@ -/** - * インスタンスごとのチャート - */ +import Chart from '../../core'; + +export const name = 'instance'; + export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -154,4 +155,4 @@ export const schema = { }, }; -export const name = 'instance'; +export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/schemas/network.ts b/packages/backend/src/services/chart/charts/entities/network.ts similarity index 89% rename from packages/backend/src/services/chart/charts/schemas/network.ts rename to packages/backend/src/services/chart/charts/entities/network.ts index 1aeb2a8ad5..3d4fffb855 100644 --- a/packages/backend/src/services/chart/charts/schemas/network.ts +++ b/packages/backend/src/services/chart/charts/entities/network.ts @@ -1,6 +1,7 @@ -/** - * ネットワークに関するチャート - */ +import Chart from '../../core'; + +export const name = 'network'; + export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -28,4 +29,4 @@ export const schema = { }, }; -export const name = 'network'; +export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/schemas/notes.ts b/packages/backend/src/services/chart/charts/entities/notes.ts similarity index 92% rename from packages/backend/src/services/chart/charts/schemas/notes.ts rename to packages/backend/src/services/chart/charts/entities/notes.ts index a33e7aa8b9..554d3abe12 100644 --- a/packages/backend/src/services/chart/charts/schemas/notes.ts +++ b/packages/backend/src/services/chart/charts/entities/notes.ts @@ -1,3 +1,7 @@ +import Chart from '../../core'; + +export const name = 'notes'; + const logSchema = { total: { type: 'number' as const, @@ -53,4 +57,4 @@ export const schema = { }, }; -export const name = 'notes'; +export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/schemas/per-user-drive.ts b/packages/backend/src/services/chart/charts/entities/per-user-drive.ts similarity index 92% rename from packages/backend/src/services/chart/charts/schemas/per-user-drive.ts rename to packages/backend/src/services/chart/charts/entities/per-user-drive.ts index 1c7c57afda..ebf64e733e 100644 --- a/packages/backend/src/services/chart/charts/schemas/per-user-drive.ts +++ b/packages/backend/src/services/chart/charts/entities/per-user-drive.ts @@ -1,3 +1,7 @@ +import Chart from '../../core'; + +export const name = 'perUserDrive'; + export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -52,4 +56,4 @@ export const schema = { }, }; -export const name = 'perUserDrive'; +export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/schemas/per-user-following.ts b/packages/backend/src/services/chart/charts/entities/per-user-following.ts similarity index 93% rename from packages/backend/src/services/chart/charts/schemas/per-user-following.ts rename to packages/backend/src/services/chart/charts/entities/per-user-following.ts index 9e7e71f3bb..8016c5fe97 100644 --- a/packages/backend/src/services/chart/charts/schemas/per-user-following.ts +++ b/packages/backend/src/services/chart/charts/entities/per-user-following.ts @@ -1,4 +1,8 @@ -export const logSchema = { +import Chart from '../../core'; + +export const name = 'perUserFollowing'; + +const logSchema = { /** * フォローしている */ @@ -83,4 +87,4 @@ export const schema = { }, }; -export const name = 'perUserFollowing'; +export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/schemas/per-user-notes.ts b/packages/backend/src/services/chart/charts/entities/per-user-notes.ts similarity index 90% rename from packages/backend/src/services/chart/charts/schemas/per-user-notes.ts rename to packages/backend/src/services/chart/charts/entities/per-user-notes.ts index 55b4ff40c0..d8f645b36e 100644 --- a/packages/backend/src/services/chart/charts/schemas/per-user-notes.ts +++ b/packages/backend/src/services/chart/charts/entities/per-user-notes.ts @@ -1,3 +1,7 @@ +import Chart from '../../core'; + +export const name = 'perUserNotes'; + export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -40,4 +44,4 @@ export const schema = { }, }; -export const name = 'perUserNotes'; +export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/schemas/per-user-reactions.ts b/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts similarity index 78% rename from packages/backend/src/services/chart/charts/schemas/per-user-reactions.ts rename to packages/backend/src/services/chart/charts/entities/per-user-reactions.ts index 9af6c3cd54..bcb7012661 100644 --- a/packages/backend/src/services/chart/charts/schemas/per-user-reactions.ts +++ b/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts @@ -1,6 +1,10 @@ -export const logSchema = { +import Chart from '../../core'; + +export const name = 'perUserReaction'; + +const logSchema = { /** - * フォローしている合計 + * 被リアクション数 */ count: { type: 'number' as const, @@ -8,9 +12,6 @@ export const logSchema = { }, }; -/** - * ユーザーごとのリアクションに関するチャート - */ export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -28,4 +29,4 @@ export const schema = { }, }; -export const name = 'perUserReaction'; +export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/schemas/test-grouped.ts b/packages/backend/src/services/chart/charts/entities/test-grouped.ts similarity index 85% rename from packages/backend/src/services/chart/charts/schemas/test-grouped.ts rename to packages/backend/src/services/chart/charts/entities/test-grouped.ts index c2f2e7e886..ca1c8c5700 100644 --- a/packages/backend/src/services/chart/charts/schemas/test-grouped.ts +++ b/packages/backend/src/services/chart/charts/entities/test-grouped.ts @@ -1,3 +1,7 @@ +import Chart from '../../core'; + +export const name = 'testGrouped'; + export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -25,4 +29,4 @@ export const schema = { }, }; -export const name = 'testGrouped'; +export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/schemas/test-unique.ts b/packages/backend/src/services/chart/charts/entities/test-unique.ts similarity index 79% rename from packages/backend/src/services/chart/charts/schemas/test-unique.ts rename to packages/backend/src/services/chart/charts/entities/test-unique.ts index b8da60dc53..2e917ee9ed 100644 --- a/packages/backend/src/services/chart/charts/schemas/test-unique.ts +++ b/packages/backend/src/services/chart/charts/entities/test-unique.ts @@ -1,3 +1,7 @@ +import Chart from '../../core'; + +export const name = 'testUnique'; + export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -13,4 +17,4 @@ export const schema = { }, }; -export const name = 'testUnique'; +export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/schemas/test.ts b/packages/backend/src/services/chart/charts/entities/test.ts similarity index 86% rename from packages/backend/src/services/chart/charts/schemas/test.ts rename to packages/backend/src/services/chart/charts/entities/test.ts index 19c732fece..fa536ff2cf 100644 --- a/packages/backend/src/services/chart/charts/schemas/test.ts +++ b/packages/backend/src/services/chart/charts/entities/test.ts @@ -1,3 +1,7 @@ +import Chart from '../../core'; + +export const name = 'test'; + export const schema = { type: 'object' as const, optional: false as const, nullable: false as const, @@ -25,4 +29,4 @@ export const schema = { }, }; -export const name = 'test'; +export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/schemas/users.ts b/packages/backend/src/services/chart/charts/entities/users.ts similarity index 90% rename from packages/backend/src/services/chart/charts/schemas/users.ts rename to packages/backend/src/services/chart/charts/entities/users.ts index 47e7791974..08d51c9414 100644 --- a/packages/backend/src/services/chart/charts/schemas/users.ts +++ b/packages/backend/src/services/chart/charts/entities/users.ts @@ -1,3 +1,7 @@ +import Chart from '../../core'; + +export const name = 'users'; + const logSchema = { /** * 集計期間時点での、全ユーザー数 @@ -41,4 +45,4 @@ export const schema = { }, }; -export const name = 'users'; +export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/classes/federation.ts b/packages/backend/src/services/chart/charts/federation.ts similarity index 80% rename from packages/backend/src/services/chart/charts/classes/federation.ts rename to packages/backend/src/services/chart/charts/federation.ts index 9f8b7ec0ae..8abb18b51f 100644 --- a/packages/backend/src/services/chart/charts/classes/federation.ts +++ b/packages/backend/src/services/chart/charts/federation.ts @@ -1,11 +1,15 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; import { Instances } from '@/models/index'; -import { name, schema } from '../schemas/federation'; +import { name, schema } from './entities/federation'; type FederationLog = SchemaType; +/** + * フェデレーションに関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class FederationChart extends Chart { constructor() { super(name, schema); @@ -45,7 +49,7 @@ export default class FederationChart extends Chart { } @autobind - public async update(isAdditional: boolean) { + public async update(isAdditional: boolean): Promise { const update: Obj = {}; update.total = isAdditional ? 1 : -1; diff --git a/packages/backend/src/services/chart/charts/classes/hashtag.ts b/packages/backend/src/services/chart/charts/hashtag.ts similarity index 81% rename from packages/backend/src/services/chart/charts/classes/hashtag.ts rename to packages/backend/src/services/chart/charts/hashtag.ts index 53774e566d..34e0614643 100644 --- a/packages/backend/src/services/chart/charts/classes/hashtag.ts +++ b/packages/backend/src/services/chart/charts/hashtag.ts @@ -1,12 +1,16 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { User } from '@/models/entities/user'; import { SchemaType } from '@/misc/schema'; import { Users } from '@/models/index'; -import { name, schema } from '../schemas/hashtag'; +import { name, schema } from './entities/hashtag'; type HashtagLog = SchemaType; +/** + * ハッシュタグに関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class HashtagChart extends Chart { constructor() { super(name, schema, true); @@ -35,7 +39,7 @@ export default class HashtagChart extends Chart { } @autobind - public async update(hashtag: string, user: { id: User['id'], host: User['host'] }) { + public async update(hashtag: string, user: { id: User['id'], host: User['host'] }): Promise { const update: Obj = { users: [user.id], }; diff --git a/packages/backend/src/services/chart/charts/classes/instance.ts b/packages/backend/src/services/chart/charts/instance.ts similarity index 89% rename from packages/backend/src/services/chart/charts/classes/instance.ts rename to packages/backend/src/services/chart/charts/instance.ts index 8e7902d163..7f3419b69c 100644 --- a/packages/backend/src/services/chart/charts/classes/instance.ts +++ b/packages/backend/src/services/chart/charts/instance.ts @@ -1,17 +1,21 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; import { DriveFiles, Followings, Users, Notes } from '@/models/index'; import { DriveFile } from '@/models/entities/drive-file'; -import { name, schema } from '../schemas/instance'; import { Note } from '@/models/entities/note'; import { toPuny } from '@/misc/convert-host'; +import { name, schema } from './entities/instance'; type InstanceLog = SchemaType; +/** + * インスタンスごとのチャート + */ +// eslint-disable-next-line import/no-default-export export default class InstanceChart extends Chart { constructor() { - super(name, schema); + super(name, schema, true); } @autobind @@ -119,7 +123,7 @@ export default class InstanceChart extends Chart { } @autobind - public async requestReceived(host: string) { + public async requestReceived(host: string): Promise { await this.inc({ requests: { received: 1, @@ -128,7 +132,7 @@ export default class InstanceChart extends Chart { } @autobind - public async requestSent(host: string, isSucceeded: boolean) { + public async requestSent(host: string, isSucceeded: boolean): Promise { const update: Obj = {}; if (isSucceeded) { @@ -143,7 +147,7 @@ export default class InstanceChart extends Chart { } @autobind - public async newUser(host: string) { + public async newUser(host: string): Promise { await this.inc({ users: { total: 1, @@ -153,8 +157,8 @@ export default class InstanceChart extends Chart { } @autobind - public async updateNote(host: string, note: Note, isAdditional: boolean) { - const diffs = {} as any; + public async updateNote(host: string, note: Note, isAdditional: boolean): Promise { + const diffs = {} as Record; if (note.replyId != null) { diffs.reply = isAdditional ? 1 : -1; @@ -175,7 +179,7 @@ export default class InstanceChart extends Chart { } @autobind - public async updateFollowing(host: string, isAdditional: boolean) { + public async updateFollowing(host: string, isAdditional: boolean): Promise { await this.inc({ following: { total: isAdditional ? 1 : -1, @@ -186,7 +190,7 @@ export default class InstanceChart extends Chart { } @autobind - public async updateFollowers(host: string, isAdditional: boolean) { + public async updateFollowers(host: string, isAdditional: boolean): Promise { await this.inc({ followers: { total: isAdditional ? 1 : -1, @@ -197,7 +201,7 @@ export default class InstanceChart extends Chart { } @autobind - public async updateDrive(file: DriveFile, isAdditional: boolean) { + public async updateDrive(file: DriveFile, isAdditional: boolean): Promise { const update: Obj = {}; update.totalFiles = isAdditional ? 1 : -1; diff --git a/packages/backend/src/services/chart/charts/classes/network.ts b/packages/backend/src/services/chart/charts/network.ts similarity index 80% rename from packages/backend/src/services/chart/charts/classes/network.ts rename to packages/backend/src/services/chart/charts/network.ts index 838eec4916..73ea2f7e19 100644 --- a/packages/backend/src/services/chart/charts/classes/network.ts +++ b/packages/backend/src/services/chart/charts/network.ts @@ -1,10 +1,14 @@ import autobind from 'autobind-decorator'; -import Chart, { DeepPartial } from '../../core'; +import Chart, { DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; -import { name, schema } from '../schemas/network'; +import { name, schema } from './entities/network'; type NetworkLog = SchemaType; +/** + * ネットワークに関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class NetworkChart extends Chart { constructor() { super(name, schema); @@ -32,7 +36,7 @@ export default class NetworkChart extends Chart { } @autobind - public async update(incomingRequests: number, time: number, incomingBytes: number, outgoingBytes: number) { + public async update(incomingRequests: number, time: number, incomingBytes: number, outgoingBytes: number): Promise { const inc: DeepPartial = { incomingRequests: incomingRequests, totalTime: time, diff --git a/packages/backend/src/services/chart/charts/classes/notes.ts b/packages/backend/src/services/chart/charts/notes.ts similarity index 88% rename from packages/backend/src/services/chart/charts/classes/notes.ts rename to packages/backend/src/services/chart/charts/notes.ts index f8a580b3c0..86cda17225 100644 --- a/packages/backend/src/services/chart/charts/classes/notes.ts +++ b/packages/backend/src/services/chart/charts/notes.ts @@ -1,13 +1,17 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; import { Notes } from '@/models/index'; import { Not, IsNull } from 'typeorm'; import { Note } from '@/models/entities/note'; -import { name, schema } from '../schemas/notes'; +import { name, schema } from './entities/notes'; type NotesLog = SchemaType; +/** + * ノートに関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class NotesChart extends Chart { constructor() { super(name, schema); @@ -69,7 +73,7 @@ export default class NotesChart extends Chart { } @autobind - public async update(note: Note, isAdditional: boolean) { + public async update(note: Note, isAdditional: boolean): Promise { const update: Obj = { diffs: {}, }; diff --git a/packages/backend/src/services/chart/charts/classes/per-user-drive.ts b/packages/backend/src/services/chart/charts/per-user-drive.ts similarity index 83% rename from packages/backend/src/services/chart/charts/classes/per-user-drive.ts rename to packages/backend/src/services/chart/charts/per-user-drive.ts index 33d49d9ebb..fff790367f 100644 --- a/packages/backend/src/services/chart/charts/classes/per-user-drive.ts +++ b/packages/backend/src/services/chart/charts/per-user-drive.ts @@ -1,12 +1,16 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; import { DriveFiles } from '@/models/index'; import { DriveFile } from '@/models/entities/drive-file'; -import { name, schema } from '../schemas/per-user-drive'; +import { name, schema } from './entities/per-user-drive'; type PerUserDriveLog = SchemaType; +/** + * ユーザーごとのドライブに関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class PerUserDriveChart extends Chart { constructor() { super(name, schema, true); @@ -46,7 +50,7 @@ export default class PerUserDriveChart extends Chart { } @autobind - public async update(file: DriveFile, isAdditional: boolean) { + public async update(file: DriveFile, isAdditional: boolean): Promise { const update: Obj = {}; update.totalCount = isAdditional ? 1 : -1; diff --git a/packages/backend/src/services/chart/charts/classes/per-user-following.ts b/packages/backend/src/services/chart/charts/per-user-following.ts similarity index 92% rename from packages/backend/src/services/chart/charts/classes/per-user-following.ts rename to packages/backend/src/services/chart/charts/per-user-following.ts index 67b623057d..d0a80abdaf 100644 --- a/packages/backend/src/services/chart/charts/classes/per-user-following.ts +++ b/packages/backend/src/services/chart/charts/per-user-following.ts @@ -1,13 +1,17 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; import { Followings, Users } from '@/models/index'; import { Not, IsNull } from 'typeorm'; import { User } from '@/models/entities/user'; -import { name, schema } from '../schemas/per-user-following'; +import { name, schema } from './entities/per-user-following'; type PerUserFollowingLog = SchemaType; +/** + * ユーザーごとのフォローに関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class PerUserFollowingChart extends Chart { constructor() { super(name, schema, true); @@ -100,7 +104,7 @@ export default class PerUserFollowingChart extends Chart { } @autobind - public async update(follower: { id: User['id']; host: User['host']; }, followee: { id: User['id']; host: User['host']; }, isFollow: boolean) { + public async update(follower: { id: User['id']; host: User['host']; }, followee: { id: User['id']; host: User['host']; }, isFollow: boolean): Promise { const update: Obj = {}; update.total = isFollow ? 1 : -1; diff --git a/packages/backend/src/services/chart/charts/classes/per-user-notes.ts b/packages/backend/src/services/chart/charts/per-user-notes.ts similarity index 86% rename from packages/backend/src/services/chart/charts/classes/per-user-notes.ts rename to packages/backend/src/services/chart/charts/per-user-notes.ts index 94760c0492..d048c88885 100644 --- a/packages/backend/src/services/chart/charts/classes/per-user-notes.ts +++ b/packages/backend/src/services/chart/charts/per-user-notes.ts @@ -1,13 +1,17 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { User } from '@/models/entities/user'; import { SchemaType } from '@/misc/schema'; import { Notes } from '@/models/index'; import { Note } from '@/models/entities/note'; -import { name, schema } from '../schemas/per-user-notes'; +import { name, schema } from './entities/per-user-notes'; type PerUserNotesLog = SchemaType; +/** + * ユーザーごとのノートに関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class PerUserNotesChart extends Chart { constructor() { super(name, schema, true); @@ -46,7 +50,7 @@ export default class PerUserNotesChart extends Chart { } @autobind - public async update(user: { id: User['id'] }, note: Note, isAdditional: boolean) { + public async update(user: { id: User['id'] }, note: Note, isAdditional: boolean): Promise { const update: Obj = { diffs: {}, }; diff --git a/packages/backend/src/services/chart/charts/classes/per-user-reactions.ts b/packages/backend/src/services/chart/charts/per-user-reactions.ts similarity index 79% rename from packages/backend/src/services/chart/charts/classes/per-user-reactions.ts rename to packages/backend/src/services/chart/charts/per-user-reactions.ts index 62508eacdf..2f5353340d 100644 --- a/packages/backend/src/services/chart/charts/classes/per-user-reactions.ts +++ b/packages/backend/src/services/chart/charts/per-user-reactions.ts @@ -1,13 +1,17 @@ import autobind from 'autobind-decorator'; -import Chart, { DeepPartial } from '../../core'; +import Chart, { DeepPartial } from '../core'; import { User } from '@/models/entities/user'; import { Note } from '@/models/entities/note'; import { SchemaType } from '@/misc/schema'; import { Users } from '@/models/index'; -import { name, schema } from '../schemas/per-user-reactions'; +import { name, schema } from './entities/per-user-reactions'; type PerUserReactionsLog = SchemaType; +/** + * ユーザーごとのリアクションに関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class PerUserReactionsChart extends Chart { constructor() { super(name, schema, true); @@ -36,7 +40,7 @@ export default class PerUserReactionsChart extends Chart { } @autobind - public async update(user: { id: User['id'], host: User['host'] }, note: Note) { + public async update(user: { id: User['id'], host: User['host'] }, note: Note): Promise { this.inc({ [Users.isLocalUser(user) ? 'local' : 'remote']: { count: 1 }, }, note.userId); diff --git a/packages/backend/src/services/chart/charts/classes/test-grouped.ts b/packages/backend/src/services/chart/charts/test-grouped.ts similarity index 81% rename from packages/backend/src/services/chart/charts/classes/test-grouped.ts rename to packages/backend/src/services/chart/charts/test-grouped.ts index 2b11930af2..c851d2df01 100644 --- a/packages/backend/src/services/chart/charts/classes/test-grouped.ts +++ b/packages/backend/src/services/chart/charts/test-grouped.ts @@ -1,10 +1,14 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; -import { name, schema } from '../schemas/test-grouped'; +import { name, schema } from './entities/test-grouped'; type TestGroupedLog = SchemaType; +/** + * For testing + */ +// eslint-disable-next-line import/no-default-export export default class TestGroupedChart extends Chart { private total = {} as Record; @@ -42,7 +46,7 @@ export default class TestGroupedChart extends Chart { } @autobind - public async increment(group: string) { + public async increment(group: string): Promise { if (this.total[group] == null) this.total[group] = 0; const update: Obj = {}; diff --git a/packages/backend/src/services/chart/charts/classes/test-unique.ts b/packages/backend/src/services/chart/charts/test-unique.ts similarity index 73% rename from packages/backend/src/services/chart/charts/classes/test-unique.ts rename to packages/backend/src/services/chart/charts/test-unique.ts index f8655804d4..3564f675ad 100644 --- a/packages/backend/src/services/chart/charts/classes/test-unique.ts +++ b/packages/backend/src/services/chart/charts/test-unique.ts @@ -1,10 +1,14 @@ import autobind from 'autobind-decorator'; -import Chart, { DeepPartial } from '../../core'; +import Chart, { DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; -import { name, schema } from '../schemas/test-unique'; +import { name, schema } from './entities/test-unique'; type TestUniqueLog = SchemaType; +/** + * For testing + */ +// eslint-disable-next-line import/no-default-export export default class TestUniqueChart extends Chart { constructor() { super(name, schema); @@ -28,7 +32,7 @@ export default class TestUniqueChart extends Chart { } @autobind - public async uniqueIncrement(key: string) { + public async uniqueIncrement(key: string): Promise { await this.inc({ foo: [key], }); diff --git a/packages/backend/src/services/chart/charts/classes/test.ts b/packages/backend/src/services/chart/charts/test.ts similarity index 80% rename from packages/backend/src/services/chart/charts/classes/test.ts rename to packages/backend/src/services/chart/charts/test.ts index b3f6b76a44..06add7ede9 100644 --- a/packages/backend/src/services/chart/charts/classes/test.ts +++ b/packages/backend/src/services/chart/charts/test.ts @@ -1,10 +1,14 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; -import { name, schema } from '../schemas/test'; +import { name, schema } from './entities/test'; type TestLog = SchemaType; +/** + * For testing + */ +// eslint-disable-next-line import/no-default-export export default class TestChart extends Chart { public total = 0; // publicにするのはテストのため @@ -42,7 +46,7 @@ export default class TestChart extends Chart { } @autobind - public async increment() { + public async increment(): Promise { const update: Obj = {}; update.total = 1; @@ -55,7 +59,7 @@ export default class TestChart extends Chart { } @autobind - public async decrement() { + public async decrement(): Promise { const update: Obj = {}; update.total = -1; diff --git a/packages/backend/src/services/chart/charts/classes/users.ts b/packages/backend/src/services/chart/charts/users.ts similarity index 86% rename from packages/backend/src/services/chart/charts/classes/users.ts rename to packages/backend/src/services/chart/charts/users.ts index 6762410abf..c36c6cd979 100644 --- a/packages/backend/src/services/chart/charts/classes/users.ts +++ b/packages/backend/src/services/chart/charts/users.ts @@ -1,13 +1,17 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../../core'; +import Chart, { Obj, DeepPartial } from '../core'; import { SchemaType } from '@/misc/schema'; import { Users } from '@/models/index'; import { Not, IsNull } from 'typeorm'; import { User } from '@/models/entities/user'; -import { name, schema } from '../schemas/users'; +import { name, schema } from './entities/users'; type UsersLog = SchemaType; +/** + * ユーザー数に関するチャート + */ +// eslint-disable-next-line import/no-default-export export default class UsersChart extends Chart { constructor() { super(name, schema); @@ -59,7 +63,7 @@ export default class UsersChart extends Chart { } @autobind - public async update(user: { id: User['id'], host: User['host'] }, isAdditional: boolean) { + public async update(user: { id: User['id'], host: User['host'] }, isAdditional: boolean): Promise { const update: Obj = {}; update.total = isAdditional ? 1 : -1; diff --git a/packages/backend/src/services/chart/core.ts b/packages/backend/src/services/chart/core.ts index 59149dbc08..f97fa521d3 100644 --- a/packages/backend/src/services/chart/core.ts +++ b/packages/backend/src/services/chart/core.ts @@ -30,7 +30,7 @@ type Log = { /** * 集計のグループ */ - group: string | null; + group?: string | null; /** * 集計日時のUnixタイムスタンプ(秒) @@ -38,7 +38,7 @@ type Log = { date: number; }; -const camelToSnake = (str: string) => { +const camelToSnake = (str: string): string => { return str.replace(/([A-Z])/g, s => '_' + s.charAt(0).toLowerCase()); }; @@ -47,6 +47,7 @@ const removeDuplicates = (array: any[]) => Array.from(new Set(array)); /** * 様々なチャートの管理を司るクラス */ +// eslint-disable-next-line import/no-default-export export default abstract class Chart> { private static readonly columnPrefix = '___'; private static readonly columnDot = '_'; @@ -57,7 +58,8 @@ export default abstract class Chart> { group: string | null; }[] = []; public schema: SimpleSchema; - protected repository: Repository; + protected repositoryForHour: Repository; + protected repositoryForDay: Repository; protected abstract genNewLog(latest: T): DeepPartial; @@ -181,9 +183,15 @@ export default abstract class Chart> { } @autobind - public static schemaToEntity(name: string, schema: SimpleSchema): EntitySchema { - return new EntitySchema({ - name: `__chart__${camelToSnake(name)}`, + public static schemaToEntity(name: string, schema: SimpleSchema, grouped = false): { + hour: EntitySchema, + day: EntitySchema, + } { + const createEntity = (span: 'hour' | 'day'): EntitySchema => new EntitySchema({ + name: + span === 'hour' ? `__chart__${camelToSnake(name)}` : + span === 'day' ? `__chart_day__${camelToSnake(name)}` : + new Error('not happen') as never, columns: { id: { type: 'integer', @@ -193,37 +201,45 @@ export default abstract class Chart> { date: { type: 'integer', }, - group: { - type: 'varchar', - length: 128, - nullable: true, - }, + ...(grouped ? { + group: { + type: 'varchar', + length: 128, + }, + } : {}), ...Chart.convertSchemaToFlatColumnDefinitions(schema), }, indices: [{ - columns: ['date', 'group'], + columns: grouped ? ['date', 'group'] : ['date'], unique: true, - }, { // groupにnullが含まれると↑のuniqueは機能しないので↓の部分インデックスでカバー - columns: ['date'], - unique: true, - where: '"group" IS NULL', }], + uniques: [{ + columns: grouped ? ['date', 'group'] : ['date'], + }], + relations: { + /* TODO + group: { + target: () => Foo, + type: 'many-to-one', + onDelete: 'CASCADE', + }, + */ + }, }); + + return { + hour: createEntity('hour'), + day: createEntity('day'), + }; } constructor(name: string, schema: SimpleSchema, grouped = false) { this.name = name; this.schema = schema; - const entity = Chart.schemaToEntity(name, schema); - const keys = ['date']; - if (grouped) keys.push('group'); - - entity.options.uniques = [{ - columns: keys, - }]; - - this.repository = getRepository(entity); + const { hour, day } = Chart.schemaToEntity(name, schema, grouped); + this.repositoryForHour = getRepository(hour); + this.repositoryForDay = getRepository(day); } @autobind @@ -247,24 +263,40 @@ export default abstract class Chart> { } @autobind - private getLatestLog(group: string | null = null): Promise { - return this.repository.findOne({ + private getLatestLog(group: string | null, span: 'hour' | 'day'): Promise { + const repository = + span === 'hour' ? this.repositoryForHour : + span === 'day' ? this.repositoryForDay : + new Error('not happen') as never; + + return repository.findOne(group ? { group: group, - }, { + } : {}, { order: { date: -1, }, }).then(x => x || null); } + /** + * 現在(=今のHour or Day)のログをデータベースから探して、あればそれを返し、なければ作成して返します。 + */ @autobind - private async getCurrentLog(group: string | null = null): Promise { + private async claimCurrentLog(group: string | null, span: 'hour' | 'day'): Promise { const [y, m, d, h] = Chart.getCurrentDate(); - const current = dateUTC([y, m, d, h]); + const current = dateUTC( + span === 'hour' ? [y, m, d, h] : + span === 'day' ? [y, m, d] : + new Error('not happen') as never); - // 現在(=今のHour)のログ - const currentLog = await this.repository.findOne({ + const repository = + span === 'hour' ? this.repositoryForHour : + span === 'day' ? this.repositoryForDay : + new Error('not happen') as never; + + // 現在(=今のHour or Day)のログ + const currentLog = await repository.findOne({ date: Chart.dateToTimestamp(current), ...(group ? { group: group } : {}), }); @@ -283,7 +315,7 @@ export default abstract class Chart> { // * 昨日何もチャートを更新するような出来事がなかった場合は、 // * ログがそもそも作られずドキュメントが存在しないということがあり得るため、 // * 「昨日の」と決め打ちせずに「もっとも最近の」とします - const latest = await this.getLatestLog(group); + const latest = await this.getLatestLog(group, span); if (latest != null) { const obj = Chart.convertFlattenColumnsToObject(latest) as T; @@ -297,16 +329,16 @@ export default abstract class Chart> { // 初期ログデータを作成 data = this.getNewLog(null); - logger.info(`${this.name + (group ? `:${group}` : '')}: Initial commit created`); + logger.info(`${this.name + (group ? `:${group}` : '')}(${span}): Initial commit created`); } const date = Chart.dateToTimestamp(current); - const lockKey = `${this.name}:${date}:${group}`; + const lockKey = group ? `${this.name}:${date}:${span}:${group}` : `${this.name}:${date}:${span}`; const unlock = await getChartInsertLock(lockKey); try { // ロック内でもう1回チェックする - const currentLog = await this.repository.findOne({ + const currentLog = await repository.findOne({ date: date, ...(group ? { group: group } : {}), }); @@ -315,13 +347,13 @@ export default abstract class Chart> { if (currentLog != null) return currentLog; // 新規ログ挿入 - log = await this.repository.insert({ - group: group, + log = await repository.insert({ date: date, + ...(group ? { group: group } : {}), ...Chart.convertObjectToFlattenColumns(data), - }).then(x => this.repository.findOneOrFail(x.identifiers[0])); + }).then(x => repository.findOneOrFail(x.identifiers[0])); - logger.info(`${this.name + (group ? `:${group}` : '')}: New commit created`); + logger.info(`${this.name + (group ? `:${group}` : '')}(${span}): New commit created`); return log; } finally { @@ -349,10 +381,10 @@ export default abstract class Chart> { // そのログは本来は 01:00~ のログとしてDBに保存されて欲しいのに、02:00~ のログ扱いになってしまう。 // これを回避するための実装は複雑になりそうなため、一旦保留。 - const update = async (log: Log) => { + const update = async (logHour: Log, logDay: Log): Promise => { const finalDiffs = {} as Record; - for (const diff of this.buffer.filter(q => q.group === log.group).map(q => q.diff)) { + for (const diff of this.buffer.filter(q => q.group == null || (q.group === logHour.group)).map(q => q.diff)) { const columns = Chart.convertObjectToFlattenColumns(diff); for (const [k, v] of Object.entries(columns)) { @@ -371,36 +403,60 @@ export default abstract class Chart> { const query = Chart.convertQuery(finalDiffs); // ログ更新 - await this.repository.createQueryBuilder() - .update() - .set(query) - .where('id = :id', { id: log.id }) - .execute(); + await Promise.all([ + this.repositoryForHour.createQueryBuilder() + .update() + .set(query) + .where('id = :id', { id: logHour.id }) + .execute(), + this.repositoryForDay.createQueryBuilder() + .update() + .set(query) + .where('id = :id', { id: logDay.id }) + .execute(), + ]); - logger.info(`${this.name + (log.group ? `:${log.group}` : '')}: Updated`); + logger.info(`${this.name + (logHour.group ? `:${logHour.group}` : '')}: Updated`); // TODO: この一連の処理が始まった後に新たにbufferに入ったものは消さないようにする - this.buffer = this.buffer.filter(q => q.group !== log.group); + this.buffer = this.buffer.filter(q => q.group != null && (q.group !== logHour.group)); }; const groups = removeDuplicates(this.buffer.map(log => log.group)); - await Promise.all(groups.map(group => this.getCurrentLog(group).then(log => update(log)))); + await Promise.all( + groups.map(group => + Promise.all([ + this.claimCurrentLog(group, 'hour'), + this.claimCurrentLog(group, 'day'), + ]).then(([logHour, logDay]) => + update(logHour, logDay)))); } @autobind - public async resync(group: string | null = null): Promise { + public async resync(group: string | null = null): Promise { const data = await this.fetchActual(group); - const update = async (log: Log) => { - await this.repository.createQueryBuilder() - .update() - .set(Chart.convertObjectToFlattenColumns(data)) - .where('id = :id', { id: log.id }) - .execute(); + const update = async (logHour: Log, logDay: Log): Promise => { + await Promise.all([ + this.repositoryForHour.createQueryBuilder() + .update() + .set(Chart.convertObjectToFlattenColumns(data)) + .where('id = :id', { id: logHour.id }) + .execute(), + this.repositoryForDay.createQueryBuilder() + .update() + .set(Chart.convertObjectToFlattenColumns(data)) + .where('id = :id', { id: logDay.id }) + .execute(), + ]); }; - return this.getCurrentLog(group).then(log => update(log)); + return Promise.all([ + this.claimCurrentLog(group, 'hour'), + this.claimCurrentLog(group, 'day'), + ]).then(([logHour, logDay]) => + update(logHour, logDay)); } @autobind @@ -418,13 +474,18 @@ export default abstract class Chart> { const gt = span === 'day' ? subtractTime(cursor ? dateUTC([y2, m2, d2, 0]) : dateUTC([y, m, d, 0]), amount - 1, 'day') : span === 'hour' ? subtractTime(cursor ? dateUTC([y2, m2, d2, h2]) : dateUTC([y, m, d, h]), amount - 1, 'hour') : - null as never; + new Error('not happen') as never; + + const repository = + span === 'hour' ? this.repositoryForHour : + span === 'day' ? this.repositoryForDay : + new Error('not happen') as never; // ログ取得 - let logs = await this.repository.find({ + let logs = await repository.find({ where: { - group: group, date: Between(Chart.dateToTimestamp(gt), Chart.dateToTimestamp(lt)), + ...(group ? { group: group } : {}), }, order: { date: -1, @@ -435,9 +496,9 @@ export default abstract class Chart> { if (logs.length === 0) { // もっとも新しいログを持ってくる // (すくなくともひとつログが無いと隙間埋めできないため) - const recentLog = await this.repository.findOne({ + const recentLog = await repository.findOne(group ? { group: group, - }, { + } : {}, { order: { date: -1, }, @@ -451,9 +512,9 @@ export default abstract class Chart> { } else if (!isTimeSame(new Date(logs[logs.length - 1].date * 1000), gt)) { // 要求された範囲の最も古い箇所時点での最も新しいログを持ってきて末尾に追加する // (隙間埋めできないため) - const outdatedLog = await this.repository.findOne({ - group: group, + const outdatedLog = await repository.findOne({ date: LessThan(Chart.dateToTimestamp(gt)), + ...(group ? { group: group } : {}), }, { order: { date: -1, @@ -467,60 +528,26 @@ export default abstract class Chart> { const chart: T[] = []; - if (span === 'hour') { - for (let i = (amount - 1); i >= 0; i--) { - const current = subtractTime(dateUTC([y, m, d, h]), i, 'hour'); + for (let i = (amount - 1); i >= 0; i--) { + const current = + span === 'hour' ? subtractTime(dateUTC([y, m, d, h]), i, 'hour') : + span === 'day' ? subtractTime(dateUTC([y, m, d]), i, 'day') : + new Error('not happen') as never; - const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current)); + const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current)); - if (log) { - 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 T : null; - chart.unshift(Chart.countUniqueFields(this.getNewLog(data)) as T); - } - } - } else if (span === 'day') { - const logsForEachDays: T[][] = []; - let currentDay = -1; - let currentDayIndex = -1; - for (let i = ((amount - 1) * 24) + h; i >= 0; i--) { - const current = subtractTime(dateUTC([y, m, d, h]), i, 'hour'); - const _currentDay = Chart.parseDate(current)[2]; - if (currentDay != _currentDay) currentDayIndex++; - currentDay = _currentDay; - - const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current)); - - if (log) { - if (logsForEachDays[currentDayIndex]) { - logsForEachDays[currentDayIndex].unshift(Chart.convertFlattenColumnsToObject(log) as T); - } else { - 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 T : null; - const newLog = this.getNewLog(data); - if (logsForEachDays[currentDayIndex]) { - logsForEachDays[currentDayIndex].unshift(newLog); - } else { - logsForEachDays[currentDayIndex] = [newLog]; - } - } - } - - for (const logs of logsForEachDays) { - const log = this.aggregate(logs); - chart.unshift(Chart.countUniqueFields(log) as T); + if (log) { + 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 T : null; + chart.unshift(Chart.countUniqueFields(this.getNewLog(data)) as T); } } - const res: ArrayValue = {} as any; + const res = {} as Record; /** * [{ foo: 1, bar: 5 }, { foo: 2, bar: 6 }, { foo: 3, bar: 7 }] @@ -528,7 +555,7 @@ export default abstract class Chart> { * { foo: [1, 2, 3], bar: [5, 6, 7] } * にする */ - const compact = (x: Obj, path?: string) => { + const compact = (x: Obj, path?: string): void => { for (const [k, v] of Object.entries(x)) { const p = path ? `${path}.${k}` : k; if (typeof v === 'object' && !Array.isArray(v)) { @@ -542,7 +569,7 @@ export default abstract class Chart> { compact(chart[0]); - return res; + return res as ArrayValue; } } diff --git a/packages/backend/src/services/chart/entities.ts b/packages/backend/src/services/chart/entities.ts index 9d96a8a7ee..dedbd47080 100644 --- a/packages/backend/src/services/chart/entities.ts +++ b/packages/backend/src/services/chart/entities.ts @@ -1,15 +1,27 @@ -import { fileURLToPath } from 'url'; -import { dirname } from 'path'; -import Chart from './core'; +import { entity as FederationChart } from './charts/entities/federation'; +import { entity as NotesChart } from './charts/entities/notes'; +import { entity as UsersChart } from './charts/entities/users'; +import { entity as NetworkChart } from './charts/entities/network'; +import { entity as ActiveUsersChart } from './charts/entities/active-users'; +import { entity as InstanceChart } from './charts/entities/instance'; +import { entity as PerUserNotesChart } from './charts/entities/per-user-notes'; +import { entity as DriveChart } from './charts/entities/drive'; +import { entity as PerUserReactionsChart } from './charts/entities/per-user-reactions'; +import { entity as HashtagChart } from './charts/entities/hashtag'; +import { entity as PerUserFollowingChart } from './charts/entities/per-user-following'; +import { entity as PerUserDriveChart } from './charts/entities/per-user-drive'; -//const _filename = fileURLToPath(import.meta.url); -const _filename = __filename; -const _dirname = dirname(_filename); - -export const entities = Object.values(require('require-all')({ - dirname: _dirname + '/charts/schemas', - filter: /^.+\.[jt]s$/, - resolve: (x: any) => { - return Chart.schemaToEntity(x.name, x.schema); - }, -})); +export const entities = [ + FederationChart.hour, FederationChart.day, + NotesChart.hour, NotesChart.day, + UsersChart.hour, UsersChart.day, + NetworkChart.hour, NetworkChart.day, + ActiveUsersChart.hour, ActiveUsersChart.day, + InstanceChart.hour, InstanceChart.day, + PerUserNotesChart.hour, PerUserNotesChart.day, + DriveChart.hour, DriveChart.day, + PerUserReactionsChart.hour, PerUserReactionsChart.day, + HashtagChart.hour, HashtagChart.day, + PerUserFollowingChart.hour, PerUserFollowingChart.day, + PerUserDriveChart.hour, PerUserDriveChart.day, +]; diff --git a/packages/backend/src/services/chart/index.ts b/packages/backend/src/services/chart/index.ts index 61eb431ea3..0b9887b36f 100644 --- a/packages/backend/src/services/chart/index.ts +++ b/packages/backend/src/services/chart/index.ts @@ -1,17 +1,18 @@ -import FederationChart from './charts/classes/federation'; -import NotesChart from './charts/classes/notes'; -import UsersChart from './charts/classes/users'; -import NetworkChart from './charts/classes/network'; -import ActiveUsersChart from './charts/classes/active-users'; -import InstanceChart from './charts/classes/instance'; -import PerUserNotesChart from './charts/classes/per-user-notes'; -import DriveChart from './charts/classes/drive'; -import PerUserReactionsChart from './charts/classes/per-user-reactions'; -import HashtagChart from './charts/classes/hashtag'; -import PerUserFollowingChart from './charts/classes/per-user-following'; -import PerUserDriveChart from './charts/classes/per-user-drive'; import { beforeShutdown } from '@/misc/before-shutdown'; +import FederationChart from './charts/federation'; +import NotesChart from './charts/notes'; +import UsersChart from './charts/users'; +import NetworkChart from './charts/network'; +import ActiveUsersChart from './charts/active-users'; +import InstanceChart from './charts/instance'; +import PerUserNotesChart from './charts/per-user-notes'; +import DriveChart from './charts/drive'; +import PerUserReactionsChart from './charts/per-user-reactions'; +import HashtagChart from './charts/hashtag'; +import PerUserFollowingChart from './charts/per-user-following'; +import PerUserDriveChart from './charts/per-user-drive'; + export const federationChart = new FederationChart(); export const notesChart = new NotesChart(); export const usersChart = new UsersChart(); diff --git a/packages/backend/test/chart.ts b/packages/backend/test/chart.ts index 935ac9d8e1..66000bc928 100644 --- a/packages/backend/test/chart.ts +++ b/packages/backend/test/chart.ts @@ -3,13 +3,12 @@ process.env.NODE_ENV = 'test'; import * as assert from 'assert'; import * as lolex from '@sinonjs/fake-timers'; import { async, initTestDb } from './utils'; -import TestChart from '../src/services/chart/charts/classes/test'; -import TestGroupedChart from '../src/services/chart/charts/classes/test-grouped'; -import TestUniqueChart from '../src/services/chart/charts/classes/test-unique'; -import * as _TestChart from '../src/services/chart/charts/schemas/test'; -import * as _TestGroupedChart from '../src/services/chart/charts/schemas/test-grouped'; -import * as _TestUniqueChart from '../src/services/chart/charts/schemas/test-unique'; -import Chart from '../src/services/chart/core'; +import TestChart from '../src/services/chart/charts/test'; +import TestGroupedChart from '../src/services/chart/charts/test-grouped'; +import TestUniqueChart from '../src/services/chart/charts/test-unique'; +import * as _TestChart from '../src/services/chart/charts/entities/test'; +import * as _TestGroupedChart from '../src/services/chart/charts/entities/test-grouped'; +import * as _TestUniqueChart from '../src/services/chart/charts/entities/test-unique'; describe('Chart', () => { let testChart: TestChart; @@ -19,9 +18,9 @@ describe('Chart', () => { beforeEach(async(async () => { await initTestDb(false, [ - Chart.schemaToEntity(_TestChart.name, _TestChart.schema), - Chart.schemaToEntity(_TestGroupedChart.name, _TestGroupedChart.schema), - Chart.schemaToEntity(_TestUniqueChart.name, _TestUniqueChart.schema) + _TestChart.entity.hour, _TestChart.entity.day, + _TestGroupedChart.entity.hour, _TestGroupedChart.entity.day, + _TestUniqueChart.entity.hour, _TestUniqueChart.entity.day, ]); testChart = new TestChart(); @@ -132,6 +131,32 @@ describe('Chart', () => { }); })); + it('複数回saveされてもデータの更新は一度だけ', async(async () => { + await testChart.increment(); + await testChart.save(); + await testChart.save(); + await testChart.save(); + + const chartHours = await testChart.getChart('hour', 3, null); + const chartDays = await testChart.getChart('day', 3, null); + + assert.deepStrictEqual(chartHours, { + foo: { + dec: [0, 0, 0], + inc: [1, 0, 0], + total: [1, 0, 0] + }, + }); + + assert.deepStrictEqual(chartDays, { + foo: { + dec: [0, 0, 0], + inc: [1, 0, 0], + total: [1, 0, 0] + }, + }); + })); + it('Can updates at different times', async(async () => { await testChart.increment(); await testChart.save(); diff --git a/packages/backend/yarn.lock b/packages/backend/yarn.lock index 96fbb26c95..0652d1df3f 100644 --- a/packages/backend/yarn.lock +++ b/packages/backend/yarn.lock @@ -188,6 +188,11 @@ node-fetch "^2.6.1" yaml-ast-parser "0.0.43" +"@sindresorhus/is@^3.0.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-3.1.2.tgz#548650de521b344e3781fbdb0ece4aa6f729afb8" + integrity sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ== + "@sindresorhus/is@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4" @@ -314,13 +319,6 @@ dependencies: cbor "*" -"@types/cheerio@0.22.18": - version "0.22.18" - resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.18.tgz#19018dceae691509901e339d63edf1e935978fe6" - integrity sha512-Fq7R3fINAPSdUEhOyjG4iVxgHrOnqDJbY0/BUuiN0pvD/rfmZWekVZnv+vcs8TtpA2XF50uv50LaE4EnpEL/Hw== - dependencies: - "@types/node" "*" - "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -738,11 +736,6 @@ dependencies: "@types/node" "*" -"@types/rsvp@^4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/rsvp/-/rsvp-4.0.4.tgz#55e93e7054027f1ad4b4ebc1e60e59eb091e2d32" - integrity sha512-J3Ol++HCC7/hwZhanDvggFYU/GtxHxE/e7cGRWxR04BF7Tt3TqJZ84BkzQgDxmX0uu8IagiyfmfoUlBACh2Ilg== - "@types/sanitize-html@2.5.0": version "2.5.0" resolved "https://registry.yarnpkg.com/@types/sanitize-html/-/sanitize-html-2.5.0.tgz#bfef58fbcf2674b20ffcc23c3506faa68c3a13e3" @@ -1230,7 +1223,7 @@ ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.5.5: +ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: version "6.12.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== @@ -1290,7 +1283,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" -any-promise@^1.0.0, any-promise@^1.1.0: +any-promise@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= @@ -1483,16 +1476,6 @@ aws-sdk@2.1013.0: uuid "3.3.2" xml2js "0.4.19" -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" - integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== - axios@^0.19.2: version "0.19.2" resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" @@ -1882,11 +1865,6 @@ canonicalize@^1.0.1: resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.1.tgz#657b4f3fa38a6ecb97a9e5b7b26d7a19cc6e0da9" integrity sha512-N3cmB3QLhS5TJ5smKFf1w42rJXWe6C1qP01z4dxJiI5v269buii4fLHWETDyf7yEd0azGLNC63VxNMiPd2u0Cg== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - cbor@*: version "7.0.5" resolved "https://registry.yarnpkg.com/cbor/-/cbor-7.0.5.tgz#ed54cdbc19fa7352bb328d00a5393aa7ce45a10f" @@ -1964,31 +1942,7 @@ chartjs-plugin-zoom@1.1.1: dependencies: hammerjs "^2.0.8" -cheerio-httpcli@0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/cheerio-httpcli/-/cheerio-httpcli-0.8.2.tgz#0189bda71c8bd2852de78e154291e2288184fbf2" - integrity sha512-grIzTwQg/nE7Oy6VvL19pf0UlM6wiluy/AOpXfQLVFrSi21F8wnO3dLchtaH2hfMF6jz68ot0/ngyQQVrp2VTw== - dependencies: - "@types/cheerio" "0.22.18" - "@types/rsvp" "^4.0.4" - async "^3.2.0" - cheerio "^0.22.0" - colors "^1.4.0" - foreach "^2.0.5" - he "^1.2.0" - iconv-lite "^0.6.3" - import-fresh "^3.3.0" - jschardet "^3.0.0" - object-assign "^4.1.1" - os-locale "^5.0.0" - prettyjson "^1.2.1" - request "^2.88.2" - rsvp "^4.8.5" - tough-cookie "^2.5.0" - type-of "^2.0.1" - valid-url "^1.0.9" - -cheerio@^0.22.0: +cheerio@0.22.0: version "0.22.0" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= @@ -2169,12 +2123,7 @@ colorette@^1.2.0, colorette@^1.2.1, colorette@^1.2.2: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== -colors@^1.1.2, colors@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -2329,7 +2278,7 @@ cross-env@7.0.3: dependencies: cross-spawn "^7.0.1" -cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -2535,14 +2484,14 @@ debug@4, debug@4.3.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: dependencies: ms "2.1.2" -debug@4.3.2, debug@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== +debug@4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" -debug@=3.1.0, debug@~3.1.0: +debug@=3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== @@ -2563,6 +2512,13 @@ debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + debuglog@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -3296,21 +3252,6 @@ execa@6.0.0: signal-exit "^3.0.5" strip-final-newline "^3.0.0" -execa@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" - integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - exit-on-epipe@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" @@ -3342,11 +3283,6 @@ extend-shallow@^2.0.1: dependencies: is-extendable "^0.1.0" -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -3509,16 +3445,6 @@ follow-redirects@1.5.10: dependencies: debug "=3.1.0" -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - form-data@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" @@ -3528,15 +3454,6 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - fresh@~0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -3623,7 +3540,7 @@ get-port@^5.1.1: resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== -get-stream@^5.0.0, get-stream@^5.1.0: +get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== @@ -3744,6 +3661,23 @@ globby@^11.0.4: merge2 "^1.3.0" slash "^3.0.0" +got@11.5.1: + version "11.5.1" + resolved "https://registry.yarnpkg.com/got/-/got-11.5.1.tgz#bf098a270fe80b3fb88ffd5a043a59ebb0a391db" + integrity sha512-reQEZcEBMTGnujmQ+Wm97mJs/OK6INtO6HmLI+xt3+9CvnRwWjXutUvb2mqr+Ao4Lu05Rx6+udx9sOQAmExMxA== + dependencies: + "@sindresorhus/is" "^3.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.1" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.0" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + got@11.8.2: version "11.8.2" resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" @@ -3786,19 +3720,6 @@ hammerjs@^2.0.8: resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1" integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" @@ -3843,7 +3764,7 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -he@1.2.0, he@^1.2.0: +he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== @@ -3963,14 +3884,13 @@ http-signature@1.3.5: jsprim "^1.2.2" sshpk "^1.14.1" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= +http2-wrapper@^1.0.0-beta.5.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" http2-wrapper@^1.0.0-beta.5.2: version "1.0.0-beta.5.2" @@ -3995,11 +3915,6 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== - human-signals@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5" @@ -4031,13 +3946,6 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -iconv-lite@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" @@ -4083,14 +3991,6 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" -import-fresh@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -4158,11 +4058,6 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -invert-kv@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-3.0.1.tgz#a93c7a3d4386a1dc8325b97da9bb1620c0282523" - integrity sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw== - ioredis@^4.27.0: version "4.27.6" resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.27.6.tgz#a53d427d3fe75fbd10ed7ad150ce00559df8dcf8" @@ -4418,11 +4313,6 @@ is-shared-array-buffer@^1.0.1: resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== -is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== - is-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" @@ -4456,7 +4346,7 @@ is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -4498,11 +4388,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - jest-worker@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" @@ -4575,7 +4460,7 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jschardet@^3.0.0: +jschardet@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== @@ -4643,7 +4528,7 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -4773,26 +4658,11 @@ koa-bodyparser@4.3.0: co-body "^6.0.0" copy-to "^2.0.1" -koa-compose@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7" - integrity sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec= - dependencies: - any-promise "^1.1.0" - koa-compose@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== -koa-convert@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0" - integrity sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA= - dependencies: - co "^4.6.0" - koa-compose "^3.0.0" - koa-convert@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5" @@ -4877,35 +4747,6 @@ koa-views@7.0.2: pretty "^2.0.0" resolve-path "^1.4.0" -koa@2.13.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/koa/-/koa-2.13.1.tgz#6275172875b27bcfe1d454356a5b6b9f5a9b1051" - integrity sha512-Lb2Dloc72auj5vK4X4qqL7B5jyDPQaZucc9sR/71byg7ryoD1NCaCm63CShk9ID9quQvDEi1bGR/iGjCG7As3w== - dependencies: - accepts "^1.3.5" - cache-content-type "^1.0.0" - content-disposition "~0.5.2" - content-type "^1.0.4" - cookies "~0.8.0" - debug "~3.1.0" - delegates "^1.0.0" - depd "^2.0.0" - destroy "^1.0.4" - encodeurl "^1.0.2" - escape-html "^1.0.3" - fresh "~0.5.2" - http-assert "^1.3.0" - http-errors "^1.6.3" - is-generator-function "^1.0.7" - koa-compose "^4.1.0" - koa-convert "^1.2.0" - on-finished "^2.3.0" - only "~0.0.2" - parseurl "^1.3.2" - statuses "^1.5.0" - type-is "^1.6.16" - vary "^1.1.2" - koa@2.13.4: version "2.13.4" resolved "https://registry.yarnpkg.com/koa/-/koa-2.13.4.tgz#ee5b0cb39e0b8069c38d115139c774833d32462e" @@ -4960,13 +4801,6 @@ lazystream@^1.0.0: dependencies: readable-stream "^2.0.5" -lcid@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-3.1.1.tgz#9030ec479a058fc36b5e8243ebaac8b6ac582fd0" - integrity sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg== - dependencies: - invert-kv "^3.0.0" - levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -5193,13 +5027,6 @@ make-fetch-happen@^8.0.14: socks-proxy-agent "^5.0.0" ssri "^8.0.0" -map-age-cleaner@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - mdn-data@2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" @@ -5210,15 +5037,6 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -mem@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/mem/-/mem-5.1.1.tgz#7059b67bf9ac2c924c9f1cff7155a064394adfb3" - integrity sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw== - dependencies: - map-age-cleaner "^0.1.3" - mimic-fn "^2.1.0" - p-is-promise "^2.1.0" - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -5284,18 +5102,13 @@ mime-types@2.1.34: dependencies: mime-db "1.51.0" -mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.27, mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== dependencies: mime-db "1.44.0" -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - mimic-fn@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" @@ -5690,13 +5503,6 @@ normalize-url@^6.0.1: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== -npm-run-path@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - npm-run-path@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.0.1.tgz#748dd68ed7de377bb1f7132c7dafe657be5ab400" @@ -5738,11 +5544,6 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - oauth@0.9.15: version "0.9.15" resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" @@ -5824,13 +5625,6 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - onetime@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" @@ -5877,15 +5671,6 @@ os-homedir@^1.0.0: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-locale@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-5.0.0.tgz#6d26c1d95b6597c5d5317bf5fba37eccec3672e0" - integrity sha512-tqZcNEDAIZKBEPnHPlVDvKrp7NzgLi7jRmhKiUoa2NUmhl13FtkAGLUVR+ZsYvApBQdBfYm43A4tXXQ4IrYLBA== - dependencies: - execa "^4.0.0" - lcid "^3.0.0" - mem "^5.0.0" - os-tmpdir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -5909,21 +5694,11 @@ p-cancelable@^2.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -6066,7 +5841,7 @@ path-is-absolute@1.0.1, path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-key@^3.0.0, path-key@^3.1.0: +path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -6096,11 +5871,6 @@ peek-readable@^4.0.1: resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.0.1.tgz#9a045f291db254111c3412c1ce4fec27ddd4d202" integrity sha512-7qmhptnR0WMSpxT5rMHG9bW/mYSR1uqaPFj2MHvT+y/aOUu6msJijpKt5SkTDKySwg65OWG2JwTMBlgcbwMHrQ== -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - pg-connection-string@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" @@ -6529,14 +6299,6 @@ pretty@^2.0.0: extend-shallow "^2.0.1" js-beautify "^1.6.12" -prettyjson@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prettyjson/-/prettyjson-1.2.1.tgz#fcffab41d19cab4dfae5e575e64246619b12d289" - integrity sha1-/P+rQdGcq0365eV15kJGYZsS0ok= - dependencies: - colors "^1.1.2" - minimist "^1.2.0" - printj@~1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" @@ -6620,7 +6382,7 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -6778,11 +6540,6 @@ qs@^6.4.0, qs@^6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" @@ -6966,22 +6723,6 @@ rename@1.0.4: dependencies: debug "^2.5.2" -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.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" @@ -6990,32 +6731,6 @@ request-stats@3.0.0: http-headers "^3.0.1" once "^1.4.0" -request@2.88.2, request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-all@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/require-all/-/require-all-3.0.0.tgz#473d49704be310115ce124f77383b1ebd8671312" @@ -7102,11 +6817,6 @@ rndstr@1.0.0: rangestr "0.0.1" seedrandom "2.4.2" -rsvp@^4.8.5: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== - run-parallel@^1.1.9: version "1.1.9" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" @@ -7132,7 +6842,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== @@ -7294,7 +7004,7 @@ sigmund@^1.0.1: resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= -signal-exit@^3.0.0, signal-exit@^3.0.2: +signal-exit@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== @@ -7404,7 +7114,7 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.14.1, sshpk@^1.7.0: +sshpk@^1.14.1: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== @@ -7441,11 +7151,6 @@ standard-as-callback@^2.1.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - stream-parser@~0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773" @@ -7614,11 +7319,6 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - strip-final-newline@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" @@ -7655,18 +7355,19 @@ stylehacks@^5.0.1: browserslist "^4.16.0" postcss-selector-parser "^6.0.4" -summaly@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/summaly/-/summaly-2.4.1.tgz#d2a8fa6bad10c1651eb0b849aab3009e87216a3d" - integrity sha512-1gETEQXqK5RD7yIGgdGeTwGL1uh+uj14u99atzNLNmvsxwdtZbPvDHZBPXkAW0cqsd8teoBJln5Dh1QeAhvGIg== +summaly@2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/summaly/-/summaly-2.5.0.tgz#ec5af6e84857efcb6c844d896e83569e64a923ea" + integrity sha512-IzvO2s7yj/PUyH42qWjVjSPpIiPlgTRWGh33t4cIZKOqPQJ2INo7e83hXhHFr4hXTb3JRcIdCuM1ELjlrujiUQ== dependencies: - cheerio-httpcli "0.8.2" - debug "4.3.2" + cheerio "0.22.0" + debug "4.3.3" escape-regexp "0.0.1" + got "11.5.1" html-entities "2.3.2" - koa "2.13.1" - request "2.88.2" - request-promise-native "1.0.9" + jschardet "3.0.0" + koa "2.13.4" + private-ip "2.3.3" require-all "3.0.0" trace-redirect "1.0.6" @@ -7889,14 +7590,6 @@ token-types@^4.1.1: "@tokenizer/token" "^0.3.0" ieee754 "^1.2.1" -tough-cookie@^2.3.3, tough-cookie@^2.5.0, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -8055,11 +7748,6 @@ type-is@^1.6.14, type-is@^1.6.16, type-is@^1.6.4: media-typer "0.3.0" mime-types "~2.1.24" -type-of@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/type-of/-/type-of-2.0.1.tgz#e72a1741896568e9f628378d816d6912f7f23972" - integrity sha1-5yoXQYllaOn2KDeNgW1pEvfyOXI= - type@^1.0.1: version "1.2.0" resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" @@ -8223,21 +7911,11 @@ uuid@8.3.2, uuid@^8.3.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - v8-compile-cache@^2.0.3: version "2.2.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== -valid-url@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" - integrity sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA= - vary@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" diff --git a/packages/client/src/components/autocomplete.vue b/packages/client/src/components/autocomplete.vue index d6c972aaea..c50f032a5a 100644 --- a/packages/client/src/components/autocomplete.vue +++ b/packages/client/src/components/autocomplete.vue @@ -1,5 +1,5 @@