Merge tag '2023.12.0' into merge-upstream

This commit is contained in:
riku6460 2023-12-23 20:22:38 +09:00
commit 3df907ca56
No known key found for this signature in database
GPG Key ID: 27414FA27DB94CF6
77 changed files with 2067 additions and 530 deletions

1
.npmrc Normal file
View File

@ -0,0 +1 @@
engine-strict = true

View File

@ -5,32 +5,33 @@
- -
### Client ### Client
- Fix: ページ一覧ページの表示がモバイル環境において崩れているのを修正 -
- Fix: MFMでルビの中のテキストがnyaizeされない問題を修正
### Server ### Server
- -
--> -->
## 2023.x.x (unreleased) ## 2023.12.0
### Note ### Note
- Node.js 20.10.0が最小要件になりました - 依存関係の更新に伴い、Node.js 20.10.0が最小要件になりました
- 絵文字の追加辞書を既にインストールしている場合は、お手数ですが再インストールのほどお願いします
- 絵文字ピッカーにピン留め表示する絵文字設定が「リアクション用」と「絵文字入力用」に分かれました。以前の設定は「リアクション用」として使用されます。 - 絵文字ピッカーにピン留め表示する絵文字設定が「リアクション用」と「絵文字入力用」に分かれました。以前の設定は「リアクション用」として使用されます。
**影響:** **影響:**
それにより、投稿フォームから表示される絵文字ピッカーのピン留め絵文字がリセットされたように感じるかもしれません(新設された投稿用のピン留め絵文字が使われるため)。 それにより、投稿フォームから表示される絵文字ピッカーのピン留め絵文字がリセットされたように感じるかもしれません(新設された"ピン留め(全般)"の設定が使われるため)。
投稿用のピン留め絵文字をアップデート前の状態にするには、以下の手順で操作します。 投稿用のピン留め絵文字をアップデート前の状態にするには、以下の手順で操作します。
1. 「設定」メニューに移動し、「絵文字ピッカー」タブを選択します。 1. 「設定」メニューに移動し、「絵文字ピッカー」タブを選択します。
2. 「ピン留 (全般)」のタブを選択します。 2. 「ピン留 (全般)」のタブを選択します。
3. 「リアクション設定からコピーする」ボタンを押すことで、アップデート前の状態に戻すことができます。 3. 「リアクション設定から上書きする」ボタンを押すことで、アップデート前の状態に戻すことができます。
### General ### General
- Feat: メールアドレスの認証にverifymail.ioを使えるように (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/971ba07a44550f68d2ba31c62066db2d43a0caed) - Feat: メールアドレスの認証にverifymail.ioを使えるように (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/971ba07a44550f68d2ba31c62066db2d43a0caed)
- Feat: モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能を追加 (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/e0eb5a752f6e5616d6312bb7c9790302f9dbff83) - Feat: モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能を追加 (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/e0eb5a752f6e5616d6312bb7c9790302f9dbff83)
- Feat: TL上からートが見えなくなるワードミュートであるハードミュートを追加 - Feat: TL上からートが見えなくなるワードミュートであるハードミュートを追加
- Enhance: 指定したドメインのメールアドレスの登録を弾くことができるように
- Enhance: 公開ロールにアサインされたときに通知が作成されるように - Enhance: 公開ロールにアサインされたときに通知が作成されるように
- Enhance: アイコンデコレーションを複数設定できるように - Enhance: アイコンデコレーションを複数設定できるように
- Enhance: アイコンデコレーションの位置を微調整できるように - Enhance: アイコンデコレーションの位置を微調整できるように
@ -62,12 +63,17 @@
- Enhance: ユーザー名、プロフィール、お知らせ、ページの編集画面でMFMや絵文字のオートコンプリートが使用できるように - Enhance: ユーザー名、プロフィール、お知らせ、ページの編集画面でMFMや絵文字のオートコンプリートが使用できるように
- Enhance: プロフィール、お知らせの編集画面でMFMのプレビューを表示できるように - Enhance: プロフィール、お知らせの編集画面でMFMのプレビューを表示できるように
- Enhance: 絵文字の詳細ページに記載される情報を追加 - Enhance: 絵文字の詳細ページに記載される情報を追加
- Enhance: リアクションの表示幅制限を設定可能に
- Enhance: Unicode 15.0のサポート - Enhance: Unicode 15.0のサポート
- Enhance: コードブロックのハイライト機能を利用するには言語を明示的に指定させるように - Enhance: コードブロックのハイライト機能を利用するには言語を明示的に指定させるように
- MFMでコードブロックを利用する際に意図しないハイライトが起こらないようになりました - MFMでコードブロックを利用する際に意図しないハイライトが起こらないようになりました
- 逆に、MFMでコードハイライトを利用したい際は言語を明示的に指定する必要があります - 逆に、MFMでコードハイライトを利用したい際は言語を明示的に指定する必要があります
(例: ` ```js ` → Javascript, ` ```ais ` → AiScript (例: ` ```js ` → Javascript, ` ```ais ` → AiScript
- Enhance: 絵文字などのオートコンプリートでShift+Tabを押すと前の候補を選択できるように - Enhance: 絵文字などのオートコンプリートでShift+Tabを押すと前の候補を選択できるように
- Enhance: チャンネルに新規の投稿がある場合にバッジを表示させる
- Enhance: サウンド設定に「サウンドを出力しない」と「Misskeyがアクティブな時のみサウンドを出力する」を追加
- Enhance: 設定したタグをトレンドに表示させないようにする項目を管理画面で設定できるように
- Enhance: 絵文字ピッカーのカテゴリに「/」を入れることでフォルダ分け表示できるように
- Fix: 「設定のバックアップ」で一部の項目がバックアップに含まれていなかった問題を修正 - Fix: 「設定のバックアップ」で一部の項目がバックアップに含まれていなかった問題を修正
- Fix: ウィジェットのジョブキューにて音声の発音方法変更に追従できていなかったのを修正 #12367 - Fix: ウィジェットのジョブキューにて音声の発音方法変更に追従できていなかったのを修正 #12367
- Fix: コードエディタが正しく表示されない問題を修正 - Fix: コードエディタが正しく表示されない問題を修正
@ -83,10 +89,16 @@
- Fix: 投票のみ/画像のみの引用RNが、通知欄でただのRNとして判定されるバグを修正 - Fix: 投票のみ/画像のみの引用RNが、通知欄でただのRNとして判定されるバグを修正
- Fix: CWをつけて引用RNしても、普通のRNとして扱われてしまうバグを修正しました。 - Fix: CWをつけて引用RNしても、普通のRNとして扱われてしまうバグを修正しました。
- Fix: 「画像が1枚のみのメディアリストの高さ」を「デフォルト」以外に設定していると、CWの中などに添付された画像が見られないバグを修正 - Fix: 「画像が1枚のみのメディアリストの高さ」を「デフォルト」以外に設定していると、CWの中などに添付された画像が見られないバグを修正
- Fix: DeepL TranslationのPro accountトグルスイッチが表示されていなかったのを修正
- Fix: twitterの埋め込みカード内リンクからリンク先を開けない問題を修正
- Fix: WebKitブラウザー上でも「デバイスの画面を常にオンにする」機能が効くように
- Fix: ページ一覧ページの表示がモバイル環境において崩れているのを修正
- Fix: MFMでルビの中のテキストがnyaizeされない問題を修正
### Server ### Server
- Enhance: MFM `$[ruby ]` が他ソフトウェアと連合されるように - Enhance: MFM `$[ruby ]` が他ソフトウェアと連合されるように
- Enhance: Meilisearchを有効にした検索で、ユーザーのミュートやブロックを考慮するように - Enhance: Meilisearchを有効にした検索で、ユーザーのミュートやブロックを考慮するように
- Enhance: カスタム絵文字のインポート時の動作を改善
- Fix: 時間経過により無効化されたアンテナを再有効化したとき、サーバ再起動までその状況が反映されないのを修正 #12303 - Fix: 時間経過により無効化されたアンテナを再有効化したとき、サーバ再起動までその状況が反映されないのを修正 #12303
- Fix: ロールタイムラインが保存されない問題を修正 - Fix: ロールタイムラインが保存されない問題を修正
- Fix: api.jsonの生成ロジックを改善 #12402 - Fix: api.jsonの生成ロジックを改善 #12402
@ -123,7 +135,6 @@
- 例: `$[unixtime 1701356400]` - 例: `$[unixtime 1701356400]`
- Enhance: プラグインでエラーが発生した場合のハンドリングを強化 - Enhance: プラグインでエラーが発生した場合のハンドリングを強化
- Enhance: 細かなUIのブラッシュアップ - Enhance: 細かなUIのブラッシュアップ
- Enhance: サウンド設定に「サウンドを出力しない」と「Misskeyがアクティブな時のみサウンドを出力する」を追加
- Fix: 効果音が再生されるとデバイスで再生している動画や音声が停止する問題を修正 #12339 - Fix: 効果音が再生されるとデバイスで再生している動画や音声が停止する問題を修正 #12339
- Fix: デッキに表示されたチャンネルの表示先チャンネルを切り替えた際、即座に反映されない問題を修正 #12236 - Fix: デッキに表示されたチャンネルの表示先チャンネルを切り替えた際、即座に反映されない問題を修正 #12236
- Fix: プラグインでノートの表示を書き換えられない問題を修正 - Fix: プラグインでノートの表示を書き換えられない問題を修正
@ -151,7 +162,7 @@
### General ### General
- Feat: アイコンデコレーション機能 - Feat: アイコンデコレーション機能
- サーバーで用意された画像をアイコンに重ねることができます - サーバーで用意された画像をアイコンに重ねることができます
- 画像のテンプレートはこちらです: https://misskey-hub.net/avatar-decoration-template.png - 画像のテンプレートはこちらです: https://misskey-hub.net/brand-assets/
- 最大でも黄色いエリア内にデコレーションを収めることを推奨します。 - 最大でも黄色いエリア内にデコレーションを収めることを推奨します。
- 画像は512x512pxを推奨します。 - 画像は512x512pxを推奨します。
- Feat: チャンネル設定にリノート/引用リノートの可否を設定できる項目を追加 - Feat: チャンネル設定にリノート/引用リノートの可否を設定できる項目を追加
@ -168,7 +179,7 @@
### Client ### Client
- Feat: プラグイン・テーマを外部サイトから直接インストールできるようになりました - Feat: プラグイン・テーマを外部サイトから直接インストールできるようになりました
- 外部サイトでの実装が必要です。詳細は Misskey Hub をご覧ください - 外部サイトでの実装が必要です。詳細は Misskey Hub をご覧ください
https://misskey-hub.net/docs/advanced/publish-on-your-website.html https://misskey-hub.net/docs/for-developers/publish-on-your-website/
- Feat: 通知をグルーピングして表示するオプション(オプトアウト) - Feat: 通知をグルーピングして表示するオプション(オプトアウト)
- Feat: Misskeyの基本的なチュートリアルを実装 - Feat: Misskeyの基本的なチュートリアルを実装
- Feat: スワイプしてタイムラインを再読込できるように - Feat: スワイプしてタイムラインを再読込できるように
@ -233,7 +244,6 @@
### Client ### Client
- Enhance: TLの返信表示オプションを記憶するように - Enhance: TLの返信表示オプションを記憶するように
- Enhance: 投稿されてから時間が経過しているノートであることを視覚的に分かりやすく - Enhance: 投稿されてから時間が経過しているノートであることを視覚的に分かりやすく
- Feat: 絵文字ピッカーのカテゴリに「/」を入れることでフォルダ分け表示できるように
### Server ### Server
- Enhance: タイムライン取得時のパフォーマンスを向上 - Enhance: タイムライン取得時のパフォーマンスを向上

View File

@ -7,10 +7,10 @@
--- ---
<a href="https://misskey-hub.net/instances.html"> <a href="https://misskey-hub.net/servers/">
<img src="https://custom-icon-badges.herokuapp.com/badge/find_an-instance-acea31?logoColor=acea31&style=for-the-badge&logo=misskey&labelColor=363B40" alt="find an instance"/></a> <img src="https://custom-icon-badges.herokuapp.com/badge/find_an-instance-acea31?logoColor=acea31&style=for-the-badge&logo=misskey&labelColor=363B40" alt="find an instance"/></a>
<a href="https://misskey-hub.net/docs/install.html"> <a href="https://misskey-hub.net/docs/for-admin/install/guides/">
<img src="https://custom-icon-badges.herokuapp.com/badge/create_an-instance-FBD53C?logoColor=FBD53C&style=for-the-badge&logo=server&labelColor=363B40" alt="create an instance"/></a> <img src="https://custom-icon-badges.herokuapp.com/badge/create_an-instance-FBD53C?logoColor=FBD53C&style=for-the-badge&logo=server&labelColor=363B40" alt="create an instance"/></a>
<a href="./CONTRIBUTING.md"> <a href="./CONTRIBUTING.md">
@ -51,7 +51,7 @@ With Misskey's built in drive, you get cloud storage right in your social media,
## Documentation ## Documentation
Misskey Documentation can be found at [Misskey Hub](https://misskey-hub.net/), some of the links and graphics above also lead to specific portions of it. Misskey Documentation can be found at [Misskey Hub](https://misskey-hub.net/docs/), some of the links and graphics above also lead to specific portions of it.
## Sponsors ## Sponsors

View File

@ -121,6 +121,12 @@ sensitive: "NSFW"
add: "Afegir" add: "Afegir"
reaction: "Reaccions" reaction: "Reaccions"
reactions: "Reaccions" reactions: "Reaccions"
emojiPicker: "Selecció d'emojis"
pinnedEmojisForReactionSettingDescription: "Selecciona l'emoji amb el qual reaccionar"
pinnedEmojisSettingDescription: "Selecciona l'emoji amb el qual reaccionar"
emojiPickerDisplay: "Visualitza el selector d'emojis"
overwriteFromPinnedEmojisForReaction: "Reemplaça els emojis de la reacció"
overwriteFromPinnedEmojis: "Sobreescriu des dels emojis fixats"
reactionSettingDescription2: "Arrossega per reordenar, fes clic per suprimir, prem \"+\" per afegir." reactionSettingDescription2: "Arrossega per reordenar, fes clic per suprimir, prem \"+\" per afegir."
rememberNoteVisibility: "Recorda la configuració de visibilitat de les notes" rememberNoteVisibility: "Recorda la configuració de visibilitat de les notes"
attachCancel: "Eliminar el fitxer adjunt" attachCancel: "Eliminar el fitxer adjunt"
@ -213,6 +219,9 @@ clearQueueConfirmText: "Les notes no lliurades que quedin a la cua no es federar
clearCachedFiles: "Esborra la memòria cau" clearCachedFiles: "Esborra la memòria cau"
clearCachedFilesConfirm: "Segur que voleu eliminar tots els fitxers de la memòria cau?" clearCachedFilesConfirm: "Segur que voleu eliminar tots els fitxers de la memòria cau?"
blockedInstances: "Instàncies bloquejades" blockedInstances: "Instàncies bloquejades"
blockedInstancesDescription: "Llista els enllaços d'amfitrió de les instàncies que vols bloquejar separades per un salt de pàgina. Les instàncies llistades no podran comunicar-se amb aquesta instància."
silencedInstances: "Instàncies silenciades"
silencedInstancesDescription: "Llista els enllaços d'amfitrió de les instàncies que vols silenciar. Tots els comptes de les instàncies llistades s'establiran com silenciades i només podran fer sol·licitacions de seguiment, i no podran mencionar als comptes locals si no els segueixen. Això no afectarà les instàncies bloquejades."
muteAndBlock: "Silencia i bloca" muteAndBlock: "Silencia i bloca"
mutedUsers: "Usuaris silenciats" mutedUsers: "Usuaris silenciats"
blockedUsers: "Usuaris bloquejats" blockedUsers: "Usuaris bloquejats"
@ -227,9 +236,12 @@ preview: "Vista prèvia"
default: "Per defecte" default: "Per defecte"
defaultValueIs: "Per defecte: {value}" defaultValueIs: "Per defecte: {value}"
noCustomEmojis: "Cap emoji personalitzat" noCustomEmojis: "Cap emoji personalitzat"
noJobs: "No hi ha feines"
federating: "Federant" federating: "Federant"
blocked: "Bloquejat" blocked: "Bloquejat"
suspended: "Suspés" suspended: "Suspés"
all: "tot"
subscribing: "Subscrit a"
publishing: "S'està publicant" publishing: "S'està publicant"
notResponding: "Sense resposta" notResponding: "Sense resposta"
instanceFollowing: "Seguits del servidor" instanceFollowing: "Seguits del servidor"
@ -254,11 +266,31 @@ removed: "Eliminat"
removeAreYouSure: "Segur que voleu retirar «{x}»?" removeAreYouSure: "Segur que voleu retirar «{x}»?"
deleteAreYouSure: "Segur que voleu retirar «{x}»?" deleteAreYouSure: "Segur que voleu retirar «{x}»?"
resetAreYouSure: "Segur que voleu restablir-ho?" resetAreYouSure: "Segur que voleu restablir-ho?"
areYouSure: "Està segur?"
saved: "S'ha desat" saved: "S'ha desat"
messaging: "Xat" messaging: "Xat"
upload: "Puja" upload: "Puja"
keepOriginalUploading: "Guarda la imatge original"
keepOriginalUploadingDescription: "Guarda la imatge pujada com hi és. Si està apagat, una versió per a la visualització a la xarxa serà generada quan sigui pujada."
fromDrive: "Des de la unitat"
fromUrl: "Des d'un enllaç"
uploadFromUrl: "Carrega des d'un enllaç"
uploadFromUrlDescription: "Enllaç del fitxer que vols carregar"
uploadFromUrlRequested: "Càrrega sol·licitada"
uploadFromUrlMayTakeTime: "La càrrega des de l'enllaç pot prendre un temps"
explore: "Explora"
messageRead: "Vist"
noMoreHistory: "No hi resta més per veure"
startMessaging: "Començar a xatejar"
nUsersRead: "Vist per {n}"
agreeTo: "Accepto que {0}"
agree: "Hi estic d'acord"
agreeBelow: "Hi estic d'acord amb el següent"
basicNotesBeforeCreateAccount: "Notes importants"
termsOfService: "Condicions d'ús"
start: "Comença" start: "Comença"
home: "Inici" home: "Inici"
remoteUserCaution: "Ja que aquest usuari resideix a una instància remota, la informació mostrada es podria trobar incompleta."
activity: "Activitat" activity: "Activitat"
images: "Imatges" images: "Imatges"
image: "Imatges" image: "Imatges"
@ -274,16 +306,34 @@ dark: "Fosc"
lightThemes: "Temes clars" lightThemes: "Temes clars"
darkThemes: "Temes foscos" darkThemes: "Temes foscos"
syncDeviceDarkMode: "Sincronitza el mode fosc amb la configuració del dispositiu" syncDeviceDarkMode: "Sincronitza el mode fosc amb la configuració del dispositiu"
drive: "Unitat"
fileName: "Nom del Fitxer"
selectFile: "Selecciona fitxers"
selectFiles: "Selecciona fitxers"
selectFolder: "Selecció de carpeta"
selectFolders: "Selecció de carpeta"
renameFile: "Canvia el nom del fitxer" renameFile: "Canvia el nom del fitxer"
folderName: "Nom de la carpeta" folderName: "Nom de la carpeta"
createFolder: "Crea una carpeta" createFolder: "Crea una carpeta"
renameFolder: "Canvia el nom de la carpeta" renameFolder: "Canvia el nom de la carpeta"
deleteFolder: "Elimina la carpeta" deleteFolder: "Elimina la carpeta"
folder: "Carpeta "
addFile: "Afegeix un fitxer" addFile: "Afegeix un fitxer"
emptyDrive: "La teva unitat és buida"
emptyFolder: "La carpeta està buida" emptyFolder: "La carpeta està buida"
unableToDelete: "No es pot eliminar" unableToDelete: "No es pot eliminar"
inputNewFileName: "Introduïu el nom de fitxer nou"
inputNewDescription: "Inserta una nova llegenda"
inputNewFolderName: "Introduïu el nom de la carpeta nova"
circularReferenceFolder: "La carpeta destinatària és una subcarpeta de la carpeta a la qual la desitges moure"
hasChildFilesOrFolders: "No és possible esborrar aquesta carpeta ja que no és buida"
copyUrl: "Copia l'URL" copyUrl: "Copia l'URL"
rename: "Canvia el nom" rename: "Canvia el nom"
avatar: "Icona"
banner: "Bàner"
displayOfSensitiveMedia: "Visualització de contingut sensible"
whenServerDisconnected: "Quan es perdi la connexió al servidor"
disconnectedFromServer: "Desconnectat pel servidor"
reload: "Actualitza" reload: "Actualitza"
doNothing: "Ignora" doNothing: "Ignora"
accept: "Accepta" accept: "Accepta"
@ -353,33 +403,132 @@ notFound: "No s'ha trobat"
markAsReadAllUnreadNotes: "Marca-ho tot com a llegit" markAsReadAllUnreadNotes: "Marca-ho tot com a llegit"
help: "Ajuda" help: "Ajuda"
invites: "Convida" invites: "Convida"
title: "Títol"
text: "Text"
enable: "Habilita"
next: "Següent" next: "Següent"
retype: "Torneu a introduir-la"
noteOf: "Publicació de: {user}" noteOf: "Publicació de: {user}"
quoteAttached: "Frase adjunta"
quoteQuestion: "Vols annexar-la com a cita?"
noMessagesYet: "Encara no hi ha missatges"
newMessageExists: "Has rebut un nou missatge"
onlyOneFileCanBeAttached: "Només pots adjuntar un fitxer a un missatge"
signinRequired: "Si us plau, Registra't o inicia la sessió abans de continuar"
invitations: "Convida" invitations: "Convida"
invitationCode: "Codi d'invitació"
checking: "Comprovació en curs..."
available: "Disponible"
unavailable: "No és disponible"
usernameInvalidFormat: "Pots fer servir lletres (majúscules i minúscules), números i barres baixes (\"_\")"
tooShort: "Massa curt"
tooLong: "Massa llarg"
weakPassword: "Contrasenya insegura"
normalPassword: "Bona contrasenya"
strongPassword: "Contrasenya segura"
passwordMatched: "Correcte!"
passwordNotMatched: "No coincideix"
signinWith: "Inicia sessió amb amb {x}"
signinFailed: "Autenticació sense èxit. Intenta-ho un altre cop utilitzant la contrasenya i el nom correctes."
or: "O"
language: "Idioma"
uiLanguage: "Idioma de l'interfície"
aboutX: "Respecte a {x}"
emojiStyle: "Estil d'emoji"
native: "Nadiu"
disableDrawer: "No mostrar els menús en calaixos"
showNoteActionsOnlyHover: "Només mostra accions de la nota en passar amb el cursor"
noHistory: "No hi ha un registre previ"
signinHistory: "Historial d'autenticacions"
enableAdvancedMfm: "Habilitar l'MFM avançat"
enableAnimatedMfm: "Habilitar l'MFM amb moviment"
doing: "Processant..."
category: "Categoria"
tags: "Etiquetes" tags: "Etiquetes"
docSource: "Font del document" docSource: "Font del document"
createAccount: "Crea un compte" createAccount: "Crea un compte"
existingAccount: "Compte existent" existingAccount: "Compte existent"
regenerate: "Regenera" regenerate: "Regenera"
fontSize: "Mida del text" fontSize: "Mida del text"
mediaListWithOneImageAppearance: "Altura de la llista de fitxers amb una única imatge"
limitTo: "Limita a {x}"
noFollowRequests: "No tens sol·licituds de seguiment" noFollowRequests: "No tens sol·licituds de seguiment"
openImageInNewTab: "Obre imatges a una nova pestanya"
dashboard: "Panell de control" dashboard: "Panell de control"
local: "Local" local: "Local"
remote: "Remot" remote: "Remot"
total: "Total" total: "Total"
weekOverWeekChanges: "Canvis l'última setmana"
dayOverDayChanges: "Canvis ahir"
appearance: "Aparença" appearance: "Aparença"
clientSettings: "Configuració del client" clientSettings: "Configuració del client"
accountSettings: "Configuració del compte" accountSettings: "Configuració del compte"
promotion: "Promocionat"
promote: "Promoure"
numberOfDays: "Nombre de dies"
hideThisNote: "Amaga la publicació" hideThisNote: "Amaga la publicació"
showFeaturedNotesInTimeline: "Mostra publicacions destacades en la línia de temps" showFeaturedNotesInTimeline: "Mostra publicacions destacades en la línia de temps"
objectStorage: "Emmagatzematge d'objectes\n"
useObjectStorage: "Utilitzar l'emmagatzematge d'objectes"
objectStorageBaseUrl: "Base d'enllaç"
objectStorageBaseUrlDesc: "Prefix d'enllaç utilitzat per a fer referencia als fitxers. Especifica l'enllaç del teu CDN o Proxy si n'estàs utilitzant qualsevol, en cas contrari, especifica l'enllaç al que es pot accedir públicament segons la guia de servei que vosté utilitza.\nPer l'ús d'S3 utilitza 'https://<bucket>.s3.amazonaws.com' I per a GCS o serveis equivalents utilitza 'https://storage.googleapis.com/<bucket>'."
newNoteRecived: "Hi ha publicacions noves" newNoteRecived: "Hi ha publicacions noves"
installedDate: "Data d'instal·lació" installedDate: "Data d'instal·lació"
state: "Estat" state: "Estat"
sort: "Ordena" sort: "Ordena"
ascendingOrder: "Ascendent" ascendingOrder: "Ascendent"
descendingOrder: "Descendent" descendingOrder: "Descendent"
removeAllFollowing: "Deixar de seguir tots els usuaris seguits"
removeAllFollowingDescription: "El fet d'executar això, et farà deixar de seguir a tots els usuaris de {host}. Si us plau, executa això si l'amfitrió, per exemple, ja no existeix."
userSuspended: "Aquest usuari ha sigut suspès"
userSilenced: "Aquest usuari està sent silenciat"
yourAccountSuspendedTitle: "Aquest compte és suspès"
yourAccountSuspendedDescription: "Aquest compte ha sigut suspès a causa de la violació de les condicions d'ús o similars. Contacta l'administrador si en vol saber més. Si us plau, no en faci un altre compte."
tokenRevoked: "Codi de seguretat no vàlid"
tokenRevokedDescription: "La petició més recent ha estat denegada perquè contenia un codi de seguretat no vàlid. Actualitza la pàgina i torna-ho a provar."
accountDeleted: "Compte eliminat amb èxit"
accountDeletedDescription: "Aquest compte ha sigut eliminat"
menu: "Menú"
divider: "Divisor"
addItem: "Afegir element"
rearrange: "Torna a ordenar"
relays: "Relés"
addRelay: "Afegeix relés"
inboxUrl: "Enllaç de la safata d'entrada"
addedRelays: "Relés afegits"
serviceworkerInfo: "És obligatòria l'activació per a obtenir notificacions push"
deletedNote: "Publicacions eliminades" deletedNote: "Publicacions eliminades"
invisibleNote: "Publicacions amagades" invisibleNote: "Publicacions amagades"
enableInfiniteScroll: "Carrega més automàticament\n"
visibility: "Visibilitat"
poll: "Enquesta"
useCw: "Amaga el contingut"
enablePlayer: "Obre el reproductor de vídeo"
disablePlayer: "Tanca el reproductor de vídeo"
expandTweet: "Expandir post"
themeEditor: "Editor de temes"
description: "Descripció"
describeFile: "Afegir subtitulació"
enterFileDescription: "Afegeix un títol"
author: "Autor"
leaveConfirm: "Hi ha canvis sense guardar. Els vols descartar?"
manage: "Administració"
plugins: "Extensions"
preferencesBackups: "Configuracions de les Còpies de seguretat"
deck: "Escriptori"
undeck: "Tanca l'escriptori"
useBlurEffectForModal: "Utilitzar l'efecte de difuminació a modals"
useFullReactionPicker: "Utilitza el cercador de reaccions d'escala sencera"
width: "Amplada"
height: "Alçària"
large: "Gran"
medium: "Mitjà"
small: "Petit"
generateAccessToken: "Genera codi d'accés"
permission: "Permisos"
enableAll: "Habilita tot"
disableAll: "Deshabilita tot"
tokenRequested: "Donar accés al compte"
smtpHost: "Amfitrió" smtpHost: "Amfitrió"
smtpUser: "Nom d'usuari" smtpUser: "Nom d'usuari"
smtpPass: "Contrasenya" smtpPass: "Contrasenya"
@ -389,12 +538,17 @@ clearCache: "Esborra la memòria cau"
showingPastTimeline: "Estàs veient una línia de temps antiga" showingPastTimeline: "Estàs veient una línia de temps antiga"
info: "Informació" info: "Informació"
user: "Usuaris" user: "Usuaris"
administration: "Administració"
middle: "Mitjà"
global: "Global" global: "Global"
searchByGoogle: "Cercar" searchByGoogle: "Cercar"
file: "Fitxers" file: "Fitxers"
icon: "Icona"
replies: "Respondre" replies: "Respondre"
renotes: "Impulsa" renotes: "Impulsa"
_role: _role:
_priority:
middle: "Mitjà"
_options: _options:
antennaMax: "Nombre màxim d'antenes" antennaMax: "Nombre màxim d'antenes"
_email: _email:
@ -403,9 +557,11 @@ _email:
_instanceMute: _instanceMute:
instanceMuteDescription: "Silencia tots els impulsos dels servidors seleccionats, també els usuaris que responen a altres d'un servidor silenciat." instanceMuteDescription: "Silencia tots els impulsos dels servidors seleccionats, també els usuaris que responen a altres d'un servidor silenciat."
_theme: _theme:
description: "Descripció"
keys: keys:
mention: "Menció" mention: "Menció"
renote: "Renotar" renote: "Renotar"
divider: "Divisor"
_sfx: _sfx:
note: "Notes" note: "Notes"
notification: "Notificacions" notification: "Notificacions"
@ -447,6 +603,8 @@ _timelines:
local: "Local" local: "Local"
social: "Social" social: "Social"
global: "Global" global: "Global"
_play:
summary: "Descripció"
_pages: _pages:
contents: "Contingut" contents: "Contingut"
blocks: blocks:

View File

@ -544,7 +544,7 @@ showInPage: "Show in page"
popout: "Pop-out" popout: "Pop-out"
volume: "Volume" volume: "Volume"
masterVolume: "Master volume" masterVolume: "Master volume"
notUseSound: "No sounds output." notUseSound: "Disable sound"
useSoundOnlyWhenActive: "Output sounds only if Misskey is active." useSoundOnlyWhenActive: "Output sounds only if Misskey is active."
details: "Details" details: "Details"
chooseEmoji: "Select an emoji" chooseEmoji: "Select an emoji"
@ -1169,6 +1169,7 @@ cwNotationRequired: "If \"Hide content\" is enabled, a description must be provi
doReaction: "Add reaction" doReaction: "Add reaction"
code: "Code" code: "Code"
reloadRequiredToApplySettings: "Reloading is required to apply the settings." reloadRequiredToApplySettings: "Reloading is required to apply the settings."
decorate: "Decorate"
_announcement: _announcement:
forExistingUsers: "Existing users only" forExistingUsers: "Existing users only"
forExistingUsersDescription: "This announcement will only be shown to users existing at the point of publishment if enabled. If disabled, those newly signing up after it has been posted will also see it." forExistingUsersDescription: "This announcement will only be shown to users existing at the point of publishment if enabled. If disabled, those newly signing up after it has been posted will also see it."
@ -1258,7 +1259,7 @@ _initialTutorial:
sensitiveSucceeded: "When attaching files, please set sensitivities in accordance with the server guidelines." sensitiveSucceeded: "When attaching files, please set sensitivities in accordance with the server guidelines."
doItToContinue: "Mark the attachment file as sensitive to proceed." doItToContinue: "Mark the attachment file as sensitive to proceed."
_done: _done:
title: "The tutorial is complete! 🎉" title: "You've completed the tutorial! 🎉"
description: "The functions introduced here are just a small part. For a more detailed understanding of using Misskey, please refer to {link}." description: "The functions introduced here are just a small part. For a more detailed understanding of using Misskey, please refer to {link}."
_timelineDescription: _timelineDescription:
home: "In the Home timeline, you can see notes from accounts you follow." home: "In the Home timeline, you can see notes from accounts you follow."
@ -2161,6 +2162,7 @@ _notification:
pollEnded: "Poll results have become available" pollEnded: "Poll results have become available"
newNote: "New note" newNote: "New note"
unreadAntennaNote: "Antenna {name}" unreadAntennaNote: "Antenna {name}"
roleAssigned: "Role given"
emptyPushNotificationMessage: "Push notifications have been updated" emptyPushNotificationMessage: "Push notifications have been updated"
achievementEarned: "Achievement unlocked" achievementEarned: "Achievement unlocked"
testNotification: "Test notification" testNotification: "Test notification"
@ -2182,6 +2184,7 @@ _notification:
pollEnded: "Polls ending" pollEnded: "Polls ending"
receiveFollowRequest: "Received follow requests" receiveFollowRequest: "Received follow requests"
followRequestAccepted: "Accepted follow requests" followRequestAccepted: "Accepted follow requests"
roleAssigned: "Role given"
achievementEarned: "Achievement unlocked" achievementEarned: "Achievement unlocked"
app: "Notifications from linked apps" app: "Notifications from linked apps"
_actions: _actions:

View File

@ -1899,6 +1899,7 @@ _notification:
yourFollowRequestAccepted: "Votre demande dabonnement a été accepté" yourFollowRequestAccepted: "Votre demande dabonnement a été accepté"
pollEnded: "Les résultats du sondage sont disponibles" pollEnded: "Les résultats du sondage sont disponibles"
unreadAntennaNote: "Antenne {name}" unreadAntennaNote: "Antenne {name}"
roleAssigned: "Rôle attribué"
emptyPushNotificationMessage: "Les notifications push ont été mises à jour" emptyPushNotificationMessage: "Les notifications push ont été mises à jour"
achievementEarned: "Accomplissement" achievementEarned: "Accomplissement"
testNotification: "Tester la notification" testNotification: "Tester la notification"
@ -1916,6 +1917,7 @@ _notification:
pollEnded: "Sondages se cloturant" pollEnded: "Sondages se cloturant"
receiveFollowRequest: "Demande d'abonnement reçue" receiveFollowRequest: "Demande d'abonnement reçue"
followRequestAccepted: "Demande d'abonnement acceptée" followRequestAccepted: "Demande d'abonnement acceptée"
roleAssigned: "Rôle reçu"
achievementEarned: "Accomplissement" achievementEarned: "Accomplissement"
app: "Notifications provenant des apps" app: "Notifications provenant des apps"
_actions: _actions:

2
locales/index.d.ts vendored
View File

@ -1752,6 +1752,7 @@ export interface Locale {
"disposable": string; "disposable": string;
"mx": string; "mx": string;
"smtp": string; "smtp": string;
"banned": string;
}; };
"_ffVisibility": { "_ffVisibility": {
"public": string; "public": string;
@ -2357,6 +2358,7 @@ export interface Locale {
"pollEnded": string; "pollEnded": string;
"receiveFollowRequest": string; "receiveFollowRequest": string;
"followRequestAccepted": string; "followRequestAccepted": string;
"roleAssigned": string;
"achievementEarned": string; "achievementEarned": string;
"app": string; "app": string;
}; };

View File

@ -1659,6 +1659,7 @@ _emailUnavailable:
disposable: "恒久的に使用可能なアドレスではありません" disposable: "恒久的に使用可能なアドレスではありません"
mx: "正しいメールサーバーではありません" mx: "正しいメールサーバーではありません"
smtp: "メールサーバーが応答しません" smtp: "メールサーバーが応答しません"
banned: "このメールアドレスでは登録できません"
_ffVisibility: _ffVisibility:
public: "公開" public: "公開"
@ -2260,6 +2261,7 @@ _notification:
pollEnded: "アンケートが終了" pollEnded: "アンケートが終了"
receiveFollowRequest: "フォロー申請を受け取った" receiveFollowRequest: "フォロー申請を受け取った"
followRequestAccepted: "フォローが受理された" followRequestAccepted: "フォローが受理された"
roleAssigned: "ロールが付与された"
achievementEarned: "実績の獲得" achievementEarned: "実績の獲得"
app: "連携アプリからの通知" app: "連携アプリからの通知"

View File

@ -2171,6 +2171,7 @@ _notification:
pollEnded: "투표 결과가 발표되었습니다" pollEnded: "투표 결과가 발표되었습니다"
newNote: "새 게시물" newNote: "새 게시물"
unreadAntennaNote: "안테나 {name}" unreadAntennaNote: "안테나 {name}"
roleAssigned: "역할이 부여 되었습니다."
emptyPushNotificationMessage: "푸시 알림이 갱신되었습니다" emptyPushNotificationMessage: "푸시 알림이 갱신되었습니다"
achievementEarned: "도전 과제를 달성했습니다" achievementEarned: "도전 과제를 달성했습니다"
testNotification: "알림 테스트" testNotification: "알림 테스트"
@ -2192,6 +2193,7 @@ _notification:
pollEnded: "투표가 종료됨" pollEnded: "투표가 종료됨"
receiveFollowRequest: "팔로우 요청을 받았을 때" receiveFollowRequest: "팔로우 요청을 받았을 때"
followRequestAccepted: "팔로우 요청이 승인되었을 때" followRequestAccepted: "팔로우 요청이 승인되었을 때"
roleAssigned: "역할이 부여 됨"
achievementEarned: "도전 과제 획득" achievementEarned: "도전 과제 획득"
app: "연동된 앱을 통한 알림" app: "연동된 앱을 통한 알림"
_actions: _actions:

View File

@ -2171,6 +2171,7 @@ _notification:
pollEnded: "問卷調查已產生結果" pollEnded: "問卷調查已產生結果"
newNote: "新的貼文" newNote: "新的貼文"
unreadAntennaNote: "天線 {name}" unreadAntennaNote: "天線 {name}"
roleAssigned: "已授予角色"
emptyPushNotificationMessage: "推送通知已更新" emptyPushNotificationMessage: "推送通知已更新"
achievementEarned: "獲得成就" achievementEarned: "獲得成就"
testNotification: "通知測試" testNotification: "通知測試"
@ -2192,6 +2193,7 @@ _notification:
pollEnded: "問卷調查結束" pollEnded: "問卷調查結束"
receiveFollowRequest: "已收到追隨請求" receiveFollowRequest: "已收到追隨請求"
followRequestAccepted: "追隨請求已接受" followRequestAccepted: "追隨請求已接受"
roleAssigned: "已授予角色"
achievementEarned: "獲得成就" achievementEarned: "獲得成就"
app: "應用程式通知" app: "應用程式通知"
_actions: _actions:

View File

@ -1,6 +1,6 @@
{ {
"name": "misskey", "name": "misskey",
"version": "2023.12.0-beta.6-io", "version": "2023.12.0-io",
"codename": "nasubi", "codename": "nasubi",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class bannedEmailDomains1703209889304 {
constructor() {
this.name = 'bannedEmailDomains1703209889304';
}
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "bannedEmailDomains" character varying(1024) array NOT NULL DEFAULT '{}'`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "bannedEmailDomains"`);
}
}

View File

@ -9,6 +9,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { validate as validateEmail } from 'deep-email-validator'; import { validate as validateEmail } from 'deep-email-validator';
import { SubOutputFormat } from 'deep-email-validator/dist/output/output.js'; import { SubOutputFormat } from 'deep-email-validator/dist/output/output.js';
import { MetaService } from '@/core/MetaService.js'; import { MetaService } from '@/core/MetaService.js';
import { UtilityService } from '@/core/UtilityService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
import type Logger from '@/logger.js'; import type Logger from '@/logger.js';
@ -30,6 +31,7 @@ export class EmailService {
private metaService: MetaService, private metaService: MetaService,
private loggerService: LoggerService, private loggerService: LoggerService,
private utilityService: UtilityService,
private httpRequestService: HttpRequestService, private httpRequestService: HttpRequestService,
) { ) {
this.logger = this.loggerService.getLogger('email'); this.logger = this.loggerService.getLogger('email');
@ -155,7 +157,7 @@ export class EmailService {
@bindThis @bindThis
public async validateEmailForAccount(emailAddress: string): Promise<{ public async validateEmailForAccount(emailAddress: string): Promise<{
available: boolean; available: boolean;
reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp'; reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | 'banned';
}> { }> {
const meta = await this.metaService.fetch(); const meta = await this.metaService.fetch();
@ -164,32 +166,35 @@ export class EmailService {
email: emailAddress, email: emailAddress,
}); });
const verifymailApi = meta.enableVerifymailApi && meta.verifymailAuthKey != null;
let validated; let validated;
if (meta.enableActiveEmailValidation && meta.verifymailAuthKey) { if (meta.enableActiveEmailValidation) {
if (verifymailApi) { if (meta.enableVerifymailApi && meta.verifymailAuthKey != null) {
validated = await this.verifyMail(emailAddress, meta.verifymailAuthKey); validated = await this.verifyMail(emailAddress, meta.verifymailAuthKey);
} else { } else {
validated = meta.enableActiveEmailValidation ? await validateEmail({ validated = await validateEmail({
email: emailAddress, email: emailAddress,
validateRegex: true, validateRegex: true,
validateMx: true, validateMx: true,
validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
validateDisposable: true, // 捨てアドかどうかチェック validateDisposable: true, // 捨てアドかどうかチェック
validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
}) : { valid: true, reason: null }; });
} }
} else { } else {
validated = { valid: true, reason: null }; validated = { valid: true, reason: null };
} }
const available = exist === 0 && validated.valid; const emailDomain: string = emailAddress.split('@')[1];
const isBanned = this.utilityService.isBlockedHost(meta.bannedEmailDomains, emailDomain);
const available = exist === 0 && validated.valid && !isBanned;
return { return {
available, available,
reason: available ? null : reason: available ? null :
exist !== 0 ? 'used' : exist !== 0 ? 'used' :
isBanned ? 'banned' :
validated.reason === 'regex' ? 'format' : validated.reason === 'regex' ? 'format' :
validated.reason === 'disposable' ? 'disposable' : validated.reason === 'disposable' ? 'disposable' :
validated.reason === 'mx' ? 'mx' : validated.reason === 'mx' ? 'mx' :

View File

@ -293,7 +293,7 @@ export class NoteCreateService implements OnApplicationShutdown {
} }
// Check blocking // Check blocking
if (data.renote && this.isQuote(data)) { if (data.renote && !this.isQuote(data)) {
if (data.renote.userHost === null) { if (data.renote.userHost === null) {
if (data.renote.userId !== user.id) { if (data.renote.userId !== user.id) {
const blocked = await this.userBlockingService.checkBlocked(data.renote.userId, user.id); const blocked = await this.userBlockingService.checkBlocked(data.renote.userId, user.id);
@ -731,8 +731,9 @@ export class NoteCreateService implements OnApplicationShutdown {
} }
@bindThis @bindThis
private isQuote(note: Option): boolean { private isQuote(note: Option): note is Option & { renote: MiNote } {
return !!note.text || !!note.cw || !!note.files || !!note.poll; // sync with misc/is-quote.ts
return !!note.renote && (!!note.text || !!note.cw || (!!note.files && !!note.files.length) || !!note.poll);
} }
@bindThis @bindThis
@ -801,7 +802,7 @@ export class NoteCreateService implements OnApplicationShutdown {
private async renderNoteOrRenoteActivity(data: Option, note: MiNote) { private async renderNoteOrRenoteActivity(data: Option, note: MiNote) {
if (data.localOnly) return null; if (data.localOnly) return null;
const content = data.renote && this.isQuote(data) const content = data.renote && !this.isQuote(data)
? this.apRendererService.renderAnnounce(data.renote.uri ? data.renote.uri : `${this.config.url}/notes/${data.renote.id}`, note) ? this.apRendererService.renderAnnounce(data.renote.uri ? data.renote.uri : `${this.config.url}/notes/${data.renote.id}`, note)
: this.apRendererService.renderCreate(await this.apRendererService.renderNote(note, false), note); : this.apRendererService.renderCreate(await this.apRendererService.renderNote(note, false), note);

View File

@ -3,8 +3,9 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import { Inject, Injectable, OnApplicationShutdown, OnModuleInit } from '@nestjs/common';
import * as Redis from 'ioredis'; import * as Redis from 'ioredis';
import { ModuleRef } from '@nestjs/core';
import type { UserListMembershipsRepository } from '@/models/_.js'; import type { UserListMembershipsRepository } from '@/models/_.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { MiUserList } from '@/models/UserList.js'; import type { MiUserList } from '@/models/UserList.js';
@ -21,12 +22,15 @@ import { RedisKVCache } from '@/misc/cache.js';
import { RoleService } from '@/core/RoleService.js'; import { RoleService } from '@/core/RoleService.js';
@Injectable() @Injectable()
export class UserListService implements OnApplicationShutdown { export class UserListService implements OnApplicationShutdown, OnModuleInit {
public static TooManyUsersError = class extends Error {}; public static TooManyUsersError = class extends Error {};
public membersCache: RedisKVCache<Set<string>>; public membersCache: RedisKVCache<Set<string>>;
private roleService: RoleService;
constructor( constructor(
private moduleRef: ModuleRef,
@Inject(DI.redis) @Inject(DI.redis)
private redisClient: Redis.Redis, private redisClient: Redis.Redis,
@ -38,7 +42,6 @@ export class UserListService implements OnApplicationShutdown {
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService, private idService: IdService,
private roleService: RoleService,
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
private proxyAccountService: ProxyAccountService, private proxyAccountService: ProxyAccountService,
private queueService: QueueService, private queueService: QueueService,
@ -54,6 +57,10 @@ export class UserListService implements OnApplicationShutdown {
this.redisForSub.on('message', this.onMessage); this.redisForSub.on('message', this.onMessage);
} }
async onModuleInit() {
this.roleService = this.moduleRef.get(RoleService.name);
}
@bindThis @bindThis
private async onMessage(_: string, data: string): Promise<void> { private async onMessage(_: string, data: string): Promise<void> {
const obj = JSON.parse(data); const obj = JSON.parse(data);

View File

@ -7,5 +7,6 @@ import type { MiNote } from '@/models/Note.js';
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default function(note: MiNote): boolean { export default function(note: MiNote): boolean {
// sync with NoteCreateService.isQuote
return note.renoteId != null && (note.text != null || note.hasPoll || (note.fileIds != null && note.fileIds.length > 0)); return note.renoteId != null && (note.text != null || note.hasPoll || (note.fileIds != null && note.fileIds.length > 0));
} }

View File

@ -40,6 +40,7 @@ import { packedUserListMembershipSchema, packedUserListSchema } from '@/models/j
import { packedAnnouncementSchema } from '@/models/json-schema/announcement.js'; import { packedAnnouncementSchema } from '@/models/json-schema/announcement.js';
import { packedSigninSchema } from '@/models/json-schema/signin.js'; import { packedSigninSchema } from '@/models/json-schema/signin.js';
import { packedRoleLiteSchema, packedRoleSchema } from '@/models/json-schema/role.js'; import { packedRoleLiteSchema, packedRoleSchema } from '@/models/json-schema/role.js';
import { packedAdSchema } from '@/models/json-schema/ad.js';
export const refs = { export const refs = {
UserLite: packedUserLiteSchema, UserLite: packedUserLiteSchema,
@ -52,6 +53,7 @@ export const refs = {
UserList: packedUserListSchema, UserList: packedUserListSchema,
UserListMembership: packedUserListMembershipSchema, UserListMembership: packedUserListMembershipSchema,
Ad: packedAdSchema,
Announcement: packedAnnouncementSchema, Announcement: packedAnnouncementSchema,
App: packedAppSchema, App: packedAppSchema,
Note: packedNoteSchema, Note: packedNoteSchema,

View File

@ -495,6 +495,13 @@ export class MiMeta {
}) })
public manifestJsonOverride: string; public manifestJsonOverride: string;
@Column('varchar', {
length: 1024,
array: true,
default: '{}',
})
public bannedEmailDomains: string[];
@Column('varchar', { @Column('varchar', {
length: 1024, array: true, default: '{ "admin", "administrator", "root", "system", "maintainer", "host", "mod", "moderator", "owner", "superuser", "staff", "auth", "i", "me", "everyone", "all", "mention", "mentions", "example", "user", "users", "account", "accounts", "official", "help", "helps", "support", "supports", "info", "information", "informations", "announce", "announces", "announcement", "announcements", "notice", "notification", "notifications", "dev", "developer", "developers", "tech", "misskey" }', length: 1024, array: true, default: '{ "admin", "administrator", "root", "system", "maintainer", "host", "mod", "moderator", "owner", "superuser", "staff", "auth", "i", "me", "everyone", "all", "mention", "mentions", "example", "user", "users", "account", "accounts", "official", "help", "helps", "support", "supports", "info", "information", "informations", "announce", "announces", "announcement", "announcements", "notice", "notification", "notifications", "dev", "developer", "developers", "tech", "misskey" }',
}) })

View File

@ -0,0 +1,64 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export const packedAdSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false,
nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
expiresAt: {
type: 'string',
optional: false,
nullable: false,
format: 'date-time',
},
startsAt: {
type: 'string',
optional: false,
nullable: false,
format: 'date-time',
},
place: {
type: 'string',
optional: false,
nullable: false,
},
priority: {
type: 'string',
optional: false,
nullable: false,
},
ratio: {
type: 'number',
optional: false,
nullable: false,
},
url: {
type: 'string',
optional: false,
nullable: false,
},
imageUrl: {
type: 'string',
optional: false,
nullable: false,
},
memo: {
type: 'string',
optional: false,
nullable: false,
},
dayOfWeek: {
type: 'integer',
optional: false,
nullable: false,
},
},
} as const;

View File

@ -25,6 +25,11 @@ export const meta = {
id: 'cb865949-8af5-4062-a88c-ef55e8786d1d', id: 'cb865949-8af5-4062-a88c-ef55e8786d1d',
}, },
}, },
res: {
type: 'object',
optional: false, nullable: false,
ref: 'User',
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -17,6 +17,12 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
res: {
type: 'object',
optional: false,
nullable: false,
ref: 'Ad',
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -63,7 +69,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
ad: ad, ad: ad,
}); });
return ad; return {
id: ad.id,
expiresAt: ad.expiresAt.toISOString(),
startsAt: ad.startsAt.toISOString(),
dayOfWeek: ad.dayOfWeek,
url: ad.url,
imageUrl: ad.imageUrl,
priority: ad.priority,
ratio: ad.ratio,
place: ad.place,
memo: ad.memo,
};
}); });
} }
} }

View File

@ -16,6 +16,17 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
res: {
type: 'array',
optional: false,
nullable: false,
items: {
type: 'object',
optional: false,
nullable: false,
ref: 'Ad',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -46,7 +57,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
} }
const ads = await query.limit(ps.limit).getMany(); const ads = await query.limit(ps.limit).getMany();
return ads; return ads.map(ad => ({
id: ad.id,
expiresAt: ad.expiresAt.toISOString(),
startsAt: ad.startsAt.toISOString(),
dayOfWeek: ad.dayOfWeek,
url: ad.url,
imageUrl: ad.imageUrl,
memo: ad.memo,
place: ad.place,
priority: ad.priority,
ratio: ad.ratio,
}));
}); });
} }
} }

View File

@ -31,6 +31,8 @@ export const meta = {
id: 'f7a3462c-4e6e-4069-8421-b9bd4f4c3975', id: 'f7a3462c-4e6e-4069-8421-b9bd4f4c3975',
}, },
}, },
ref: 'EmojiDetailed',
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -15,6 +15,16 @@ export const meta = {
kind: 'read:admin', kind: 'read:admin',
tags: ['admin'], tags: ['admin'],
res: {
type: 'array',
items: {
type: 'object',
properties: {
tablename: { type: 'string' },
indexname: { type: 'string' },
},
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -16,6 +16,25 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
res: {
type: 'array',
optional: false,
nullable: false,
items: {
type: 'object',
optional: false,
nullable: false,
properties: {
ip: { type: 'string' },
createdAt: {
type: 'string',
optional: false,
nullable: false,
format: 'date-time',
},
},
},
}
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -145,6 +145,14 @@ export const meta = {
type: 'string', type: 'string',
}, },
}, },
bannedEmailDomains: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
},
},
preservedUsernames: { preservedUsernames: {
type: 'array', type: 'array',
optional: false, nullable: false, optional: false, nullable: false,
@ -521,6 +529,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
enableChartsForFederatedInstances: instance.enableChartsForFederatedInstances, enableChartsForFederatedInstances: instance.enableChartsForFederatedInstances,
enableServerMachineStats: instance.enableServerMachineStats, enableServerMachineStats: instance.enableServerMachineStats,
enableIdenticonGeneration: instance.enableIdenticonGeneration, enableIdenticonGeneration: instance.enableIdenticonGeneration,
bannedEmailDomains: instance.bannedEmailDomains,
policies: { ...DEFAULT_POLICIES, ...instance.policies }, policies: { ...DEFAULT_POLICIES, ...instance.policies },
manifestJsonOverride: instance.manifestJsonOverride, manifestJsonOverride: instance.manifestJsonOverride,
enableFanoutTimeline: instance.enableFanoutTimeline, enableFanoutTimeline: instance.enableFanoutTimeline,

View File

@ -28,6 +28,20 @@ export const meta = {
id: '224eff5e-2488-4b18-b3e7-f50d94421648', id: '224eff5e-2488-4b18-b3e7-f50d94421648',
}, },
}, },
res: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'string', format: 'misskey:id' },
createdAt: { type: 'string', format: 'date-time' },
user: { ref: 'UserDetailed' },
expiresAt: { type: 'string', format: 'date-time', nullable: true },
},
required: ['id', 'createdAt', 'user'],
},
}
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -80,7 +94,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
id: assign.id, id: assign.id,
createdAt: this.idService.parse(assign.id).date.toISOString(), createdAt: this.idService.parse(assign.id).date.toISOString(),
user: await this.userEntityService.pack(assign.user!, me, { detail: true }), user: await this.userEntityService.pack(assign.user!, me, { detail: true }),
expiresAt: assign.expiresAt, expiresAt: assign.expiresAt?.toISOString() ?? null,
}))); })));
}); });
} }

View File

@ -122,6 +122,7 @@ export const paramDef = {
enableServerMachineStats: { type: 'boolean' }, enableServerMachineStats: { type: 'boolean' },
enableIdenticonGeneration: { type: 'boolean' }, enableIdenticonGeneration: { type: 'boolean' },
serverRules: { type: 'array', items: { type: 'string' } }, serverRules: { type: 'array', items: { type: 'string' } },
bannedEmailDomains: { type: 'array', items: { type: 'string' } },
preservedUsernames: { type: 'array', items: { type: 'string' } }, preservedUsernames: { type: 'array', items: { type: 'string' } },
manifestJsonOverride: { type: 'string' }, manifestJsonOverride: { type: 'string' },
enableFanoutTimeline: { type: 'boolean' }, enableFanoutTimeline: { type: 'boolean' },
@ -534,6 +535,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
set.notesPerOneAd = ps.notesPerOneAd; set.notesPerOneAd = ps.notesPerOneAd;
} }
if (ps.bannedEmailDomains !== undefined) {
set.bannedEmailDomains = ps.bannedEmailDomains;
}
const before = await this.metaService.fetch(true); const before = await this.metaService.fetch(true);
await this.metaService.update(set); await this.metaService.update(set);

View File

@ -11,6 +11,23 @@ export const meta = {
requireCredential: false, requireCredential: false,
tags: ['meta'], tags: ['meta'],
res: {
type: 'object',
nullable: true,
properties: {
params: {
type: 'array',
items: {
type: 'object',
properties: {
name: { type: 'string' },
type: { type: 'string' },
},
},
},
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -18,6 +18,92 @@ export const meta = {
allowGet: true, allowGet: true,
cacheSec: 60 * 60, cacheSec: 60 * 60,
res: {
type: 'object',
optional: false,
nullable: false,
properties: {
topSubInstances: {
type: 'array',
optional: false,
nullable: false,
items: {
properties: {
id: { type: 'string' },
firstRetrievedAt: { type: 'string' },
host: { type: 'string' },
usersCount: { type: 'number' },
notesCount: { type: 'number' },
followingCount: { type: 'number' },
followersCount: { type: 'number' },
isNotResponding: { type: 'boolean' },
isSuspended: { type: 'boolean' },
isBlocked: { type: 'boolean' },
softwareName: { type: 'string' },
softwareVersion: { type: 'string' },
openRegistrations: { type: 'boolean' },
name: { type: 'string' },
description: { type: 'string' },
maintainerName: { type: 'string' },
maintainerEmail: { type: 'string' },
isSilenced: { type: 'boolean' },
iconUrl: { type: 'string' },
faviconUrl: { type: 'string' },
themeColor: { type: 'string' },
infoUpdatedAt: {
type: 'string',
nullable: true,
},
latestRequestReceivedAt: {
type: 'string',
nullable: true,
},
}
},
},
otherFollowersCount: { type: 'number' },
topPubInstances: {
type: 'array',
optional: false,
nullable: false,
items: {
properties: {
id: { type: 'string' },
firstRetrievedAt: { type: 'string' },
host: { type: 'string' },
usersCount: { type: 'number' },
notesCount: { type: 'number' },
followingCount: { type: 'number' },
followersCount: { type: 'number' },
isNotResponding: { type: 'boolean' },
isSuspended: { type: 'boolean' },
isBlocked: { type: 'boolean' },
softwareName: { type: 'string' },
softwareVersion: { type: 'string' },
openRegistrations: { type: 'boolean' },
name: { type: 'string' },
description: { type: 'string' },
maintainerName: { type: 'string' },
maintainerEmail: { type: 'string' },
isSilenced: { type: 'boolean' },
iconUrl: { type: 'string' },
faviconUrl: { type: 'string' },
themeColor: { type: 'string' },
infoUpdatedAt: {
type: 'string',
nullable: true,
},
latestRequestReceivedAt: {
type: 'string',
nullable: true,
},
}
},
},
otherFollowingCount: { type: 'number' },
},
}
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -32,6 +32,18 @@ export const meta = {
id: '693ba8ba-b486-40df-a174-72f8279b56a4', id: '693ba8ba-b486-40df-a174-72f8279b56a4',
}, },
}, },
res: {
type: 'object',
properties: {
type: {
type: 'string',
},
data: {
type: 'string',
},
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -16,6 +16,18 @@ export const meta = {
requireCredential: false, requireCredential: false,
allowGet: true, allowGet: true,
cacheSec: 60 * 3, cacheSec: 60 * 3,
res: {
type: 'object',
properties: {
items: {
type: 'array',
items: {
type: 'object',
},
}
}
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -28,6 +28,12 @@ export const meta = {
errors: { errors: {
}, },
res: {
type: 'object',
optional: false, nullable: false,
ref: 'Flash',
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -16,6 +16,16 @@ export const meta = {
requireCredential: false, requireCredential: false,
allowGet: true, allowGet: true,
cacheSec: 60 * 1, cacheSec: 60 * 1,
res: {
type: 'object',
optional: false, nullable: false,
properties: {
count: {
type: 'number',
nullable: false,
},
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -38,6 +38,16 @@ export const meta = {
id: '798d6847-b1ed-4f9c-b1f9-163c42655995', id: '798d6847-b1ed-4f9c-b1f9-163c42655995',
}, },
}, },
res: {
type: 'object',
nullable: false,
optional: false,
properties: {
id: { type: 'string' },
name: { type: 'string' },
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -42,6 +42,140 @@ export const meta = {
id: 'bf32b864-449b-47b8-974e-f9a5468546f1', id: 'bf32b864-449b-47b8-974e-f9a5468546f1',
}, },
}, },
res: {
type: 'object',
nullable: false,
optional: false,
properties: {
rp: {
type: 'object',
properties: {
id: {
type: 'string',
nullable: true,
},
},
},
user: {
type: 'object',
properties: {
id: {
type: 'string',
},
name: {
type: 'string',
},
displayName: {
type: 'string',
},
},
},
challenge: {
type: 'string',
},
pubKeyCredParams: {
type: 'array',
items: {
type: 'object',
properties: {
type: {
type: 'string',
},
alg: {
type: 'number',
},
},
},
},
timeout: {
type: 'number',
nullable: true,
},
excludeCredentials: {
type: 'array',
nullable: true,
items: {
type: 'object',
properties: {
id: {
type: 'string',
},
type: {
type: 'string',
},
transports: {
type: 'array',
items: {
type: 'string',
enum: [
"ble",
"cable",
"hybrid",
"internal",
"nfc",
"smart-card",
"usb",
],
},
},
},
},
},
authenticatorSelection: {
type: 'object',
nullable: true,
properties: {
authenticatorAttachment: {
type: 'string',
enum: [
"cross-platform",
"platform",
],
},
requireResidentKey: {
type: 'boolean',
},
userVerification: {
type: 'string',
enum: [
"discouraged",
"preferred",
"required",
],
},
},
},
attestation: {
type: 'string',
nullable: true,
enum: [
"direct",
"enterprise",
"indirect",
"none",
],
},
extensions: {
type: 'object',
nullable: true,
properties: {
appid: {
type: 'string',
nullable: true,
},
credProps: {
type: 'boolean',
nullable: true,
},
hmacCreateSecret: {
type: 'boolean',
nullable: true,
},
},
},
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -32,6 +32,19 @@ export const meta = {
id: 'e428f177-c6ae-4e91-9c7e-334b1836f9aa', id: 'e428f177-c6ae-4e91-9c7e-334b1836f9aa',
}, },
}, },
res: {
type: 'object',
nullable: false,
optional: false,
properties: {
qr: { type: 'string' },
url: { type: 'string' },
secret: { type: 'string' },
label: { type: 'string' },
issuer: { type: 'string' },
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -13,6 +13,37 @@ export const meta = {
requireCredential: true, requireCredential: true,
secure: true, secure: true,
res: {
type: 'array',
items: {
type: 'object',
properties: {
id: {
type: 'string',
format: 'misskey:id',
},
name: {
type: 'string',
},
createdAt: {
type: 'string',
format: 'date-time',
},
lastUsedAt: {
type: 'string',
format: 'date-time',
},
permission: {
type: 'array',
uniqueItems: true,
items: {
type: 'string'
},
}
},
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -50,7 +81,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
id: token.id, id: token.id,
name: token.name ?? token.app?.name, name: token.name ?? token.app?.name,
createdAt: this.idService.parse(token.id).date.toISOString(), createdAt: this.idService.parse(token.id).date.toISOString(),
lastUsedAt: token.lastUsedAt, lastUsedAt: token.lastUsedAt?.toISOString(),
permission: token.permission, permission: token.permission,
}))); })));
}); });

View File

@ -14,6 +14,36 @@ export const meta = {
requireCredential: true, requireCredential: true,
secure: true, secure: true,
res: {
type: 'array',
items: {
type: 'object',
properties: {
id: {
type: 'string',
format: 'misskey:id',
},
name: {
type: 'string',
},
callbackUrl: {
type: 'string',
nullable: true,
},
permission: {
type: 'array',
uniqueItems: true,
items: {
type: 'string'
},
},
isAuthorized: {
type: 'boolean',
},
},
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -67,6 +67,10 @@ export const meta = {
id: 'b234a14e-9ebe-4581-8000-074b3c215962', id: 'b234a14e-9ebe-4581-8000-074b3c215962',
}, },
}, },
res: {
type: 'object',
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -9,6 +9,10 @@ import { RegistryApiService } from '@/core/RegistryApiService.js';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
res: {
type: 'object',
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -18,6 +18,10 @@ export const meta = {
id: '97a1e8e7-c0f7-47d2-957a-92e61256e01a', id: '97a1e8e7-c0f7-47d2-957a-92e61256e01a',
}, },
}, },
res: {
type: 'object',
}
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -18,6 +18,10 @@ export const meta = {
id: 'ac3ed68a-62f0-422b-a7bc-d5e09e8f6a6a', id: 'ac3ed68a-62f0-422b-a7bc-d5e09e8f6a6a',
}, },
}, },
res: {
type: 'object',
}
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -9,6 +9,10 @@ import { RegistryApiService } from '@/core/RegistryApiService.js';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
res: {
type: 'object',
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -10,6 +10,28 @@ import { RegistryApiService } from '@/core/RegistryApiService.js';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
secure: true, secure: true,
res: {
type: 'array',
items: {
type: 'object',
properties: {
scopes: {
type: 'array',
items: {
type: 'array',
items: {
type: 'string',
}
}
},
domain: {
type: 'string',
nullable: true,
},
},
},
}
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -47,6 +47,11 @@ export const meta = {
id: 'a2defefb-f220-8849-0af6-17f816099323', id: 'a2defefb-f220-8849-0af6-17f816099323',
}, },
}, },
res: {
type: 'object',
ref: 'UserDetailed',
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -28,6 +28,33 @@ export const meta = {
id: '87a9bb19-111e-4e37-81d3-a3e7426453b0', id: '87a9bb19-111e-4e37-81d3-a3e7426453b0',
}, },
}, },
res: {
type: 'object',
properties: {
id: {
type: 'string',
format: 'misskey:id'
},
userId: {
type: 'string',
format: 'misskey:id',
},
name: { type: 'string' },
on: {
type: 'array',
items: {
type: 'string',
enum: webhookEventTypes,
}
},
url: { type: 'string' },
secret: { type: 'string' },
active: { type: 'boolean' },
latestSentAt: { type: 'string', format: 'date-time', nullable: true },
latestStatus: { type: 'integer', nullable: true },
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -74,7 +101,17 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
this.globalEventService.publishInternalEvent('webhookCreated', webhook); this.globalEventService.publishInternalEvent('webhookCreated', webhook);
return webhook; return {
id: webhook.id,
userId: webhook.userId,
name: webhook.name,
on: webhook.on,
url: webhook.url,
secret: webhook.secret,
active: webhook.active,
latestSentAt: webhook.latestSentAt?.toISOString(),
latestStatus: webhook.latestStatus,
};
}); });
} }
} }

View File

@ -5,6 +5,7 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import { webhookEventTypes } from '@/models/Webhook.js';
import type { WebhooksRepository } from '@/models/_.js'; import type { WebhooksRepository } from '@/models/_.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
@ -14,6 +15,36 @@ export const meta = {
requireCredential: true, requireCredential: true,
kind: 'read:account', kind: 'read:account',
res: {
type: 'array',
items: {
type: 'object',
properties: {
id: {
type: 'string',
format: 'misskey:id'
},
userId: {
type: 'string',
format: 'misskey:id',
},
name: { type: 'string' },
on: {
type: 'array',
items: {
type: 'string',
enum: webhookEventTypes,
}
},
url: { type: 'string' },
secret: { type: 'string' },
active: { type: 'boolean' },
latestSentAt: { type: 'string', format: 'date-time', nullable: true },
latestStatus: { type: 'integer', nullable: true },
},
}
}
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -33,7 +64,19 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
userId: me.id, userId: me.id,
}); });
return webhooks; return webhooks.map(webhook => (
{
id: webhook.id,
userId: webhook.userId,
name: webhook.name,
on: webhook.on,
url: webhook.url,
secret: webhook.secret,
active: webhook.active,
latestSentAt: webhook.latestSentAt?.toISOString(),
latestStatus: webhook.latestStatus,
}
));
}); });
} }
} }

View File

@ -5,6 +5,7 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import { webhookEventTypes } from '@/models/Webhook.js';
import type { WebhooksRepository } from '@/models/_.js'; import type { WebhooksRepository } from '@/models/_.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js'; import { ApiError } from '../../../error.js';
@ -23,6 +24,33 @@ export const meta = {
id: '50f614d9-3047-4f7e-90d8-ad6b2d5fb098', id: '50f614d9-3047-4f7e-90d8-ad6b2d5fb098',
}, },
}, },
res: {
type: 'object',
properties: {
id: {
type: 'string',
format: 'misskey:id'
},
userId: {
type: 'string',
format: 'misskey:id',
},
name: { type: 'string' },
on: {
type: 'array',
items: {
type: 'string',
enum: webhookEventTypes,
}
},
url: { type: 'string' },
secret: { type: 'string' },
active: { type: 'boolean' },
latestSentAt: { type: 'string', format: 'date-time', nullable: true },
latestStatus: { type: 'integer', nullable: true },
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -49,7 +77,17 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new ApiError(meta.errors.noSuchWebhook); throw new ApiError(meta.errors.noSuchWebhook);
} }
return webhook; return {
id: webhook.id,
userId: webhook.userId,
name: webhook.name,
on: webhook.on,
url: webhook.url,
secret: webhook.secret,
active: webhook.active,
latestSentAt: webhook.latestSentAt?.toISOString(),
latestStatus: webhook.latestStatus,
};
}); });
} }
} }

View File

@ -24,6 +24,25 @@ export const meta = {
id: '30aaaee3-4792-48dc-ab0d-cf501a575ac5', id: '30aaaee3-4792-48dc-ab0d-cf501a575ac5',
}, },
}, },
res: {
type: 'array',
items: {
type: 'object',
nullable: false,
properties: {
id: {
type: 'string',
format: 'misskey:id'
},
user: {
type: 'object',
ref: 'User'
},
},
required: ['id', 'user'],
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -15,6 +15,53 @@ export const meta = {
cacheSec: 60 * 1, cacheSec: 60 * 1,
tags: ['meta'], tags: ['meta'],
res: {
type: 'object',
optional: false, nullable: false,
properties: {
machine: {
type: 'string',
nullable: false,
},
cpu: {
type: 'object',
nullable: false,
properties: {
model: {
type: 'string',
nullable: false,
},
cores: {
type: 'number',
nullable: false,
},
},
},
mem: {
type: 'object',
properties: {
total: {
type: 'number',
nullable: false,
},
},
},
fs: {
type: 'object',
nullable: false,
properties: {
total: {
type: 'number',
nullable: false,
},
used: {
type: 'number',
nullable: false,
},
},
},
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -12,6 +12,30 @@ export const meta = {
description: 'Endpoint for testing input validation.', description: 'Endpoint for testing input validation.',
requireCredential: false, requireCredential: false,
res: {
type: 'object',
properties: {
id: {
type: 'string',
format: 'misskey:id'
},
required: {
type: 'boolean',
},
string: {
type: 'string',
},
default: {
type: 'string',
},
nullableDefault: {
type: 'string',
default: 'hello',
nullable: true,
},
}
}
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -10,6 +10,21 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
res: {
type: 'array',
items: {
type: 'object',
properties: {
name: {
type: 'string',
},
unlockedAt: {
type: 'number',
},
},
},
}
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -25,6 +25,35 @@ export const meta = {
id: '7bc05c21-1d7a-41ae-88f1-66820f4dc686', id: '7bc05c21-1d7a-41ae-88f1-66820f4dc686',
}, },
}, },
res: {
type: 'array',
items: {
type: 'object',
nullable: false,
properties: {
id: {
type: 'string',
format: 'misskey:id',
},
createdAt: {
type: 'string',
format: 'date-time',
},
userId: {
type: 'string',
format: 'misskey:id',
},
user: {
type: 'object',
ref: 'User',
},
withReplies: {
type: 'boolean',
},
},
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View File

@ -10,9 +10,8 @@ process.env.NODE_ENV = 'test';
process.env.FORCE_FOLLOW_REMOTE_USER_FOR_TESTING = 'true'; process.env.FORCE_FOLLOW_REMOTE_USER_FOR_TESTING = 'true';
import * as assert from 'assert'; import * as assert from 'assert';
import { signup, api, post, react, startServer, waitFire, sleep, uploadUrl, randomString } from '../utils.js'; import { api, post, randomString, signup, sleep, startServer, uploadUrl } from '../utils.js';
import type { INestApplicationContext } from '@nestjs/common'; import type { INestApplicationContext } from '@nestjs/common';
import type * as misskey from 'misskey-js';
function genHost() { function genHost() {
return randomString() + '.example.com'; return randomString() + '.example.com';
@ -366,8 +365,8 @@ describe('Timelines', () => {
await api('/following/create', { userId: bob.id }, alice); await api('/following/create', { userId: bob.id }, alice);
await sleep(1000); await sleep(1000);
const [bobFile, carolFile] = await Promise.all([ const [bobFile, carolFile] = await Promise.all([
uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png'), uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png'),
uploadUrl(carol, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png'), uploadUrl(carol, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png'),
]); ]);
const bobNote1 = await post(bob, { text: 'hi' }); const bobNote1 = await post(bob, { text: 'hi' });
const bobNote2 = await post(bob, { fileIds: [bobFile.id] }); const bobNote2 = await post(bob, { fileIds: [bobFile.id] });
@ -666,7 +665,7 @@ describe('Timelines', () => {
test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => { test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]); const [alice, bob] = await Promise.all([signup(), signup()]);
const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png'); const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png');
const bobNote1 = await post(bob, { text: 'hi' }); const bobNote1 = await post(bob, { text: 'hi' });
const bobNote2 = await post(bob, { fileIds: [file.id] }); const bobNote2 = await post(bob, { fileIds: [file.id] });
@ -804,7 +803,7 @@ describe('Timelines', () => {
test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => { test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]); const [alice, bob] = await Promise.all([signup(), signup()]);
const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png'); const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png');
const bobNote1 = await post(bob, { text: 'hi' }); const bobNote1 = await post(bob, { text: 'hi' });
const bobNote2 = await post(bob, { fileIds: [file.id] }); const bobNote2 = await post(bob, { fileIds: [file.id] });
@ -1000,7 +999,7 @@ describe('Timelines', () => {
const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body); const list = await api('/users/lists/create', { name: 'list' }, alice).then(res => res.body);
await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice); await api('/users/lists/push', { listId: list.id, userId: bob.id }, alice);
const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png'); const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png');
const bobNote1 = await post(bob, { text: 'hi' }); const bobNote1 = await post(bob, { text: 'hi' });
const bobNote2 = await post(bob, { fileIds: [file.id] }); const bobNote2 = await post(bob, { fileIds: [file.id] });
@ -1159,7 +1158,7 @@ describe('Timelines', () => {
test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => { test.concurrent('[withFiles: true] ファイル付きノートのみ含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]); const [alice, bob] = await Promise.all([signup(), signup()]);
const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/icon.png'); const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png');
const bobNote1 = await post(bob, { text: 'hi' }); const bobNote1 = await post(bob, { text: 'hi' });
const bobNote2 = await post(bob, { fileIds: [file.id] }); const bobNote2 = await post(bob, { fileIds: [file.id] });

View File

@ -73,13 +73,21 @@ describe('RoleService', () => {
CacheService, CacheService,
IdService, IdService,
GlobalEventService, GlobalEventService,
{
provide: NotificationService,
useFactory: () => ({
createNotification: jest.fn(),
}),
},
{
provide: NotificationService.name,
useExisting: NotificationService,
},
], ],
}) })
.useMocker((token) => { .useMocker((token) => {
if (token === MetaService) { if (token === MetaService) {
return { fetch: jest.fn() }; return { fetch: jest.fn() };
} else if (token === NotificationService) {
return { createNotification: jest.fn() };
} }
if (typeof token === 'function') { if (typeof token === 'function') {
const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata<any, any>; const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata<any, any>;
@ -98,6 +106,8 @@ describe('RoleService', () => {
metaService = app.get<MetaService>(MetaService) as jest.Mocked<MetaService>; metaService = app.get<MetaService>(MetaService) as jest.Mocked<MetaService>;
notificationService = app.get<NotificationService>(NotificationService) as jest.Mocked<NotificationService>; notificationService = app.get<NotificationService>(NotificationService) as jest.Mocked<NotificationService>;
await roleService.onModuleInit();
}); });
afterEach(async () => { afterEach(async () => {
@ -284,10 +294,12 @@ describe('RoleService', () => {
const user = await createUser(); const user = await createUser();
const role = await createRole({ const role = await createRole({
isPublic: true, isPublic: true,
name: 'a',
}); });
await roleService.assign(user.id, role.id); await roleService.assign(user.id, role.id);
clock.uninstall();
await sleep(100); await sleep(100);
const assignments = await roleAssignmentsRepository.find({ const assignments = await roleAssignmentsRepository.find({
@ -301,7 +313,7 @@ describe('RoleService', () => {
expect(notificationService.createNotification).toHaveBeenCalled(); expect(notificationService.createNotification).toHaveBeenCalled();
expect(notificationService.createNotification.mock.lastCall![0]).toBe(user.id); expect(notificationService.createNotification.mock.lastCall![0]).toBe(user.id);
expect(notificationService.createNotification.mock.lastCall![1]).toBe('roleAssigned'); expect(notificationService.createNotification.mock.lastCall![1]).toBe('roleAssigned');
expect(notificationService.createNotification.mock.lastCall![2]).toBe({ expect(notificationService.createNotification.mock.lastCall![2]).toEqual({
roleId: role.id, roleId: role.id,
}); });
}); });
@ -310,10 +322,12 @@ describe('RoleService', () => {
const user = await createUser(); const user = await createUser();
const role = await createRole({ const role = await createRole({
isPublic: false, isPublic: false,
name: 'a',
}); });
await roleService.assign(user.id, role.id); await roleService.assign(user.id, role.id);
clock.uninstall();
await sleep(100); await sleep(100);
const assignments = await roleAssignmentsRepository.find({ const assignments = await roleAssignmentsRepository.find({

View File

@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<MkA :to="`/channels/${channel.id}`" class="eftoefju _panel" tabindex="-1"> <div style="position: relative;">
<MkA :to="`/channels/${channel.id}`" class="eftoefju _panel" tabindex="-1" @click="updateLastReadedAt">
<div class="banner" :style="bannerStyle"> <div class="banner" :style="bannerStyle">
<div class="fade"></div> <div class="fade"></div>
<div class="name"><i class="ti ti-device-tv"></i> {{ channel.name }}</div> <div class="name"><i class="ti ti-device-tv"></i> {{ channel.name }}</div>
@ -37,16 +38,36 @@ SPDX-License-Identifier: AGPL-3.0-only
</span> </span>
</footer> </footer>
</MkA> </MkA>
<div
v-if="channel.lastNotedAt && (channel.isFavorited || channel.isFollowing) && (!lastReadedAt || Date.parse(channel.lastNotedAt) > lastReadedAt)"
class="indicator"
></div>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue'; import { computed, ref, watch } from 'vue';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { miLocalStorage } from '@/local-storage.js';
const props = defineProps<{ const props = defineProps<{
channel: Record<string, any>; channel: Record<string, any>;
}>(); }>();
const getLastReadedAt = (): number | null => {
return miLocalStorage.getItemAsJson(`channelLastReadedAt:${props.channel.id}`) ?? null;
};
const lastReadedAt = ref(getLastReadedAt());
watch(() => props.channel.id, () => {
lastReadedAt.value = getLastReadedAt();
});
const updateLastReadedAt = () => {
lastReadedAt.value = props.channel.lastNotedAt ? Date.parse(props.channel.lastNotedAt) : Date.now();
};
const bannerStyle = computed(() => { const bannerStyle = computed(() => {
if (props.channel.bannerUrl) { if (props.channel.bannerUrl) {
return { backgroundImage: `url(${props.channel.bannerUrl})` }; return { backgroundImage: `url(${props.channel.bannerUrl})` };
@ -170,4 +191,17 @@ const bannerStyle = computed(() => {
} }
} }
.indicator {
position: absolute;
top: 0;
right: 0;
transform: translate(25%, -25%);
background-color: var(--accent);
border: solid var(--bg) 4px;
border-radius: 100%;
width: 1.5rem;
height: 1.5rem;
aspect-ratio: 1 / 1;
}
</style> </style>

View File

@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
</I18n> </I18n>
<div style="margin-top: 0.2em;"> <div style="margin-top: 0.2em;">
<MkLink target="_blank" url="https://misskey-hub.net/docs/donate.html">{{ i18n.ts.learnMore }}</MkLink> <MkLink target="_blank" url="https://misskey-hub.net/docs/for-users/resources/donate/">{{ i18n.ts.learnMore }}</MkLink>
</div> </div>
</div> </div>
<div class="_buttons"> <div class="_buttons">

View File

@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template v-for="(item, i) in items2"> <template v-for="(item, i) in items2">
<div v-if="item.type === 'divider'" role="separator" :class="$style.divider"></div> <div v-if="item.type === 'divider'" role="separator" :class="$style.divider"></div>
<span v-else-if="item.type === 'label'" role="menuitem" :class="[$style.label, $style.item]"> <span v-else-if="item.type === 'label'" role="menuitem" :class="[$style.label, $style.item]">
<span>{{ item.text }}</span> <span style="opacity: 0.7;">{{ item.text }}</span>
</span> </span>
<span v-else-if="item.type === 'pending'" role="menuitem" :tabindex="i" :class="[$style.pending, $style.item]"> <span v-else-if="item.type === 'pending'" role="menuitem" :tabindex="i" :class="[$style.pending, $style.item]">
<span><MkEllipsis/></span> <span><MkEllipsis/></span>
@ -23,32 +23,44 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkA v-else-if="item.type === 'link'" role="menuitem" :to="item.to" :tabindex="i" class="_button" :class="$style.item" @click.passive="close(true)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)"> <MkA v-else-if="item.type === 'link'" role="menuitem" :to="item.to" :tabindex="i" class="_button" :class="$style.item" @click.passive="close(true)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i> <i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i>
<MkAvatar v-if="item.avatar" :user="item.avatar" :class="$style.avatar"/> <MkAvatar v-if="item.avatar" :user="item.avatar" :class="$style.avatar"/>
<span>{{ item.text }}</span> <div :class="$style.item_content">
<span :class="$style.item_content_text">{{ item.text }}</span>
<span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span> <span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span>
</div>
</MkA> </MkA>
<a v-else-if="item.type === 'a'" role="menuitem" :href="item.href" :target="item.target" :download="item.download" :tabindex="i" class="_button" :class="$style.item" @click="close(true)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)"> <a v-else-if="item.type === 'a'" role="menuitem" :href="item.href" :target="item.target" :download="item.download" :tabindex="i" class="_button" :class="$style.item" @click="close(true)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i> <i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i>
<span>{{ item.text }}</span> <div :class="$style.item_content">
<span :class="$style.item_content_text">{{ item.text }}</span>
<span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span> <span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span>
</div>
</a> </a>
<button v-else-if="item.type === 'user'" role="menuitem" :tabindex="i" class="_button" :class="[$style.item, { [$style.active]: item.active }]" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)"> <button v-else-if="item.type === 'user'" role="menuitem" :tabindex="i" class="_button" :class="[$style.item, { [$style.active]: item.active }]" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<MkAvatar :user="item.user" :class="$style.avatar"/><MkUserName :user="item.user"/> <MkAvatar :user="item.user" :class="$style.avatar"/><MkUserName :user="item.user"/>
<span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span> <div v-if="item.indicate" :class="$style.item_content">
<span :class="$style.indicator"><i class="_indicatorCircle"></i></span>
</div>
</button> </button>
<button v-else-if="item.type === 'switch'" role="menuitemcheckbox" :tabindex="i" class="_button" :class="[$style.item, $style.switch, { [$style.switchDisabled]: item.disabled } ]" @click="switchItem(item)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)"> <button v-else-if="item.type === 'switch'" role="menuitemcheckbox" :tabindex="i" class="_button" :class="[$style.item, $style.switch, { [$style.switchDisabled]: item.disabled } ]" @click="switchItem(item)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<MkSwitchButton :class="$style.switchButton" :checked="item.ref" :disabled="item.disabled" @toggle="switchItem(item)"/> <MkSwitchButton :class="$style.switchButton" :checked="item.ref" :disabled="item.disabled" @toggle="switchItem(item)"/>
<span :class="$style.switchText">{{ item.text }}</span> <div :class="$style.item_content">
<span :class="[$style.item_content_text, $style.switchText]">{{ item.text }}</span>
</div>
</button> </button>
<button v-else-if="item.type === 'parent'" class="_button" role="menuitem" :tabindex="i" :class="[$style.item, $style.parent, { [$style.childShowing]: childShowingItem === item }]" @mouseenter="preferClick ? null : showChildren(item, $event)" @click="!preferClick ? null : showChildren(item, $event)"> <button v-else-if="item.type === 'parent'" class="_button" role="menuitem" :tabindex="i" :class="[$style.item, $style.parent, { [$style.childShowing]: childShowingItem === item }]" @mouseenter="preferClick ? null : showChildren(item, $event)" @click="!preferClick ? null : showChildren(item, $event)">
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]" style="pointer-events: none;"></i> <i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]" style="pointer-events: none;"></i>
<span style="pointer-events: none;">{{ item.text }}</span> <div :class="$style.item_content">
<span :class="$style.item_content_text" style="pointer-events: none;">{{ item.text }}</span>
<span :class="$style.caret" style="pointer-events: none;"><i class="ti ti-chevron-right ti-fw"></i></span> <span :class="$style.caret" style="pointer-events: none;"><i class="ti ti-chevron-right ti-fw"></i></span>
</div>
</button> </button>
<button v-else :tabindex="i" class="_button" role="menuitem" :class="[$style.item, { [$style.danger]: item.danger, [$style.active]: item.active }]" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)"> <button v-else :tabindex="i" class="_button" role="menuitem" :class="[$style.item, { [$style.danger]: item.danger, [$style.active]: item.active }]" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i> <i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i>
<MkAvatar v-if="item.avatar" :user="item.avatar" :class="$style.avatar"/> <MkAvatar v-if="item.avatar" :user="item.avatar" :class="$style.avatar"/>
<span>{{ item.text }}</span> <div :class="$style.item_content">
<span :class="$style.item_content_text">{{ item.text }}</span>
<span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span> <span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span>
</div>
</button> </button>
</template> </template>
<span v-if="items2.length === 0" :class="[$style.none, $style.item]"> <span v-if="items2.length === 0" :class="[$style.none, $style.item]">
@ -228,6 +240,7 @@ onBeforeUnmount(() => {
.root { .root {
padding: 8px 0; padding: 8px 0;
box-sizing: border-box; box-sizing: border-box;
max-width: 100vw;
min-width: 200px; min-width: 200px;
overflow: auto; overflow: auto;
overscroll-behavior: contain; overscroll-behavior: contain;
@ -267,7 +280,8 @@ onBeforeUnmount(() => {
} }
.item { .item {
display: block; display: flex;
align-items: center;
position: relative; position: relative;
padding: 5px 16px; padding: 5px 16px;
width: 100%; width: 100%;
@ -340,10 +354,6 @@ onBeforeUnmount(() => {
pointer-events: none; pointer-events: none;
font-size: 0.7em; font-size: 0.7em;
padding-bottom: 4px; padding-bottom: 4px;
> span {
opacity: 0.7;
}
} }
&.pending { &.pending {
@ -373,6 +383,22 @@ onBeforeUnmount(() => {
} }
} }
.item_content {
width: 100%;
max-width: 100vw;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
text-overflow: ellipsis;
}
.item_content_text {
max-width: calc(100vw - 4rem);
text-overflow: ellipsis;
overflow: hidden;
}
.switch { .switch {
position: relative; position: relative;
display: flex; display: flex;
@ -406,6 +432,7 @@ onBeforeUnmount(() => {
.icon { .icon {
margin-right: 8px; margin-right: 8px;
line-height: 1;
} }
.caret { .caret {
@ -419,9 +446,8 @@ onBeforeUnmount(() => {
} }
.indicator { .indicator {
position: absolute; display: flex;
top: 5px; align-items: center;
left: 13px;
color: var(--indicator); color: var(--indicator);
font-size: 12px; font-size: 12px;
animation: blink 1s infinite; animation: blink 1s infinite;

View File

@ -38,6 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span v-else-if="emailState === 'unavailable:used'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.used }}</span> <span v-else-if="emailState === 'unavailable:used'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.used }}</span>
<span v-else-if="emailState === 'unavailable:format'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.format }}</span> <span v-else-if="emailState === 'unavailable:format'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.format }}</span>
<span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.disposable }}</span> <span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.disposable }}</span>
<span v-else-if="emailState === 'unavailable:banned'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.banned }}</span>
<span v-else-if="emailState === 'unavailable:mx'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.mx }}</span> <span v-else-if="emailState === 'unavailable:mx'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.mx }}</span>
<span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.smtp }}</span> <span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.smtp }}</span>
<span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span> <span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
@ -110,7 +111,7 @@ const retypedPassword = ref<string>('');
const invitationCode = ref<string>(''); const invitationCode = ref<string>('');
const email = ref(''); const email = ref('');
const usernameState = ref<null | 'wait' | 'ok' | 'unavailable' | 'error' | 'invalid-format' | 'min-range' | 'max-range'>(null); const usernameState = ref<null | 'wait' | 'ok' | 'unavailable' | 'error' | 'invalid-format' | 'min-range' | 'max-range'>(null);
const emailState = ref<null | 'wait' | 'ok' | 'unavailable:used' | 'unavailable:format' | 'unavailable:disposable' | 'unavailable:mx' | 'unavailable:smtp' | 'unavailable' | 'error'>(null); const emailState = ref<null | 'wait' | 'ok' | 'unavailable:used' | 'unavailable:format' | 'unavailable:disposable' | 'unavailable:banned' | 'unavailable:mx' | 'unavailable:smtp' | 'unavailable' | 'error'>(null);
const passwordStrength = ref<'' | 'low' | 'medium' | 'high'>(''); const passwordStrength = ref<'' | 'low' | 'medium' | 'high'>('');
const passwordRetypeState = ref<null | 'match' | 'not-match'>(null); const passwordRetypeState = ref<null | 'match' | 'not-match'>(null);
const submitting = ref<boolean>(false); const submitting = ref<boolean>(false);
@ -209,6 +210,7 @@ function onChangeEmail(): void {
result.reason === 'used' ? 'unavailable:used' : result.reason === 'used' ? 'unavailable:used' :
result.reason === 'format' ? 'unavailable:format' : result.reason === 'format' ? 'unavailable:format' :
result.reason === 'disposable' ? 'unavailable:disposable' : result.reason === 'disposable' ? 'unavailable:disposable' :
result.reason === 'banned' ? 'unavailable:banned' :
result.reason === 'mx' ? 'unavailable:mx' : result.reason === 'mx' ? 'unavailable:mx' :
result.reason === 'smtp' ? 'unavailable:smtp' : result.reason === 'smtp' ? 'unavailable:smtp' :
'unavailable'; 'unavailable';

View File

@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>{{ i18n.ts.basicNotesBeforeCreateAccount }}</template> <template #label>{{ i18n.ts.basicNotesBeforeCreateAccount }}</template>
<template #suffix><i v-if="agreeNote" class="ti ti-check" style="color: var(--success)"></i></template> <template #suffix><i v-if="agreeNote" class="ti ti-check" style="color: var(--success)"></i></template>
<a href="https://misskey-hub.net/docs/notes.html" class="_link" target="_blank">{{ i18n.ts.basicNotesBeforeCreateAccount }} <i class="ti ti-external-link"></i></a> <a href="https://misskey-hub.net/docs/for-users/onboarding/warning/" class="_link" target="_blank">{{ i18n.ts.basicNotesBeforeCreateAccount }} <i class="ti ti-external-link"></i></a>
<MkSwitch :modelValue="agreeNote" style="margin-top: 16px;" data-cy-signup-rules-notes-agree @update:modelValue="updateAgreeNote">{{ i18n.ts.agree }}</MkSwitch> <MkSwitch :modelValue="agreeNote" style="margin-top: 16px;" data-cy-signup-rules-notes-agree @update:modelValue="updateAgreeNote">{{ i18n.ts.agree }}</MkSwitch>
</MkFolder> </MkFolder>

View File

@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="$style.divider"></div> <div :class="$style.divider"></div>
<I18n :src="i18n.ts._initialTutorial._timeline.description3" tag="div" style="padding: 0 16px;"> <I18n :src="i18n.ts._initialTutorial._timeline.description3" tag="div" style="padding: 0 16px;">
<template #link> <template #link>
<a href="https://misskey-hub.net/docs/features/timeline.html" target="_blank" class="_link">{{ i18n.ts.help }}</a> <a href="https://misskey-hub.net/docs/for-users/features/timeline/" target="_blank" class="_link">{{ i18n.ts.help }}</a>
</template> </template>
</I18n> </I18n>

View File

@ -130,7 +130,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div style="font-size: 120%;">{{ i18n.ts._initialTutorial._done.title }}</div> <div style="font-size: 120%;">{{ i18n.ts._initialTutorial._done.title }}</div>
<I18n :src="i18n.ts._initialTutorial._done.description" tag="div" style="padding: 0 16px;"> <I18n :src="i18n.ts._initialTutorial._done.description" tag="div" style="padding: 0 16px;">
<template #link> <template #link>
<a href="https://misskey-hub.net/help.html" target="_blank" class="_link">{{ i18n.ts.help }}</a> <a href="https://misskey-hub.net/docs/for-users/" target="_blank" class="_link">{{ i18n.ts.help }}</a>
</template> </template>
</I18n> </I18n>
<div>{{ i18n.t('_initialAccountSetting.haveFun', { name: instance.name ?? host }) }}</div> <div>{{ i18n.t('_initialAccountSetting.haveFun', { name: instance.name ?? host }) }}</div>

View File

@ -123,13 +123,13 @@ function showMenu(ev) {
text: i18n.ts.help, text: i18n.ts.help,
icon: 'ti ti-help-circle', icon: 'ti ti-help-circle',
action: () => { action: () => {
window.open('https://misskey-hub.net/help.md', '_blank', 'noopener'); window.open('https://misskey-hub.net/docs/for-users/', '_blank', 'noopener');
}, },
}], ev.currentTarget ?? ev.target); }], ev.currentTarget ?? ev.target);
} }
function exploreOtherServers() { function exploreOtherServers() {
window.open('https://join.misskey.page/instances', '_blank', 'noopener'); window.open('https://misskey-hub.net/servers/', '_blank', 'noopener');
} }
</script> </script>

View File

@ -53,7 +53,7 @@ import { PageHeaderItem } from '@/types/page-header.js';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
tabs?: Tab[]; tabs?: Tab[];
tab?: string; tab?: string;
actions?: PageHeaderItem[]; actions?: PageHeaderItem[] | null;
thin?: boolean; thin?: boolean;
displayMyAvatar?: boolean; displayMyAvatar?: boolean;
}>(), { }>(), {

View File

@ -35,7 +35,8 @@ type Keys =
`themes:${string}` | `themes:${string}` |
`aiscript:${string}` | `aiscript:${string}` |
'lastEmojisFetchedAt' | // DEPRECATED, stored in indexeddb (13.9.0~) 'lastEmojisFetchedAt' | // DEPRECATED, stored in indexeddb (13.9.0~)
'emojis' // DEPRECATED, stored in indexeddb (13.9.0~); 'emojis' | // DEPRECATED, stored in indexeddb (13.9.0~);
`channelLastReadedAt:${string}`
export const miLocalStorage = { export const miLocalStorage = {
getItem: (key: Keys): string | null => window.localStorage.getItem(key), getItem: (key: Keys): string | null => window.localStorage.getItem(key),

View File

@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<button v-if="thereIsTreasure" class="_button treasure" @click="getTreasure"><img src="/fluent-emoji/1f3c6.png" class="treasureImg"></button> <button v-if="thereIsTreasure" class="_button treasure" @click="getTreasure"><img src="/fluent-emoji/1f3c6.png" class="treasureImg"></button>
</div> </div>
<div style="text-align: center;"> <div style="text-align: center;">
{{ i18n.ts._aboutMisskey.about }}<br><a href="https://misskey-hub.net/docs/misskey.html" target="_blank" class="_link">{{ i18n.ts.learnMore }}</a> {{ i18n.ts._aboutMisskey.about }}<br><a href="https://misskey-hub.net/docs/about-misskey/" target="_blank" class="_link">{{ i18n.ts.learnMore }}</a>
</div> </div>
<div v-if="$i != null" style="text-align: center;"> <div v-if="$i != null" style="text-align: center;">
<MkButton primary rounded inline @click="iLoveMisskey">I <Mfm text="$[jelly ❤]"/> #Misskey</MkButton> <MkButton primary rounded inline @click="iLoveMisskey">I <Mfm text="$[jelly ❤]"/> #Misskey</MkButton>
@ -139,73 +139,73 @@ import { $i } from '@/account.js';
const patronsWithIcon = [{ const patronsWithIcon = [{
name: 'カイヤン', name: 'カイヤン',
icon: 'https://misskey-hub.net/patrons/a2820716883e408cb87773e377ce7c8d.jpg', icon: 'https://assets.misskey-hub.net/patrons/a2820716883e408cb87773e377ce7c8d.jpg',
}, { }, {
name: 'だれかさん', name: 'だれかさん',
icon: 'https://misskey-hub.net/patrons/f7409b5e5a88477a9b9d740c408de125.jpg', icon: 'https://assets.misskey-hub.net/patrons/f7409b5e5a88477a9b9d740c408de125.jpg',
}, { }, {
name: 'narazaka', name: 'narazaka',
icon: 'https://misskey-hub.net/patrons/e3affff31ffb4877b1196c7360abc3e5.jpg', icon: 'https://assets.misskey-hub.net/patrons/e3affff31ffb4877b1196c7360abc3e5.jpg',
}, { }, {
name: 'ひとぅ', name: 'ひとぅ',
icon: 'https://misskey-hub.net/patrons/8cc0d0a0a6d84c88bca1aedabf6ed5ab.jpg', icon: 'https://assets.misskey-hub.net/patrons/8cc0d0a0a6d84c88bca1aedabf6ed5ab.jpg',
}, { }, {
name: 'ぱーこ', name: 'ぱーこ',
icon: 'https://misskey-hub.net/patrons/79c6602ffade489e8df2fcf2c2bc5d9d.jpg', icon: 'https://assets.misskey-hub.net/patrons/79c6602ffade489e8df2fcf2c2bc5d9d.jpg',
}, { }, {
name: 'わっほー☆', name: 'わっほー☆',
icon: 'https://misskey-hub.net/patrons/d31d5d13924443a082f3da7966318a0a.jpg', icon: 'https://assets.misskey-hub.net/patrons/d31d5d13924443a082f3da7966318a0a.jpg',
}, { }, {
name: 'mollinaca', name: 'mollinaca',
icon: 'https://misskey-hub.net/patrons/ceb36b8f66e549bdadb3b90d5da62314.jpg', icon: 'https://assets.misskey-hub.net/patrons/ceb36b8f66e549bdadb3b90d5da62314.jpg',
}, { }, {
name: '坂本龍', name: '坂本龍',
icon: 'https://misskey-hub.net/patrons/a631cf8b490145cf8dbbe4e7508cfbc2.jpg', icon: 'https://assets.misskey-hub.net/patrons/a631cf8b490145cf8dbbe4e7508cfbc2.jpg',
}, { }, {
name: 'takke', name: 'takke',
icon: 'https://misskey-hub.net/patrons/6c3327e626c046f2914fbcd9f7557935.jpg', icon: 'https://assets.misskey-hub.net/patrons/6c3327e626c046f2914fbcd9f7557935.jpg',
}, { }, {
name: 'ぺんぎん', name: 'ぺんぎん',
icon: 'https://misskey-hub.net/patrons/6a652e0534ff4cb1836e7ce4968d76a7.jpg', icon: 'https://assets.misskey-hub.net/patrons/6a652e0534ff4cb1836e7ce4968d76a7.jpg',
}, { }, {
name: 'かみらえっと', name: 'かみらえっと',
icon: 'https://misskey-hub.net/patrons/be1326bda7d940a482f3758ffd9ffaf6.jpg', icon: 'https://assets.misskey-hub.net/patrons/be1326bda7d940a482f3758ffd9ffaf6.jpg',
}, { }, {
name: 'へてて', name: 'へてて',
icon: 'https://misskey-hub.net/patrons/0431eacd7c6843d09de8ea9984307e86.jpg', icon: 'https://assets.misskey-hub.net/patrons/0431eacd7c6843d09de8ea9984307e86.jpg',
}, { }, {
name: 'spinlock', name: 'spinlock',
icon: 'https://misskey-hub.net/patrons/6a1cebc819d540a78bf20e9e3115baa8.jpg', icon: 'https://assets.misskey-hub.net/patrons/6a1cebc819d540a78bf20e9e3115baa8.jpg',
}, { }, {
name: 'じゅくま', name: 'じゅくま',
icon: 'https://misskey-hub.net/patrons/3e56bdac69dd42f7a06e0f12cf2fc895.jpg', icon: 'https://assets.misskey-hub.net/patrons/3e56bdac69dd42f7a06e0f12cf2fc895.jpg',
}, { }, {
name: '清遊あみ', name: '清遊あみ',
icon: 'https://misskey-hub.net/patrons/de25195b88e940a388388bea2e7637d8.jpg', icon: 'https://assets.misskey-hub.net/patrons/de25195b88e940a388388bea2e7637d8.jpg',
}, { }, {
name: 'Nagi8410', name: 'Nagi8410',
icon: 'https://misskey-hub.net/patrons/31b102ab4fc540ed806b0461575d38be.jpg', icon: 'https://assets.misskey-hub.net/patrons/31b102ab4fc540ed806b0461575d38be.jpg',
}, { }, {
name: '山岡士郎', name: '山岡士郎',
icon: 'https://misskey-hub.net/patrons/84b9056341684266bb1eda3e680d094d.jpg', icon: 'https://assets.misskey-hub.net/patrons/84b9056341684266bb1eda3e680d094d.jpg',
}, { }, {
name: 'よもやまたろう', name: 'よもやまたろう',
icon: 'https://misskey-hub.net/patrons/4273c9cce50d445f8f7d0f16113d6d7f.jpg', icon: 'https://assets.misskey-hub.net/patrons/4273c9cce50d445f8f7d0f16113d6d7f.jpg',
}, { }, {
name: '花咲ももか', name: '花咲ももか',
icon: 'https://misskey-hub.net/patrons/8c9b2b9128cb4fee99f04bb4f86f2efa.jpg', icon: 'https://assets.misskey-hub.net/patrons/8c9b2b9128cb4fee99f04bb4f86f2efa.jpg',
}, { }, {
name: 'カガミ', name: 'カガミ',
icon: 'https://misskey-hub.net/patrons/226ea3a4617749548580ec2d9a263e24.jpg', icon: 'https://assets.misskey-hub.net/patrons/226ea3a4617749548580ec2d9a263e24.jpg',
}, { }, {
name: 'フランギ・シュウ', name: 'フランギ・シュウ',
icon: 'https://misskey-hub.net/patrons/3016d37e35f3430b90420176c912d304.jpg', icon: 'https://assets.misskey-hub.net/patrons/3016d37e35f3430b90420176c912d304.jpg',
}, { }, {
name: '百日紅', name: '百日紅',
icon: 'https://misskey-hub.net/patrons/302dce2898dd457ba03c3f7dc037900b.jpg', icon: 'https://assets.misskey-hub.net/patrons/302dce2898dd457ba03c3f7dc037900b.jpg',
}, { }, {
name: 'taichan', name: 'taichan',
icon: 'https://misskey-hub.net/patrons/f981ab0159fb4e2c998e05f7263e1cd9.png', icon: 'https://assets.misskey-hub.net/patrons/f981ab0159fb4e2c998e05f7263e1cd9.png',
}]; }];
const patrons = [ const patrons = [

View File

@ -74,15 +74,26 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>Enable</template> <template #label>Enable</template>
</MkSwitch> </MkSwitch>
<MkSwitch v-model="enableVerifymailApi" @update:modelValue="save"> <MkSwitch v-model="enableVerifymailApi" @update:modelValue="save">
<template #label>Use Verifymail API</template> <template #label>Use Verifymail.io API</template>
</MkSwitch> </MkSwitch>
<MkInput v-model="verifymailAuthKey" @update:modelValue="save"> <MkInput v-model="verifymailAuthKey" @update:modelValue="save">
<template #prefix><i class="ti ti-key"></i></template> <template #prefix><i class="ti ti-key"></i></template>
<template #label>Verifymail API Auth Key</template> <template #label>Verifymail.io API Auth Key</template>
</MkInput> </MkInput>
</div> </div>
</MkFolder> </MkFolder>
<MkFolder>
<template #label>Banned Email Domains</template>
<div class="_gaps_m">
<MkTextarea v-model="bannedEmailDomains">
<template #label>Banned Email Domains List</template>
</MkTextarea>
<MkButton primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
</div>
</MkFolder>
<MkFolder> <MkFolder>
<template #label>Log IP address</template> <template #label>Log IP address</template>
<template v-if="enableIpLogging" #suffix>Enabled</template> <template v-if="enableIpLogging" #suffix>Enabled</template>
@ -124,6 +135,7 @@ import FormSuspense from '@/components/form/suspense.vue';
import MkRange from '@/components/MkRange.vue'; import MkRange from '@/components/MkRange.vue';
import MkInput from '@/components/MkInput.vue'; import MkInput from '@/components/MkInput.vue';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';
import MkTextarea from '@/components/MkTextarea.vue';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { fetchInstance } from '@/instance.js'; import { fetchInstance } from '@/instance.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
@ -141,6 +153,7 @@ const enableIpLogging = ref<boolean>(false);
const enableActiveEmailValidation = ref<boolean>(false); const enableActiveEmailValidation = ref<boolean>(false);
const enableVerifymailApi = ref<boolean>(false); const enableVerifymailApi = ref<boolean>(false);
const verifymailAuthKey = ref<string | null>(null); const verifymailAuthKey = ref<string | null>(null);
const bannedEmailDomains = ref<string>('');
async function init() { async function init() {
const meta = await os.api('admin/meta'); const meta = await os.api('admin/meta');
@ -161,6 +174,7 @@ async function init() {
enableActiveEmailValidation.value = meta.enableActiveEmailValidation; enableActiveEmailValidation.value = meta.enableActiveEmailValidation;
enableVerifymailApi.value = meta.enableVerifymailApi; enableVerifymailApi.value = meta.enableVerifymailApi;
verifymailAuthKey.value = meta.verifymailAuthKey; verifymailAuthKey.value = meta.verifymailAuthKey;
bannedEmailDomains.value = meta.bannedEmailDomains.join('\n');
} }
function save() { function save() {
@ -180,6 +194,7 @@ function save() {
enableActiveEmailValidation: enableActiveEmailValidation.value, enableActiveEmailValidation: enableActiveEmailValidation.value,
enableVerifymailApi: enableVerifymailApi.value, enableVerifymailApi: enableVerifymailApi.value,
verifymailAuthKey: verifymailAuthKey.value, verifymailAuthKey: verifymailAuthKey.value,
bannedEmailDomains: bannedEmailDomains.value.split('\n'),
}).then(() => { }).then(() => {
fetchInstance(); fetchInstance();
}); });

View File

@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<XChannelFollowButton :channel="channel" :full="true" :class="$style.subscribe"/> <XChannelFollowButton :channel="channel" :full="true" :class="$style.subscribe"/>
<MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" asLike class="button" rounded primary :class="$style.favorite" @click="unfavorite()"><i class="ti ti-star"></i></MkButton> <MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" asLike class="button" rounded primary :class="$style.favorite" @click="unfavorite()"><i class="ti ti-star"></i></MkButton>
<MkButton v-else v-tooltip="i18n.ts.favorite" asLike class="button" rounded :class="$style.favorite" @click="favorite()"><i class="ti ti-star"></i></MkButton> <MkButton v-else v-tooltip="i18n.ts.favorite" asLike class="button" rounded :class="$style.favorite" @click="favorite()"><i class="ti ti-star"></i></MkButton>
<div :style="{ backgroundImage: channel.bannerUrl ? `url(${channel.bannerUrl})` : null }" :class="$style.banner"> <div :style="{ backgroundImage: channel.bannerUrl ? `url(${channel.bannerUrl})` : undefined }" :class="$style.banner">
<div :class="$style.bannerStatus"> <div :class="$style.bannerStatus">
<div><i class="ti ti-users ti-fw"></i><I18n :src="i18n.ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div> <div><i class="ti ti-users ti-fw"></i><I18n :src="i18n.ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div>
<div><i class="ti ti-pencil ti-fw"></i><I18n :src="i18n.ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div> <div><i class="ti ti-pencil ti-fw"></i><I18n :src="i18n.ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div>
@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkFoldableSection> <MkFoldableSection>
<template #header><i class="ti ti-pin ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.pinnedNotes }}</template> <template #header><i class="ti ti-pin ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.pinnedNotes }}</template>
<div v-if="channel.pinnedNotes.length > 0" class="_gaps"> <div v-if="channel.pinnedNotes && channel.pinnedNotes.length > 0" class="_gaps">
<MkNote v-for="note in channel.pinnedNotes" :key="note.id" class="_panel" :note="note"/> <MkNote v-for="note in channel.pinnedNotes" :key="note.id" class="_panel" :note="note"/>
</div> </div>
</MkFoldableSection> </MkFoldableSection>
@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<!-- スマホタブレットの場合キーボードが表示されると投稿が見づらくなるのでデスクトップ場合のみ自動でフォーカスを当てる --> <!-- スマホタブレットの場合キーボードが表示されると投稿が見づらくなるのでデスクトップ場合のみ自動でフォーカスを当てる -->
<MkPostForm v-if="$i && defaultStore.reactiveState.showFixedPostFormInChannel.value" :channel="channel" class="post-form _panel" fixed :autofocus="deviceKind === 'desktop'"/> <MkPostForm v-if="$i && defaultStore.reactiveState.showFixedPostFormInChannel.value" :channel="channel" class="post-form _panel" fixed :autofocus="deviceKind === 'desktop'"/>
<MkTimeline :key="channelId" src="channel" :channel="channelId" @before="before" @after="after"/> <MkTimeline :key="channelId" src="channel" :channel="channelId" @before="before" @after="after" @note="miLocalStorage.setItemAsJson(`channelLastReadedAt:${channel.id}`, Date.now())"/>
</div> </div>
<div v-else-if="tab === 'featured'"> <div v-else-if="tab === 'featured'">
<MkNotes :pagination="featuredPagination"/> <MkNotes :pagination="featuredPagination"/>
@ -69,6 +69,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import { computed, watch, ref } from 'vue'; import { computed, watch, ref } from 'vue';
import * as Misskey from 'misskey-js';
import MkPostForm from '@/components/MkPostForm.vue'; import MkPostForm from '@/components/MkPostForm.vue';
import MkTimeline from '@/components/MkTimeline.vue'; import MkTimeline from '@/components/MkTimeline.vue';
import XChannelFollowButton from '@/components/MkChannelFollowButton.vue'; import XChannelFollowButton from '@/components/MkChannelFollowButton.vue';
@ -89,6 +90,7 @@ import MkFoldableSection from '@/components/MkFoldableSection.vue';
import { PageHeaderItem } from '@/types/page-header.js'; import { PageHeaderItem } from '@/types/page-header.js';
import { isSupportShare } from '@/scripts/navigator.js'; import { isSupportShare } from '@/scripts/navigator.js';
import copyToClipboard from '@/scripts/copy-to-clipboard.js'; import copyToClipboard from '@/scripts/copy-to-clipboard.js';
import { miLocalStorage } from '@/local-storage.js';
const router = useRouter(); const router = useRouter();
@ -97,7 +99,7 @@ const props = defineProps<{
}>(); }>();
const tab = ref('overview'); const tab = ref('overview');
const channel = ref(null); const channel = ref<Misskey.entities.Channel | null>(null);
const favorited = ref(false); const favorited = ref(false);
const searchQuery = ref(''); const searchQuery = ref('');
const searchPagination = ref(); const searchPagination = ref();
@ -114,14 +116,23 @@ watch(() => props.channelId, async () => {
channel.value = await os.api('channels/show', { channel.value = await os.api('channels/show', {
channelId: props.channelId, channelId: props.channelId,
}); });
favorited.value = channel.value.isFavorited; favorited.value = channel.value.isFavorited ?? false;
if (favorited.value || channel.value.isFollowing) { if (favorited.value || channel.value.isFollowing) {
tab.value = 'timeline'; tab.value = 'timeline';
} }
if ((favorited.value || channel.value.isFollowing) && channel.value.lastNotedAt) {
const lastReadedAt: number = miLocalStorage.getItemAsJson(`channelLastReadedAt:${channel.value.id}`) ?? 0;
const lastNotedAt = Date.parse(channel.value.lastNotedAt);
if (lastNotedAt > lastReadedAt) {
miLocalStorage.setItemAsJson(`channelLastReadedAt:${channel.value.id}`, lastNotedAt);
}
}
}, { immediate: true }); }, { immediate: true });
function edit() { function edit() {
router.push(`/channels/${channel.value.id}/edit`); router.push(`/channels/${channel.value?.id}/edit`);
} }
function openPostForm() { function openPostForm() {
@ -131,6 +142,8 @@ function openPostForm() {
} }
function favorite() { function favorite() {
if (!channel.value) return;
os.apiWithDialog('channels/favorite', { os.apiWithDialog('channels/favorite', {
channelId: channel.value.id, channelId: channel.value.id,
}).then(() => { }).then(() => {
@ -139,6 +152,8 @@ function favorite() {
} }
async function unfavorite() { async function unfavorite() {
if (!channel.value) return;
const confirm = await os.confirm({ const confirm = await os.confirm({
type: 'warning', type: 'warning',
text: i18n.ts.unfavoriteConfirm, text: i18n.ts.unfavoriteConfirm,
@ -152,6 +167,8 @@ async function unfavorite() {
} }
async function search() { async function search() {
if (!channel.value) return;
const query = searchQuery.value.toString().trim(); const query = searchQuery.value.toString().trim();
if (query == null) return; if (query == null) return;
@ -176,6 +193,10 @@ const headerActions = computed(() => {
icon: 'ti ti-link', icon: 'ti ti-link',
text: i18n.ts.copyUrl, text: i18n.ts.copyUrl,
handler: async (): Promise<void> => { handler: async (): Promise<void> => {
if (!channel.value) {
console.warn('failed to copy channel URL. channel.value is null.');
return;
}
copyToClipboard(`${url}/channels/${channel.value.id}`); copyToClipboard(`${url}/channels/${channel.value.id}`);
os.success(); os.success();
}, },
@ -186,9 +207,14 @@ const headerActions = computed(() => {
icon: 'ti ti-share', icon: 'ti ti-share',
text: i18n.ts.share, text: i18n.ts.share,
handler: async (): Promise<void> => { handler: async (): Promise<void> => {
if (!channel.value) {
console.warn('failed to share channel. channel.value is null.');
return;
}
navigator.share({ navigator.share({
title: channel.value.name, title: channel.value.name,
text: channel.value.description, text: channel.value.description ?? undefined,
url: `${url}/channels/${channel.value.id}`, url: `${url}/channels/${channel.value.id}`,
}); });
}, },

View File

@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
// SPECIFICATION: https://misskey-hub.net/docs/features/share-form.html // SPECIFICATION: https://misskey-hub.net/docs/for-users/features/share-form/
import { ref, computed } from 'vue'; import { ref, computed } from 'vue';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';

View File

@ -48,6 +48,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import { antennasCache, userListsCache } from '@/cache.js'; import { antennasCache, userListsCache } from '@/cache.js';
import { deviceKind } from '@/scripts/device-kind.js'; import { deviceKind } from '@/scripts/device-kind.js';
import { MenuItem } from '@/types/menu.js'; import { MenuItem } from '@/types/menu.js';
import { miLocalStorage } from '@/local-storage.js';
provide('shouldOmitHeaderTitle', true); provide('shouldOmitHeaderTitle', true);
@ -125,12 +126,17 @@ async function chooseChannel(ev: MouseEvent): Promise<void> {
limit: 100, limit: 100,
}); });
const items: MenuItem[] = [ const items: MenuItem[] = [
...channels.map(channel => ({ ...channels.map(channel => {
const lastReadedAt = miLocalStorage.getItemAsJson(`channelLastReadedAt:${channel.id}`) ?? null;
const hasUnreadNote = (lastReadedAt && channel.lastNotedAt) ? Date.parse(channel.lastNotedAt) > lastReadedAt : !!(!lastReadedAt && channel.lastNotedAt);
return {
type: 'link' as const, type: 'link' as const,
text: channel.name, text: channel.name,
indicate: channel.hasUnreadNote, indicate: hasUnreadNote,
to: `/channels/${channel.id}`, to: `/channels/${channel.id}`,
})), };
}),
(channels.length === 0 ? undefined : { type: 'divider' }), (channels.length === 0 ? undefined : { type: 'divider' }),
{ {
type: 'link' as const, type: 'link' as const,

View File

@ -101,7 +101,7 @@ export function openInstanceMenu(ev: MouseEvent) {
text: i18n.ts.help, text: i18n.ts.help,
icon: 'ti ti-help-circle', icon: 'ti ti-help-circle',
action: () => { action: () => {
window.open('https://misskey-hub.net/help.html', '_blank', 'noopener'); window.open('https://misskey-hub.net/docs/for-users/', '_blank', 'noopener');
}, },
}, ($i) ? { }, ($i) ? {
text: i18n.ts._initialTutorial.launchTutorial, text: i18n.ts._initialTutorial.launchTutorial,

View File

@ -1,6 +1,6 @@
/* /*
* version: 2023.12.0-beta.5-io * version: 2023.12.0-io
* generatedAt: 2023-12-21T02:55:40.813Z * generatedAt: 2023-12-23T11:38:40.644Z
*/ */
import type { SwitchCaseResponseType } from '../api.js'; import type { SwitchCaseResponseType } from '../api.js';
@ -11,7 +11,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/meta', P extends Endpoints[E]['req']>( request<E extends 'admin/meta', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -22,7 +22,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/abuse-user-reports', P extends Endpoints[E]['req']>( request<E extends 'admin/abuse-user-reports', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -33,7 +33,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *No* * **Credential required**: *No* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/accounts/create', P extends Endpoints[E]['req']>( request<E extends 'admin/accounts/create', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -44,7 +44,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/accounts/delete', P extends Endpoints[E]['req']>( request<E extends 'admin/accounts/delete', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -55,7 +55,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/accounts/find-by-email', P extends Endpoints[E]['req']>( request<E extends 'admin/accounts/find-by-email', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -66,7 +66,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/ad/create', P extends Endpoints[E]['req']>( request<E extends 'admin/ad/create', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -77,7 +77,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/ad/delete', P extends Endpoints[E]['req']>( request<E extends 'admin/ad/delete', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -88,7 +88,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/ad/list', P extends Endpoints[E]['req']>( request<E extends 'admin/ad/list', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -99,7 +99,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/ad/update', P extends Endpoints[E]['req']>( request<E extends 'admin/ad/update', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -110,7 +110,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/announcements/create', P extends Endpoints[E]['req']>( request<E extends 'admin/announcements/create', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -121,7 +121,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/announcements/delete', P extends Endpoints[E]['req']>( request<E extends 'admin/announcements/delete', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -132,7 +132,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/announcements/list', P extends Endpoints[E]['req']>( request<E extends 'admin/announcements/list', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -143,7 +143,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/announcements/update', P extends Endpoints[E]['req']>( request<E extends 'admin/announcements/update', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -198,7 +198,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/avatar-decorations/create', P extends Endpoints[E]['req']>( request<E extends 'admin/avatar-decorations/create', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -209,7 +209,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/avatar-decorations/delete', P extends Endpoints[E]['req']>( request<E extends 'admin/avatar-decorations/delete', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -220,7 +220,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/avatar-decorations/list', P extends Endpoints[E]['req']>( request<E extends 'admin/avatar-decorations/list', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -231,7 +231,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/avatar-decorations/update', P extends Endpoints[E]['req']>( request<E extends 'admin/avatar-decorations/update', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -242,7 +242,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/delete-all-files-of-a-user', P extends Endpoints[E]['req']>( request<E extends 'admin/delete-all-files-of-a-user', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -253,7 +253,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/unset-user-avatar', P extends Endpoints[E]['req']>( request<E extends 'admin/unset-user-avatar', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -264,7 +264,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/unset-user-banner', P extends Endpoints[E]['req']>( request<E extends 'admin/unset-user-banner', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -275,7 +275,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/drive/clean-remote-files', P extends Endpoints[E]['req']>( request<E extends 'admin/drive/clean-remote-files', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -286,7 +286,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/drive/cleanup', P extends Endpoints[E]['req']>( request<E extends 'admin/drive/cleanup', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -297,7 +297,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/drive/files', P extends Endpoints[E]['req']>( request<E extends 'admin/drive/files', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -308,7 +308,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/drive/show-file', P extends Endpoints[E]['req']>( request<E extends 'admin/drive/show-file', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -319,7 +319,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/emoji/add-aliases-bulk', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/add-aliases-bulk', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -330,7 +330,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/emoji/add', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/add', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -341,7 +341,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/emoji/copy', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/copy', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -352,7 +352,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/emoji/delete-bulk', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/delete-bulk', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -363,7 +363,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/emoji/delete', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/delete', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -374,8 +374,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. * **Credential required**: *Yes* / **Permission**: *write:admin*
* **Credential required**: *Yes*
*/ */
request<E extends 'admin/emoji/import-zip', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/import-zip', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -386,7 +385,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/emoji/list-remote', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/list-remote', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -397,7 +396,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/emoji/list', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/list', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -408,7 +407,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/emoji/remove-aliases-bulk', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/remove-aliases-bulk', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -419,7 +418,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/emoji/set-aliases-bulk', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/set-aliases-bulk', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -430,7 +429,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/emoji/set-category-bulk', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/set-category-bulk', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -441,7 +440,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/emoji/set-license-bulk', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/set-license-bulk', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -452,7 +451,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/emoji/update', P extends Endpoints[E]['req']>( request<E extends 'admin/emoji/update', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -463,7 +462,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/federation/delete-all-files', P extends Endpoints[E]['req']>( request<E extends 'admin/federation/delete-all-files', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -474,7 +473,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/federation/refresh-remote-instance-metadata', P extends Endpoints[E]['req']>( request<E extends 'admin/federation/refresh-remote-instance-metadata', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -485,7 +484,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/federation/remove-all-following', P extends Endpoints[E]['req']>( request<E extends 'admin/federation/remove-all-following', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -496,7 +495,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/federation/update-instance', P extends Endpoints[E]['req']>( request<E extends 'admin/federation/update-instance', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -507,7 +506,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/get-index-stats', P extends Endpoints[E]['req']>( request<E extends 'admin/get-index-stats', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -518,7 +517,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/get-table-stats', P extends Endpoints[E]['req']>( request<E extends 'admin/get-table-stats', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -529,7 +528,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/get-user-ips', P extends Endpoints[E]['req']>( request<E extends 'admin/get-user-ips', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -540,7 +539,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/invite/create', P extends Endpoints[E]['req']>( request<E extends 'admin/invite/create', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -551,7 +550,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/invite/list', P extends Endpoints[E]['req']>( request<E extends 'admin/invite/list', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -562,7 +561,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/promo/create', P extends Endpoints[E]['req']>( request<E extends 'admin/promo/create', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -573,7 +572,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/queue/clear', P extends Endpoints[E]['req']>( request<E extends 'admin/queue/clear', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -584,7 +583,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/queue/deliver-delayed', P extends Endpoints[E]['req']>( request<E extends 'admin/queue/deliver-delayed', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -595,7 +594,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/queue/inbox-delayed', P extends Endpoints[E]['req']>( request<E extends 'admin/queue/inbox-delayed', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -606,7 +605,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/queue/promote', P extends Endpoints[E]['req']>( request<E extends 'admin/queue/promote', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -617,7 +616,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/queue/stats', P extends Endpoints[E]['req']>( request<E extends 'admin/queue/stats', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -628,7 +627,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/relays/add', P extends Endpoints[E]['req']>( request<E extends 'admin/relays/add', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -639,7 +638,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/relays/list', P extends Endpoints[E]['req']>( request<E extends 'admin/relays/list', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -650,7 +649,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/relays/remove', P extends Endpoints[E]['req']>( request<E extends 'admin/relays/remove', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -661,7 +660,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/reset-password', P extends Endpoints[E]['req']>( request<E extends 'admin/reset-password', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -672,7 +671,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/resolve-abuse-user-report', P extends Endpoints[E]['req']>( request<E extends 'admin/resolve-abuse-user-report', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -683,7 +682,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/send-email', P extends Endpoints[E]['req']>( request<E extends 'admin/send-email', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -694,7 +693,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/server-info', P extends Endpoints[E]['req']>( request<E extends 'admin/server-info', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -705,7 +704,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/show-moderation-logs', P extends Endpoints[E]['req']>( request<E extends 'admin/show-moderation-logs', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -716,7 +715,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/show-user', P extends Endpoints[E]['req']>( request<E extends 'admin/show-user', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -727,7 +726,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/show-users', P extends Endpoints[E]['req']>( request<E extends 'admin/show-users', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -738,7 +737,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/suspend-user', P extends Endpoints[E]['req']>( request<E extends 'admin/suspend-user', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -749,7 +748,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/unsuspend-user', P extends Endpoints[E]['req']>( request<E extends 'admin/unsuspend-user', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -760,7 +759,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/update-meta', P extends Endpoints[E]['req']>( request<E extends 'admin/update-meta', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -771,7 +770,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/delete-account', P extends Endpoints[E]['req']>( request<E extends 'admin/delete-account', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -782,7 +781,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/update-user-note', P extends Endpoints[E]['req']>( request<E extends 'admin/update-user-note', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -793,7 +792,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/roles/create', P extends Endpoints[E]['req']>( request<E extends 'admin/roles/create', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -804,7 +803,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/roles/delete', P extends Endpoints[E]['req']>( request<E extends 'admin/roles/delete', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -815,7 +814,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/roles/list', P extends Endpoints[E]['req']>( request<E extends 'admin/roles/list', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -826,7 +825,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/roles/show', P extends Endpoints[E]['req']>( request<E extends 'admin/roles/show', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -837,7 +836,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/roles/update', P extends Endpoints[E]['req']>( request<E extends 'admin/roles/update', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -848,7 +847,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/roles/assign', P extends Endpoints[E]['req']>( request<E extends 'admin/roles/assign', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -859,7 +858,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/roles/unassign', P extends Endpoints[E]['req']>( request<E extends 'admin/roles/unassign', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -870,7 +869,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *Yes* * **Credential required**: *Yes* / **Permission**: *write:admin*
*/ */
request<E extends 'admin/roles/update-default-policies', P extends Endpoints[E]['req']>( request<E extends 'admin/roles/update-default-policies', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,
@ -881,7 +880,7 @@ declare module '../api.js' {
/** /**
* No description provided. * No description provided.
* *
* **Credential required**: *No* * **Credential required**: *No* / **Permission**: *read:admin*
*/ */
request<E extends 'admin/roles/users', P extends Endpoints[E]['req']>( request<E extends 'admin/roles/users', P extends Endpoints[E]['req']>(
endpoint: E, endpoint: E,

View File

@ -1,6 +1,6 @@
/* /*
* version: 2023.12.0-beta.5-io * version: 2023.12.0-io
* generatedAt: 2023-12-21T02:55:40.808Z * generatedAt: 2023-12-23T11:38:40.635Z
*/ */
import type { import type {
@ -13,9 +13,12 @@ import type {
AdminAccountsCreateResponse, AdminAccountsCreateResponse,
AdminAccountsDeleteRequest, AdminAccountsDeleteRequest,
AdminAccountsFindByEmailRequest, AdminAccountsFindByEmailRequest,
AdminAccountsFindByEmailResponse,
AdminAdCreateRequest, AdminAdCreateRequest,
AdminAdCreateResponse,
AdminAdDeleteRequest, AdminAdDeleteRequest,
AdminAdListRequest, AdminAdListRequest,
AdminAdListResponse,
AdminAdUpdateRequest, AdminAdUpdateRequest,
AdminAnnouncementsCreateRequest, AdminAnnouncementsCreateRequest,
AdminAnnouncementsCreateResponse, AdminAnnouncementsCreateResponse,
@ -61,8 +64,10 @@ import type {
AdminFederationRefreshRemoteInstanceMetadataRequest, AdminFederationRefreshRemoteInstanceMetadataRequest,
AdminFederationRemoveAllFollowingRequest, AdminFederationRemoveAllFollowingRequest,
AdminFederationUpdateInstanceRequest, AdminFederationUpdateInstanceRequest,
AdminGetIndexStatsResponse,
AdminGetTableStatsResponse, AdminGetTableStatsResponse,
AdminGetUserIpsRequest, AdminGetUserIpsRequest,
AdminGetUserIpsResponse,
AdminInviteCreateRequest, AdminInviteCreateRequest,
AdminInviteCreateResponse, AdminInviteCreateResponse,
AdminInviteListRequest, AdminInviteListRequest,
@ -104,6 +109,7 @@ import type {
AdminRolesUnassignRequest, AdminRolesUnassignRequest,
AdminRolesUpdateDefaultPoliciesRequest, AdminRolesUpdateDefaultPoliciesRequest,
AdminRolesUsersRequest, AdminRolesUsersRequest,
AdminRolesUsersResponse,
AnnouncementsRequest, AnnouncementsRequest,
AnnouncementsResponse, AnnouncementsResponse,
AntennasCreateRequest, AntennasCreateRequest,
@ -231,6 +237,7 @@ import type {
EmailAddressAvailableRequest, EmailAddressAvailableRequest,
EmailAddressAvailableResponse, EmailAddressAvailableResponse,
EndpointRequest, EndpointRequest,
EndpointResponse,
EndpointsResponse, EndpointsResponse,
FederationFollowersRequest, FederationFollowersRequest,
FederationFollowersResponse, FederationFollowersResponse,
@ -244,6 +251,7 @@ import type {
FederationUsersRequest, FederationUsersRequest,
FederationUsersResponse, FederationUsersResponse,
FederationStatsRequest, FederationStatsRequest,
FederationStatsResponse,
FollowingCreateRequest, FollowingCreateRequest,
FollowingCreateResponse, FollowingCreateResponse,
FollowingDeleteRequest, FollowingDeleteRequest,
@ -273,6 +281,7 @@ import type {
GalleryPostsUnlikeRequest, GalleryPostsUnlikeRequest,
GalleryPostsUpdateRequest, GalleryPostsUpdateRequest,
GalleryPostsUpdateResponse, GalleryPostsUpdateResponse,
GetOnlineUsersCountResponse,
GetAvatarDecorationsResponse, GetAvatarDecorationsResponse,
HashtagsListRequest, HashtagsListRequest,
HashtagsListResponse, HashtagsListResponse,
@ -286,14 +295,19 @@ import type {
IResponse, IResponse,
I2faDoneRequest, I2faDoneRequest,
I2faKeyDoneRequest, I2faKeyDoneRequest,
I2faKeyDoneResponse,
I2faPasswordLessRequest, I2faPasswordLessRequest,
I2faRegisterKeyRequest, I2faRegisterKeyRequest,
I2faRegisterKeyResponse,
I2faRegisterRequest, I2faRegisterRequest,
I2faRegisterResponse,
I2faUpdateKeyRequest, I2faUpdateKeyRequest,
I2faRemoveKeyRequest, I2faRemoveKeyRequest,
I2faUnregisterRequest, I2faUnregisterRequest,
IAppsRequest, IAppsRequest,
IAppsResponse,
IAuthorizedAppsRequest, IAuthorizedAppsRequest,
IAuthorizedAppsResponse,
IClaimAchievementRequest, IClaimAchievementRequest,
IChangePasswordRequest, IChangePasswordRequest,
IDeleteAccountRequest, IDeleteAccountRequest,
@ -322,11 +336,16 @@ import type {
IReadAnnouncementRequest, IReadAnnouncementRequest,
IRegenerateTokenRequest, IRegenerateTokenRequest,
IRegistryGetAllRequest, IRegistryGetAllRequest,
IRegistryGetAllResponse,
IRegistryGetDetailRequest, IRegistryGetDetailRequest,
IRegistryGetDetailResponse,
IRegistryGetRequest, IRegistryGetRequest,
IRegistryGetResponse,
IRegistryKeysWithTypeRequest, IRegistryKeysWithTypeRequest,
IRegistryKeysWithTypeResponse,
IRegistryKeysRequest, IRegistryKeysRequest,
IRegistryRemoveRequest, IRegistryRemoveRequest,
IRegistryScopesWithDomainResponse,
IRegistrySetRequest, IRegistrySetRequest,
IRevokeTokenRequest, IRevokeTokenRequest,
ISigninHistoryRequest, ISigninHistoryRequest,
@ -334,11 +353,16 @@ import type {
IUnpinRequest, IUnpinRequest,
IUnpinResponse, IUnpinResponse,
IUpdateEmailRequest, IUpdateEmailRequest,
IUpdateEmailResponse,
IUpdateRequest, IUpdateRequest,
IUpdateResponse, IUpdateResponse,
IMoveRequest, IMoveRequest,
IMoveResponse,
IWebhooksCreateRequest, IWebhooksCreateRequest,
IWebhooksCreateResponse,
IWebhooksListResponse,
IWebhooksShowRequest, IWebhooksShowRequest,
IWebhooksShowResponse,
IWebhooksUpdateRequest, IWebhooksUpdateRequest,
IWebhooksDeleteRequest, IWebhooksDeleteRequest,
InviteCreateResponse, InviteCreateResponse,
@ -426,6 +450,7 @@ import type {
PagesUnlikeRequest, PagesUnlikeRequest,
PagesUpdateRequest, PagesUpdateRequest,
FlashCreateRequest, FlashCreateRequest,
FlashCreateResponse,
FlashDeleteRequest, FlashDeleteRequest,
FlashFeaturedResponse, FlashFeaturedResponse,
FlashLikeRequest, FlashLikeRequest,
@ -444,10 +469,12 @@ import type {
RolesShowRequest, RolesShowRequest,
RolesShowResponse, RolesShowResponse,
RolesUsersRequest, RolesUsersRequest,
RolesUsersResponse,
RolesNotesRequest, RolesNotesRequest,
RolesNotesResponse, RolesNotesResponse,
RequestResetPasswordRequest, RequestResetPasswordRequest,
ResetPasswordRequest, ResetPasswordRequest,
ServerInfoResponse,
StatsResponse, StatsResponse,
SwShowRegistrationRequest, SwShowRegistrationRequest,
SwShowRegistrationResponse, SwShowRegistrationResponse,
@ -457,6 +484,7 @@ import type {
SwRegisterResponse, SwRegisterResponse,
SwUnregisterRequest, SwUnregisterRequest,
TestRequest, TestRequest,
TestResponse,
UsernameAvailableRequest, UsernameAvailableRequest,
UsernameAvailableResponse, UsernameAvailableResponse,
UsersRequest, UsersRequest,
@ -490,6 +518,7 @@ import type {
UsersListsCreateFromPublicResponse, UsersListsCreateFromPublicResponse,
UsersListsUpdateMembershipRequest, UsersListsUpdateMembershipRequest,
UsersListsGetMembershipsRequest, UsersListsGetMembershipsRequest,
UsersListsGetMembershipsResponse,
UsersNotesRequest, UsersNotesRequest,
UsersNotesResponse, UsersNotesResponse,
UsersPagesRequest, UsersPagesRequest,
@ -512,9 +541,12 @@ import type {
UsersStatsRequest, UsersStatsRequest,
UsersStatsResponse, UsersStatsResponse,
UsersAchievementsRequest, UsersAchievementsRequest,
UsersAchievementsResponse,
UsersUpdateMemoRequest, UsersUpdateMemoRequest,
FetchRssRequest, FetchRssRequest,
FetchRssResponse,
FetchExternalResourcesRequest, FetchExternalResourcesRequest,
FetchExternalResourcesResponse,
RetentionResponse, RetentionResponse,
} from './entities.js'; } from './entities.js';
@ -523,10 +555,10 @@ export type Endpoints = {
'admin/abuse-user-reports': { req: AdminAbuseUserReportsRequest; res: AdminAbuseUserReportsResponse }; 'admin/abuse-user-reports': { req: AdminAbuseUserReportsRequest; res: AdminAbuseUserReportsResponse };
'admin/accounts/create': { req: AdminAccountsCreateRequest; res: AdminAccountsCreateResponse }; 'admin/accounts/create': { req: AdminAccountsCreateRequest; res: AdminAccountsCreateResponse };
'admin/accounts/delete': { req: AdminAccountsDeleteRequest; res: EmptyResponse }; 'admin/accounts/delete': { req: AdminAccountsDeleteRequest; res: EmptyResponse };
'admin/accounts/find-by-email': { req: AdminAccountsFindByEmailRequest; res: EmptyResponse }; 'admin/accounts/find-by-email': { req: AdminAccountsFindByEmailRequest; res: AdminAccountsFindByEmailResponse };
'admin/ad/create': { req: AdminAdCreateRequest; res: EmptyResponse }; 'admin/ad/create': { req: AdminAdCreateRequest; res: AdminAdCreateResponse };
'admin/ad/delete': { req: AdminAdDeleteRequest; res: EmptyResponse }; 'admin/ad/delete': { req: AdminAdDeleteRequest; res: EmptyResponse };
'admin/ad/list': { req: AdminAdListRequest; res: EmptyResponse }; 'admin/ad/list': { req: AdminAdListRequest; res: AdminAdListResponse };
'admin/ad/update': { req: AdminAdUpdateRequest; res: EmptyResponse }; 'admin/ad/update': { req: AdminAdUpdateRequest; res: EmptyResponse };
'admin/announcements/create': { req: AdminAnnouncementsCreateRequest; res: AdminAnnouncementsCreateResponse }; 'admin/announcements/create': { req: AdminAnnouncementsCreateRequest; res: AdminAnnouncementsCreateResponse };
'admin/announcements/delete': { req: AdminAnnouncementsDeleteRequest; res: EmptyResponse }; 'admin/announcements/delete': { req: AdminAnnouncementsDeleteRequest; res: EmptyResponse };
@ -564,9 +596,9 @@ export type Endpoints = {
'admin/federation/refresh-remote-instance-metadata': { req: AdminFederationRefreshRemoteInstanceMetadataRequest; res: EmptyResponse }; 'admin/federation/refresh-remote-instance-metadata': { req: AdminFederationRefreshRemoteInstanceMetadataRequest; res: EmptyResponse };
'admin/federation/remove-all-following': { req: AdminFederationRemoveAllFollowingRequest; res: EmptyResponse }; 'admin/federation/remove-all-following': { req: AdminFederationRemoveAllFollowingRequest; res: EmptyResponse };
'admin/federation/update-instance': { req: AdminFederationUpdateInstanceRequest; res: EmptyResponse }; 'admin/federation/update-instance': { req: AdminFederationUpdateInstanceRequest; res: EmptyResponse };
'admin/get-index-stats': { req: EmptyRequest; res: EmptyResponse }; 'admin/get-index-stats': { req: EmptyRequest; res: AdminGetIndexStatsResponse };
'admin/get-table-stats': { req: EmptyRequest; res: AdminGetTableStatsResponse }; 'admin/get-table-stats': { req: EmptyRequest; res: AdminGetTableStatsResponse };
'admin/get-user-ips': { req: AdminGetUserIpsRequest; res: EmptyResponse }; 'admin/get-user-ips': { req: AdminGetUserIpsRequest; res: AdminGetUserIpsResponse };
'admin/invite/create': { req: AdminInviteCreateRequest; res: AdminInviteCreateResponse }; 'admin/invite/create': { req: AdminInviteCreateRequest; res: AdminInviteCreateResponse };
'admin/invite/list': { req: AdminInviteListRequest; res: AdminInviteListResponse }; 'admin/invite/list': { req: AdminInviteListRequest; res: AdminInviteListResponse };
'admin/promo/create': { req: AdminPromoCreateRequest; res: EmptyResponse }; 'admin/promo/create': { req: AdminPromoCreateRequest; res: EmptyResponse };
@ -598,7 +630,7 @@ export type Endpoints = {
'admin/roles/assign': { req: AdminRolesAssignRequest; res: EmptyResponse }; 'admin/roles/assign': { req: AdminRolesAssignRequest; res: EmptyResponse };
'admin/roles/unassign': { req: AdminRolesUnassignRequest; res: EmptyResponse }; 'admin/roles/unassign': { req: AdminRolesUnassignRequest; res: EmptyResponse };
'admin/roles/update-default-policies': { req: AdminRolesUpdateDefaultPoliciesRequest; res: EmptyResponse }; 'admin/roles/update-default-policies': { req: AdminRolesUpdateDefaultPoliciesRequest; res: EmptyResponse };
'admin/roles/users': { req: AdminRolesUsersRequest; res: EmptyResponse }; 'admin/roles/users': { req: AdminRolesUsersRequest; res: AdminRolesUsersResponse };
'announcements': { req: AnnouncementsRequest; res: AnnouncementsResponse }; 'announcements': { req: AnnouncementsRequest; res: AnnouncementsResponse };
'antennas/create': { req: AntennasCreateRequest; res: AntennasCreateResponse }; 'antennas/create': { req: AntennasCreateRequest; res: AntennasCreateResponse };
'antennas/delete': { req: AntennasDeleteRequest; res: EmptyResponse }; 'antennas/delete': { req: AntennasDeleteRequest; res: EmptyResponse };
@ -672,7 +704,7 @@ export type Endpoints = {
'drive/folders/update': { req: DriveFoldersUpdateRequest; res: DriveFoldersUpdateResponse }; 'drive/folders/update': { req: DriveFoldersUpdateRequest; res: DriveFoldersUpdateResponse };
'drive/stream': { req: DriveStreamRequest; res: DriveStreamResponse }; 'drive/stream': { req: DriveStreamRequest; res: DriveStreamResponse };
'email-address/available': { req: EmailAddressAvailableRequest; res: EmailAddressAvailableResponse }; 'email-address/available': { req: EmailAddressAvailableRequest; res: EmailAddressAvailableResponse };
'endpoint': { req: EndpointRequest; res: EmptyResponse }; 'endpoint': { req: EndpointRequest; res: EndpointResponse };
'endpoints': { req: EmptyRequest; res: EndpointsResponse }; 'endpoints': { req: EmptyRequest; res: EndpointsResponse };
'export-custom-emojis': { req: EmptyRequest; res: EmptyResponse }; 'export-custom-emojis': { req: EmptyRequest; res: EmptyResponse };
'federation/followers': { req: FederationFollowersRequest; res: FederationFollowersResponse }; 'federation/followers': { req: FederationFollowersRequest; res: FederationFollowersResponse };
@ -681,7 +713,7 @@ export type Endpoints = {
'federation/show-instance': { req: FederationShowInstanceRequest; res: FederationShowInstanceResponse }; 'federation/show-instance': { req: FederationShowInstanceRequest; res: FederationShowInstanceResponse };
'federation/update-remote-user': { req: FederationUpdateRemoteUserRequest; res: EmptyResponse }; 'federation/update-remote-user': { req: FederationUpdateRemoteUserRequest; res: EmptyResponse };
'federation/users': { req: FederationUsersRequest; res: FederationUsersResponse }; 'federation/users': { req: FederationUsersRequest; res: FederationUsersResponse };
'federation/stats': { req: FederationStatsRequest; res: EmptyResponse }; 'federation/stats': { req: FederationStatsRequest; res: FederationStatsResponse };
'following/create': { req: FollowingCreateRequest; res: FollowingCreateResponse }; 'following/create': { req: FollowingCreateRequest; res: FollowingCreateResponse };
'following/delete': { req: FollowingDeleteRequest; res: FollowingDeleteResponse }; 'following/delete': { req: FollowingDeleteRequest; res: FollowingDeleteResponse };
'following/update': { req: FollowingUpdateRequest; res: FollowingUpdateResponse }; 'following/update': { req: FollowingUpdateRequest; res: FollowingUpdateResponse };
@ -700,7 +732,7 @@ export type Endpoints = {
'gallery/posts/show': { req: GalleryPostsShowRequest; res: GalleryPostsShowResponse }; 'gallery/posts/show': { req: GalleryPostsShowRequest; res: GalleryPostsShowResponse };
'gallery/posts/unlike': { req: GalleryPostsUnlikeRequest; res: EmptyResponse }; 'gallery/posts/unlike': { req: GalleryPostsUnlikeRequest; res: EmptyResponse };
'gallery/posts/update': { req: GalleryPostsUpdateRequest; res: GalleryPostsUpdateResponse }; 'gallery/posts/update': { req: GalleryPostsUpdateRequest; res: GalleryPostsUpdateResponse };
'get-online-users-count': { req: EmptyRequest; res: EmptyResponse }; 'get-online-users-count': { req: EmptyRequest; res: GetOnlineUsersCountResponse };
'get-avatar-decorations': { req: EmptyRequest; res: GetAvatarDecorationsResponse }; 'get-avatar-decorations': { req: EmptyRequest; res: GetAvatarDecorationsResponse };
'hashtags/list': { req: HashtagsListRequest; res: HashtagsListResponse }; 'hashtags/list': { req: HashtagsListRequest; res: HashtagsListResponse };
'hashtags/search': { req: HashtagsSearchRequest; res: HashtagsSearchResponse }; 'hashtags/search': { req: HashtagsSearchRequest; res: HashtagsSearchResponse };
@ -709,15 +741,15 @@ export type Endpoints = {
'hashtags/users': { req: HashtagsUsersRequest; res: HashtagsUsersResponse }; 'hashtags/users': { req: HashtagsUsersRequest; res: HashtagsUsersResponse };
'i': { req: EmptyRequest; res: IResponse }; 'i': { req: EmptyRequest; res: IResponse };
'i/2fa/done': { req: I2faDoneRequest; res: EmptyResponse }; 'i/2fa/done': { req: I2faDoneRequest; res: EmptyResponse };
'i/2fa/key-done': { req: I2faKeyDoneRequest; res: EmptyResponse }; 'i/2fa/key-done': { req: I2faKeyDoneRequest; res: I2faKeyDoneResponse };
'i/2fa/password-less': { req: I2faPasswordLessRequest; res: EmptyResponse }; 'i/2fa/password-less': { req: I2faPasswordLessRequest; res: EmptyResponse };
'i/2fa/register-key': { req: I2faRegisterKeyRequest; res: EmptyResponse }; 'i/2fa/register-key': { req: I2faRegisterKeyRequest; res: I2faRegisterKeyResponse };
'i/2fa/register': { req: I2faRegisterRequest; res: EmptyResponse }; 'i/2fa/register': { req: I2faRegisterRequest; res: I2faRegisterResponse };
'i/2fa/update-key': { req: I2faUpdateKeyRequest; res: EmptyResponse }; 'i/2fa/update-key': { req: I2faUpdateKeyRequest; res: EmptyResponse };
'i/2fa/remove-key': { req: I2faRemoveKeyRequest; res: EmptyResponse }; 'i/2fa/remove-key': { req: I2faRemoveKeyRequest; res: EmptyResponse };
'i/2fa/unregister': { req: I2faUnregisterRequest; res: EmptyResponse }; 'i/2fa/unregister': { req: I2faUnregisterRequest; res: EmptyResponse };
'i/apps': { req: IAppsRequest; res: EmptyResponse }; 'i/apps': { req: IAppsRequest; res: IAppsResponse };
'i/authorized-apps': { req: IAuthorizedAppsRequest; res: EmptyResponse }; 'i/authorized-apps': { req: IAuthorizedAppsRequest; res: IAuthorizedAppsResponse };
'i/claim-achievement': { req: IClaimAchievementRequest; res: EmptyResponse }; 'i/claim-achievement': { req: IClaimAchievementRequest; res: EmptyResponse };
'i/change-password': { req: IChangePasswordRequest; res: EmptyResponse }; 'i/change-password': { req: IChangePasswordRequest; res: EmptyResponse };
'i/delete-account': { req: IDeleteAccountRequest; res: EmptyResponse }; 'i/delete-account': { req: IDeleteAccountRequest; res: EmptyResponse };
@ -744,23 +776,23 @@ export type Endpoints = {
'i/read-all-unread-notes': { req: EmptyRequest; res: EmptyResponse }; 'i/read-all-unread-notes': { req: EmptyRequest; res: EmptyResponse };
'i/read-announcement': { req: IReadAnnouncementRequest; res: EmptyResponse }; 'i/read-announcement': { req: IReadAnnouncementRequest; res: EmptyResponse };
'i/regenerate-token': { req: IRegenerateTokenRequest; res: EmptyResponse }; 'i/regenerate-token': { req: IRegenerateTokenRequest; res: EmptyResponse };
'i/registry/get-all': { req: IRegistryGetAllRequest; res: EmptyResponse }; 'i/registry/get-all': { req: IRegistryGetAllRequest; res: IRegistryGetAllResponse };
'i/registry/get-detail': { req: IRegistryGetDetailRequest; res: EmptyResponse }; 'i/registry/get-detail': { req: IRegistryGetDetailRequest; res: IRegistryGetDetailResponse };
'i/registry/get': { req: IRegistryGetRequest; res: EmptyResponse }; 'i/registry/get': { req: IRegistryGetRequest; res: IRegistryGetResponse };
'i/registry/keys-with-type': { req: IRegistryKeysWithTypeRequest; res: EmptyResponse }; 'i/registry/keys-with-type': { req: IRegistryKeysWithTypeRequest; res: IRegistryKeysWithTypeResponse };
'i/registry/keys': { req: IRegistryKeysRequest; res: EmptyResponse }; 'i/registry/keys': { req: IRegistryKeysRequest; res: EmptyResponse };
'i/registry/remove': { req: IRegistryRemoveRequest; res: EmptyResponse }; 'i/registry/remove': { req: IRegistryRemoveRequest; res: EmptyResponse };
'i/registry/scopes-with-domain': { req: EmptyRequest; res: EmptyResponse }; 'i/registry/scopes-with-domain': { req: EmptyRequest; res: IRegistryScopesWithDomainResponse };
'i/registry/set': { req: IRegistrySetRequest; res: EmptyResponse }; 'i/registry/set': { req: IRegistrySetRequest; res: EmptyResponse };
'i/revoke-token': { req: IRevokeTokenRequest; res: EmptyResponse }; 'i/revoke-token': { req: IRevokeTokenRequest; res: EmptyResponse };
'i/signin-history': { req: ISigninHistoryRequest; res: ISigninHistoryResponse }; 'i/signin-history': { req: ISigninHistoryRequest; res: ISigninHistoryResponse };
'i/unpin': { req: IUnpinRequest; res: IUnpinResponse }; 'i/unpin': { req: IUnpinRequest; res: IUnpinResponse };
'i/update-email': { req: IUpdateEmailRequest; res: EmptyResponse }; 'i/update-email': { req: IUpdateEmailRequest; res: IUpdateEmailResponse };
'i/update': { req: IUpdateRequest; res: IUpdateResponse }; 'i/update': { req: IUpdateRequest; res: IUpdateResponse };
'i/move': { req: IMoveRequest; res: EmptyResponse }; 'i/move': { req: IMoveRequest; res: IMoveResponse };
'i/webhooks/create': { req: IWebhooksCreateRequest; res: EmptyResponse }; 'i/webhooks/create': { req: IWebhooksCreateRequest; res: IWebhooksCreateResponse };
'i/webhooks/list': { req: EmptyRequest; res: EmptyResponse }; 'i/webhooks/list': { req: EmptyRequest; res: IWebhooksListResponse };
'i/webhooks/show': { req: IWebhooksShowRequest; res: EmptyResponse }; 'i/webhooks/show': { req: IWebhooksShowRequest; res: IWebhooksShowResponse };
'i/webhooks/update': { req: IWebhooksUpdateRequest; res: EmptyResponse }; 'i/webhooks/update': { req: IWebhooksUpdateRequest; res: EmptyResponse };
'i/webhooks/delete': { req: IWebhooksDeleteRequest; res: EmptyResponse }; 'i/webhooks/delete': { req: IWebhooksDeleteRequest; res: EmptyResponse };
'invite/create': { req: EmptyRequest; res: InviteCreateResponse }; 'invite/create': { req: EmptyRequest; res: InviteCreateResponse };
@ -819,7 +851,7 @@ export type Endpoints = {
'pages/show': { req: PagesShowRequest; res: PagesShowResponse }; 'pages/show': { req: PagesShowRequest; res: PagesShowResponse };
'pages/unlike': { req: PagesUnlikeRequest; res: EmptyResponse }; 'pages/unlike': { req: PagesUnlikeRequest; res: EmptyResponse };
'pages/update': { req: PagesUpdateRequest; res: EmptyResponse }; 'pages/update': { req: PagesUpdateRequest; res: EmptyResponse };
'flash/create': { req: FlashCreateRequest; res: EmptyResponse }; 'flash/create': { req: FlashCreateRequest; res: FlashCreateResponse };
'flash/delete': { req: FlashDeleteRequest; res: EmptyResponse }; 'flash/delete': { req: FlashDeleteRequest; res: EmptyResponse };
'flash/featured': { req: EmptyRequest; res: FlashFeaturedResponse }; 'flash/featured': { req: EmptyRequest; res: FlashFeaturedResponse };
'flash/like': { req: FlashLikeRequest; res: EmptyResponse }; 'flash/like': { req: FlashLikeRequest; res: EmptyResponse };
@ -833,18 +865,18 @@ export type Endpoints = {
'promo/read': { req: PromoReadRequest; res: EmptyResponse }; 'promo/read': { req: PromoReadRequest; res: EmptyResponse };
'roles/list': { req: EmptyRequest; res: RolesListResponse }; 'roles/list': { req: EmptyRequest; res: RolesListResponse };
'roles/show': { req: RolesShowRequest; res: RolesShowResponse }; 'roles/show': { req: RolesShowRequest; res: RolesShowResponse };
'roles/users': { req: RolesUsersRequest; res: EmptyResponse }; 'roles/users': { req: RolesUsersRequest; res: RolesUsersResponse };
'roles/notes': { req: RolesNotesRequest; res: RolesNotesResponse }; 'roles/notes': { req: RolesNotesRequest; res: RolesNotesResponse };
'request-reset-password': { req: RequestResetPasswordRequest; res: EmptyResponse }; 'request-reset-password': { req: RequestResetPasswordRequest; res: EmptyResponse };
'reset-db': { req: EmptyRequest; res: EmptyResponse }; 'reset-db': { req: EmptyRequest; res: EmptyResponse };
'reset-password': { req: ResetPasswordRequest; res: EmptyResponse }; 'reset-password': { req: ResetPasswordRequest; res: EmptyResponse };
'server-info': { req: EmptyRequest; res: EmptyResponse }; 'server-info': { req: EmptyRequest; res: ServerInfoResponse };
'stats': { req: EmptyRequest; res: StatsResponse }; 'stats': { req: EmptyRequest; res: StatsResponse };
'sw/show-registration': { req: SwShowRegistrationRequest; res: SwShowRegistrationResponse }; 'sw/show-registration': { req: SwShowRegistrationRequest; res: SwShowRegistrationResponse };
'sw/update-registration': { req: SwUpdateRegistrationRequest; res: SwUpdateRegistrationResponse }; 'sw/update-registration': { req: SwUpdateRegistrationRequest; res: SwUpdateRegistrationResponse };
'sw/register': { req: SwRegisterRequest; res: SwRegisterResponse }; 'sw/register': { req: SwRegisterRequest; res: SwRegisterResponse };
'sw/unregister': { req: SwUnregisterRequest; res: EmptyResponse }; 'sw/unregister': { req: SwUnregisterRequest; res: EmptyResponse };
'test': { req: TestRequest; res: EmptyResponse }; 'test': { req: TestRequest; res: TestResponse };
'username/available': { req: UsernameAvailableRequest; res: UsernameAvailableResponse }; 'username/available': { req: UsernameAvailableRequest; res: UsernameAvailableResponse };
'users': { req: UsersRequest; res: UsersResponse }; 'users': { req: UsersRequest; res: UsersResponse };
'users/clips': { req: UsersClipsRequest; res: UsersClipsResponse }; 'users/clips': { req: UsersClipsRequest; res: UsersClipsResponse };
@ -864,7 +896,7 @@ export type Endpoints = {
'users/lists/update': { req: UsersListsUpdateRequest; res: UsersListsUpdateResponse }; 'users/lists/update': { req: UsersListsUpdateRequest; res: UsersListsUpdateResponse };
'users/lists/create-from-public': { req: UsersListsCreateFromPublicRequest; res: UsersListsCreateFromPublicResponse }; 'users/lists/create-from-public': { req: UsersListsCreateFromPublicRequest; res: UsersListsCreateFromPublicResponse };
'users/lists/update-membership': { req: UsersListsUpdateMembershipRequest; res: EmptyResponse }; 'users/lists/update-membership': { req: UsersListsUpdateMembershipRequest; res: EmptyResponse };
'users/lists/get-memberships': { req: UsersListsGetMembershipsRequest; res: EmptyResponse }; 'users/lists/get-memberships': { req: UsersListsGetMembershipsRequest; res: UsersListsGetMembershipsResponse };
'users/notes': { req: UsersNotesRequest; res: UsersNotesResponse }; 'users/notes': { req: UsersNotesRequest; res: UsersNotesResponse };
'users/pages': { req: UsersPagesRequest; res: UsersPagesResponse }; 'users/pages': { req: UsersPagesRequest; res: UsersPagesResponse };
'users/flashs': { req: UsersFlashsRequest; res: UsersFlashsResponse }; 'users/flashs': { req: UsersFlashsRequest; res: UsersFlashsResponse };
@ -876,9 +908,9 @@ export type Endpoints = {
'users/search': { req: UsersSearchRequest; res: UsersSearchResponse }; 'users/search': { req: UsersSearchRequest; res: UsersSearchResponse };
'users/show': { req: UsersShowRequest; res: UsersShowResponse }; 'users/show': { req: UsersShowRequest; res: UsersShowResponse };
'users/stats': { req: UsersStatsRequest; res: UsersStatsResponse }; 'users/stats': { req: UsersStatsRequest; res: UsersStatsResponse };
'users/achievements': { req: UsersAchievementsRequest; res: EmptyResponse }; 'users/achievements': { req: UsersAchievementsRequest; res: UsersAchievementsResponse };
'users/update-memo': { req: UsersUpdateMemoRequest; res: EmptyResponse }; 'users/update-memo': { req: UsersUpdateMemoRequest; res: EmptyResponse };
'fetch-rss': { req: FetchRssRequest; res: EmptyResponse }; 'fetch-rss': { req: FetchRssRequest; res: FetchRssResponse };
'fetch-external-resources': { req: FetchExternalResourcesRequest; res: EmptyResponse }; 'fetch-external-resources': { req: FetchExternalResourcesRequest; res: FetchExternalResourcesResponse };
'retention': { req: EmptyRequest; res: RetentionResponse }; 'retention': { req: EmptyRequest; res: RetentionResponse };
} }

View File

@ -1,6 +1,6 @@
/* /*
* version: 2023.12.0-beta.5-io * version: 2023.12.0-io
* generatedAt: 2023-12-21T02:55:40.804Z * generatedAt: 2023-12-23T11:38:40.630Z
*/ */
import { operations } from './types.js'; import { operations } from './types.js';
@ -15,9 +15,12 @@ export type AdminAccountsCreateRequest = operations['admin/accounts/create']['re
export type AdminAccountsCreateResponse = operations['admin/accounts/create']['responses']['200']['content']['application/json']; export type AdminAccountsCreateResponse = operations['admin/accounts/create']['responses']['200']['content']['application/json'];
export type AdminAccountsDeleteRequest = operations['admin/accounts/delete']['requestBody']['content']['application/json']; export type AdminAccountsDeleteRequest = operations['admin/accounts/delete']['requestBody']['content']['application/json'];
export type AdminAccountsFindByEmailRequest = operations['admin/accounts/find-by-email']['requestBody']['content']['application/json']; export type AdminAccountsFindByEmailRequest = operations['admin/accounts/find-by-email']['requestBody']['content']['application/json'];
export type AdminAccountsFindByEmailResponse = operations['admin/accounts/find-by-email']['responses']['200']['content']['application/json'];
export type AdminAdCreateRequest = operations['admin/ad/create']['requestBody']['content']['application/json']; export type AdminAdCreateRequest = operations['admin/ad/create']['requestBody']['content']['application/json'];
export type AdminAdCreateResponse = operations['admin/ad/create']['responses']['200']['content']['application/json'];
export type AdminAdDeleteRequest = operations['admin/ad/delete']['requestBody']['content']['application/json']; export type AdminAdDeleteRequest = operations['admin/ad/delete']['requestBody']['content']['application/json'];
export type AdminAdListRequest = operations['admin/ad/list']['requestBody']['content']['application/json']; export type AdminAdListRequest = operations['admin/ad/list']['requestBody']['content']['application/json'];
export type AdminAdListResponse = operations['admin/ad/list']['responses']['200']['content']['application/json'];
export type AdminAdUpdateRequest = operations['admin/ad/update']['requestBody']['content']['application/json']; export type AdminAdUpdateRequest = operations['admin/ad/update']['requestBody']['content']['application/json'];
export type AdminAnnouncementsCreateRequest = operations['admin/announcements/create']['requestBody']['content']['application/json']; export type AdminAnnouncementsCreateRequest = operations['admin/announcements/create']['requestBody']['content']['application/json'];
export type AdminAnnouncementsCreateResponse = operations['admin/announcements/create']['responses']['200']['content']['application/json']; export type AdminAnnouncementsCreateResponse = operations['admin/announcements/create']['responses']['200']['content']['application/json'];
@ -63,8 +66,10 @@ export type AdminFederationDeleteAllFilesRequest = operations['admin/federation/
export type AdminFederationRefreshRemoteInstanceMetadataRequest = operations['admin/federation/refresh-remote-instance-metadata']['requestBody']['content']['application/json']; export type AdminFederationRefreshRemoteInstanceMetadataRequest = operations['admin/federation/refresh-remote-instance-metadata']['requestBody']['content']['application/json'];
export type AdminFederationRemoveAllFollowingRequest = operations['admin/federation/remove-all-following']['requestBody']['content']['application/json']; export type AdminFederationRemoveAllFollowingRequest = operations['admin/federation/remove-all-following']['requestBody']['content']['application/json'];
export type AdminFederationUpdateInstanceRequest = operations['admin/federation/update-instance']['requestBody']['content']['application/json']; export type AdminFederationUpdateInstanceRequest = operations['admin/federation/update-instance']['requestBody']['content']['application/json'];
export type AdminGetIndexStatsResponse = operations['admin/get-index-stats']['responses']['200']['content']['application/json'];
export type AdminGetTableStatsResponse = operations['admin/get-table-stats']['responses']['200']['content']['application/json']; export type AdminGetTableStatsResponse = operations['admin/get-table-stats']['responses']['200']['content']['application/json'];
export type AdminGetUserIpsRequest = operations['admin/get-user-ips']['requestBody']['content']['application/json']; export type AdminGetUserIpsRequest = operations['admin/get-user-ips']['requestBody']['content']['application/json'];
export type AdminGetUserIpsResponse = operations['admin/get-user-ips']['responses']['200']['content']['application/json'];
export type AdminInviteCreateRequest = operations['admin/invite/create']['requestBody']['content']['application/json']; export type AdminInviteCreateRequest = operations['admin/invite/create']['requestBody']['content']['application/json'];
export type AdminInviteCreateResponse = operations['admin/invite/create']['responses']['200']['content']['application/json']; export type AdminInviteCreateResponse = operations['admin/invite/create']['responses']['200']['content']['application/json'];
export type AdminInviteListRequest = operations['admin/invite/list']['requestBody']['content']['application/json']; export type AdminInviteListRequest = operations['admin/invite/list']['requestBody']['content']['application/json'];
@ -106,6 +111,7 @@ export type AdminRolesAssignRequest = operations['admin/roles/assign']['requestB
export type AdminRolesUnassignRequest = operations['admin/roles/unassign']['requestBody']['content']['application/json']; export type AdminRolesUnassignRequest = operations['admin/roles/unassign']['requestBody']['content']['application/json'];
export type AdminRolesUpdateDefaultPoliciesRequest = operations['admin/roles/update-default-policies']['requestBody']['content']['application/json']; export type AdminRolesUpdateDefaultPoliciesRequest = operations['admin/roles/update-default-policies']['requestBody']['content']['application/json'];
export type AdminRolesUsersRequest = operations['admin/roles/users']['requestBody']['content']['application/json']; export type AdminRolesUsersRequest = operations['admin/roles/users']['requestBody']['content']['application/json'];
export type AdminRolesUsersResponse = operations['admin/roles/users']['responses']['200']['content']['application/json'];
export type AnnouncementsRequest = operations['announcements']['requestBody']['content']['application/json']; export type AnnouncementsRequest = operations['announcements']['requestBody']['content']['application/json'];
export type AnnouncementsResponse = operations['announcements']['responses']['200']['content']['application/json']; export type AnnouncementsResponse = operations['announcements']['responses']['200']['content']['application/json'];
export type AntennasCreateRequest = operations['antennas/create']['requestBody']['content']['application/json']; export type AntennasCreateRequest = operations['antennas/create']['requestBody']['content']['application/json'];
@ -233,6 +239,7 @@ export type DriveStreamResponse = operations['drive/stream']['responses']['200']
export type EmailAddressAvailableRequest = operations['email-address/available']['requestBody']['content']['application/json']; export type EmailAddressAvailableRequest = operations['email-address/available']['requestBody']['content']['application/json'];
export type EmailAddressAvailableResponse = operations['email-address/available']['responses']['200']['content']['application/json']; export type EmailAddressAvailableResponse = operations['email-address/available']['responses']['200']['content']['application/json'];
export type EndpointRequest = operations['endpoint']['requestBody']['content']['application/json']; export type EndpointRequest = operations['endpoint']['requestBody']['content']['application/json'];
export type EndpointResponse = operations['endpoint']['responses']['200']['content']['application/json'];
export type EndpointsResponse = operations['endpoints']['responses']['200']['content']['application/json']; export type EndpointsResponse = operations['endpoints']['responses']['200']['content']['application/json'];
export type FederationFollowersRequest = operations['federation/followers']['requestBody']['content']['application/json']; export type FederationFollowersRequest = operations['federation/followers']['requestBody']['content']['application/json'];
export type FederationFollowersResponse = operations['federation/followers']['responses']['200']['content']['application/json']; export type FederationFollowersResponse = operations['federation/followers']['responses']['200']['content']['application/json'];
@ -246,6 +253,7 @@ export type FederationUpdateRemoteUserRequest = operations['federation/update-re
export type FederationUsersRequest = operations['federation/users']['requestBody']['content']['application/json']; export type FederationUsersRequest = operations['federation/users']['requestBody']['content']['application/json'];
export type FederationUsersResponse = operations['federation/users']['responses']['200']['content']['application/json']; export type FederationUsersResponse = operations['federation/users']['responses']['200']['content']['application/json'];
export type FederationStatsRequest = operations['federation/stats']['requestBody']['content']['application/json']; export type FederationStatsRequest = operations['federation/stats']['requestBody']['content']['application/json'];
export type FederationStatsResponse = operations['federation/stats']['responses']['200']['content']['application/json'];
export type FollowingCreateRequest = operations['following/create']['requestBody']['content']['application/json']; export type FollowingCreateRequest = operations['following/create']['requestBody']['content']['application/json'];
export type FollowingCreateResponse = operations['following/create']['responses']['200']['content']['application/json']; export type FollowingCreateResponse = operations['following/create']['responses']['200']['content']['application/json'];
export type FollowingDeleteRequest = operations['following/delete']['requestBody']['content']['application/json']; export type FollowingDeleteRequest = operations['following/delete']['requestBody']['content']['application/json'];
@ -275,6 +283,7 @@ export type GalleryPostsShowResponse = operations['gallery/posts/show']['respons
export type GalleryPostsUnlikeRequest = operations['gallery/posts/unlike']['requestBody']['content']['application/json']; export type GalleryPostsUnlikeRequest = operations['gallery/posts/unlike']['requestBody']['content']['application/json'];
export type GalleryPostsUpdateRequest = operations['gallery/posts/update']['requestBody']['content']['application/json']; export type GalleryPostsUpdateRequest = operations['gallery/posts/update']['requestBody']['content']['application/json'];
export type GalleryPostsUpdateResponse = operations['gallery/posts/update']['responses']['200']['content']['application/json']; export type GalleryPostsUpdateResponse = operations['gallery/posts/update']['responses']['200']['content']['application/json'];
export type GetOnlineUsersCountResponse = operations['get-online-users-count']['responses']['200']['content']['application/json'];
export type GetAvatarDecorationsResponse = operations['get-avatar-decorations']['responses']['200']['content']['application/json']; export type GetAvatarDecorationsResponse = operations['get-avatar-decorations']['responses']['200']['content']['application/json'];
export type HashtagsListRequest = operations['hashtags/list']['requestBody']['content']['application/json']; export type HashtagsListRequest = operations['hashtags/list']['requestBody']['content']['application/json'];
export type HashtagsListResponse = operations['hashtags/list']['responses']['200']['content']['application/json']; export type HashtagsListResponse = operations['hashtags/list']['responses']['200']['content']['application/json'];
@ -288,14 +297,19 @@ export type HashtagsUsersResponse = operations['hashtags/users']['responses']['2
export type IResponse = operations['i']['responses']['200']['content']['application/json']; export type IResponse = operations['i']['responses']['200']['content']['application/json'];
export type I2faDoneRequest = operations['i/2fa/done']['requestBody']['content']['application/json']; export type I2faDoneRequest = operations['i/2fa/done']['requestBody']['content']['application/json'];
export type I2faKeyDoneRequest = operations['i/2fa/key-done']['requestBody']['content']['application/json']; export type I2faKeyDoneRequest = operations['i/2fa/key-done']['requestBody']['content']['application/json'];
export type I2faKeyDoneResponse = operations['i/2fa/key-done']['responses']['200']['content']['application/json'];
export type I2faPasswordLessRequest = operations['i/2fa/password-less']['requestBody']['content']['application/json']; export type I2faPasswordLessRequest = operations['i/2fa/password-less']['requestBody']['content']['application/json'];
export type I2faRegisterKeyRequest = operations['i/2fa/register-key']['requestBody']['content']['application/json']; export type I2faRegisterKeyRequest = operations['i/2fa/register-key']['requestBody']['content']['application/json'];
export type I2faRegisterKeyResponse = operations['i/2fa/register-key']['responses']['200']['content']['application/json'];
export type I2faRegisterRequest = operations['i/2fa/register']['requestBody']['content']['application/json']; export type I2faRegisterRequest = operations['i/2fa/register']['requestBody']['content']['application/json'];
export type I2faRegisterResponse = operations['i/2fa/register']['responses']['200']['content']['application/json'];
export type I2faUpdateKeyRequest = operations['i/2fa/update-key']['requestBody']['content']['application/json']; export type I2faUpdateKeyRequest = operations['i/2fa/update-key']['requestBody']['content']['application/json'];
export type I2faRemoveKeyRequest = operations['i/2fa/remove-key']['requestBody']['content']['application/json']; export type I2faRemoveKeyRequest = operations['i/2fa/remove-key']['requestBody']['content']['application/json'];
export type I2faUnregisterRequest = operations['i/2fa/unregister']['requestBody']['content']['application/json']; export type I2faUnregisterRequest = operations['i/2fa/unregister']['requestBody']['content']['application/json'];
export type IAppsRequest = operations['i/apps']['requestBody']['content']['application/json']; export type IAppsRequest = operations['i/apps']['requestBody']['content']['application/json'];
export type IAppsResponse = operations['i/apps']['responses']['200']['content']['application/json'];
export type IAuthorizedAppsRequest = operations['i/authorized-apps']['requestBody']['content']['application/json']; export type IAuthorizedAppsRequest = operations['i/authorized-apps']['requestBody']['content']['application/json'];
export type IAuthorizedAppsResponse = operations['i/authorized-apps']['responses']['200']['content']['application/json'];
export type IClaimAchievementRequest = operations['i/claim-achievement']['requestBody']['content']['application/json']; export type IClaimAchievementRequest = operations['i/claim-achievement']['requestBody']['content']['application/json'];
export type IChangePasswordRequest = operations['i/change-password']['requestBody']['content']['application/json']; export type IChangePasswordRequest = operations['i/change-password']['requestBody']['content']['application/json'];
export type IDeleteAccountRequest = operations['i/delete-account']['requestBody']['content']['application/json']; export type IDeleteAccountRequest = operations['i/delete-account']['requestBody']['content']['application/json'];
@ -324,11 +338,16 @@ export type IPinResponse = operations['i/pin']['responses']['200']['content']['a
export type IReadAnnouncementRequest = operations['i/read-announcement']['requestBody']['content']['application/json']; export type IReadAnnouncementRequest = operations['i/read-announcement']['requestBody']['content']['application/json'];
export type IRegenerateTokenRequest = operations['i/regenerate-token']['requestBody']['content']['application/json']; export type IRegenerateTokenRequest = operations['i/regenerate-token']['requestBody']['content']['application/json'];
export type IRegistryGetAllRequest = operations['i/registry/get-all']['requestBody']['content']['application/json']; export type IRegistryGetAllRequest = operations['i/registry/get-all']['requestBody']['content']['application/json'];
export type IRegistryGetAllResponse = operations['i/registry/get-all']['responses']['200']['content']['application/json'];
export type IRegistryGetDetailRequest = operations['i/registry/get-detail']['requestBody']['content']['application/json']; export type IRegistryGetDetailRequest = operations['i/registry/get-detail']['requestBody']['content']['application/json'];
export type IRegistryGetDetailResponse = operations['i/registry/get-detail']['responses']['200']['content']['application/json'];
export type IRegistryGetRequest = operations['i/registry/get']['requestBody']['content']['application/json']; export type IRegistryGetRequest = operations['i/registry/get']['requestBody']['content']['application/json'];
export type IRegistryGetResponse = operations['i/registry/get']['responses']['200']['content']['application/json'];
export type IRegistryKeysWithTypeRequest = operations['i/registry/keys-with-type']['requestBody']['content']['application/json']; export type IRegistryKeysWithTypeRequest = operations['i/registry/keys-with-type']['requestBody']['content']['application/json'];
export type IRegistryKeysWithTypeResponse = operations['i/registry/keys-with-type']['responses']['200']['content']['application/json'];
export type IRegistryKeysRequest = operations['i/registry/keys']['requestBody']['content']['application/json']; export type IRegistryKeysRequest = operations['i/registry/keys']['requestBody']['content']['application/json'];
export type IRegistryRemoveRequest = operations['i/registry/remove']['requestBody']['content']['application/json']; export type IRegistryRemoveRequest = operations['i/registry/remove']['requestBody']['content']['application/json'];
export type IRegistryScopesWithDomainResponse = operations['i/registry/scopes-with-domain']['responses']['200']['content']['application/json'];
export type IRegistrySetRequest = operations['i/registry/set']['requestBody']['content']['application/json']; export type IRegistrySetRequest = operations['i/registry/set']['requestBody']['content']['application/json'];
export type IRevokeTokenRequest = operations['i/revoke-token']['requestBody']['content']['application/json']; export type IRevokeTokenRequest = operations['i/revoke-token']['requestBody']['content']['application/json'];
export type ISigninHistoryRequest = operations['i/signin-history']['requestBody']['content']['application/json']; export type ISigninHistoryRequest = operations['i/signin-history']['requestBody']['content']['application/json'];
@ -336,11 +355,16 @@ export type ISigninHistoryResponse = operations['i/signin-history']['responses']
export type IUnpinRequest = operations['i/unpin']['requestBody']['content']['application/json']; export type IUnpinRequest = operations['i/unpin']['requestBody']['content']['application/json'];
export type IUnpinResponse = operations['i/unpin']['responses']['200']['content']['application/json']; export type IUnpinResponse = operations['i/unpin']['responses']['200']['content']['application/json'];
export type IUpdateEmailRequest = operations['i/update-email']['requestBody']['content']['application/json']; export type IUpdateEmailRequest = operations['i/update-email']['requestBody']['content']['application/json'];
export type IUpdateEmailResponse = operations['i/update-email']['responses']['200']['content']['application/json'];
export type IUpdateRequest = operations['i/update']['requestBody']['content']['application/json']; export type IUpdateRequest = operations['i/update']['requestBody']['content']['application/json'];
export type IUpdateResponse = operations['i/update']['responses']['200']['content']['application/json']; export type IUpdateResponse = operations['i/update']['responses']['200']['content']['application/json'];
export type IMoveRequest = operations['i/move']['requestBody']['content']['application/json']; export type IMoveRequest = operations['i/move']['requestBody']['content']['application/json'];
export type IMoveResponse = operations['i/move']['responses']['200']['content']['application/json'];
export type IWebhooksCreateRequest = operations['i/webhooks/create']['requestBody']['content']['application/json']; export type IWebhooksCreateRequest = operations['i/webhooks/create']['requestBody']['content']['application/json'];
export type IWebhooksCreateResponse = operations['i/webhooks/create']['responses']['200']['content']['application/json'];
export type IWebhooksListResponse = operations['i/webhooks/list']['responses']['200']['content']['application/json'];
export type IWebhooksShowRequest = operations['i/webhooks/show']['requestBody']['content']['application/json']; export type IWebhooksShowRequest = operations['i/webhooks/show']['requestBody']['content']['application/json'];
export type IWebhooksShowResponse = operations['i/webhooks/show']['responses']['200']['content']['application/json'];
export type IWebhooksUpdateRequest = operations['i/webhooks/update']['requestBody']['content']['application/json']; export type IWebhooksUpdateRequest = operations['i/webhooks/update']['requestBody']['content']['application/json'];
export type IWebhooksDeleteRequest = operations['i/webhooks/delete']['requestBody']['content']['application/json']; export type IWebhooksDeleteRequest = operations['i/webhooks/delete']['requestBody']['content']['application/json'];
export type InviteCreateResponse = operations['invite/create']['responses']['200']['content']['application/json']; export type InviteCreateResponse = operations['invite/create']['responses']['200']['content']['application/json'];
@ -428,6 +452,7 @@ export type PagesShowResponse = operations['pages/show']['responses']['200']['co
export type PagesUnlikeRequest = operations['pages/unlike']['requestBody']['content']['application/json']; export type PagesUnlikeRequest = operations['pages/unlike']['requestBody']['content']['application/json'];
export type PagesUpdateRequest = operations['pages/update']['requestBody']['content']['application/json']; export type PagesUpdateRequest = operations['pages/update']['requestBody']['content']['application/json'];
export type FlashCreateRequest = operations['flash/create']['requestBody']['content']['application/json']; export type FlashCreateRequest = operations['flash/create']['requestBody']['content']['application/json'];
export type FlashCreateResponse = operations['flash/create']['responses']['200']['content']['application/json'];
export type FlashDeleteRequest = operations['flash/delete']['requestBody']['content']['application/json']; export type FlashDeleteRequest = operations['flash/delete']['requestBody']['content']['application/json'];
export type FlashFeaturedResponse = operations['flash/featured']['responses']['200']['content']['application/json']; export type FlashFeaturedResponse = operations['flash/featured']['responses']['200']['content']['application/json'];
export type FlashLikeRequest = operations['flash/like']['requestBody']['content']['application/json']; export type FlashLikeRequest = operations['flash/like']['requestBody']['content']['application/json'];
@ -446,10 +471,12 @@ export type RolesListResponse = operations['roles/list']['responses']['200']['co
export type RolesShowRequest = operations['roles/show']['requestBody']['content']['application/json']; export type RolesShowRequest = operations['roles/show']['requestBody']['content']['application/json'];
export type RolesShowResponse = operations['roles/show']['responses']['200']['content']['application/json']; export type RolesShowResponse = operations['roles/show']['responses']['200']['content']['application/json'];
export type RolesUsersRequest = operations['roles/users']['requestBody']['content']['application/json']; export type RolesUsersRequest = operations['roles/users']['requestBody']['content']['application/json'];
export type RolesUsersResponse = operations['roles/users']['responses']['200']['content']['application/json'];
export type RolesNotesRequest = operations['roles/notes']['requestBody']['content']['application/json']; export type RolesNotesRequest = operations['roles/notes']['requestBody']['content']['application/json'];
export type RolesNotesResponse = operations['roles/notes']['responses']['200']['content']['application/json']; export type RolesNotesResponse = operations['roles/notes']['responses']['200']['content']['application/json'];
export type RequestResetPasswordRequest = operations['request-reset-password']['requestBody']['content']['application/json']; export type RequestResetPasswordRequest = operations['request-reset-password']['requestBody']['content']['application/json'];
export type ResetPasswordRequest = operations['reset-password']['requestBody']['content']['application/json']; export type ResetPasswordRequest = operations['reset-password']['requestBody']['content']['application/json'];
export type ServerInfoResponse = operations['server-info']['responses']['200']['content']['application/json'];
export type StatsResponse = operations['stats']['responses']['200']['content']['application/json']; export type StatsResponse = operations['stats']['responses']['200']['content']['application/json'];
export type SwShowRegistrationRequest = operations['sw/show-registration']['requestBody']['content']['application/json']; export type SwShowRegistrationRequest = operations['sw/show-registration']['requestBody']['content']['application/json'];
export type SwShowRegistrationResponse = operations['sw/show-registration']['responses']['200']['content']['application/json']; export type SwShowRegistrationResponse = operations['sw/show-registration']['responses']['200']['content']['application/json'];
@ -459,6 +486,7 @@ export type SwRegisterRequest = operations['sw/register']['requestBody']['conten
export type SwRegisterResponse = operations['sw/register']['responses']['200']['content']['application/json']; export type SwRegisterResponse = operations['sw/register']['responses']['200']['content']['application/json'];
export type SwUnregisterRequest = operations['sw/unregister']['requestBody']['content']['application/json']; export type SwUnregisterRequest = operations['sw/unregister']['requestBody']['content']['application/json'];
export type TestRequest = operations['test']['requestBody']['content']['application/json']; export type TestRequest = operations['test']['requestBody']['content']['application/json'];
export type TestResponse = operations['test']['responses']['200']['content']['application/json'];
export type UsernameAvailableRequest = operations['username/available']['requestBody']['content']['application/json']; export type UsernameAvailableRequest = operations['username/available']['requestBody']['content']['application/json'];
export type UsernameAvailableResponse = operations['username/available']['responses']['200']['content']['application/json']; export type UsernameAvailableResponse = operations['username/available']['responses']['200']['content']['application/json'];
export type UsersRequest = operations['users']['requestBody']['content']['application/json']; export type UsersRequest = operations['users']['requestBody']['content']['application/json'];
@ -492,6 +520,7 @@ export type UsersListsCreateFromPublicRequest = operations['users/lists/create-f
export type UsersListsCreateFromPublicResponse = operations['users/lists/create-from-public']['responses']['200']['content']['application/json']; export type UsersListsCreateFromPublicResponse = operations['users/lists/create-from-public']['responses']['200']['content']['application/json'];
export type UsersListsUpdateMembershipRequest = operations['users/lists/update-membership']['requestBody']['content']['application/json']; export type UsersListsUpdateMembershipRequest = operations['users/lists/update-membership']['requestBody']['content']['application/json'];
export type UsersListsGetMembershipsRequest = operations['users/lists/get-memberships']['requestBody']['content']['application/json']; export type UsersListsGetMembershipsRequest = operations['users/lists/get-memberships']['requestBody']['content']['application/json'];
export type UsersListsGetMembershipsResponse = operations['users/lists/get-memberships']['responses']['200']['content']['application/json'];
export type UsersNotesRequest = operations['users/notes']['requestBody']['content']['application/json']; export type UsersNotesRequest = operations['users/notes']['requestBody']['content']['application/json'];
export type UsersNotesResponse = operations['users/notes']['responses']['200']['content']['application/json']; export type UsersNotesResponse = operations['users/notes']['responses']['200']['content']['application/json'];
export type UsersPagesRequest = operations['users/pages']['requestBody']['content']['application/json']; export type UsersPagesRequest = operations['users/pages']['requestBody']['content']['application/json'];
@ -514,7 +543,10 @@ export type UsersShowResponse = operations['users/show']['responses']['200']['co
export type UsersStatsRequest = operations['users/stats']['requestBody']['content']['application/json']; export type UsersStatsRequest = operations['users/stats']['requestBody']['content']['application/json'];
export type UsersStatsResponse = operations['users/stats']['responses']['200']['content']['application/json']; export type UsersStatsResponse = operations['users/stats']['responses']['200']['content']['application/json'];
export type UsersAchievementsRequest = operations['users/achievements']['requestBody']['content']['application/json']; export type UsersAchievementsRequest = operations['users/achievements']['requestBody']['content']['application/json'];
export type UsersAchievementsResponse = operations['users/achievements']['responses']['200']['content']['application/json'];
export type UsersUpdateMemoRequest = operations['users/update-memo']['requestBody']['content']['application/json']; export type UsersUpdateMemoRequest = operations['users/update-memo']['requestBody']['content']['application/json'];
export type FetchRssRequest = operations['fetch-rss']['requestBody']['content']['application/json']; export type FetchRssRequest = operations['fetch-rss']['requestBody']['content']['application/json'];
export type FetchRssResponse = operations['fetch-rss']['responses']['200']['content']['application/json'];
export type FetchExternalResourcesRequest = operations['fetch-external-resources']['requestBody']['content']['application/json']; export type FetchExternalResourcesRequest = operations['fetch-external-resources']['requestBody']['content']['application/json'];
export type FetchExternalResourcesResponse = operations['fetch-external-resources']['responses']['200']['content']['application/json'];
export type RetentionResponse = operations['retention']['responses']['200']['content']['application/json']; export type RetentionResponse = operations['retention']['responses']['200']['content']['application/json'];

View File

@ -1,6 +1,6 @@
/* /*
* version: 2023.12.0-beta.5-io * version: 2023.12.0-io
* generatedAt: 2023-12-21T02:55:40.802Z * generatedAt: 2023-12-23T11:38:40.627Z
*/ */
import { components } from './types.js'; import { components } from './types.js';
@ -14,6 +14,7 @@ export type UserDetailed = components['schemas']['UserDetailed'];
export type User = components['schemas']['User']; export type User = components['schemas']['User'];
export type UserList = components['schemas']['UserList']; export type UserList = components['schemas']['UserList'];
export type UserListMembership = components['schemas']['UserListMembership']; export type UserListMembership = components['schemas']['UserListMembership'];
export type Ad = components['schemas']['Ad'];
export type Announcement = components['schemas']['Announcement']; export type Announcement = components['schemas']['Announcement'];
export type App = components['schemas']['App']; export type App = components['schemas']['App'];
export type Note = components['schemas']['Note']; export type Note = components['schemas']['Note'];

File diff suppressed because it is too large Load Diff