Compare commits

..

No commits in common. "develop" and "2025.10.0-beta.2" have entirely different histories.

58 changed files with 3251 additions and 2818 deletions

View file

@ -1,22 +1,7 @@
## 2025.10.1
### General
- 依存関係の更新
### Client
- Fix: カスタム絵文字画面(beta)のaliasesで使用される区切り文字が一致していないのを修正 #15614
- Fix: バナー画像の幅が表示領域と一致していない問題を修正
- Fix: 一部のブラウザでバナー画像が上下中央に表示されない問題を修正
### Server
-
## 2025.10.0 ## 2025.10.0
### NOTE ### NOTE
- pnpm 10.16.0 が必要です - pnpm 10.16.0 が必要です
- ロールのインポート機能の利用可否ポリシーのデフォルト値が「いいえ」に変わったため、デフォルトから変更していないサーバーでは適宜設定を変更してください。
- ロールのアップロード可能なファイル種別ポリシーのデフォルト値に「text/*」が追加されたため、デフォルトから変更していないサーバーでは適宜設定を変更してください。
### General ### General
- Feat: 予約投稿ができるようになりました - Feat: 予約投稿ができるようになりました
@ -35,12 +20,10 @@
- Enhance: ウォーターマークにアカウントのQRコードを追加できるように - Enhance: ウォーターマークにアカウントのQRコードを追加できるように
- Enhance: テーマをドラッグ&ドロップできるように - Enhance: テーマをドラッグ&ドロップできるように
- Enhance: 絵文字ピッカーのサイズをより大きくできるように - Enhance: 絵文字ピッカーのサイズをより大きくできるように
- Enhance: カスタム絵文字が多い場合にサーバーの絵文字一覧ページがフリーズしないように
- Enhance: 時刻計算のための基準値を一か所で管理するようにし、パフォーマンスを向上 - Enhance: 時刻計算のための基準値を一か所で管理するようにし、パフォーマンスを向上
- Enhance: 「お問い合わせ」ページから、バグの調査等に役立つ情報OSやブラウザのバージョン等を取得・コピーできるように - Enhance: 「お問い合わせ」ページから、バグの調査等に役立つ情報OSやブラウザのバージョン等を取得・コピーできるように
- Fix: iOSで、デバイスがダークモードだと初回読み込み時にエラーになる問題を修正 - Fix: iOSで、デバイスがダークモードだと初回読み込み時にエラーになる問題を修正
- Fix: アクティビティウィジェットのグラフモードが動作しない問題を修正 - Fix: アクティビティウィジェットのグラフモードが動作しない問題を修正
- Fix: ユニコード絵文字の追加辞書をインストールするとユニコード絵文字が絵文字ピッカーで検索できなくなる絵文字があるバグを修正
### Server ### Server
- Enhance: ユーザーIPを確実に取得できるために設定ファイルにFastifyOptions.trustProxyを追加しました - Enhance: ユーザーIPを確実に取得できるために設定ファイルにFastifyOptions.trustProxyを追加しました

View file

@ -1010,7 +1010,6 @@ postForm: "أنشئ ملاحظة"
information: "عن" information: "عن"
inMinutes: "د" inMinutes: "د"
inDays: "ي" inDays: "ي"
widgets: "التطبيقات المُصغّرة"
_chat: _chat:
invitations: "دعوة" invitations: "دعوة"
noHistory: "السجل فارغ" noHistory: "السجل فارغ"

View file

@ -850,7 +850,6 @@ postForm: "নোট লিখুন"
information: "আপনার সম্পর্কে" information: "আপনার সম্পর্কে"
inMinutes: "মিনিট" inMinutes: "মিনিট"
inDays: "দিন" inDays: "দিন"
widgets: "উইজেটগুলি"
_chat: _chat:
invitations: "আমন্ত্রণ" invitations: "আমন্ত্রণ"
noHistory: "কোনো ইতিহাস নেই" noHistory: "কোনো ইতিহাস নেই"

View file

@ -334,7 +334,6 @@ fileName: "Nom del Fitxer"
selectFile: "Selecciona un fitxer" selectFile: "Selecciona un fitxer"
selectFiles: "Selecciona fitxers" selectFiles: "Selecciona fitxers"
selectFolder: "Selecció de carpeta" selectFolder: "Selecció de carpeta"
unselectFolder: "Deixa de seleccionar la carpeta"
selectFolders: "Selecció de carpetes" selectFolders: "Selecció de carpetes"
fileNotSelected: "Cap fitxer seleccionat" fileNotSelected: "Cap fitxer seleccionat"
renameFile: "Canvia el nom del fitxer" renameFile: "Canvia el nom del fitxer"
@ -347,7 +346,6 @@ addFile: "Afegeix un fitxer"
showFile: "Mostrar fitxer" showFile: "Mostrar fitxer"
emptyDrive: "El teu Disc és buit" emptyDrive: "El teu Disc és buit"
emptyFolder: "La carpeta està buida" emptyFolder: "La carpeta està buida"
dropHereToUpload: "Arrossega els arxius fins aquí per pujar-los al servidor"
unableToDelete: "No es pot eliminar" unableToDelete: "No es pot eliminar"
inputNewFileName: "Introduïu el nom de fitxer nou" inputNewFileName: "Introduïu el nom de fitxer nou"
inputNewDescription: "Escriu el peu de foto." inputNewDescription: "Escriu el peu de foto."
@ -1391,9 +1389,6 @@ scheduleToPostOnX: "Programar una nota per {x}"
scheduledToPostOnX: "S'ha programat la nota per {x}" scheduledToPostOnX: "S'ha programat la nota per {x}"
schedule: "Programa" schedule: "Programa"
scheduled: "Programat" scheduled: "Programat"
widgets: "Ginys"
deviceInfo: "Informació del dispositiu"
deviceInfoDescription: "En fer consultes tècniques influir la següent informació pot ajudar a resoldre'l més ràpidament."
_compression: _compression:
_quality: _quality:
high: "Qualitat alta" high: "Qualitat alta"
@ -2018,7 +2013,6 @@ _role:
canManageAvatarDecorations: "Gestiona les decoracions dels avatars " canManageAvatarDecorations: "Gestiona les decoracions dels avatars "
driveCapacity: "Capacitat del disc" driveCapacity: "Capacitat del disc"
maxFileSize: "Mida màxima de l'arxiu que es pot carregar" maxFileSize: "Mida màxima de l'arxiu que es pot carregar"
maxFileSize_caption: "Pot haver-hi la possibilitat que existeixin altres opcions de configuració de l'etapa anterior, com podria ser el proxy invers i la CDN."
alwaysMarkNsfw: "Marca sempre els fitxers com a sensibles" alwaysMarkNsfw: "Marca sempre els fitxers com a sensibles"
canUpdateBioMedia: "Permet l'edició d'una icona o un bàner" canUpdateBioMedia: "Permet l'edició d'una icona o un bàner"
pinMax: "Nombre màxim de notes fixades" pinMax: "Nombre màxim de notes fixades"
@ -2437,7 +2431,6 @@ _auth:
scopeUser: "Opera com si fossis aquest usuari" scopeUser: "Opera com si fossis aquest usuari"
pleaseLogin: "Si us plau, identificat per autoritzar l'aplicació." pleaseLogin: "Si us plau, identificat per autoritzar l'aplicació."
byClickingYouWillBeRedirectedToThisUrl: "Si es garanteix l'accés, seràs redirigit automàticament a la següent adreça URL" byClickingYouWillBeRedirectedToThisUrl: "Si es garanteix l'accés, seràs redirigit automàticament a la següent adreça URL"
alreadyAuthorized: "Aquesta aplicació ja té accés."
_antennaSources: _antennaSources:
all: "Totes les publicacions" all: "Totes les publicacions"
homeTimeline: "Publicacions dels usuaris seguits" homeTimeline: "Publicacions dels usuaris seguits"
@ -2704,8 +2697,6 @@ _notification:
quote: "Citar" quote: "Citar"
reaction: "Reaccions" reaction: "Reaccions"
pollEnded: "Enquesta terminada" pollEnded: "Enquesta terminada"
scheduledNotePosted: "Nota programada amb èxit "
scheduledNotePostFailed: "Ha fallat la programació de la nota"
receiveFollowRequest: "Rebuda una petició de seguiment" receiveFollowRequest: "Rebuda una petició de seguiment"
followRequestAccepted: "Petició de seguiment acceptada" followRequestAccepted: "Petició de seguiment acceptada"
roleAssigned: "Rol donat" roleAssigned: "Rol donat"

View file

@ -1109,7 +1109,6 @@ postForm: "Formulář pro odeslání"
information: "Informace" information: "Informace"
inMinutes: "Minut" inMinutes: "Minut"
inDays: "Dnů" inDays: "Dnů"
widgets: "Widgety"
_chat: _chat:
invitations: "Pozvat" invitations: "Pozvat"
noHistory: "Žádná historie" noHistory: "Žádná historie"

View file

@ -1370,7 +1370,6 @@ defaultImageCompressionLevel: "Standard-Bildkomprimierungsstufe"
defaultImageCompressionLevel_description: "Ein niedrigerer Wert erhält die Bildqualität, erhöht aber die Dateigröße. <br>Höhere Werte reduzieren die Dateigröße, verringern aber die Bildqualität." defaultImageCompressionLevel_description: "Ein niedrigerer Wert erhält die Bildqualität, erhöht aber die Dateigröße. <br>Höhere Werte reduzieren die Dateigröße, verringern aber die Bildqualität."
inMinutes: "Minute(n)" inMinutes: "Minute(n)"
inDays: "Tag(en)" inDays: "Tag(en)"
widgets: "Widgets"
_order: _order:
newest: "Neueste zuerst" newest: "Neueste zuerst"
oldest: "Älteste zuerst" oldest: "Älteste zuerst"

View file

@ -288,7 +288,6 @@ replies: "Απάντηση"
renotes: "Κοινοποίηση σημειώματος" renotes: "Κοινοποίηση σημειώματος"
postForm: "Φόρμα δημοσίευσης" postForm: "Φόρμα δημοσίευσης"
information: "Πληροφορίες" information: "Πληροφορίες"
widgets: "Μαραφέτια"
_chat: _chat:
members: "Μέλη" members: "Μέλη"
home: "Κεντρικό" home: "Κεντρικό"

View file

@ -334,7 +334,6 @@ fileName: "Filename"
selectFile: "Select a file" selectFile: "Select a file"
selectFiles: "Select files" selectFiles: "Select files"
selectFolder: "Select a folder" selectFolder: "Select a folder"
unselectFolder: "Deselect folder"
selectFolders: "Select folders" selectFolders: "Select folders"
fileNotSelected: "No file selected" fileNotSelected: "No file selected"
renameFile: "Rename file" renameFile: "Rename file"
@ -347,7 +346,6 @@ addFile: "Add a file"
showFile: "Show files" showFile: "Show files"
emptyDrive: "Your Drive is empty" emptyDrive: "Your Drive is empty"
emptyFolder: "This folder is empty" emptyFolder: "This folder is empty"
dropHereToUpload: "Drop files here to upload"
unableToDelete: "Unable to delete" unableToDelete: "Unable to delete"
inputNewFileName: "Enter a new filename" inputNewFileName: "Enter a new filename"
inputNewDescription: "Enter new alt text" inputNewDescription: "Enter new alt text"
@ -1391,9 +1389,6 @@ scheduleToPostOnX: "Scheduled to note on {x}"
scheduledToPostOnX: "Note is scheduled for {x}" scheduledToPostOnX: "Note is scheduled for {x}"
schedule: "Schedule" schedule: "Schedule"
scheduled: "Scheduled" scheduled: "Scheduled"
widgets: "Widgets"
deviceInfo: "Device information"
deviceInfoDescription: "When making technical inquiries, including the following information may help resolve the issue."
_compression: _compression:
_quality: _quality:
high: "High quality" high: "High quality"
@ -2018,7 +2013,6 @@ _role:
canManageAvatarDecorations: "Manage avatar decorations" canManageAvatarDecorations: "Manage avatar decorations"
driveCapacity: "Drive capacity" driveCapacity: "Drive capacity"
maxFileSize: "Upload-able max file size" maxFileSize: "Upload-able max file size"
maxFileSize_caption: "Reverse proxies, CDNs, and other front-end components may have their own configuration settings."
alwaysMarkNsfw: "Always mark files as NSFW" alwaysMarkNsfw: "Always mark files as NSFW"
canUpdateBioMedia: "Can edit an icon or a banner image" canUpdateBioMedia: "Can edit an icon or a banner image"
pinMax: "Maximum number of pinned notes" pinMax: "Maximum number of pinned notes"
@ -2437,7 +2431,6 @@ _auth:
scopeUser: "Operate as the following user" scopeUser: "Operate as the following user"
pleaseLogin: "Please log in to authorize applications." pleaseLogin: "Please log in to authorize applications."
byClickingYouWillBeRedirectedToThisUrl: "When access is granted, you will automatically be redirected to the following URL" byClickingYouWillBeRedirectedToThisUrl: "When access is granted, you will automatically be redirected to the following URL"
alreadyAuthorized: "This application already has access permission."
_antennaSources: _antennaSources:
all: "All notes" all: "All notes"
homeTimeline: "Notes from followed users" homeTimeline: "Notes from followed users"
@ -2704,8 +2697,6 @@ _notification:
quote: "Quotes" quote: "Quotes"
reaction: "Reactions" reaction: "Reactions"
pollEnded: "Polls ending" pollEnded: "Polls ending"
scheduledNotePosted: "Scheduled note was successful"
scheduledNotePostFailed: "Scheduled note failed"
receiveFollowRequest: "Received follow requests" receiveFollowRequest: "Received follow requests"
followRequestAccepted: "Accepted follow requests" followRequestAccepted: "Accepted follow requests"
roleAssigned: "Role given" roleAssigned: "Role given"

View file

@ -334,7 +334,6 @@ fileName: "Nombre de archivo"
selectFile: "Elegir archivo" selectFile: "Elegir archivo"
selectFiles: "Elegir archivos" selectFiles: "Elegir archivos"
selectFolder: "Seleccione una carpeta" selectFolder: "Seleccione una carpeta"
unselectFolder: "Deseleccionar carpeta"
selectFolders: "Seleccione carpetas" selectFolders: "Seleccione carpetas"
fileNotSelected: "Archivo no seleccionado." fileNotSelected: "Archivo no seleccionado."
renameFile: "Renombrar archivo" renameFile: "Renombrar archivo"
@ -347,7 +346,6 @@ addFile: "Agregar archivo"
showFile: "Examinar archivos" showFile: "Examinar archivos"
emptyDrive: "El drive está vacío" emptyDrive: "El drive está vacío"
emptyFolder: "La carpeta está vacía" emptyFolder: "La carpeta está vacía"
dropHereToUpload: "Arrastra los archivos aquí para subirlos."
unableToDelete: "No se puede borrar" unableToDelete: "No se puede borrar"
inputNewFileName: "Ingrese un nuevo nombre de archivo" inputNewFileName: "Ingrese un nuevo nombre de archivo"
inputNewDescription: "Ingrese nueva descripción" inputNewDescription: "Ingrese nueva descripción"
@ -1391,9 +1389,6 @@ scheduleToPostOnX: "Programar una nota para {x}"
scheduledToPostOnX: "La nota está programada para {x}." scheduledToPostOnX: "La nota está programada para {x}."
schedule: "Programado" schedule: "Programado"
scheduled: "Programado" scheduled: "Programado"
widgets: "Widgets"
deviceInfo: "Información del dispositivo"
deviceInfoDescription: "Al realizar consultas técnicas, incluir la siguiente información puede ayudar a resolver el problema."
_compression: _compression:
_quality: _quality:
high: "Calidad alta" high: "Calidad alta"
@ -2018,7 +2013,6 @@ _role:
canManageAvatarDecorations: "Administrar decoraciones de avatar" canManageAvatarDecorations: "Administrar decoraciones de avatar"
driveCapacity: "Capacidad del drive" driveCapacity: "Capacidad del drive"
maxFileSize: "Tamaño máximo de archivo que se puede cargar." maxFileSize: "Tamaño máximo de archivo que se puede cargar."
maxFileSize_caption: "Los proxies inversos o las CDN pueden tener diferentes valores de configuración aguas arriba."
alwaysMarkNsfw: "Siempre marcar archivos como NSFW" alwaysMarkNsfw: "Siempre marcar archivos como NSFW"
canUpdateBioMedia: "Puede editar un icono o una imagen de fondo (banner)" canUpdateBioMedia: "Puede editar un icono o una imagen de fondo (banner)"
pinMax: "Máximo de notas fijadas" pinMax: "Máximo de notas fijadas"
@ -2437,7 +2431,6 @@ _auth:
scopeUser: "Operar como el siguiente usuario" scopeUser: "Operar como el siguiente usuario"
pleaseLogin: "Se requiere un inicio de sesión para darle permisos a la aplicación" pleaseLogin: "Se requiere un inicio de sesión para darle permisos a la aplicación"
byClickingYouWillBeRedirectedToThisUrl: "Cuando el acceso es concedido, serás automáticamente redireccionado a la siguiente URL" byClickingYouWillBeRedirectedToThisUrl: "Cuando el acceso es concedido, serás automáticamente redireccionado a la siguiente URL"
alreadyAuthorized: "Esta aplicación ya ha obtenido acceso."
_antennaSources: _antennaSources:
all: "Todas las notas" all: "Todas las notas"
homeTimeline: "Notas de los usuarios que sigues" homeTimeline: "Notas de los usuarios que sigues"
@ -2704,8 +2697,6 @@ _notification:
quote: "Citar" quote: "Citar"
reaction: "Reacción" reaction: "Reacción"
pollEnded: "La encuesta terminó" pollEnded: "La encuesta terminó"
scheduledNotePosted: "Publicación programada con éxito"
scheduledNotePostFailed: "Publicación programada fallida"
receiveFollowRequest: "Recibió una solicitud de seguimiento" receiveFollowRequest: "Recibió una solicitud de seguimiento"
followRequestAccepted: "El seguimiento fue aceptado" followRequestAccepted: "El seguimiento fue aceptado"
roleAssigned: "Rol asignado" roleAssigned: "Rol asignado"

View file

@ -1273,7 +1273,6 @@ postForm: "Formulaire de publication"
information: "Informations" information: "Informations"
inMinutes: "min" inMinutes: "min"
inDays: "j" inDays: "j"
widgets: "Widgets"
_chat: _chat:
invitations: "Inviter" invitations: "Inviter"
noHistory: "Pas d'historique" noHistory: "Pas d'historique"

View file

@ -1264,7 +1264,6 @@ postForm: "Buat catatan"
information: "Informasi" information: "Informasi"
inMinutes: "menit" inMinutes: "menit"
inDays: "hari" inDays: "hari"
widgets: "Widget"
_chat: _chat:
invitations: "Undang" invitations: "Undang"
noHistory: "Tidak ada riwayat" noHistory: "Tidak ada riwayat"

4
locales/index.d.ts vendored
View file

@ -7869,10 +7869,6 @@ export interface Locale extends ILocale {
* *
*/ */
"maxFileSize": string; "maxFileSize": string;
/**
* CDNなど
*/
"maxFileSize_caption": string;
/** /**
* NSFWを常に付与 * NSFWを常に付与
*/ */

View file

@ -334,7 +334,6 @@ fileName: "Nome dell'allegato"
selectFile: "Scelta allegato" selectFile: "Scelta allegato"
selectFiles: "Scelta allegato" selectFiles: "Scelta allegato"
selectFolder: "Seleziona cartella" selectFolder: "Seleziona cartella"
unselectFolder: "Deseleziona la cartella"
selectFolders: "Seleziona cartella" selectFolders: "Seleziona cartella"
fileNotSelected: "Nessun file selezionato" fileNotSelected: "Nessun file selezionato"
renameFile: "Rinomina file" renameFile: "Rinomina file"
@ -347,7 +346,6 @@ addFile: "Allega"
showFile: "Visualizza file" showFile: "Visualizza file"
emptyDrive: "Il Drive è vuoto" emptyDrive: "Il Drive è vuoto"
emptyFolder: "La cartella è vuota" emptyFolder: "La cartella è vuota"
dropHereToUpload: "Trascina qui il tuo file per caricarlo"
unableToDelete: "Eliminazione impossibile" unableToDelete: "Eliminazione impossibile"
inputNewFileName: "Inserisci nome del nuovo file" inputNewFileName: "Inserisci nome del nuovo file"
inputNewDescription: "Inserisci una nuova descrizione" inputNewDescription: "Inserisci una nuova descrizione"
@ -1391,9 +1389,6 @@ scheduleToPostOnX: "Pianificare la pubblicazione {x}"
scheduledToPostOnX: "Pubblicazione pianificata {x}" scheduledToPostOnX: "Pubblicazione pianificata {x}"
schedule: "Pianificare" schedule: "Pianificare"
scheduled: "Pianificata" scheduled: "Pianificata"
widgets: "Riquadri"
deviceInfo: "Informazioni sul dispositivo"
deviceInfoDescription: "Se ci contatti per ricevere supporto tecnico, ti preghiamo di includere le seguenti informazioni per aiutarci a risolvere il tuo problema."
_compression: _compression:
_quality: _quality:
high: "Alta qualità" high: "Alta qualità"
@ -2018,7 +2013,6 @@ _role:
canManageAvatarDecorations: "Gestisce le decorazioni di immagini del profilo" canManageAvatarDecorations: "Gestisce le decorazioni di immagini del profilo"
driveCapacity: "Capienza del Drive" driveCapacity: "Capienza del Drive"
maxFileSize: "Dimensione massima del file caricabile" maxFileSize: "Dimensione massima del file caricabile"
maxFileSize_caption: "Potrebbero esserci altre impostazioni nella fase precedente, come reverse proxy o CDN."
alwaysMarkNsfw: "Impostare sempre come esplicito (NSFW)" alwaysMarkNsfw: "Impostare sempre come esplicito (NSFW)"
canUpdateBioMedia: "Può aggiornare foto profilo e di testata" canUpdateBioMedia: "Può aggiornare foto profilo e di testata"
pinMax: "Quantità massima di Note in primo piano" pinMax: "Quantità massima di Note in primo piano"
@ -2437,7 +2431,6 @@ _auth:
scopeUser: "Sto funzionando per il seguente profilo" scopeUser: "Sto funzionando per il seguente profilo"
pleaseLogin: "Per favore accedi al tuo account per cambiare i permessi dell'applicazione" pleaseLogin: "Per favore accedi al tuo account per cambiare i permessi dell'applicazione"
byClickingYouWillBeRedirectedToThisUrl: "Consentendo l'accesso, si verrà reindirizzati presso questo indirizzo URL" byClickingYouWillBeRedirectedToThisUrl: "Consentendo l'accesso, si verrà reindirizzati presso questo indirizzo URL"
alreadyAuthorized: "Questa applicazione è già autorizzata ad accedere."
_antennaSources: _antennaSources:
all: "Tutte le note" all: "Tutte le note"
homeTimeline: "Note dai tuoi Following" homeTimeline: "Note dai tuoi Following"
@ -2704,8 +2697,6 @@ _notification:
quote: "Cita" quote: "Cita"
reaction: "Reazioni" reaction: "Reazioni"
pollEnded: "Sondaggio terminato" pollEnded: "Sondaggio terminato"
scheduledNotePosted: "Nota pianificata correttamente"
scheduledNotePostFailed: "La pianificazione della Nota è fallita"
receiveFollowRequest: "Richieste di follow in arrivo" receiveFollowRequest: "Richieste di follow in arrivo"
followRequestAccepted: "Richieste di follow accettate" followRequestAccepted: "Richieste di follow accettate"
roleAssigned: "Ruolo concesso" roleAssigned: "Ruolo concesso"

View file

@ -2040,7 +2040,6 @@ _role:
canManageAvatarDecorations: "アバターデコレーションの管理" canManageAvatarDecorations: "アバターデコレーションの管理"
driveCapacity: "ドライブ容量" driveCapacity: "ドライブ容量"
maxFileSize: "アップロード可能な最大ファイルサイズ" maxFileSize: "アップロード可能な最大ファイルサイズ"
maxFileSize_caption: "リバースプロキシやCDNなど、前段で別の設定値が存在する場合があります。"
alwaysMarkNsfw: "ファイルにNSFWを常に付与" alwaysMarkNsfw: "ファイルにNSFWを常に付与"
canUpdateBioMedia: "アイコンとバナーの更新を許可" canUpdateBioMedia: "アイコンとバナーの更新を許可"
pinMax: "ノートのピン留めの最大数" pinMax: "ノートのピン留めの最大数"

View file

@ -1337,7 +1337,6 @@ safeModeEnabled: "セーフモードがオンになってるで"
pluginsAreDisabledBecauseSafeMode: "セーフモードがオンやから、プラグインは全部無効化されてるで。" pluginsAreDisabledBecauseSafeMode: "セーフモードがオンやから、プラグインは全部無効化されてるで。"
customCssIsDisabledBecauseSafeMode: "セーフモードがオンやから、カスタムCSSは適用されてへんで。" customCssIsDisabledBecauseSafeMode: "セーフモードがオンやから、カスタムCSSは適用されてへんで。"
themeIsDefaultBecauseSafeMode: "セーフモードがオンの間はデフォルトのテーマを使うで。セーフモードをオフにれば元に戻るで。" themeIsDefaultBecauseSafeMode: "セーフモードがオンの間はデフォルトのテーマを使うで。セーフモードをオフにれば元に戻るで。"
widgets: "ウィジェット"
_chat: _chat:
noMessagesYet: "まだメッセージはあらへんで" noMessagesYet: "まだメッセージはあらへんで"
individualChat_description: "特定のユーザーと一対一でチャットができるで。" individualChat_description: "特定のユーザーと一対一でチャットができるで。"

View file

@ -334,7 +334,6 @@ fileName: "파일명"
selectFile: "파일 선택" selectFile: "파일 선택"
selectFiles: "파일 선택" selectFiles: "파일 선택"
selectFolder: "폴더 선택" selectFolder: "폴더 선택"
unselectFolder: "폴더 선택 해제"
selectFolders: "폴더 선택" selectFolders: "폴더 선택"
fileNotSelected: "파일을 선택하지 않았습니다" fileNotSelected: "파일을 선택하지 않았습니다"
renameFile: "파일 이름 변경" renameFile: "파일 이름 변경"
@ -347,7 +346,6 @@ addFile: "파일 추가"
showFile: "파일 표시하기" showFile: "파일 표시하기"
emptyDrive: "드라이브가 비어 있습니다" emptyDrive: "드라이브가 비어 있습니다"
emptyFolder: "폴더가 비어 있습니다" emptyFolder: "폴더가 비어 있습니다"
dropHereToUpload: "업로드할 파일을 여기로 드롭하십시오"
unableToDelete: "삭제할 수 없습니다" unableToDelete: "삭제할 수 없습니다"
inputNewFileName: "바꿀 파일명을 입력해 주세요" inputNewFileName: "바꿀 파일명을 입력해 주세요"
inputNewDescription: "새 캡션을 입력해 주세요" inputNewDescription: "새 캡션을 입력해 주세요"
@ -1391,9 +1389,6 @@ scheduleToPostOnX: "{x}에 게시를 예약합니다."
scheduledToPostOnX: "{x}에 게시가 예약돼있습니다." scheduledToPostOnX: "{x}에 게시가 예약돼있습니다."
schedule: "예약" schedule: "예약"
scheduled: "예약" scheduled: "예약"
widgets: "위젯"
deviceInfo: "장치 정보"
deviceInfoDescription: "기술적 문의의 경우 아래의 정보를 병기하면 문제의 해결에 도움이 됩니다."
_compression: _compression:
_quality: _quality:
high: "고품질" high: "고품질"
@ -2018,7 +2013,6 @@ _role:
canManageAvatarDecorations: "아바타 꾸미기 관리" canManageAvatarDecorations: "아바타 꾸미기 관리"
driveCapacity: "드라이브 용량" driveCapacity: "드라이브 용량"
maxFileSize: "업로드 가능한 최대 파일 크기" maxFileSize: "업로드 가능한 최대 파일 크기"
maxFileSize_caption: "리버스 프록시나 CDN 등 전단에서 다른 설정값이 존재하는 경우가 있습니다."
alwaysMarkNsfw: "파일을 항상 NSFW로 지정" alwaysMarkNsfw: "파일을 항상 NSFW로 지정"
canUpdateBioMedia: "아바타 및 배너 이미지 변경 허용" canUpdateBioMedia: "아바타 및 배너 이미지 변경 허용"
pinMax: "고정할 수 있는 노트 수" pinMax: "고정할 수 있는 노트 수"
@ -2437,7 +2431,6 @@ _auth:
scopeUser: "다음 유저로 활동하고 있습니다." scopeUser: "다음 유저로 활동하고 있습니다."
pleaseLogin: "어플리케이션의 접근을 허가하려면 로그인하십시오." pleaseLogin: "어플리케이션의 접근을 허가하려면 로그인하십시오."
byClickingYouWillBeRedirectedToThisUrl: "접근을 허용하면 자동으로 다음 URL로 이동합니다." byClickingYouWillBeRedirectedToThisUrl: "접근을 허용하면 자동으로 다음 URL로 이동합니다."
alreadyAuthorized: "이 애플리케이션은 이미 접근이 허가돼있습니다."
_antennaSources: _antennaSources:
all: "모든 노트" all: "모든 노트"
homeTimeline: "팔로우중인 유저의 노트" homeTimeline: "팔로우중인 유저의 노트"
@ -2704,8 +2697,6 @@ _notification:
quote: "인용" quote: "인용"
reaction: "리액션" reaction: "리액션"
pollEnded: "투표가 종료됨" pollEnded: "투표가 종료됨"
scheduledNotePosted: "예약 게시에 성공했습니다"
scheduledNotePostFailed: "예약 게시에 실패했습니다"
receiveFollowRequest: "팔로우 요청을 받았을 때" receiveFollowRequest: "팔로우 요청을 받았을 때"
followRequestAccepted: "팔로우 요청이 승인되었을 때" followRequestAccepted: "팔로우 요청이 승인되었을 때"
roleAssigned: "역할이 부여됨" roleAssigned: "역할이 부여됨"

View file

@ -1042,7 +1042,6 @@ postForm: "Formularz tworzenia wpisu"
information: "Informacje" information: "Informacje"
inMinutes: "minuta" inMinutes: "minuta"
inDays: "dzień" inDays: "dzień"
widgets: "Widżety"
_chat: _chat:
invitations: "Zaproś" invitations: "Zaproś"
noHistory: "Brak historii" noHistory: "Brak historii"

View file

@ -1389,7 +1389,6 @@ scheduleToPostOnX: "Agendar nota para {x}"
scheduledToPostOnX: "A nota está agendada para {x}" scheduledToPostOnX: "A nota está agendada para {x}"
schedule: "Agendar" schedule: "Agendar"
scheduled: "Agendado" scheduled: "Agendado"
widgets: "Widgets"
_compression: _compression:
_quality: _quality:
high: "Qualidade alta" high: "Qualidade alta"

View file

@ -1277,7 +1277,6 @@ textCount: "Количество символов"
information: "Описание" information: "Описание"
inMinutes: "мин" inMinutes: "мин"
inDays: "сут" inDays: "сут"
widgets: "Виджеты"
_chat: _chat:
invitations: "Пригласить" invitations: "Пригласить"
noHistory: "История пока пуста" noHistory: "История пока пуста"

View file

@ -915,7 +915,6 @@ postForm: "Napísať poznámku"
information: "Informácie" information: "Informácie"
inMinutes: "min" inMinutes: "min"
inDays: "dní" inDays: "dní"
widgets: "Widgety"
_chat: _chat:
invitations: "Pozvať" invitations: "Pozvať"
noHistory: "Žiadna história" noHistory: "Žiadna história"

View file

@ -1389,7 +1389,6 @@ scheduleToPostOnX: "กำหนดเวลาให้โพสต์ไว้
scheduledToPostOnX: "มีการกำหนดเวลาให้โพสต์ไว้ที่ {x}" scheduledToPostOnX: "มีการกำหนดเวลาให้โพสต์ไว้ที่ {x}"
schedule: "กำหนดเวลา" schedule: "กำหนดเวลา"
scheduled: "กำหนดเวลา" scheduled: "กำหนดเวลา"
widgets: "วิดเจ็ต"
_compression: _compression:
_quality: _quality:
high: "คุณภาพสูง" high: "คุณภาพสูง"

View file

@ -1378,7 +1378,6 @@ pluginsAreDisabledBecauseSafeMode: "Güvenli mod etkinleştirildiği için tüm
customCssIsDisabledBecauseSafeMode: "Güvenli mod etkin olduğu için özel CSS uygulanmıyor." customCssIsDisabledBecauseSafeMode: "Güvenli mod etkin olduğu için özel CSS uygulanmıyor."
themeIsDefaultBecauseSafeMode: "Güvenli mod etkinken, varsayılan tema kullanılır. Güvenli modu devre dışı bırakmak bu değişiklikleri geri alır." themeIsDefaultBecauseSafeMode: "Güvenli mod etkinken, varsayılan tema kullanılır. Güvenli modu devre dışı bırakmak bu değişiklikleri geri alır."
thankYouForTestingBeta: "Beta sürümünü test ettiğin için teşekkür ederiz!" thankYouForTestingBeta: "Beta sürümünü test ettiğin için teşekkür ederiz!"
widgets: "Widget'lar"
_order: _order:
newest: "Önce yeni" newest: "Önce yeni"
oldest: "Önce eski" oldest: "Önce eski"

View file

@ -921,7 +921,6 @@ postForm: "Створення нотатки"
information: "Інформація" information: "Інформація"
inMinutes: "х" inMinutes: "х"
inDays: "д" inDays: "д"
widgets: "Віджети"
_chat: _chat:
invitations: "Запросити" invitations: "Запросити"
noHistory: "Історія порожня" noHistory: "Історія порожня"

View file

@ -1222,7 +1222,6 @@ migrateOldSettings: "Di chuyển cài đặt cũ"
migrateOldSettings_description: "Thông thường, quá trình này diễn ra tự động, nhưng nếu vì lý do nào đó mà quá trình di chuyển không thành công, bạn có thể kích hoạt thủ công quy trình di chuyển, quá trình này sẽ ghi đè lên thông tin cấu hình hiện tại của bạn." migrateOldSettings_description: "Thông thường, quá trình này diễn ra tự động, nhưng nếu vì lý do nào đó mà quá trình di chuyển không thành công, bạn có thể kích hoạt thủ công quy trình di chuyển, quá trình này sẽ ghi đè lên thông tin cấu hình hiện tại của bạn."
inMinutes: "phút" inMinutes: "phút"
inDays: "ngày" inDays: "ngày"
widgets: "Tiện ích"
_chat: _chat:
invitations: "Mời" invitations: "Mời"
noHistory: "Không có dữ liệu" noHistory: "Không có dữ liệu"

View file

@ -56,7 +56,7 @@ deleteAndEdit: "删除并编辑"
deleteAndEditConfirm: "要删除此帖并再次编辑吗?对此帖的所有回应、转发和回复也将被删除。" deleteAndEditConfirm: "要删除此帖并再次编辑吗?对此帖的所有回应、转发和回复也将被删除。"
addToList: "添加至列表" addToList: "添加至列表"
addToAntenna: "添加到天线" addToAntenna: "添加到天线"
sendMessage: "发送消息" sendMessage: "发送"
copyRSS: "复制RSS" copyRSS: "复制RSS"
copyUsername: "复制用户名" copyUsername: "复制用户名"
copyUserId: "复制用户 ID" copyUserId: "复制用户 ID"
@ -334,7 +334,6 @@ fileName: "文件名称"
selectFile: "选择文件" selectFile: "选择文件"
selectFiles: "选择文件" selectFiles: "选择文件"
selectFolder: "选择文件夹" selectFolder: "选择文件夹"
unselectFolder: "取消全选文件夹"
selectFolders: "选择多个文件夹" selectFolders: "选择多个文件夹"
fileNotSelected: "未选择文件" fileNotSelected: "未选择文件"
renameFile: "重命名文件" renameFile: "重命名文件"
@ -347,7 +346,6 @@ addFile: "添加文件"
showFile: "显示文件" showFile: "显示文件"
emptyDrive: "网盘中无文件" emptyDrive: "网盘中无文件"
emptyFolder: "此文件夹中无文件" emptyFolder: "此文件夹中无文件"
dropHereToUpload: "将文件拖动到这里来上传"
unableToDelete: "无法删除" unableToDelete: "无法删除"
inputNewFileName: "请输入新文件名" inputNewFileName: "请输入新文件名"
inputNewDescription: "请输入新标题" inputNewDescription: "请输入新标题"
@ -1391,9 +1389,6 @@ scheduleToPostOnX: "预定在 {x} 发出"
scheduledToPostOnX: "已预定在 {x} 发出" scheduledToPostOnX: "已预定在 {x} 发出"
schedule: "定时" schedule: "定时"
scheduled: "定时" scheduled: "定时"
widgets: "小工具"
deviceInfo: "设备信息"
deviceInfoDescription: "咨询技术问题时,将以下信息一并发送有助于解决问题。"
_compression: _compression:
_quality: _quality:
high: "高质量" high: "高质量"
@ -2018,7 +2013,6 @@ _role:
canManageAvatarDecorations: "管理头像挂件" canManageAvatarDecorations: "管理头像挂件"
driveCapacity: "网盘容量" driveCapacity: "网盘容量"
maxFileSize: "可上传的最大文件大小" maxFileSize: "可上传的最大文件大小"
maxFileSize_caption: "可能在反向代理或 CDN 等前端存在其它设定值。"
alwaysMarkNsfw: "总是将文件标记为 NSFW" alwaysMarkNsfw: "总是将文件标记为 NSFW"
canUpdateBioMedia: "可以更新头像和横幅" canUpdateBioMedia: "可以更新头像和横幅"
pinMax: "帖子置顶数量限制" pinMax: "帖子置顶数量限制"
@ -2437,7 +2431,6 @@ _auth:
scopeUser: "以下面的用户进行操作" scopeUser: "以下面的用户进行操作"
pleaseLogin: "在对应用进行授权许可之前,请先登录" pleaseLogin: "在对应用进行授权许可之前,请先登录"
byClickingYouWillBeRedirectedToThisUrl: "允许访问后将会自动重定向到以下 URL" byClickingYouWillBeRedirectedToThisUrl: "允许访问后将会自动重定向到以下 URL"
alreadyAuthorized: "此应用已有访问许可。"
_antennaSources: _antennaSources:
all: "所有帖子" all: "所有帖子"
homeTimeline: "已关注用户的帖子" homeTimeline: "已关注用户的帖子"
@ -2704,8 +2697,6 @@ _notification:
quote: "引用" quote: "引用"
reaction: "回应" reaction: "回应"
pollEnded: "问卷调查结束" pollEnded: "问卷调查结束"
scheduledNotePosted: "定时发送成功"
scheduledNotePostFailed: "定时发送失败"
receiveFollowRequest: "收到关注请求" receiveFollowRequest: "收到关注请求"
followRequestAccepted: "关注请求已通过" followRequestAccepted: "关注请求已通过"
roleAssigned: "授予的角色" roleAssigned: "授予的角色"

View file

@ -334,7 +334,6 @@ fileName: "檔案名稱"
selectFile: "選擇檔案" selectFile: "選擇檔案"
selectFiles: "選擇檔案" selectFiles: "選擇檔案"
selectFolder: "選擇資料夾" selectFolder: "選擇資料夾"
unselectFolder: "取消選擇資料夾"
selectFolders: "選擇資料夾" selectFolders: "選擇資料夾"
fileNotSelected: "尚未選擇檔案" fileNotSelected: "尚未選擇檔案"
renameFile: "重新命名檔案" renameFile: "重新命名檔案"
@ -347,7 +346,6 @@ addFile: "加入附件"
showFile: "瀏覽文件" showFile: "瀏覽文件"
emptyDrive: "雲端硬碟為空" emptyDrive: "雲端硬碟為空"
emptyFolder: "資料夾為空" emptyFolder: "資料夾為空"
dropHereToUpload: "將檔案拖放至此處即可上傳"
unableToDelete: "無法刪除" unableToDelete: "無法刪除"
inputNewFileName: "輸入檔案名稱" inputNewFileName: "輸入檔案名稱"
inputNewDescription: "請輸入新標題 " inputNewDescription: "請輸入新標題 "
@ -1391,9 +1389,6 @@ scheduleToPostOnX: "排定在 {x} 發布"
scheduledToPostOnX: "已排定在 {x} 發布貼文" scheduledToPostOnX: "已排定在 {x} 發布貼文"
schedule: "排定" schedule: "排定"
scheduled: "排定" scheduled: "排定"
widgets: "小工具"
deviceInfo: "硬體資訊"
deviceInfoDescription: "在提出技術性諮詢時,若能同時提供以下資訊,將有助於解決問題。"
_compression: _compression:
_quality: _quality:
high: "高品質" high: "高品質"
@ -2018,7 +2013,6 @@ _role:
canManageAvatarDecorations: "管理頭像裝飾" canManageAvatarDecorations: "管理頭像裝飾"
driveCapacity: "雲端硬碟容量" driveCapacity: "雲端硬碟容量"
maxFileSize: "可上傳的最大檔案大小" maxFileSize: "可上傳的最大檔案大小"
maxFileSize_caption: "前端可能還有其他設定值,例如反向代理或 CDN。"
alwaysMarkNsfw: "總是將檔案標記為NSFW" alwaysMarkNsfw: "總是將檔案標記為NSFW"
canUpdateBioMedia: "允許更新大頭貼和橫幅" canUpdateBioMedia: "允許更新大頭貼和橫幅"
pinMax: "置頂貼文的最大數量" pinMax: "置頂貼文的最大數量"
@ -2437,7 +2431,6 @@ _auth:
scopeUser: "以下列使用者身分操作" scopeUser: "以下列使用者身分操作"
pleaseLogin: "必須登入以提供應用程式的存取權限。" pleaseLogin: "必須登入以提供應用程式的存取權限。"
byClickingYouWillBeRedirectedToThisUrl: "如果授予存取權限,就會自動導向到以下的網址" byClickingYouWillBeRedirectedToThisUrl: "如果授予存取權限,就會自動導向到以下的網址"
alreadyAuthorized: "此應用程式已被授予存取權限。"
_antennaSources: _antennaSources:
all: "全部貼文" all: "全部貼文"
homeTimeline: "來自已追隨使用者的貼文" homeTimeline: "來自已追隨使用者的貼文"
@ -2704,8 +2697,6 @@ _notification:
quote: "引用" quote: "引用"
reaction: "反應" reaction: "反應"
pollEnded: "問卷調查結束" pollEnded: "問卷調查結束"
scheduledNotePosted: "預約發佈成功"
scheduledNotePostFailed: "預約發佈失敗"
receiveFollowRequest: "已收到追隨請求" receiveFollowRequest: "已收到追隨請求"
followRequestAccepted: "追隨請求已接受" followRequestAccepted: "追隨請求已接受"
roleAssigned: "已授予角色" roleAssigned: "已授予角色"

View file

@ -1,6 +1,6 @@
{ {
"name": "misskey", "name": "misskey",
"version": "2025.10.1-alpha.1", "version": "2025.10.0-beta.2",
"codename": "nasubi", "codename": "nasubi",
"repository": { "repository": {
"type": "git", "type": "git",
@ -58,21 +58,21 @@
"execa": "9.6.0", "execa": "9.6.0",
"fast-glob": "3.3.3", "fast-glob": "3.3.3",
"glob": "11.0.3", "glob": "11.0.3",
"ignore-walk": "8.0.0", "ignore-walk": "7.0.0",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"postcss": "8.5.6", "postcss": "8.5.6",
"tar": "7.5.1", "tar": "7.5.1",
"terser": "5.44.0", "terser": "5.44.0",
"typescript": "5.9.3" "typescript": "5.9.2"
}, },
"devDependencies": { "devDependencies": {
"@misskey-dev/eslint-plugin": "2.1.0", "@misskey-dev/eslint-plugin": "2.1.0",
"@types/js-yaml": "4.0.9", "@types/js-yaml": "4.0.9",
"@types/node": "22.18.8", "@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/parser": "8.44.1",
"cross-env": "10.1.0", "cross-env": "7.0.3",
"cypress": "15.3.0", "cypress": "14.5.4",
"eslint": "9.36.0", "eslint": "9.36.0",
"globals": "16.4.0", "globals": "16.4.0",
"ncp": "2.0.0", "ncp": "2.0.0",

View file

@ -39,17 +39,17 @@
}, },
"optionalDependencies": { "optionalDependencies": {
"@swc/core-android-arm64": "1.3.11", "@swc/core-android-arm64": "1.3.11",
"@swc/core-darwin-arm64": "1.13.20", "@swc/core-darwin-arm64": "1.13.19",
"@swc/core-darwin-x64": "1.13.20", "@swc/core-darwin-x64": "1.13.19",
"@swc/core-freebsd-x64": "1.3.11", "@swc/core-freebsd-x64": "1.3.11",
"@swc/core-linux-arm-gnueabihf": "1.13.20", "@swc/core-linux-arm-gnueabihf": "1.13.19",
"@swc/core-linux-arm64-gnu": "1.13.20", "@swc/core-linux-arm64-gnu": "1.13.19",
"@swc/core-linux-arm64-musl": "1.13.20", "@swc/core-linux-arm64-musl": "1.13.19",
"@swc/core-linux-x64-gnu": "1.13.20", "@swc/core-linux-x64-gnu": "1.13.19",
"@swc/core-linux-x64-musl": "1.13.20", "@swc/core-linux-x64-musl": "1.13.19",
"@swc/core-win32-arm64-msvc": "1.13.20", "@swc/core-win32-arm64-msvc": "1.13.19",
"@swc/core-win32-ia32-msvc": "1.13.20", "@swc/core-win32-ia32-msvc": "1.13.19",
"@swc/core-win32-x64-msvc": "1.13.20", "@swc/core-win32-x64-msvc": "1.13.19",
"@tensorflow/tfjs": "4.22.0", "@tensorflow/tfjs": "4.22.0",
"@tensorflow/tfjs-node": "4.22.0", "@tensorflow/tfjs-node": "4.22.0",
"bufferutil": "4.0.9", "bufferutil": "4.0.9",
@ -69,10 +69,10 @@
"utf-8-validate": "6.0.5" "utf-8-validate": "6.0.5"
}, },
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "3.901.0", "@aws-sdk/client-s3": "3.896.0",
"@aws-sdk/lib-storage": "3.901.0", "@aws-sdk/lib-storage": "3.895.0",
"@discordapp/twemoji": "16.0.1", "@discordapp/twemoji": "16.0.1",
"@fastify/accepts": "5.0.3", "@fastify/accepts": "5.0.2",
"@fastify/cookie": "11.0.2", "@fastify/cookie": "11.0.2",
"@fastify/cors": "10.1.0", "@fastify/cors": "10.1.0",
"@fastify/express": "4.0.2", "@fastify/express": "4.0.2",
@ -81,7 +81,7 @@
"@fastify/static": "8.2.0", "@fastify/static": "8.2.0",
"@fastify/view": "10.0.2", "@fastify/view": "10.0.2",
"@misskey-dev/sharp-read-bmp": "1.2.0", "@misskey-dev/sharp-read-bmp": "1.2.0",
"@misskey-dev/summaly": "5.2.4", "@misskey-dev/summaly": "5.2.3",
"@napi-rs/canvas": "0.1.80", "@napi-rs/canvas": "0.1.80",
"@nestjs/common": "11.1.6", "@nestjs/common": "11.1.6",
"@nestjs/core": "11.1.6", "@nestjs/core": "11.1.6",
@ -103,7 +103,7 @@
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"blurhash": "2.0.5", "blurhash": "2.0.5",
"body-parser": "1.20.3", "body-parser": "1.20.3",
"bullmq": "5.59.0", "bullmq": "5.58.8",
"cacheable-lookup": "7.0.0", "cacheable-lookup": "7.0.0",
"cbor": "9.0.2", "cbor": "9.0.2",
"chalk": "5.6.2", "chalk": "5.6.2",
@ -134,7 +134,7 @@
"json5": "2.2.3", "json5": "2.2.3",
"jsonld": "8.3.3", "jsonld": "8.3.3",
"jsrsasign": "11.1.0", "jsrsasign": "11.1.0",
"juice": "11.0.3", "juice": "11.0.1",
"meilisearch": "0.53.0", "meilisearch": "0.53.0",
"mfm-js": "0.25.0", "mfm-js": "0.25.0",
"microformats-parser": "2.0.4", "microformats-parser": "2.0.4",
@ -181,7 +181,7 @@
"tsc-alias": "1.8.16", "tsc-alias": "1.8.16",
"tsconfig-paths": "4.2.0", "tsconfig-paths": "4.2.0",
"typeorm": "0.3.27", "typeorm": "0.3.27",
"typescript": "5.9.3", "typescript": "5.9.2",
"ulid": "2.4.0", "ulid": "2.4.0",
"vary": "1.1.2", "vary": "1.1.2",
"web-push": "3.6.7", "web-push": "3.6.7",
@ -210,8 +210,8 @@
"@types/jsrsasign": "10.5.15", "@types/jsrsasign": "10.5.15",
"@types/mime-types": "2.1.4", "@types/mime-types": "2.1.4",
"@types/ms": "0.7.34", "@types/ms": "0.7.34",
"@types/node": "22.18.8", "@types/node": "22.18.6",
"@types/nodemailer": "6.4.20", "@types/nodemailer": "6.4.19",
"@types/oauth": "0.9.6", "@types/oauth": "0.9.6",
"@types/oauth2orize": "1.11.5", "@types/oauth2orize": "1.11.5",
"@types/oauth2orize-pkce": "0.1.2", "@types/oauth2orize-pkce": "0.1.2",
@ -231,8 +231,8 @@
"@types/vary": "1.1.3", "@types/vary": "1.1.3",
"@types/web-push": "3.6.4", "@types/web-push": "3.6.4",
"@types/ws": "8.18.1", "@types/ws": "8.18.1",
"@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/parser": "8.44.1",
"aws-sdk-client-mock": "4.1.0", "aws-sdk-client-mock": "4.1.0",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"eslint-plugin-import": "2.32.0", "eslint-plugin-import": "2.32.0",

View file

@ -172,14 +172,6 @@ export class NoteDraftService {
me: MiLocalUser, me: MiLocalUser,
data: Partial<NoteDraftOptions>, data: Partial<NoteDraftOptions>,
): Promise<void> { ): Promise<void> {
if (data.isActuallyScheduled) {
if (data.scheduledAt == null) {
throw new IdentifiableError('94a89a43-3591-400a-9c17-dd166e71fdfa', 'scheduledAt is required when isActuallyScheduled is true');
} else if (data.scheduledAt.getTime() < Date.now()) {
throw new IdentifiableError('b34d0c1b-996f-4e34-a428-c636d98df457', 'scheduledAt must be in the future');
}
}
if (data.pollExpiresAt != null) { if (data.pollExpiresAt != null) {
if (data.pollExpiresAt.getTime() < Date.now()) { if (data.pollExpiresAt.getTime() < Date.now()) {
throw new IdentifiableError('04da457d-b083-4055-9082-955525eda5a5', 'Cannot create expired poll'); throw new IdentifiableError('04da457d-b083-4055-9082-955525eda5a5', 'Cannot create expired poll');
@ -328,7 +320,6 @@ export class NoteDraftService {
@bindThis @bindThis
public async clearSchedule(draftId: MiNoteDraft['id']): Promise<void> { public async clearSchedule(draftId: MiNoteDraft['id']): Promise<void> {
// TODO: 線形探索なのをどうにかする
const jobs = await this.queueService.postScheduledNoteQueue.getJobs(['delayed', 'waiting', 'active']); const jobs = await this.queueService.postScheduledNoteQueue.getJobs(['delayed', 'waiting', 'active']);
for (const job of jobs) { for (const job of jobs) {
if (job.data.noteDraftId === draftId) { if (job.data.noteDraftId === draftId) {

View file

@ -109,7 +109,8 @@ export const DEFAULT_POLICIES: RolePolicies = {
canImportUserLists: false, canImportUserLists: false,
chatAvailability: 'available', chatAvailability: 'available',
uploadableFileTypes: [ uploadableFileTypes: [
'text/*', 'text/plain',
'text/csv',
'application/json', 'application/json',
'image/*', 'image/*',
'video/*', 'video/*',

View file

@ -153,14 +153,11 @@ export class MiNoteDraft {
//#endregion //#endregion
// 予約日時
// これがあるだけでは実際に予約されているかどうかはわからない
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
nullable: true, nullable: true,
}) })
public scheduledAt: Date | null; public scheduledAt: Date | null;
// scheduledAtに基づいて実際にスケジュールされているか
@Column('boolean', { @Column('boolean', {
default: false, default: false,
}) })

View file

@ -192,7 +192,7 @@ export const paramDef = {
scheduledAt: { type: 'integer', nullable: true }, scheduledAt: { type: 'integer', nullable: true },
isActuallyScheduled: { type: 'boolean', default: false }, isActuallyScheduled: { type: 'boolean', default: false },
}, },
required: [], required: ['visibility', 'visibleUserIds', 'cw', 'hashtag', 'localOnly', 'reactionAcceptance', 'replyId', 'renoteId', 'channelId', 'text', 'fileIds', 'poll', 'scheduledAt', 'isActuallyScheduled'],
} as const; } as const;
@Injectable() @Injectable()
@ -203,22 +203,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const draft = await this.noteDraftService.create(me, { const draft = await this.noteDraftService.create(me, {
fileIds: ps.fileIds ?? [], fileIds: ps.fileIds,
pollChoices: ps.poll?.choices ?? [], pollChoices: ps.poll?.choices ?? [],
pollMultiple: ps.poll?.multiple ?? false, pollMultiple: ps.poll?.multiple ?? false,
pollExpiresAt: ps.poll?.expiresAt ? new Date(ps.poll.expiresAt) : null, pollExpiresAt: ps.poll?.expiresAt ? new Date(ps.poll.expiresAt) : null,
pollExpiredAfter: ps.poll?.expiredAfter ?? null, pollExpiredAfter: ps.poll?.expiredAfter ?? null,
hasPoll: ps.poll != null, hasPoll: ps.poll != null,
text: ps.text ?? null, text: ps.text,
replyId: ps.replyId ?? null, replyId: ps.replyId,
renoteId: ps.renoteId ?? null, renoteId: ps.renoteId,
cw: ps.cw ?? null, cw: ps.cw,
hashtag: ps.hashtag ?? null, hashtag: ps.hashtag,
localOnly: ps.localOnly, localOnly: ps.localOnly,
reactionAcceptance: ps.reactionAcceptance, reactionAcceptance: ps.reactionAcceptance,
visibility: ps.visibility, visibility: ps.visibility,
visibleUserIds: ps.visibleUserIds ?? [], visibleUserIds: ps.visibleUserIds,
channelId: ps.channelId ?? null, channelId: ps.channelId,
scheduledAt: ps.scheduledAt ? new Date(ps.scheduledAt) : null, scheduledAt: ps.scheduledAt ? new Date(ps.scheduledAt) : null,
isActuallyScheduled: ps.isActuallyScheduled, isActuallyScheduled: ps.isActuallyScheduled,
}).catch((err) => { }).catch((err) => {

View file

@ -11,11 +11,11 @@
}, },
"devDependencies": { "devDependencies": {
"@types/estree": "1.0.8", "@types/estree": "1.0.8",
"@types/node": "22.18.8", "@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/parser": "8.44.1",
"rollup": "4.52.3", "rollup": "4.52.2",
"typescript": "5.9.3" "typescript": "5.9.2"
}, },
"dependencies": { "dependencies": {
"estree-walker": "3.0.3", "estree-walker": "3.0.3",

View file

@ -26,37 +26,37 @@
"mfm-js": "0.25.0", "mfm-js": "0.25.0",
"misskey-js": "workspace:*", "misskey-js": "workspace:*",
"punycode.js": "2.3.1", "punycode.js": "2.3.1",
"rollup": "4.52.3", "rollup": "4.52.2",
"sass": "1.93.2", "sass": "1.93.2",
"shiki": "3.13.0", "shiki": "3.13.0",
"tinycolor2": "1.6.0", "tinycolor2": "1.6.0",
"tsc-alias": "1.8.16", "tsc-alias": "1.8.16",
"tsconfig-paths": "4.2.0", "tsconfig-paths": "4.2.0",
"typescript": "5.9.3", "typescript": "5.9.2",
"uuid": "13.0.0", "uuid": "11.1.0",
"vite": "7.1.7", "vite": "7.1.7",
"vue": "3.5.22" "vue": "3.5.22"
}, },
"devDependencies": { "devDependencies": {
"@misskey-dev/summaly": "5.2.4", "@misskey-dev/summaly": "5.2.3",
"@tabler/icons-webfont": "3.35.0", "@tabler/icons-webfont": "3.35.0",
"@testing-library/vue": "8.1.0", "@testing-library/vue": "8.1.0",
"@types/estree": "1.0.8", "@types/estree": "1.0.8",
"@types/micromatch": "4.0.9", "@types/micromatch": "4.0.9",
"@types/node": "22.18.8", "@types/node": "22.18.6",
"@types/punycode.js": "npm:@types/punycode@2.1.4", "@types/punycode.js": "npm:@types/punycode@2.1.4",
"@types/tinycolor2": "1.4.6", "@types/tinycolor2": "1.4.6",
"@types/ws": "8.18.1", "@types/ws": "8.18.1",
"@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/parser": "8.44.1",
"@vitest/coverage-v8": "3.2.4", "@vitest/coverage-v8": "3.2.4",
"@vue/runtime-core": "3.5.22", "@vue/runtime-core": "3.5.22",
"acorn": "8.15.0", "acorn": "8.15.0",
"cross-env": "10.1.0", "cross-env": "10.0.0",
"eslint-plugin-import": "2.32.0", "eslint-plugin-import": "2.32.0",
"eslint-plugin-vue": "10.5.0", "eslint-plugin-vue": "10.5.0",
"fast-glob": "3.3.3", "fast-glob": "3.3.3",
"happy-dom": "19.0.2", "happy-dom": "18.0.1",
"intersection-observer": "0.12.2", "intersection-observer": "0.12.2",
"micromatch": "4.0.8", "micromatch": "4.0.8",
"msw": "2.11.3", "msw": "2.11.3",
@ -65,8 +65,8 @@
"start-server-and-test": "2.1.2", "start-server-and-test": "2.1.2",
"tsx": "4.20.6", "tsx": "4.20.6",
"vite-plugin-turbosnap": "1.0.3", "vite-plugin-turbosnap": "1.0.3",
"vue-component-type-helpers": "3.1.0", "vue-component-type-helpers": "3.0.8",
"vue-eslint-parser": "10.2.0", "vue-eslint-parser": "10.2.0",
"vue-tsc": "3.1.0" "vue-tsc": "3.0.8"
} }
} }

View file

@ -21,13 +21,13 @@
"lint": "pnpm typecheck && pnpm eslint" "lint": "pnpm typecheck && pnpm eslint"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "22.18.8", "@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/parser": "8.44.1",
"esbuild": "0.25.10", "esbuild": "0.25.10",
"eslint-plugin-vue": "10.5.0", "eslint-plugin-vue": "10.5.0",
"nodemon": "3.1.10", "nodemon": "3.1.10",
"typescript": "5.9.3", "typescript": "5.9.2",
"vue-eslint-parser": "10.2.0" "vue-eslint-parser": "10.2.0"
}, },
"files": [ "files": [

View file

@ -24,7 +24,7 @@
"@rollup/plugin-json": "6.1.0", "@rollup/plugin-json": "6.1.0",
"@rollup/plugin-replace": "6.0.2", "@rollup/plugin-replace": "6.0.2",
"@rollup/pluginutils": "5.3.0", "@rollup/pluginutils": "5.3.0",
"@sentry/vue": "10.17.0", "@sentry/vue": "10.15.0",
"@syuilo/aiscript": "1.1.2", "@syuilo/aiscript": "1.1.2",
"@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0", "@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0",
"@twemoji/parser": "16.0.0", "@twemoji/parser": "16.0.0",
@ -41,7 +41,7 @@
"chartjs-chart-matrix": "3.0.0", "chartjs-chart-matrix": "3.0.0",
"chartjs-plugin-gradient": "0.6.1", "chartjs-plugin-gradient": "0.6.1",
"chartjs-plugin-zoom": "2.2.0", "chartjs-plugin-zoom": "2.2.0",
"chromatic": "13.3.0", "chromatic": "13.2.1",
"compare-versions": "6.1.1", "compare-versions": "6.1.1",
"cropperjs": "2.0.1", "cropperjs": "2.0.1",
"date-fns": "4.1.0", "date-fns": "4.1.0",
@ -57,7 +57,7 @@
"json5": "2.2.3", "json5": "2.2.3",
"magic-string": "0.30.19", "magic-string": "0.30.19",
"matter-js": "0.20.0", "matter-js": "0.20.0",
"mediabunny": "1.21.1", "mediabunny": "1.21.0",
"mfm-js": "0.25.0", "mfm-js": "0.25.0",
"misskey-bubble-game": "workspace:*", "misskey-bubble-game": "workspace:*",
"misskey-js": "workspace:*", "misskey-js": "workspace:*",
@ -66,7 +66,7 @@
"punycode.js": "2.3.1", "punycode.js": "2.3.1",
"qr-code-styling": "1.9.2", "qr-code-styling": "1.9.2",
"qr-scanner": "1.4.2", "qr-scanner": "1.4.2",
"rollup": "4.52.3", "rollup": "4.52.2",
"sanitize-html": "2.17.0", "sanitize-html": "2.17.0",
"sass": "1.93.2", "sass": "1.93.2",
"shiki": "3.13.0", "shiki": "3.13.0",
@ -77,7 +77,7 @@
"tinycolor2": "1.6.0", "tinycolor2": "1.6.0",
"tsc-alias": "1.8.16", "tsc-alias": "1.8.16",
"tsconfig-paths": "4.2.0", "tsconfig-paths": "4.2.0",
"typescript": "5.9.3", "typescript": "5.9.2",
"v-code-diff": "1.13.1", "v-code-diff": "1.13.1",
"vite": "7.1.7", "vite": "7.1.7",
"vue": "3.5.22", "vue": "3.5.22",
@ -85,10 +85,10 @@
"wanakana": "5.3.1" "wanakana": "5.3.1"
}, },
"devDependencies": { "devDependencies": {
"@misskey-dev/summaly": "5.2.4", "@misskey-dev/summaly": "5.2.3",
"@storybook/addon-essentials": "8.6.14", "@storybook/addon-essentials": "8.6.14",
"@storybook/addon-interactions": "8.6.14", "@storybook/addon-interactions": "8.6.14",
"@storybook/addon-links": "9.1.10", "@storybook/addon-links": "9.1.8",
"@storybook/addon-mdx-gfm": "8.6.14", "@storybook/addon-mdx-gfm": "8.6.14",
"@storybook/addon-storysource": "8.6.14", "@storybook/addon-storysource": "8.6.14",
"@storybook/blocks": "8.6.14", "@storybook/blocks": "8.6.14",
@ -96,38 +96,38 @@
"@storybook/core-events": "8.6.14", "@storybook/core-events": "8.6.14",
"@storybook/manager-api": "8.6.14", "@storybook/manager-api": "8.6.14",
"@storybook/preview-api": "8.6.14", "@storybook/preview-api": "8.6.14",
"@storybook/react": "9.1.10", "@storybook/react": "9.1.8",
"@storybook/react-vite": "9.1.10", "@storybook/react-vite": "9.1.8",
"@storybook/test": "8.6.14", "@storybook/test": "8.6.14",
"@storybook/theming": "8.6.14", "@storybook/theming": "8.6.14",
"@storybook/types": "8.6.14", "@storybook/types": "8.6.14",
"@storybook/vue3": "9.1.10", "@storybook/vue3": "9.1.8",
"@storybook/vue3-vite": "9.1.10", "@storybook/vue3-vite": "9.1.8",
"@tabler/icons-webfont": "3.35.0", "@tabler/icons-webfont": "3.35.0",
"@testing-library/vue": "8.1.0", "@testing-library/vue": "8.1.0",
"@types/canvas-confetti": "1.9.0", "@types/canvas-confetti": "1.9.0",
"@types/estree": "1.0.8", "@types/estree": "1.0.8",
"@types/matter-js": "0.20.2", "@types/matter-js": "0.20.2",
"@types/micromatch": "4.0.9", "@types/micromatch": "4.0.9",
"@types/node": "22.18.8", "@types/node": "22.18.6",
"@types/punycode.js": "npm:@types/punycode@2.1.4", "@types/punycode.js": "npm:@types/punycode@2.1.4",
"@types/sanitize-html": "2.16.0", "@types/sanitize-html": "2.16.0",
"@types/seedrandom": "3.0.8", "@types/seedrandom": "3.0.8",
"@types/throttle-debounce": "5.0.2", "@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6", "@types/tinycolor2": "1.4.6",
"@types/ws": "8.18.1", "@types/ws": "8.18.1",
"@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/parser": "8.44.1",
"@vitest/coverage-v8": "3.2.4", "@vitest/coverage-v8": "3.2.4",
"@vue/compiler-core": "3.5.22", "@vue/compiler-core": "3.5.22",
"@vue/runtime-core": "3.5.22", "@vue/runtime-core": "3.5.22",
"acorn": "8.15.0", "acorn": "8.15.0",
"cross-env": "10.1.0", "cross-env": "10.0.0",
"cypress": "15.3.0", "cypress": "14.5.4",
"eslint-plugin-import": "2.32.0", "eslint-plugin-import": "2.32.0",
"eslint-plugin-vue": "10.5.0", "eslint-plugin-vue": "10.5.0",
"fast-glob": "3.3.3", "fast-glob": "3.3.3",
"happy-dom": "19.0.2", "happy-dom": "18.0.1",
"intersection-observer": "0.12.2", "intersection-observer": "0.12.2",
"micromatch": "4.0.8", "micromatch": "4.0.8",
"minimatch": "10.0.3", "minimatch": "10.0.3",
@ -135,18 +135,18 @@
"msw-storybook-addon": "2.0.5", "msw-storybook-addon": "2.0.5",
"nodemon": "3.1.10", "nodemon": "3.1.10",
"prettier": "3.6.2", "prettier": "3.6.2",
"react": "19.2.0", "react": "19.1.1",
"react-dom": "19.2.0", "react-dom": "19.1.1",
"seedrandom": "3.0.5", "seedrandom": "3.0.5",
"start-server-and-test": "2.1.2", "start-server-and-test": "2.1.2",
"storybook": "9.1.10", "storybook": "9.1.8",
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
"tsx": "4.20.6", "tsx": "4.20.6",
"vite-plugin-turbosnap": "1.0.3", "vite-plugin-turbosnap": "1.0.3",
"vitest": "3.2.4", "vitest": "3.2.4",
"vitest-fetch-mock": "0.4.5", "vitest-fetch-mock": "0.4.5",
"vue-component-type-helpers": "3.1.0", "vue-component-type-helpers": "3.0.8",
"vue-eslint-parser": "10.2.0", "vue-eslint-parser": "10.2.0",
"vue-tsc": "3.1.0" "vue-tsc": "3.0.8"
} }
} }

View file

@ -66,7 +66,7 @@ export function createAiScriptEnv(opts: { storageKey: string, token?: string })
}); });
return confirm.canceled ? values.FALSE : values.TRUE; return confirm.canceled ? values.FALSE : values.TRUE;
}), }),
'Mk:toast': values.FN_NATIVE(([text]) => { 'Mk:toast': values.FN_NATIVE(async ([text]) => {
utils.assertString(text); utils.assertString(text);
os.toast(text.value); os.toast(text.value);
return values.NULL; return values.NULL;

View file

@ -326,7 +326,7 @@ watch(q, () => {
for (const index of Object.values(store.s.additionalUnicodeEmojiIndexes)) { for (const index of Object.values(store.s.additionalUnicodeEmojiIndexes)) {
for (const emoji of emojis) { for (const emoji of emojis) {
if (keywords.every(keyword => index[emoji.char]?.some(k => k.includes(keyword)))) { if (keywords.every(keyword => index[emoji.char].some(k => k.includes(keyword)))) {
matches.add(emoji); matches.add(emoji);
if (matches.size >= max) break; if (matches.size >= max) break;
} }
@ -343,7 +343,7 @@ watch(q, () => {
for (const index of Object.values(store.s.additionalUnicodeEmojiIndexes)) { for (const index of Object.values(store.s.additionalUnicodeEmojiIndexes)) {
for (const emoji of emojis) { for (const emoji of emojis) {
if (index[emoji.char]?.some(k => k.startsWith(newQ))) { if (index[emoji.char].some(k => k.startsWith(newQ))) {
matches.add(emoji); matches.add(emoji);
if (matches.size >= max) break; if (matches.size >= max) break;
} }
@ -360,7 +360,7 @@ watch(q, () => {
for (const index of Object.values(store.s.additionalUnicodeEmojiIndexes)) { for (const index of Object.values(store.s.additionalUnicodeEmojiIndexes)) {
for (const emoji of emojis) { for (const emoji of emojis) {
if (index[emoji.char]?.some(k => k.includes(newQ))) { if (index[emoji.char].some(k => k.includes(newQ))) {
matches.add(emoji); matches.add(emoji);
if (matches.size >= max) break; if (matches.size >= max) break;
} }

View file

@ -68,7 +68,7 @@ export type GetMkSelectValueTypesFromDef<T extends MkSelectItem[]> = T[number] e
</script> </script>
<script lang="ts" setup generic="const ITEMS extends MkSelectItem[], MODELT extends OptionValue"> <script lang="ts" setup generic="const ITEMS extends MkSelectItem[], MODELT extends OptionValue">
import { onMounted, nextTick, ref, watch, computed, toRefs, useTemplateRef } from 'vue'; import { onMounted, nextTick, ref, watch, computed, toRefs } from 'vue';
import { useInterval } from '@@/js/use-interval.js'; import { useInterval } from '@@/js/use-interval.js';
import type { MenuItem } from '@/types/menu.js'; import type { MenuItem } from '@/types/menu.js';
import * as os from '@/os.js'; import * as os from '@/os.js';
@ -87,8 +87,8 @@ const props = defineProps<{
type ModelTChecked = MODELT & ( type ModelTChecked = MODELT & (
MODELT extends GetMkSelectValueTypesFromDef<ITEMS> MODELT extends GetMkSelectValueTypesFromDef<ITEMS>
? unknown ? unknown
: 'Error: The type of model does not match the type of items.' : 'Error: The type of model does not match the type of items.'
); );
const model = defineModel<ModelTChecked>({ required: true }); const model = defineModel<ModelTChecked>({ required: true });
@ -97,10 +97,10 @@ const { autofocus } = toRefs(props);
const focused = ref(false); const focused = ref(false);
const opening = ref(false); const opening = ref(false);
const currentValueText = ref<string | null>(null); const currentValueText = ref<string | null>(null);
const inputEl = useTemplateRef('inputEl'); const inputEl = ref<HTMLObjectElement | null>(null);
const prefixEl = useTemplateRef('prefixEl'); const prefixEl = ref<HTMLElement | null>(null);
const suffixEl = useTemplateRef('suffixEl'); const suffixEl = ref<HTMLElement | null>(null);
const container = useTemplateRef('container'); const container = ref<HTMLElement | null>(null);
const height = const height =
props.small ? 33 : props.small ? 33 :
props.large ? 39 : props.large ? 39 :

View file

@ -71,7 +71,7 @@ import {
import * as os from '@/os.js'; import * as os from '@/os.js';
import { createColumn } from '@/components/grid/column.js'; import { createColumn } from '@/components/grid/column.js';
import { createRow, defaultGridRowSetting, resetRow } from '@/components/grid/row.js'; import { createRow, defaultGridRowSetting, resetRow } from '@/components/grid/row.js';
import { makeHotkey } from '@/utility/hotkey.js'; import { handleKeyEvent } from '@/utility/key-event.js';
type RowHolder = { type RowHolder = {
row: GridRow, row: GridRow,
@ -289,143 +289,161 @@ function onKeyDown(ev: KeyboardEvent) {
const max = availableBounds.value; const max = availableBounds.value;
const bounds = rangedBounds.value; const bounds = rangedBounds.value;
makeHotkey({ handleKeyEvent(ev, [
'delete': () => { {
if (rangedRows.value.length > 0) { code: 'Delete', handler: () => {
if (rowSetting.events.delete) { if (rangedRows.value.length > 0) {
rowSetting.events.delete(rangedRows.value); if (rowSetting.events.delete) {
rowSetting.events.delete(rangedRows.value);
}
} else {
const context = createContext();
removeDataFromGrid(context, (cell) => {
emitCellValue(cell, undefined);
});
} }
} else { },
},
{
code: 'KeyC', modifiers: ['Control'], handler: () => {
const context = createContext(); const context = createContext();
removeDataFromGrid(context, (cell) => { copyGridDataToClipboard(data.value, context);
emitCellValue(cell, undefined); },
},
{
code: 'KeyV', modifiers: ['Control'], handler: async () => {
const _cells = cells.value;
const context = createContext();
await pasteToGridFromClipboard(context, (row, col, parsedValue) => {
emitCellValue(_cells[row.index].cells[col.index], parsedValue);
}); });
} },
}, },
'ctrl+c|meta+c': () => { {
const context = createContext(); code: 'ArrowRight', modifiers: ['Control', 'Shift'], handler: () => {
copyGridDataToClipboard(data.value, context); updateSelectionRange({
leftTop: { col: selectedCellAddress.col, row: bounds.leftTop.row },
rightBottom: { col: max.rightBottom.col, row: bounds.rightBottom.row },
});
},
}, },
'ctrl+v|meta+v': async () => { {
const _cells = cells.value; code: 'ArrowLeft', modifiers: ['Control', 'Shift'], handler: () => {
const context = createContext(); updateSelectionRange({
await pasteToGridFromClipboard(context, (row, col, parsedValue) => { leftTop: { col: max.leftTop.col, row: bounds.leftTop.row },
emitCellValue(_cells[row.index].cells[col.index], parsedValue); rightBottom: { col: selectedCellAddress.col, row: bounds.rightBottom.row },
}); });
},
}, },
'ctrl+shift+right|meta+shift+right': () => { {
updateSelectionRange({ code: 'ArrowUp', modifiers: ['Control', 'Shift'], handler: () => {
leftTop: { col: selectedCellAddress.col, row: bounds.leftTop.row }, updateSelectionRange({
rightBottom: { col: max.rightBottom.col, row: bounds.rightBottom.row }, leftTop: { col: bounds.leftTop.col, row: max.leftTop.row },
}); rightBottom: { col: bounds.rightBottom.col, row: selectedCellAddress.row },
});
},
}, },
'ctrl+shift+left|meta+shift+left': () => { {
updateSelectionRange({ code: 'ArrowDown', modifiers: ['Control', 'Shift'], handler: () => {
leftTop: { col: max.leftTop.col, row: bounds.leftTop.row }, updateSelectionRange({
rightBottom: { col: selectedCellAddress.col, row: bounds.rightBottom.row }, leftTop: { col: bounds.leftTop.col, row: selectedCellAddress.row },
}); rightBottom: { col: bounds.rightBottom.col, row: max.rightBottom.row },
});
},
}, },
'ctrl+shift+up|meta+shift+up': () => { {
updateSelectionRange({ code: 'ArrowRight', modifiers: ['Shift'], handler: () => {
leftTop: { col: bounds.leftTop.col, row: max.leftTop.row }, updateSelectionRange({
rightBottom: { col: bounds.rightBottom.col, row: selectedCellAddress.row }, leftTop: {
}); col: bounds.leftTop.col < selectedCellAddress.col
? bounds.leftTop.col + 1
: selectedCellAddress.col,
row: bounds.leftTop.row,
},
rightBottom: {
col: (bounds.rightBottom.col > selectedCellAddress.col || bounds.leftTop.col === selectedCellAddress.col)
? bounds.rightBottom.col + 1
: selectedCellAddress.col,
row: bounds.rightBottom.row,
},
});
},
}, },
'ctrl+shift+down|meta+shift+down': () => { {
updateSelectionRange({ code: 'ArrowLeft', modifiers: ['Shift'], handler: () => {
leftTop: { col: bounds.leftTop.col, row: selectedCellAddress.row }, updateSelectionRange({
rightBottom: { col: bounds.rightBottom.col, row: max.rightBottom.row }, leftTop: {
}); col: (bounds.leftTop.col < selectedCellAddress.col || bounds.rightBottom.col === selectedCellAddress.col)
? bounds.leftTop.col - 1
: selectedCellAddress.col,
row: bounds.leftTop.row,
},
rightBottom: {
col: bounds.rightBottom.col > selectedCellAddress.col
? bounds.rightBottom.col - 1
: selectedCellAddress.col,
row: bounds.rightBottom.row,
},
});
},
}, },
'ctrl+right|meta+right': () => { {
selectionCell({ col: max.rightBottom.col, row: selectedCellAddress.row }); code: 'ArrowUp', modifiers: ['Shift'], handler: () => {
updateSelectionRange({
leftTop: {
col: bounds.leftTop.col,
row: (bounds.leftTop.row < selectedCellAddress.row || bounds.rightBottom.row === selectedCellAddress.row)
? bounds.leftTop.row - 1
: selectedCellAddress.row,
},
rightBottom: {
col: bounds.rightBottom.col,
row: bounds.rightBottom.row > selectedCellAddress.row
? bounds.rightBottom.row - 1
: selectedCellAddress.row,
},
});
},
}, },
'ctrl+left|meta+left': () => { {
selectionCell({ col: max.leftTop.col, row: selectedCellAddress.row }); code: 'ArrowDown', modifiers: ['Shift'], handler: () => {
updateSelectionRange({
leftTop: {
col: bounds.leftTop.col,
row: bounds.leftTop.row < selectedCellAddress.row
? bounds.leftTop.row + 1
: selectedCellAddress.row,
},
rightBottom: {
col: bounds.rightBottom.col,
row: (bounds.rightBottom.row > selectedCellAddress.row || bounds.leftTop.row === selectedCellAddress.row)
? bounds.rightBottom.row + 1
: selectedCellAddress.row,
},
});
},
}, },
'ctrl+up|meta+up': () => { {
selectionCell({ col: selectedCellAddress.col, row: max.leftTop.row }); code: 'ArrowDown', handler: () => {
selectionCell({ col: selectedCellAddress.col, row: selectedCellAddress.row + 1 });
},
}, },
'ctrl+down|meta+down': () => { {
selectionCell({ col: selectedCellAddress.col, row: max.rightBottom.row }); code: 'ArrowUp', handler: () => {
selectionCell({ col: selectedCellAddress.col, row: selectedCellAddress.row - 1 });
},
}, },
'shift+right': () => { {
updateSelectionRange({ code: 'ArrowRight', handler: () => {
leftTop: { selectionCell({ col: selectedCellAddress.col + 1, row: selectedCellAddress.row });
col: bounds.leftTop.col < selectedCellAddress.col },
? bounds.leftTop.col + 1
: selectedCellAddress.col,
row: bounds.leftTop.row,
},
rightBottom: {
col: (bounds.rightBottom.col > selectedCellAddress.col || bounds.leftTop.col === selectedCellAddress.col)
? bounds.rightBottom.col + 1
: selectedCellAddress.col,
row: bounds.rightBottom.row,
},
});
}, },
'shift+left': () => { {
updateSelectionRange({ code: 'ArrowLeft', handler: () => {
leftTop: { selectionCell({ col: selectedCellAddress.col - 1, row: selectedCellAddress.row });
col: (bounds.leftTop.col < selectedCellAddress.col || bounds.rightBottom.col === selectedCellAddress.col) },
? bounds.leftTop.col - 1
: selectedCellAddress.col,
row: bounds.leftTop.row,
},
rightBottom: {
col: bounds.rightBottom.col > selectedCellAddress.col
? bounds.rightBottom.col - 1
: selectedCellAddress.col,
row: bounds.rightBottom.row,
},
});
}, },
'shift+up': () => { ]);
updateSelectionRange({
leftTop: {
col: bounds.leftTop.col,
row: (bounds.leftTop.row < selectedCellAddress.row || bounds.rightBottom.row === selectedCellAddress.row)
? bounds.leftTop.row - 1
: selectedCellAddress.row,
},
rightBottom: {
col: bounds.rightBottom.col,
row: bounds.rightBottom.row > selectedCellAddress.row
? bounds.rightBottom.row - 1
: selectedCellAddress.row,
},
});
},
'shift+down': () => {
updateSelectionRange({
leftTop: {
col: bounds.leftTop.col,
row: bounds.leftTop.row < selectedCellAddress.row
? bounds.leftTop.row + 1
: selectedCellAddress.row,
},
rightBottom: {
col: bounds.rightBottom.col,
row: (bounds.rightBottom.row > selectedCellAddress.row || bounds.leftTop.row === selectedCellAddress.row)
? bounds.rightBottom.row + 1
: selectedCellAddress.row,
},
});
},
'down': () => {
selectionCell({ col: selectedCellAddress.col, row: selectedCellAddress.row + 1 });
},
'up': () => {
selectionCell({ col: selectedCellAddress.col, row: selectedCellAddress.row - 1 });
},
'right': () => {
selectionCell({ col: selectedCellAddress.col + 1, row: selectedCellAddress.row });
},
'left': () => {
selectionCell({ col: selectedCellAddress.col - 1, row: selectedCellAddress.row });
},
}, [])(ev);
break; break;
} }

View file

@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</MkFoldableSection> </MkFoldableSection>
<MkFoldableSection v-for="category in customEmojiCategories" v-once :key="category ?? '___root___'" :expanded="false"> <MkFoldableSection v-for="category in customEmojiCategories" v-once :key="category ?? '___root___'">
<template #header>{{ category || i18n.ts.other }}</template> <template #header>{{ category || i18n.ts.other }}</template>
<div :class="$style.emojis"> <div :class="$style.emojis">
<XEmoji v-for="emoji in customEmojis.filter(e => e.category === category)" :key="emoji.name" :emoji="emoji"/> <XEmoji v-for="emoji in customEmojis.filter(e => e.category === category)" :key="emoji.name" :emoji="emoji"/>

View file

@ -503,7 +503,7 @@ function refreshGridItems() {
name: it.name, name: it.name,
host: it.host ?? '', host: it.host ?? '',
category: it.category ?? '', category: it.category ?? '',
aliases: it.aliases.join(' '), aliases: it.aliases.join(','),
license: it.license ?? '', license: it.license ?? '',
isSensitive: it.isSensitive, isSensitive: it.isSensitive,
localOnly: it.localOnly, localOnly: it.localOnly,

View file

@ -420,9 +420,6 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSwitch> </MkSwitch>
<MkInput v-model="role.policies.maxFileSizeMb.value" :disabled="role.policies.maxFileSizeMb.useDefault" type="number" :readonly="readonly"> <MkInput v-model="role.policies.maxFileSizeMb.value" :disabled="role.policies.maxFileSizeMb.useDefault" type="number" :readonly="readonly">
<template #suffix>MB</template> <template #suffix>MB</template>
<template #caption>
<div><i class="ti ti-alert-triangle" style="color: var(--MI_THEME-warn);"></i> {{ i18n.ts._role._options.maxFileSize_caption }}</div>
</template>
</MkInput> </MkInput>
<MkRange v-model="role.policies.maxFileSizeMb.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''"> <MkRange v-model="role.policies.maxFileSizeMb.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
<template #label>{{ i18n.ts._role.priority }}</template> <template #label>{{ i18n.ts._role.priority }}</template>

View file

@ -155,9 +155,6 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #suffix>{{ policies.maxFileSizeMb }}MB</template> <template #suffix>{{ policies.maxFileSizeMb }}MB</template>
<MkInput v-model="policies.maxFileSizeMb" type="number"> <MkInput v-model="policies.maxFileSizeMb" type="number">
<template #suffix>MB</template> <template #suffix>MB</template>
<template #caption>
<div><i class="ti ti-alert-triangle" style="color: var(--MI_THEME-warn);"></i> {{ i18n.ts._role._options.maxFileSize_caption }}</div>
</template>
</MkInput> </MkInput>
</MkFolder> </MkFolder>

View file

@ -159,7 +159,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { defineAsyncComponent, computed, onMounted, onUnmounted, onActivated, onDeactivated, nextTick, watch, ref, useTemplateRef } from 'vue'; import { defineAsyncComponent, computed, onMounted, onUnmounted, onActivated, onDeactivated, nextTick, watch, ref } from 'vue';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { getScrollContainer } from '@@/js/scroll.js'; import { getScrollContainer } from '@@/js/scroll.js';
import MkNote from '@/components/MkNote.vue'; import MkNote from '@/components/MkNote.vue';
@ -222,9 +222,9 @@ const router = useRouter();
const user = ref(props.user); const user = ref(props.user);
const narrow = ref<null | boolean>(null); const narrow = ref<null | boolean>(null);
const rootEl = useTemplateRef('rootEl'); const rootEl = ref<null | HTMLElement>(null);
const bannerEl = useTemplateRef('bannerEl'); const bannerEl = ref<null | HTMLElement>(null);
const memoTextareaEl = useTemplateRef('memoTextareaEl'); const memoTextareaEl = ref<null | HTMLElement>(null);
const memoDraft = ref(props.user.memo); const memoDraft = ref(props.user.memo);
const isEditingMemo = ref(false); const isEditingMemo = ref(false);
const moderationNote = ref(props.user.moderationNote ?? ''); const moderationNote = ref(props.user.moderationNote ?? '');
@ -372,6 +372,9 @@ onDeactivated(disposeBannerParallaxResizeObserver);
overflow: clip; overflow: clip;
background-size: cover; background-size: cover;
background-position: center; background-position: center;
view-timeline-name: --bannerParallax;
view-timeline-inset: var(--bannerParallaxInset, auto);
view-timeline-axis: block;
> .banner { > .banner {
position: absolute; position: absolute;
@ -379,12 +382,13 @@ onDeactivated(disposeBannerParallaxResizeObserver);
left: 0; left: 0;
width: 100%; width: 100%;
height: 300%; height: 300%;
background-size: 100% auto;
background-color: #4c5e6d; background-color: #4c5e6d;
background-repeat: repeat-y; background-repeat: repeat-y;
background-position: center; background-position: center;
will-change: transform; will-change: transform;
transform: translateY(-50%); animation: bannerParallaxKeyframes linear both;
animation-timeline: --bannerParallax;
animation-range: cover;
} }
> .fade { > .fade {
@ -741,26 +745,6 @@ onDeactivated(disposeBannerParallaxResizeObserver);
} }
} }
@supports (view-timeline-name: --name) {
.ftskorzw {
> .main {
> .profile > .main {
> .banner-container {
view-timeline-name: --bannerParallax;
view-timeline-inset: var(--bannerParallaxInset, auto);
view-timeline-axis: block;
> .banner {
animation: bannerParallaxKeyframes linear both;
animation-timeline: --bannerParallax;
animation-range: cover;
}
}
}
}
}
}
@keyframes bannerParallaxKeyframes { @keyframes bannerParallaxKeyframes {
from { from {
transform: translateY(-50%); transform: translateY(-50%);

View file

@ -50,12 +50,12 @@ let latestHotkey: Pattern & { callback: CallbackFunction } | null = null;
//#endregion //#endregion
//#region impl //#region impl
export const makeHotkey = (keymap: Keymap, ignoreElements = IGNORE_ELEMENTS) => { export const makeHotkey = (keymap: Keymap) => {
const actions = parseKeymap(keymap); const actions = parseKeymap(keymap);
return (ev: KeyboardEvent) => { return (ev: KeyboardEvent) => {
if ('pswp' in window && window.pswp != null) return; if ('pswp' in window && window.pswp != null) return;
if (window.document.activeElement != null) { if (window.document.activeElement != null) {
if (ignoreElements.includes(window.document.activeElement.tagName.toLowerCase())) return; if (IGNORE_ELEMENTS.includes(window.document.activeElement.tagName.toLowerCase())) return;
if (getHTMLElementOrNull(window.document.activeElement)?.isContentEditable) return; if (getHTMLElementOrNull(window.document.activeElement)?.isContentEditable) return;
} }
for (const action of actions) { for (const action of actions) {

View file

@ -0,0 +1,153 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/**
* {@link KeyboardEvent.code}
* @see https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_code_values
*/
export type KeyCode = (
| 'Backspace'
| 'Tab'
| 'Enter'
| 'Shift'
| 'Control'
| 'Alt'
| 'Pause'
| 'CapsLock'
| 'Escape'
| 'Space'
| 'PageUp'
| 'PageDown'
| 'End'
| 'Home'
| 'ArrowLeft'
| 'ArrowUp'
| 'ArrowRight'
| 'ArrowDown'
| 'Insert'
| 'Delete'
| 'Digit0'
| 'Digit1'
| 'Digit2'
| 'Digit3'
| 'Digit4'
| 'Digit5'
| 'Digit6'
| 'Digit7'
| 'Digit8'
| 'Digit9'
| 'KeyA'
| 'KeyB'
| 'KeyC'
| 'KeyD'
| 'KeyE'
| 'KeyF'
| 'KeyG'
| 'KeyH'
| 'KeyI'
| 'KeyJ'
| 'KeyK'
| 'KeyL'
| 'KeyM'
| 'KeyN'
| 'KeyO'
| 'KeyP'
| 'KeyQ'
| 'KeyR'
| 'KeyS'
| 'KeyT'
| 'KeyU'
| 'KeyV'
| 'KeyW'
| 'KeyX'
| 'KeyY'
| 'KeyZ'
| 'MetaLeft'
| 'MetaRight'
| 'ContextMenu'
| 'F1'
| 'F2'
| 'F3'
| 'F4'
| 'F5'
| 'F6'
| 'F7'
| 'F8'
| 'F9'
| 'F10'
| 'F11'
| 'F12'
| 'NumLock'
| 'ScrollLock'
| 'Semicolon'
| 'Equal'
| 'Comma'
| 'Minus'
| 'Period'
| 'Slash'
| 'Backquote'
| 'BracketLeft'
| 'Backslash'
| 'BracketRight'
| 'Quote'
| 'Meta'
| 'AltGraph'
);
/**
*
*/
export type KeyModifier = (
| 'Shift'
| 'Control'
| 'Alt'
| 'Meta'
);
/**
*
*/
export type KeyState = (
| 'composing'
| 'repeat'
);
export type KeyEventHandler = {
modifiers?: KeyModifier[];
states?: KeyState[];
code: KeyCode | 'any';
handler: (event: KeyboardEvent) => void;
};
export function handleKeyEvent(event: KeyboardEvent, handlers: KeyEventHandler[]) {
function checkModifier(ev: KeyboardEvent, modifiers? : KeyModifier[]) {
if (modifiers) {
return modifiers.every(modifier => ev.getModifierState(modifier));
}
return true;
}
function checkState(ev: KeyboardEvent, states?: KeyState[]) {
if (states) {
return states.every(state => ev.getModifierState(state));
}
return true;
}
let hit = false;
for (const handler of handlers.filter(it => it.code === event.code)) {
if (checkModifier(event, handler.modifiers) && checkState(event, handler.states)) {
handler.handler(event);
hit = true;
break;
}
}
if (!hit) {
for (const handler of handlers.filter(it => it.code === 'any')) {
handler.handler(event);
}
}
}

View file

@ -11,17 +11,17 @@
"lint": "pnpm typecheck && pnpm eslint" "lint": "pnpm typecheck && pnpm eslint"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "22.18.8", "@types/node": "22.18.6",
"@types/wawoff2": "1.0.2", "@types/wawoff2": "1.0.2",
"@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.45.0" "@typescript-eslint/parser": "8.44.1"
}, },
"dependencies": { "dependencies": {
"@tabler/icons-webfont": "3.35.0", "@tabler/icons-webfont": "3.35.0",
"harfbuzzjs": "0.4.13", "harfbuzzjs": "0.4.12",
"tiny-glob": "0.2.9", "tiny-glob": "0.2.9",
"tsx": "4.20.6", "tsx": "4.20.6",
"typescript": "5.9.3", "typescript": "5.9.2",
"wawoff2": "2.0.1" "wawoff2": "2.0.1"
}, },
"files": [ "files": [

View file

@ -23,15 +23,15 @@
}, },
"devDependencies": { "devDependencies": {
"@types/matter-js": "0.20.2", "@types/matter-js": "0.20.2",
"@types/node": "22.18.8",
"@types/seedrandom": "3.0.8", "@types/seedrandom": "3.0.8",
"@typescript-eslint/eslint-plugin": "8.45.0", "@types/node": "22.18.6",
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"esbuild": "0.25.10", "@typescript-eslint/parser": "8.44.1",
"execa": "9.6.0",
"glob": "11.0.3",
"nodemon": "3.1.10", "nodemon": "3.1.10",
"typescript": "5.9.3" "execa": "9.6.0",
"typescript": "5.9.2",
"esbuild": "0.25.10",
"glob": "11.0.3"
}, },
"files": [ "files": [
"built" "built"

View file

@ -8,14 +8,14 @@
}, },
"devDependencies": { "devDependencies": {
"@readme/openapi-parser": "5.0.1", "@readme/openapi-parser": "5.0.1",
"@types/node": "22.18.8", "@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/parser": "8.44.1",
"openapi-types": "12.1.3", "openapi-types": "12.1.3",
"openapi-typescript": "7.9.1", "openapi-typescript": "7.9.1",
"ts-case-convert": "2.1.0", "ts-case-convert": "2.1.0",
"tsx": "4.20.6", "tsx": "4.20.6",
"typescript": "5.9.3" "typescript": "5.9.2"
}, },
"files": [ "files": [
"built" "built"

View file

@ -1,7 +1,7 @@
{ {
"type": "module", "type": "module",
"name": "misskey-js", "name": "misskey-js",
"version": "2025.10.1-alpha.1", "version": "2025.10.0-beta.2",
"description": "Misskey SDK for JavaScript", "description": "Misskey SDK for JavaScript",
"license": "MIT", "license": "MIT",
"main": "./built/index.js", "main": "./built/index.js",
@ -35,10 +35,10 @@
"directory": "packages/misskey-js" "directory": "packages/misskey-js"
}, },
"devDependencies": { "devDependencies": {
"@microsoft/api-extractor": "7.52.15", "@microsoft/api-extractor": "7.52.13",
"@types/node": "22.18.8", "@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/parser": "8.44.1",
"@vitest/coverage-v8": "3.2.4", "@vitest/coverage-v8": "3.2.4",
"esbuild": "0.25.10", "esbuild": "0.25.10",
"execa": "9.6.0", "execa": "9.6.0",
@ -46,7 +46,7 @@
"ncp": "2.0.0", "ncp": "2.0.0",
"nodemon": "3.1.10", "nodemon": "3.1.10",
"tsd": "0.33.0", "tsd": "0.33.0",
"typescript": "5.9.3", "typescript": "5.9.2",
"vitest": "3.2.4", "vitest": "3.2.4",
"vitest-websocket-mock": "0.5.0" "vitest-websocket-mock": "0.5.0"
}, },

View file

@ -29205,34 +29205,34 @@ export interface operations {
* @default public * @default public
* @enum {string} * @enum {string}
*/ */
visibility?: 'public' | 'home' | 'followers' | 'specified'; visibility: 'public' | 'home' | 'followers' | 'specified';
visibleUserIds?: string[]; visibleUserIds: string[];
cw?: string | null; cw: string | null;
hashtag?: string | null; hashtag: string | null;
/** @default false */ /** @default false */
localOnly?: boolean; localOnly: boolean;
/** /**
* @default null * @default null
* @enum {string|null} * @enum {string|null}
*/ */
reactionAcceptance?: null | 'likeOnly' | 'likeOnlyForRemote' | 'nonSensitiveOnly' | 'nonSensitiveOnlyForLocalLikeOnlyForRemote'; reactionAcceptance: null | 'likeOnly' | 'likeOnlyForRemote' | 'nonSensitiveOnly' | 'nonSensitiveOnlyForLocalLikeOnlyForRemote';
/** Format: misskey:id */ /** Format: misskey:id */
replyId?: string | null; replyId: string | null;
/** Format: misskey:id */ /** Format: misskey:id */
renoteId?: string | null; renoteId: string | null;
/** Format: misskey:id */ /** Format: misskey:id */
channelId?: string | null; channelId: string | null;
text?: string | null; text: string | null;
fileIds?: string[]; fileIds: string[];
poll?: { poll: {
choices: string[]; choices: string[];
multiple?: boolean; multiple?: boolean;
expiresAt?: number | null; expiresAt?: number | null;
expiredAfter?: number | null; expiredAfter?: number | null;
} | null; } | null;
scheduledAt?: number | null; scheduledAt: number | null;
/** @default false */ /** @default false */
isActuallyScheduled?: boolean; isActuallyScheduled: boolean;
}; };
}; };
}; };

View file

@ -22,14 +22,14 @@
"lint": "pnpm typecheck && pnpm eslint" "lint": "pnpm typecheck && pnpm eslint"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "22.18.8", "@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/parser": "8.44.1",
"esbuild": "0.25.10",
"execa": "9.6.0", "execa": "9.6.0",
"glob": "11.0.3",
"nodemon": "3.1.10", "nodemon": "3.1.10",
"typescript": "5.9.3" "typescript": "5.9.2",
"esbuild": "0.25.10",
"glob": "11.0.3"
}, },
"files": [ "files": [
"built" "built"

View file

@ -14,11 +14,11 @@
"misskey-js": "workspace:*" "misskey-js": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"@typescript-eslint/parser": "8.45.0", "@typescript-eslint/parser": "8.44.1",
"@typescript/lib-webworker": "npm:@types/serviceworker@0.0.74", "@typescript/lib-webworker": "npm:@types/serviceworker@0.0.74",
"eslint-plugin-import": "2.32.0", "eslint-plugin-import": "2.32.0",
"nodemon": "3.1.10", "nodemon": "3.1.10",
"typescript": "5.9.3" "typescript": "5.9.2"
}, },
"type": "module" "type": "module"
} }

5189
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -23,8 +23,7 @@
'nsfwjs', 'nsfwjs',
// https://github.com/misskey-dev/misskey/issues/15920 // https://github.com/misskey-dev/misskey/issues/15920
'sharp', 'sharp',
'@misskey-dev/sharp-read-bmp', '@misskey-dev/sharp-read-bmp'
'@syuilo/aiscript-0-19-0',
], ],
packageRules: [ packageRules: [
{ {

View file

@ -9,12 +9,12 @@
"version": "1.0.0", "version": "1.0.0",
"devDependencies": { "devDependencies": {
"@types/mdast": "4.0.4", "@types/mdast": "4.0.4",
"@types/node": "22.18.8", "@types/node": "22.17.1",
"@vitest/coverage-v8": "3.2.4", "@vitest/coverage-v8": "3.2.4",
"mdast-util-to-string": "4.0.0", "mdast-util-to-string": "4.0.0",
"remark": "15.0.1", "remark": "15.0.1",
"remark-parse": "11.0.0", "remark-parse": "11.0.0",
"typescript": "5.9.3", "typescript": "5.9.2",
"unified": "11.0.5", "unified": "11.0.5",
"vite": "6.3.6", "vite": "6.3.6",
"vite-node": "3.2.4", "vite-node": "3.2.4",
@ -940,12 +940,11 @@
"dev": true "dev": true
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.18.8", "version": "22.17.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.8.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.1.tgz",
"integrity": "sha512-pAZSHMiagDR7cARo/cch1f3rXy0AEXwsVsVH09FcyeJVAzCnGgmYis7P3JidtTUjyadhTeSo8TgRPswstghDaw==", "integrity": "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"undici-types": "~6.21.0" "undici-types": "~6.21.0"
} }
@ -2298,7 +2297,6 @@
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=12" "node": ">=12"
}, },
@ -2714,9 +2712,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.9.3", "version": "5.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
@ -2844,7 +2842,6 @@
"integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==", "integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"esbuild": "^0.25.0", "esbuild": "^0.25.0",
"fdir": "^6.4.4", "fdir": "^6.4.4",
@ -2943,7 +2940,6 @@
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/chai": "^5.2.2", "@types/chai": "^5.2.2",
"@vitest/expect": "3.2.4", "@vitest/expect": "3.2.4",

View file

@ -10,12 +10,12 @@
}, },
"devDependencies": { "devDependencies": {
"@types/mdast": "4.0.4", "@types/mdast": "4.0.4",
"@types/node": "22.18.8", "@types/node": "22.17.1",
"@vitest/coverage-v8": "3.2.4", "@vitest/coverage-v8": "3.2.4",
"mdast-util-to-string": "4.0.0", "mdast-util-to-string": "4.0.0",
"remark": "15.0.1", "remark": "15.0.1",
"remark-parse": "11.0.0", "remark-parse": "11.0.0",
"typescript": "5.9.3", "typescript": "5.9.2",
"unified": "11.0.5", "unified": "11.0.5",
"vite": "6.3.6", "vite": "6.3.6",
"vite-node": "3.2.4", "vite-node": "3.2.4",