Merge branch 'develop' into feat/note-edit-history

This commit is contained in:
naskya 2024-03-28 14:27:29 +09:00
commit 293afc7fe4
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C
115 changed files with 1069 additions and 951 deletions

View file

@ -2,6 +2,8 @@
## Checklist ## Checklist
- [ ] There are no pending changes on Weblate
I have updated... I have updated...
- [ ] `package.json` - [ ] `package.json`

View file

@ -19,7 +19,7 @@ The full-text search engine used in Firefish has been changed to [PGroonga](http
[Edit (2024/03/23 23:55 UTC+9)] ~~**Warning**: You may fail to install PGroonga, since the package registry of Apache Arrow (one of the subdependencies of PGroonga) is currently down ([GitHub issue](https://github.com/apache/arrow/issues/40759)). We recommend that you hold off on upgrading until this problem is resolved.~~ [Edit (2024/03/23 23:55 UTC+9)] ~~**Warning**: You may fail to install PGroonga, since the package registry of Apache Arrow (one of the subdependencies of PGroonga) is currently down ([GitHub issue](https://github.com/apache/arrow/issues/40759)). We recommend that you hold off on upgrading until this problem is resolved.~~
[Edit (2025/03/25 22:31 UTC+9)] The Apache Arrow repository is now back up and running again. [Edit (2024/03/25 22:31 UTC+9)] The Apache Arrow repository is now back up and running again.
#### 1. Install PGroonga #### 1. Install PGroonga
@ -131,8 +131,8 @@ db:
After that, execute this command to enable PGroonga: After that, execute this command to enable PGroonga:
```sh ```sh
docker-compose up db --detach && docker-compose exec db sh -c 'psql --user="${POSTGRES_USER}" --dbname="${POSTGRES_DB}" --command="CREATE EXTENSION pgroonga;"' docker-compose up db --detach && sleep 5 && docker-compose exec db sh -c 'psql --user="${POSTGRES_USER}" --dbname="${POSTGRES_DB}" --command="CREATE EXTENSION pgroonga;"'
# or podman-compose up db --detach && podman-compose exec db sh -c 'psql --user="${POSTGRES_USER}" --dbname="${POSTGRES_DB}" --command="CREATE EXTENSION pgroonga;"' # or podman-compose up db --detach && sleep 5 && podman-compose exec db sh -c 'psql --user="${POSTGRES_USER}" --dbname="${POSTGRES_DB}" --command="CREATE EXTENSION pgroonga;"'
``` ```
Once this is done, you can start Firefish as usual. Once this is done, you can start Firefish as usual.

View file

@ -9,14 +9,14 @@ notifications: "Notificacions"
username: "Nom d'usuari" username: "Nom d'usuari"
password: "Contrasenya" password: "Contrasenya"
forgotPassword: "Contrasenya oblidada" forgotPassword: "Contrasenya oblidada"
fetchingAsApObject: "Cercant en el Fediverse" fetchingAsApObject: "Obtenint des de el Fediverse"
ok: "D'acord" ok: "D'acord"
gotIt: "Ho he entès!" gotIt: "Ho he entès!"
cancel: "Cancel·la" cancel: "Cancel·la"
enterUsername: "Introdueix el teu nom d'usuari" enterUsername: "Introdueix el teu nom d'usuari"
renotedBy: "Impulsat per {user}" renotedBy: "Impulsat per {user}"
noNotes: "Cap publicació" noNotes: "Sense publicacions"
noNotifications: "Cap notificació" noNotifications: "Sense notificacions"
instance: "Servidor" instance: "Servidor"
settings: "Preferències" settings: "Preferències"
basicSettings: "Configuració bàsica" basicSettings: "Configuració bàsica"
@ -35,23 +35,23 @@ users: "Usuaris"
addUser: "Afegeix un usuari" addUser: "Afegeix un usuari"
favorite: "Afegeix a les adreces d'interès" favorite: "Afegeix a les adreces d'interès"
favorites: "Adreces d'interès" favorites: "Adreces d'interès"
unfavorite: "Eliminar de les adreces d'interès" unfavorite: "Suprimeix de les adreces d'interès"
favorited: "Afegit a les adreces d'interès." favorited: "S'ha afegit a les adreces d'interès."
alreadyFavorited: "Ja es troba a les adreces d'interès." alreadyFavorited: "Ja s'ha afegit a les adreces d'interès."
cantFavorite: "No s'ha pogut afegir a les adreces d'interès." cantFavorite: "No s'ha pogut afegir a les adreces d'interès."
pin: "Fixar al perfil" pin: "Fixa al perfil"
unpin: "Deixa de fixar al perfil" unpin: "No fixis al perfil"
copyContent: "Copia el contingut" copyContent: "Copia el contingut"
copyLink: "Copia l'enllaç" copyLink: "Copia l'enllaç"
delete: "Elimina" delete: "Suprimeix"
deleteAndEdit: "Elimina i edita" deleteAndEdit: "Suprimeix i edita"
deleteAndEditConfirm: "Segur que vols eliminar la publicació i editar-la? Perdràs deleteAndEditConfirm: "Segur que vols suprimir aquesta publicació i editar-la? Perdràs
totes les reaccions, impulsos i respostes." totes les reaccions, impulsos i respostes."
addToList: "Afegeix a la llista" addToList: "Afegeix a la llista"
sendMessage: "Envia un missatge" sendMessage: "Envia un missatge"
copyUsername: "Copia el nom d'usuari" copyUsername: "Copia el nom d'usuari"
searchUser: "Cerca un usuari" searchUser: "Cerca un usuari"
reply: "Respon" reply: "Resposta"
loadMore: "Carrega'n més" loadMore: "Carrega'n més"
showMore: "Mostra'n més" showMore: "Mostra'n més"
youGotNewFollower: "t'ha seguit" youGotNewFollower: "t'ha seguit"
@ -66,20 +66,20 @@ export: "Exporta"
files: "Fitxers" files: "Fitxers"
download: "Baixa" download: "Baixa"
driveFileDeleteConfirm: "Segur que vols eliminar el fitxer «{name}»? S'eliminarà de driveFileDeleteConfirm: "Segur que vols eliminar el fitxer «{name}»? S'eliminarà de
totes les notes que el continguin com a fitxer adjunt." totes les publicacions que el continguin com a fitxer adjunt."
unfollowConfirm: "Segur que vols deixar de seguir a {name}?" unfollowConfirm: "Segur que vols deixar de seguir a {name}?"
exportRequested: "Has demanat exportar dades. Això pot trigar una estona. S'afegirà exportRequested: "Has sol·licitat una exportació. Això pot trigar una estona. S'afegirà
al teu Disc un cop completada." al teu Disc un cop finalitzada."
importRequested: "Has demanat importar dades. Això pot trigar una estona." importRequested: "Has sol·licitat una importació de dades. Això pot trigar una estona."
lists: "Llistes" lists: "Llistes"
noLists: "No tens cap llista" noLists: "No tens cap llista"
note: "Publica" note: "Publicació"
notes: "Publicacions" notes: "Publicacions"
following: "Seguint" following: "Seguint"
followers: "Seguidors" followers: "Seguidors"
followsYou: "Et segueix" followsYou: "Et segueix"
createList: "Crear una llista" createList: "Crea una llista"
manageLists: "Gestionar les llistes" manageLists: "Gestiona les llistes"
error: "Error" error: "Error"
somethingHappened: "S'ha produït un error" somethingHappened: "S'ha produït un error"
retry: "Torna-ho a intentar" retry: "Torna-ho a intentar"
@ -91,7 +91,7 @@ serverIsDead: "Aquest servidor no respon. Espera una estona i torna-ho a provar.
youShouldUpgradeClient: "Per veure aquesta pàgina, actualitzeu-la per actualitzar youShouldUpgradeClient: "Per veure aquesta pàgina, actualitzeu-la per actualitzar
el vostre client." el vostre client."
enterListName: "Introdueix un nom per a la llista" enterListName: "Introdueix un nom per a la llista"
privacy: "Privadesa" privacy: "Privacitat"
makeFollowManuallyApprove: "Les sol·licituds de seguiment requereixen aprovació" makeFollowManuallyApprove: "Les sol·licituds de seguiment requereixen aprovació"
defaultNoteVisibility: "Visibilitat per defecte" defaultNoteVisibility: "Visibilitat per defecte"
follow: "Segueix" follow: "Segueix"
@ -2066,7 +2066,7 @@ _relayStatus:
rejected: Rebutjat rejected: Rebutjat
deleted: Eliminat deleted: Eliminat
editNote: Edita la publicació editNote: Edita la publicació
edited: 'Editat el {date} {time}' edited: 'Editat a les {time} {date}'
signupsDisabled: Actualment, les inscripcions en aquest servidor estan desactivades. signupsDisabled: Actualment, les inscripcions en aquest servidor estan desactivades.
Si teniu un codi d'invitació per a aquest servidor, introduïu-lo a continuació. Si teniu un codi d'invitació per a aquest servidor, introduïu-lo a continuació.
userSaysSomethingReasonQuote: '{name} ha citat una publicació que conté {reason}' userSaysSomethingReasonQuote: '{name} ha citat una publicació que conté {reason}'
@ -2096,7 +2096,7 @@ newer: Més nou
older: Més antic older: Més antic
silencedWarning: S'està mostrant aquesta pàgina per què aquest usuari és d'un servidor silencedWarning: S'està mostrant aquesta pàgina per què aquest usuari és d'un servidor
que l'administrador a silenciat, així que pot ser spam. que l'administrador a silenciat, així que pot ser spam.
jumpToPrevious: Vés a l'anterior jumpToPrevious: Salta a l'anterior
cw: Avís de contingut cw: Avís de contingut
antennasDesc: "Les antenes mostren publicacions noves que coincideixen amb els criteris antennasDesc: "Les antenes mostren publicacions noves que coincideixen amb els criteris
establerts!\nS'hi pot accedir des de la pàgina de línies de temps." establerts!\nS'hi pot accedir des de la pàgina de línies de temps."
@ -2104,7 +2104,7 @@ expandOnNoteClick: Obre la publicació amb un clic
expandOnNoteClickDesc: Si està desactivat, encara pots obrir les publicacions al menú expandOnNoteClickDesc: Si està desactivat, encara pots obrir les publicacions al menú
del botó dret o fent clic a la marca de temps. del botó dret o fent clic a la marca de temps.
channelFederationWarn: Els canals encara no es federen amb altres servidors channelFederationWarn: Els canals encara no es federen amb altres servidors
searchPlaceholder: Cerca a Firefish searchPlaceholder: Cercar a Firefish
listsDesc: Les llistes et permeten crear línies de temps amb usuaris específics. Es listsDesc: Les llistes et permeten crear línies de temps amb usuaris específics. Es
pot accedir des de la pàgina de línies de temps. pot accedir des de la pàgina de línies de temps.
clipsDesc: Els clips són com marcadors categoritzats que es poden compartir. Podeu clipsDesc: Els clips són com marcadors categoritzats que es poden compartir. Podeu
@ -2264,8 +2264,8 @@ publishTimelinesDescription: Si està activat, les línies de temps Global i Loc
noAltTextWarning: Alguns fitxers adjunts no tenen una descripció. T'has s oblidat noAltTextWarning: Alguns fitxers adjunts no tenen una descripció. T'has s oblidat
d'escriure-les? d'escriure-les?
showNoAltTextWarning: Mostra un avís si públiques un fitxer sense descripció showNoAltTextWarning: Mostra un avís si públiques un fitxer sense descripció
toReply: Respon toReply: Resposta
toQuote: Cita toQuote: Citar
toEdit: Edita toEdit: Edita
searchUsersDescription: "Per buscar publicacions concretes d'un usuari/servidor, escriu searchUsersDescription: "Per buscar publicacions concretes d'un usuari/servidor, escriu
la ID (@usuari@exemple.com, o @usuari per un usuari local) o nom del domini (exemple.com).\n la ID (@usuari@exemple.com, o @usuari per un usuari local) o nom del domini (exemple.com).\n
@ -2285,3 +2285,12 @@ searchRangeDescription: "Si vols filtrar per un període de temps, has de fer se
moderationNote: Nota de moderació moderationNote: Nota de moderació
ipFirstAcknowledged: Data en què es va veure la adreça IP per primera vegada ipFirstAcknowledged: Data en què es va veure la adreça IP per primera vegada
driveCapacityOverride: Capacitat del disc esgotada driveCapacityOverride: Capacitat del disc esgotada
incorrectLanguageWarning: "Semblar ser que la teva publicació es troba en {detected},
però has seleccionat {current}.\nVols canviar l'idioma a {detected}?"
markLocalFilesNsfwByDefault: Marcar tots els fitxers locals nous com a sensibles per
defecte
markLocalFilesNsfwByDefaultDescription: Independentment d'aquest ajust, els usuaris
poden treure l'etiqueta NSFW els mateixos. Els fitxers que ja existeixen no es veuen
afectats.
autocorrectNoteLanguage: Mostra un avís si l'idioma de la publicació no coincideix
amb el resultat de l'idioma detectat automàticament

View file

@ -1196,16 +1196,16 @@ releaseToReload: "Release to reload"
reloading: "Reloading" reloading: "Reloading"
enableTimelineStreaming: "Update timelines automatically" enableTimelineStreaming: "Update timelines automatically"
searchWords: "Words to search / ID or URL to lookup" searchWords: "Words to search / ID or URL to lookup"
searchWordsDescription: "Enter the search term here to search for posts. Separate words searchWordsDescription: "Enter the search term here to search for posts. Separate
with a space for an AND search, or 'OR' (without quotes) between words for an OR words with a space for an AND search, or 'OR' (without quotes) between words for
search.\nFor example, 'morning night' will find posts that contain both 'morning' an OR search.\nFor example, 'morning night' will find posts that contain both 'morning'
and 'night', and 'morning OR night' will find posts that contain either 'morning' and 'night', and 'morning OR night' will find posts that contain either 'morning'
or 'night' (or both).\nYou can also combine AND/OR conditions like '(morning OR or 'night' (or both).\nYou can also combine AND/OR conditions like '(morning OR
night) sleepy'.\nIf you want to search for a sequence of words (e.g., a sentence), you night) sleepy'.\nIf you want to search for a sequence of words (e.g., a sentence),
must put it in double quotes, not to make it an AND search: \"Today I learned\"\n\n you must put it in double quotes, not to make it an AND search: \"Today I learned\"\
If you want to go to a specific user page or post page, enter \n\n If you want to go to a specific user page or post page, enter the ID or URL
the ID or URL in this field and click the 'Lookup' button. Clicking 'Search' will in this field and click the 'Lookup' button. Clicking 'Search' will search for posts
search for posts that literally contain the ID/URL." that literally contain the ID/URL."
searchUsers: "Posted by (optional)" searchUsers: "Posted by (optional)"
searchUsersDescription: "To search for posts by a specific user/server, enter the searchUsersDescription: "To search for posts by a specific user/server, enter the
ID (@user@example.com, or @user for a local user) or domain name (example.com).\n ID (@user@example.com, or @user for a local user) or domain name (example.com).\n
@ -2230,6 +2230,8 @@ moreUrlsDescription: "Enter the pages you want to pin to the help menu in the lo
left corner using this notation:\n\"Display name\": https://example.com/" left corner using this notation:\n\"Display name\": https://example.com/"
messagingUnencryptedInfo: "Chats on Firefish are not end-to-end encrypted. Don't share messagingUnencryptedInfo: "Chats on Firefish are not end-to-end encrypted. Don't share
any sensitive infomation over Firefish." any sensitive infomation over Firefish."
autocorrectNoteLanguage: "Show a warning if the post language does not match the auto-detected result" autocorrectNoteLanguage: "Show a warning if the post language does not match the auto-detected
incorrectLanguageWarning: "It looks like your post is in {detected}, but you selected {current}.\nWould you like to set the language to {detected} instead?" result"
incorrectLanguageWarning: "It looks like your post is in {detected}, but you selected
{current}.\nWould you like to set the language to {detected} instead?"
noteEditHistory: "Post edit history" noteEditHistory: "Post edit history"

View file

@ -2315,3 +2315,12 @@ noAltTextWarning: Certains fichiers joints n'ont aucune description. Avez-vous o
de l'écrire? de l'écrire?
showNoAltTextWarning: Afficher un avertissement si vous essayez de publier des fichiers showNoAltTextWarning: Afficher un avertissement si vous essayez de publier des fichiers
sans description sans description
autocorrectNoteLanguage: Afficher un avertissement si la langue de publication ne
correspond pas au résultat autodétecté
incorrectLanguageWarning: "Il semble que votre publication est en {detected}, mais
vous avez sélectionné {current}.\nVoulez-vous sélectionner {detected} à la place?"
markLocalFilesNsfwByDefault: Marquer tous les nouveaux fichiers locaux comme sensibles
par défaut
markLocalFilesNsfwByDefaultDescription: Indépendamment de ce réglage, les utilisateurs
peuvent supprimer le drapeau « sensible » (NSFW) eux-mêmes. Les fichiers existants
ne sont pas affectés.

View file

@ -2269,3 +2269,6 @@ incorrectLanguageWarning: "Sepertinya kirimanmu dalam bahasa {detected}, tetapi
memilih {current}.\nApakah kamu ingin ubah bahasanya ke bahasa {detected} saja?" memilih {current}.\nApakah kamu ingin ubah bahasanya ke bahasa {detected} saja?"
autocorrectNoteLanguage: Tampilkan peringatan jika bahasa kiriman tidak cocok dengan autocorrectNoteLanguage: Tampilkan peringatan jika bahasa kiriman tidak cocok dengan
hasil yang dideteksi secara otomatis hasil yang dideteksi secara otomatis
markLocalFilesNsfwByDefault: Tandai semua berkas lokal baru sensitif secara bawaan
markLocalFilesNsfwByDefaultDescription: Terlepas dari pengaturan ini, pengguna dapat
menghapus sendiri tanda NSFW. Berkas yang ada tidak berpengaruh.

View file

@ -2058,3 +2058,5 @@ ipFirstAcknowledged: IPアドレスが最初に取得された日
driveCapacityOverride: ドライブ容量の変更 driveCapacityOverride: ドライブ容量の変更
autocorrectNoteLanguage: 設定した投稿言語が自動検出されたものと異なる場合に警告する autocorrectNoteLanguage: 設定した投稿言語が自動検出されたものと異なる場合に警告する
incorrectLanguageWarning: "この投稿は{detected}で書かれていると判定されました。\n投稿言語を{current}ではなく{detected}にしますか?" incorrectLanguageWarning: "この投稿は{detected}で書かれていると判定されました。\n投稿言語を{current}ではなく{detected}にしますか?"
markLocalFilesNsfwByDefault: このサーバーの全てのファイルをデフォルトでNSFWに設定する
markLocalFilesNsfwByDefaultDescription: この設定が有効でも、ユーザーは自分でNSFWのフラグを外すことができます。また、この設定は既存のファイルには影響しません。

View file

@ -39,11 +39,11 @@
"gulp-terser": "2.1.0" "gulp-terser": "2.1.0"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "1.6.2", "@biomejs/biome": "1.6.3",
"@biomejs/cli-darwin-arm64": "^1.6.2", "@biomejs/cli-darwin-arm64": "^1.6.3",
"@biomejs/cli-darwin-x64": "^1.6.2", "@biomejs/cli-darwin-x64": "^1.6.3",
"@biomejs/cli-linux-arm64": "^1.6.2", "@biomejs/cli-linux-arm64": "^1.6.3",
"@biomejs/cli-linux-x64": "^1.6.2", "@biomejs/cli-linux-x64": "^1.6.3",
"@types/node": "20.11.30", "@types/node": "20.11.30",
"execa": "8.0.1", "execa": "8.0.1",
"pnpm": "8.15.5", "pnpm": "8.15.5",

View file

@ -6,5 +6,5 @@ This directory contains all of the packages Firefish uses.
- `backend-rs`: Backend code written in Rust, bound to NodeJS by [NAPI-RS](https://napi.rs/) - `backend-rs`: Backend code written in Rust, bound to NodeJS by [NAPI-RS](https://napi.rs/)
- `client`: Web interface written in Vue3 and TypeScript - `client`: Web interface written in Vue3 and TypeScript
- `sw`: Web [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) written in TypeScript - `sw`: Web [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) written in TypeScript
- `firefish-js`: TypeScript SDK for both backend and client, also published on [NPM](https://www.npmjs.com/package/firefish-js) for public use - `firefish-js`: TypeScript SDK for both backend and client
- `megalodon`: TypeScript library used for partial Mastodon API compatibility - `megalodon`: TypeScript library used for partial Mastodon API compatibility

View file

@ -157,18 +157,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.78" version = "0.1.79"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -182,9 +182,9 @@ dependencies = [
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]] [[package]]
name = "backend-rs" name = "backend-rs"
@ -326,7 +326,7 @@ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
"syn_derive", "syn_derive",
] ]
@ -411,9 +411,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.3" version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@ -433,14 +433,14 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.5.3" version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f" checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
dependencies = [ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -542,7 +542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad291aa74992b9b7a7e88c38acbbf6ad7e107f1d90ee8775b7bc1fc3394f485c" checksum = "ad291aa74992b9b7a7e88c38acbbf6ad7e107f1d90ee8775b7bc1fc3394f485c"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -688,9 +688,9 @@ dependencies = [
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "2.0.1" version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
[[package]] [[package]]
name = "finl_unicode" name = "finl_unicode"
@ -1066,7 +1066,7 @@ checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -1095,9 +1095,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.10" version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
@ -1261,9 +1261,9 @@ dependencies = [
[[package]] [[package]]
name = "napi" name = "napi"
version = "2.16.0" version = "2.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54a63d0570e4c3e0daf7a8d380563610e159f538e20448d6c911337246f40e84" checksum = "c4ca998356d8ff9fba7a070dae4508a2298439c98c9f3bc9c07669538b999e8f"
dependencies = [ dependencies = [
"bitflags 2.5.0", "bitflags 2.5.0",
"ctor", "ctor",
@ -1281,23 +1281,23 @@ checksum = "2f9130fccc5f763cf2069b34a089a18f0d0883c66aceb81f2fad541a3d823c43"
[[package]] [[package]]
name = "napi-derive" name = "napi-derive"
version = "2.16.0" version = "2.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05bb7c37e3c1dda9312fdbe4a9fc7507fca72288ba154ec093e2d49114e727ce" checksum = "b138cecf1141ae0ff5d62f4aa0e2f269aec339f66070f346ba6fb4279f1fc178"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"convert_case", "convert_case",
"napi-derive-backend", "napi-derive-backend",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
name = "napi-derive-backend" name = "napi-derive-backend"
version = "1.0.62" version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f785a8b8d7b83e925f5aa6d2ae3c159d17fe137ac368dc185bef410e7acdaeb4" checksum = "ce5126b64f6ad9e28e30e6d15213dd378626b38f556454afebc42f7f02a90902"
dependencies = [ dependencies = [
"convert_case", "convert_case",
"once_cell", "once_cell",
@ -1305,7 +1305,7 @@ dependencies = [
"quote", "quote",
"regex", "regex",
"semver", "semver",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -1487,7 +1487,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -1536,7 +1536,7 @@ dependencies = [
"regex", "regex",
"regex-syntax 0.7.5", "regex-syntax 0.7.5",
"structmeta", "structmeta",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -2003,7 +2003,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -2044,7 +2044,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"sea-bae", "sea-bae",
"syn 2.0.53", "syn 2.0.55",
"unicode-ident", "unicode-ident",
] ]
@ -2110,7 +2110,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -2126,9 +2126,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.114" version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -2513,7 +2513,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"structmeta-derive", "structmeta-derive",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -2524,7 +2524,7 @@ checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -2552,9 +2552,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.53" version = "2.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2570,7 +2570,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -2635,7 +2635,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -2711,7 +2711,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -2782,7 +2782,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]
@ -2931,7 +2931,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2965,7 +2965,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -3194,7 +3194,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.53", "syn 2.0.55",
] ]
[[package]] [[package]]

View file

@ -12,7 +12,7 @@ napi = ["dep:napi", "dep:napi-derive"]
crate-type = ["cdylib", "lib"] crate-type = ["cdylib", "lib"]
[dependencies] [dependencies]
async-trait = "0.1.78" async-trait = "0.1.79"
cfg-if = "1.0.0" cfg-if = "1.0.0"
chrono = "0.4.35" chrono = "0.4.35"
cuid2 = "0.1.2" cuid2 = "0.1.2"
@ -23,13 +23,13 @@ rand = "0.8.5"
schemars = { version = "0.8.16", features = ["chrono"] } schemars = { version = "0.8.16", features = ["chrono"] }
sea-orm = { version = "0.12.15", features = ["sqlx-postgres", "runtime-tokio-rustls"] } sea-orm = { version = "0.12.15", features = ["sqlx-postgres", "runtime-tokio-rustls"] }
serde = { version = "1.0.197", features = ["derive"] } serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.114" serde_json = "1.0.115"
thiserror = "1.0.58" thiserror = "1.0.58"
tokio = { version = "1.36.0", features = ["full"] } tokio = { version = "1.36.0", features = ["full"] }
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix # Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
napi = { version = "2.16.0", default-features = false, features = ["napi9", "tokio_rt"], optional = true } napi = { version = "2.16.1", default-features = false, features = ["napi9", "tokio_rt"], optional = true }
napi-derive = { version = "2.16.0", optional = true } napi-derive = { version = "2.16.1", optional = true }
basen = "0.1.0" basen = "0.1.0"
[dev-dependencies] [dev-dependencies]

View file

@ -33,10 +33,10 @@
}, },
"scripts": { "scripts": {
"artifacts": "napi artifacts", "artifacts": "napi artifacts",
"build": "napi build --features napi --platform --release --cargo-flags=--locked ./built/", "build": "napi build --features napi --platform --release ./built/",
"build:debug": "napi build --features napi --platform --cargo-flags=--locked ./built/", "build:debug": "napi build --features napi --platform ./built/",
"prepublishOnly": "napi prepublish -t npm", "prepublishOnly": "napi prepublish -t npm",
"test": "pnpm run cargo:test && pnpm run build:napi && ava", "test": "pnpm run cargo:test && pnpm run build:debug && ava",
"universal": "napi universal", "universal": "napi universal",
"version": "napi version", "version": "napi version",
"format": "cargo fmt --all --", "format": "cargo fmt --all --",

View file

@ -22,30 +22,30 @@
"@swc/core-android-arm64": "1.3.11" "@swc/core-android-arm64": "1.3.11"
}, },
"dependencies": { "dependencies": {
"@bull-board/api": "5.15.1", "@bull-board/api": "5.15.2",
"@bull-board/koa": "5.15.1", "@bull-board/koa": "5.15.2",
"@bull-board/ui": "5.15.1", "@bull-board/ui": "5.15.2",
"@discordapp/twemoji": "^15.0.2", "@discordapp/twemoji": "^15.0.2",
"@koa/cors": "5.0.0", "@koa/cors": "5.0.0",
"@koa/multer": "3.0.2", "@koa/multer": "3.0.2",
"@koa/router": "12.0.1", "@koa/router": "12.0.1",
"@ladjs/koa-views": "9.0.0", "@ladjs/koa-views": "9.0.0",
"@peertube/http-signature": "1.7.0", "@peertube/http-signature": "1.7.0",
"@redocly/openapi-core": "1.10.5", "@redocly/openapi-core": "1.10.6",
"@sinonjs/fake-timers": "11.2.2", "@sinonjs/fake-timers": "11.2.2",
"@twemoji/parser": "^15.0.0", "@twemoji/parser": "^15.0.0",
"adm-zip": "0.5.10", "adm-zip": "0.5.10",
"ajv": "8.12.0", "ajv": "8.12.0",
"archiver": "7.0.1", "archiver": "7.0.1",
"argon2": "^0.40.1", "argon2": "^0.40.1",
"aws-sdk": "2.1584.0", "aws-sdk": "2.1585.0",
"axios": "^1.6.8", "axios": "^1.6.8",
"backend-rs": "workspace:*", "backend-rs": "workspace:*",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"blurhash": "2.0.5", "blurhash": "2.0.5",
"bull": "4.12.2", "bull": "4.12.2",
"cacheable-lookup": "TheEssem/cacheable-lookup", "cacheable-lookup": "TheEssem/cacheable-lookup",
"cbor-x": "^1.5.8", "cbor-x": "^1.5.9",
"chalk": "5.3.0", "chalk": "5.3.0",
"chalk-template": "1.1.0", "chalk-template": "1.1.0",
"cli-highlight": "2.1.11", "cli-highlight": "2.1.11",
@ -62,7 +62,7 @@
"form-data": "^4.0.0", "form-data": "^4.0.0",
"got": "14.2.1", "got": "14.2.1",
"gunzip-maybe": "^1.4.2", "gunzip-maybe": "^1.4.2",
"happy-dom": "^14.3.1", "happy-dom": "^14.3.8",
"hpagent": "1.2.0", "hpagent": "1.2.0",
"ioredis": "5.3.2", "ioredis": "5.3.2",
"ip-cidr": "4.0.0", "ip-cidr": "4.0.0",
@ -129,7 +129,7 @@
}, },
"devDependencies": { "devDependencies": {
"@swc/cli": "0.3.10", "@swc/cli": "0.3.10",
"@swc/core": "1.4.8", "@swc/core": "1.4.11",
"@types/adm-zip": "^0.5.5", "@types/adm-zip": "^0.5.5",
"@types/bcryptjs": "2.4.6", "@types/bcryptjs": "2.4.6",
"@types/color-convert": "^2.0.3", "@types/color-convert": "^2.0.3",

View file

@ -213,7 +213,7 @@ export const db = new DataSource({
db: config.redis.db || 0, db: config.redis.db || 0,
tls: config.redis.tls, tls: config.redis.tls,
}, },
} }
: false, : false,
logging: log, logging: log,
logger: log ? new MyCustomLogger() : undefined, logger: log ? new MyCustomLogger() : undefined,

View file

@ -126,7 +126,7 @@ export const httpAgent = config.proxy
scheduling: "lifo", scheduling: "lifo",
proxy: config.proxy, proxy: config.proxy,
localAddress: config.outgoingAddress, localAddress: config.outgoingAddress,
}) })
: _http; : _http;
/** /**
@ -141,7 +141,7 @@ export const httpsAgent = config.proxy
scheduling: "lifo", scheduling: "lifo",
proxy: config.proxy, proxy: config.proxy,
localAddress: config.outgoingAddress, localAddress: config.outgoingAddress,
}) })
: _https; : _https;
/** /**

View file

@ -30,10 +30,10 @@ function normalizeHost(
src === "." src === "."
? null // .はローカルホスト (ここがマッチするのはリアクションのみ) ? null // .はローカルホスト (ここがマッチするのはリアクションのみ)
: src === undefined : src === undefined
? noteUserHost // ノートなどでホスト省略表記の場合はローカルホスト (ここがリアクションにマッチすることはない) ? noteUserHost // ノートなどでホスト省略表記の場合はローカルホスト (ここがリアクションにマッチすることはない)
: isSelfHost(src) : isSelfHost(src)
? null // 自ホスト指定 ? null // 自ホスト指定
: src || noteUserHost; // 指定されたホスト || ノートなどの所有者のホスト (こっちがリアクションにマッチすることはない) : src || noteUserHost; // 指定されたホスト || ノートなどの所有者のホスト (こっちがリアクションにマッチすることはない)
host = toPunyNullable(host); host = toPunyNullable(host);
@ -87,7 +87,7 @@ export async function populateEmoji(
? emojiUrl ? emojiUrl
: `${config.url}/proxy/${encodeURIComponent( : `${config.url}/proxy/${encodeURIComponent(
new URL(emojiUrl).pathname, new URL(emojiUrl).pathname,
)}?${query({ url: emojiUrl })}`; )}?${query({ url: emojiUrl })}`;
return { return {
name: emojiName, name: emojiName,
@ -168,7 +168,7 @@ export async function prefetchEmojis(
? await Emojis.find({ ? await Emojis.find({
where: emojisQuery, where: emojisQuery,
select: ["name", "host", "originalUrl", "publicUrl"], select: ["name", "host", "originalUrl", "publicUrl"],
}) })
: []; : [];
const trans = redisClient.multi(); const trans = redisClient.multi();
for (const emoji of _emojis) { for (const emoji of _emojis) {

View file

@ -85,18 +85,18 @@ type TypeStringef =
type StringDefToType<T extends TypeStringef> = T extends "null" type StringDefToType<T extends TypeStringef> = T extends "null"
? null ? null
: T extends "boolean" : T extends "boolean"
? boolean ? boolean
: T extends "integer" : T extends "integer"
? number ? number
: T extends "number" : T extends "number"
? number ? number
: T extends "string" : T extends "string"
? string | Date ? string | Date
: T extends "array" : T extends "array"
? ReadonlyArray<any> ? ReadonlyArray<any>
: T extends "object" : T extends "object"
? Record<string, any> ? Record<string, any>
: any; : any;
// https://swagger.io/specification/?sbsearch=optional#schema-object // https://swagger.io/specification/?sbsearch=optional#schema-object
type OfSchema = { type OfSchema = {
@ -134,14 +134,14 @@ type RequiredPropertyNames<s extends Obj> = {
s[K]["optional"] extends false s[K]["optional"] extends false
? K ? K
: // K has default value : // K has default value
s[K]["default"] extends s[K]["default"] extends
| null | null
| string | string
| number | number
| boolean | boolean
| Record<string, unknown> | Record<string, unknown>
? K ? K
: never; : never;
}[keyof s]; }[keyof s];
export type Obj = Record<string, Schema>; export type Obj = Record<string, Schema>;
@ -186,47 +186,47 @@ type ArrayUnion<T> = T extends any ? Array<T> : never;
export type SchemaTypeDef<p extends Schema> = p["type"] extends "null" export type SchemaTypeDef<p extends Schema> = p["type"] extends "null"
? null ? null
: p["type"] extends "integer" : p["type"] extends "integer"
? number ? number
: p["type"] extends "number" : p["type"] extends "number"
? number ? number
: p["type"] extends "string" : p["type"] extends "string"
? p["enum"] extends readonly string[] ? p["enum"] extends readonly string[]
? p["enum"][number] ? p["enum"][number]
: p["format"] extends "date-time" : p["format"] extends "date-time"
? string ? string
: // Dateにする : // Dateにする
string string
: p["type"] extends "boolean" : p["type"] extends "boolean"
? boolean ? boolean
: p["type"] extends "object" : p["type"] extends "object"
? p["ref"] extends keyof typeof refs ? p["ref"] extends keyof typeof refs
? Packed<p["ref"]> ? Packed<p["ref"]>
: p["properties"] extends NonNullable<Obj> : p["properties"] extends NonNullable<Obj>
? ObjType<p["properties"], NonNullable<p["required"]>[number]> ? ObjType<p["properties"], NonNullable<p["required"]>[number]>
: p["anyOf"] extends ReadonlyArray<Schema> : p["anyOf"] extends ReadonlyArray<Schema>
? UnionSchemaType<p["anyOf"]> & ? UnionSchemaType<p["anyOf"]> &
Partial<UnionToIntersection<UnionSchemaType<p["anyOf"]>>> Partial<UnionToIntersection<UnionSchemaType<p["anyOf"]>>>
: p["allOf"] extends ReadonlyArray<Schema> : p["allOf"] extends ReadonlyArray<Schema>
? UnionToIntersection<UnionSchemaType<p["allOf"]>> ? UnionToIntersection<UnionSchemaType<p["allOf"]>>
: any : any
: p["type"] extends "array" : p["type"] extends "array"
? p["items"] extends OfSchema ? p["items"] extends OfSchema
? p["items"]["anyOf"] extends ReadonlyArray<Schema> ? p["items"]["anyOf"] extends ReadonlyArray<Schema>
? UnionSchemaType<NonNullable<p["items"]["anyOf"]>>[] ? UnionSchemaType<NonNullable<p["items"]["anyOf"]>>[]
: p["items"]["oneOf"] extends ReadonlyArray<Schema> : p["items"]["oneOf"] extends ReadonlyArray<Schema>
? ArrayUnion< ? ArrayUnion<
UnionSchemaType<NonNullable<p["items"]["oneOf"]>> UnionSchemaType<NonNullable<p["items"]["oneOf"]>>
> >
: p["items"]["allOf"] extends ReadonlyArray<Schema> : p["items"]["allOf"] extends ReadonlyArray<Schema>
? UnionToIntersection< ? UnionToIntersection<
UnionSchemaType<NonNullable<p["items"]["allOf"]>> UnionSchemaType<NonNullable<p["items"]["allOf"]>>
>[] >[]
: never : never
: p["items"] extends NonNullable<Schema> : p["items"] extends NonNullable<Schema>
? SchemaTypeDef<p["items"]>[] ? SchemaTypeDef<p["items"]>[]
: any[] : any[]
: p["oneOf"] extends ReadonlyArray<Schema> : p["oneOf"] extends ReadonlyArray<Schema>
? UnionSchemaType<p["oneOf"]> ? UnionSchemaType<p["oneOf"]>
: any; : any;
export type SchemaType<p extends Schema> = NullOrUndefined<p, SchemaTypeDef<p>>; export type SchemaType<p extends Schema> = NullOrUndefined<p, SchemaTypeDef<p>>;

View file

@ -27,7 +27,7 @@ export const AbuseUserReportRepository = db
assignee: report.assigneeId assignee: report.assigneeId
? Users.pack(report.assignee || report.assigneeId, null, { ? Users.pack(report.assignee || report.assigneeId, null, {
detail: true, detail: true,
}) })
: null, : null,
forwarded: report.forwarded, forwarded: report.forwarded,
}); });

View file

@ -38,7 +38,7 @@ export const AppRepository = db.getRepository(App).extend({
appId: app.id, appId: app.id,
userId: me.id, userId: me.id,
}).then((count) => count > 0), }).then((count) => count > 0),
} }
: {}), : {}),
}; };
}, },

View file

@ -21,14 +21,14 @@ export const ChannelRepository = db.getRepository(Channel).extend({
? (await NoteUnreads.findOneBy({ ? (await NoteUnreads.findOneBy({
noteChannelId: channel.id, noteChannelId: channel.id,
userId: meId, userId: meId,
})) != null })) != null
: undefined; : undefined;
const following = meId const following = meId
? await ChannelFollowings.findOneBy({ ? await ChannelFollowings.findOneBy({
followerId: meId, followerId: meId,
followeeId: channel.id, followeeId: channel.id,
}) })
: null; : null;
return { return {
@ -48,7 +48,7 @@ export const ChannelRepository = db.getRepository(Channel).extend({
? { ? {
isFollowing: following != null, isFollowing: following != null,
hasUnreadNote, hasUnreadNote,
} }
: {}), : {}),
}; };
}, },

View file

@ -162,7 +162,7 @@ export const DriveFileRepository = db.getRepository(DriveFile).extend({
opts.detail && file.folderId opts.detail && file.folderId
? DriveFolders.pack(file.folderId, { ? DriveFolders.pack(file.folderId, {
detail: true, detail: true,
}) })
: null, : null,
userId: opts.withUser ? file.userId : null, userId: opts.withUser ? file.userId : null,
user: opts.withUser && file.userId ? Users.pack(file.userId) : null, user: opts.withUser && file.userId ? Users.pack(file.userId) : null,
@ -203,7 +203,7 @@ export const DriveFileRepository = db.getRepository(DriveFile).extend({
opts.detail && file.folderId opts.detail && file.folderId
? DriveFolders.pack(file.folderId, { ? DriveFolders.pack(file.folderId, {
detail: true, detail: true,
}) })
: null, : null,
userId: opts.withUser ? file.userId : null, userId: opts.withUser ? file.userId : null,
user: opts.withUser && file.userId ? Users.pack(file.userId) : null, user: opts.withUser && file.userId ? Users.pack(file.userId) : null,

View file

@ -41,9 +41,9 @@ export const DriveFolderRepository = db.getRepository(DriveFolder).extend({
parent: this.pack(folder.parentId, { parent: this.pack(folder.parentId, {
detail: true, detail: true,
}), }),
} }
: {}), : {}),
} }
: {}), : {}),
}); });
}, },

View file

@ -67,12 +67,12 @@ export const FollowingRepository = db.getRepository(Following).extend({
followee: opts.populateFollowee followee: opts.populateFollowee
? Users.pack(following.followee || following.followeeId, me, { ? Users.pack(following.followee || following.followeeId, me, {
detail: true, detail: true,
}) })
: undefined, : undefined,
follower: opts.populateFollower follower: opts.populateFollower
? Users.pack(following.follower || following.followerId, me, { ? Users.pack(following.follower || following.followerId, me, {
detail: true, detail: true,
}) })
: undefined, : undefined,
}); });
}, },

View file

@ -30,7 +30,7 @@ export const GalleryPostRepository = db.getRepository(GalleryPost).extend({
isLiked: meId isLiked: meId
? await GalleryLikes.findOneBy({ postId: post.id, userId: meId }).then( ? await GalleryLikes.findOneBy({ postId: post.id, userId: meId }).then(
(x) => x != null, (x) => x != null,
) )
: undefined, : undefined,
}); });
}, },

View file

@ -32,7 +32,7 @@ export const NoteReactionRepository = db.getRepository(NoteReaction).extend({
? { ? {
// may throw error // may throw error
note: await Notes.pack(reaction.note ?? reaction.noteId, me), note: await Notes.pack(reaction.note ?? reaction.noteId, me),
} }
: {}), : {}),
}; };
}, },

View file

@ -227,7 +227,7 @@ export const NoteRepository = db.getRepository(Note).extend({
? { ? {
id: channel.id, id: channel.id,
name: channel.name, name: channel.name,
} }
: undefined, : undefined,
mentions: note.mentions.length > 0 ? note.mentions : undefined, mentions: note.mentions.length > 0 ? note.mentions : undefined,
uri: note.uri || undefined, uri: note.uri || undefined,
@ -237,7 +237,7 @@ export const NoteRepository = db.getRepository(Note).extend({
...(meId ...(meId
? { ? {
myReaction: populateMyReaction(note, meId, options?._hint_), myReaction: populateMyReaction(note, meId, options?._hint_),
} }
: {}), : {}),
...(opts.detail ...(opts.detail
@ -246,16 +246,16 @@ export const NoteRepository = db.getRepository(Note).extend({
? this.pack(note.reply || note.replyId, me, { ? this.pack(note.reply || note.replyId, me, {
detail: false, detail: false,
_hint_: options?._hint_, _hint_: options?._hint_,
}) })
: undefined, : undefined,
renote: note.renoteId renote: note.renoteId
? this.pack(note.renote || note.renoteId, me, { ? this.pack(note.renote || note.renoteId, me, {
detail: true, detail: true,
_hint_: options?._hint_, _hint_: options?._hint_,
}) })
: undefined, : undefined,
} }
: {}), : {}),
lang: note.lang, lang: note.lang,
}); });

View file

@ -29,7 +29,7 @@ export const NotificationRepository = db.getRepository(Notification).extend({
const token = notification.appAccessTokenId const token = notification.appAccessTokenId
? await AccessTokens.findOneByOrFail({ ? await AccessTokens.findOneByOrFail({
id: notification.appAccessTokenId, id: notification.appAccessTokenId,
}) })
: null; : null;
return await awaitAll({ return await awaitAll({
@ -51,7 +51,7 @@ export const NotificationRepository = db.getRepository(Notification).extend({
_hint_: options._hintForEachNotes_, _hint_: options._hintForEachNotes_,
}, },
), ),
} }
: {}), : {}),
...(notification.type === "reply" ...(notification.type === "reply"
? { ? {
@ -63,7 +63,7 @@ export const NotificationRepository = db.getRepository(Notification).extend({
_hint_: options._hintForEachNotes_, _hint_: options._hintForEachNotes_,
}, },
), ),
} }
: {}), : {}),
...(notification.type === "renote" ...(notification.type === "renote"
? { ? {
@ -75,7 +75,7 @@ export const NotificationRepository = db.getRepository(Notification).extend({
_hint_: options._hintForEachNotes_, _hint_: options._hintForEachNotes_,
}, },
), ),
} }
: {}), : {}),
...(notification.type === "quote" ...(notification.type === "quote"
? { ? {
@ -87,7 +87,7 @@ export const NotificationRepository = db.getRepository(Notification).extend({
_hint_: options._hintForEachNotes_, _hint_: options._hintForEachNotes_,
}, },
), ),
} }
: {}), : {}),
...(notification.type === "reaction" ...(notification.type === "reaction"
? { ? {
@ -100,7 +100,7 @@ export const NotificationRepository = db.getRepository(Notification).extend({
}, },
), ),
reaction: notification.reaction, reaction: notification.reaction,
} }
: {}), : {}),
...(notification.type === "pollVote" ...(notification.type === "pollVote"
? { ? {
@ -113,7 +113,7 @@ export const NotificationRepository = db.getRepository(Notification).extend({
}, },
), ),
choice: notification.choice, choice: notification.choice,
} }
: {}), : {}),
...(notification.type === "pollEnded" ...(notification.type === "pollEnded"
? { ? {
@ -125,21 +125,21 @@ export const NotificationRepository = db.getRepository(Notification).extend({
_hint_: options._hintForEachNotes_, _hint_: options._hintForEachNotes_,
}, },
), ),
} }
: {}), : {}),
...(notification.type === "groupInvited" ...(notification.type === "groupInvited"
? { ? {
invitation: UserGroupInvitations.pack( invitation: UserGroupInvitations.pack(
notification.userGroupInvitationId!, notification.userGroupInvitationId!,
), ),
} }
: {}), : {}),
...(notification.type === "app" ...(notification.type === "app"
? { ? {
body: notification.customBody, body: notification.customBody,
header: notification.customHeader || token?.name, header: notification.customHeader || token?.name,
icon: notification.customIcon || token?.iconUrl, icon: notification.customIcon || token?.iconUrl,
} }
: {}), : {}),
}); });
}, },

View file

@ -88,7 +88,7 @@ export const PageRepository = db.getRepository(Page).extend({
isLiked: meId isLiked: meId
? await PageLikes.findOneBy({ pageId: page.id, userId: meId }).then( ? await PageLikes.findOneBy({ pageId: page.id, userId: meId }).then(
(x) => x != null, (x) => x != null,
) )
: undefined, : undefined,
}); });
}, },

View file

@ -53,8 +53,8 @@ type IsMeAndIsUserDetailed<
? ExpectsMe extends true ? ExpectsMe extends true
? Packed<"MeDetailed"> ? Packed<"MeDetailed">
: ExpectsMe extends false : ExpectsMe extends false
? Packed<"UserDetailedNotMe"> ? Packed<"UserDetailedNotMe">
: Packed<"UserDetailed"> : Packed<"UserDetailed">
: Packed<"UserLite">; : Packed<"UserLite">;
const ajv = new Ajv(); const ajv = new Ajv();
@ -235,7 +235,7 @@ export const UserRepository = db.getRepository(User).extend({
reads.length > 0 reads.length > 0
? { ? {
id: Not(In(reads.map((read) => read.announcementId))), id: Not(In(reads.map((read) => read.announcementId))),
} }
: {}, : {},
); );
@ -292,7 +292,7 @@ export const UserRepository = db.getRepository(User).extend({
? await NoteUnreads.findOneBy({ ? await NoteUnreads.findOneBy({
userId: userId, userId: userId,
noteChannelId: In(channels.map((x) => x.followeeId)), noteChannelId: In(channels.map((x) => x.followeeId)),
}) })
: null; : null;
return unread != null; return unread != null;
@ -335,8 +335,8 @@ export const UserRepository = db.getRepository(User).extend({
return elapsed < USER_ONLINE_THRESHOLD return elapsed < USER_ONLINE_THRESHOLD
? "online" ? "online"
: elapsed < USER_ACTIVE_THRESHOLD : elapsed < USER_ACTIVE_THRESHOLD
? "active" ? "active"
: "offline"; : "offline";
}, },
async getAvatarUrl(user: User): Promise<string> { async getAvatarUrl(user: User): Promise<string> {
@ -429,23 +429,23 @@ export const UserRepository = db.getRepository(User).extend({
profile == null profile == null
? null ? null
: profile.ffVisibility === "public" || isMe : profile.ffVisibility === "public" || isMe
? user.followingCount ? user.followingCount
: profile.ffVisibility === "followers" && : profile.ffVisibility === "followers" &&
relation && relation &&
relation.isFollowing relation.isFollowing
? user.followingCount ? user.followingCount
: null; : null;
const followersCount = const followersCount =
profile == null profile == null
? null ? null
: profile.ffVisibility === "public" || isMe : profile.ffVisibility === "public" || isMe
? user.followersCount ? user.followersCount
: profile.ffVisibility === "followers" && : profile.ffVisibility === "followers" &&
relation && relation &&
relation.isFollowing relation.isFollowing
? user.followersCount ? user.followersCount
: null; : null;
const falsy = opts.detail ? false : undefined; const falsy = opts.detail ? false : undefined;
@ -481,7 +481,7 @@ export const UserRepository = db.getRepository(User).extend({
iconUrl: instance.iconUrl, iconUrl: instance.iconUrl,
faviconUrl: instance.faviconUrl, faviconUrl: instance.faviconUrl,
themeColor: instance.themeColor, themeColor: instance.themeColor,
} }
: undefined, : undefined,
) )
: undefined, : undefined,
@ -538,7 +538,7 @@ export const UserRepository = db.getRepository(User).extend({
securityKeys: UserSecurityKeys.countBy({ securityKeys: UserSecurityKeys.countBy({
userId: user.id, userId: user.id,
}).then((result) => result >= 1), }).then((result) => result >= 1),
} }
: {}), : {}),
...(opts.detail && isMe ...(opts.detail && isMe
@ -577,7 +577,7 @@ export const UserRepository = db.getRepository(User).extend({
mutedInstances: profile?.mutedInstances, mutedInstances: profile?.mutedInstances,
mutingNotificationTypes: profile?.mutingNotificationTypes, mutingNotificationTypes: profile?.mutingNotificationTypes,
emailNotificationTypes: profile?.emailNotificationTypes, emailNotificationTypes: profile?.emailNotificationTypes,
} }
: {}), : {}),
...(opts.includeSecrets ...(opts.includeSecrets
@ -594,7 +594,7 @@ export const UserRepository = db.getRepository(User).extend({
lastUsed: true, lastUsed: true,
}, },
}), }),
} }
: {}), : {}),
...(relation ...(relation
@ -609,7 +609,7 @@ export const UserRepository = db.getRepository(User).extend({
isMuted: relation.isMuted, isMuted: relation.isMuted,
isRenoteMuted: relation.isRenoteMuted, isRenoteMuted: relation.isRenoteMuted,
isReplyMuted: relation.isReplyMuted, isReplyMuted: relation.isReplyMuted,
} }
: {}), : {}),
} as Promiseable<Packed<"User">> as Promiseable< } as Promiseable<Packed<"User">> as Promiseable<
IsMeAndIsUserDetailed<ExpectsMe, D> IsMeAndIsUserDetailed<ExpectsMe, D>

View file

@ -3,7 +3,6 @@ import type { EndoRelation, Predicate } from "./relation.js";
/** /**
* Count the number of elements that satisfy the predicate * Count the number of elements that satisfy the predicate
*/ */
export function countIf<T>(f: Predicate<T>, xs: T[]): number { export function countIf<T>(f: Predicate<T>, xs: T[]): number {
return xs.filter(f).length; return xs.filter(f).length;
} }
@ -60,6 +59,21 @@ export function maximum(xs: number[]): number {
return Math.max(...xs); return Math.max(...xs);
} }
/**
* Returns if two arrays are equal
*
* examples:
* equal([1, 2, 3], [1, 2, 3]) === true
* equal([1, 2, 3], [1, 3, 2]) === false
* equal([1, 2, 3], [1, 2]) === false
*/
export function equal<T>(lhs: T[], rhs: T[]): boolean {
return (
lhs.length === rhs.length &&
lhs.every((value, index) => value === rhs[index])
);
}
/** /**
* Splits an array based on the equivalence relation. * Splits an array based on the equivalence relation.
* The concatenation of the result is equal to the argument. * The concatenation of the result is equal to the argument.

View file

@ -9,15 +9,15 @@ export function dateUTC(time: number[]): Date {
time.length === 2 time.length === 2
? Date.UTC(time[0], time[1]) ? Date.UTC(time[0], time[1])
: time.length === 3 : time.length === 3
? Date.UTC(time[0], time[1], time[2]) ? Date.UTC(time[0], time[1], time[2])
: time.length === 4 : time.length === 4
? Date.UTC(time[0], time[1], time[2], time[3]) ? Date.UTC(time[0], time[1], time[2], time[3])
: time.length === 5 : time.length === 5
? Date.UTC(time[0], time[1], time[2], time[3], time[4]) ? Date.UTC(time[0], time[1], time[2], time[3], time[4])
: time.length === 6 : time.length === 6
? Date.UTC(time[0], time[1], time[2], time[3], time[4], time[5]) ? Date.UTC(time[0], time[1], time[2], time[3], time[4], time[5])
: time.length === 7 : time.length === 7
? Date.UTC( ? Date.UTC(
time[0], time[0],
time[1], time[1],
time[2], time[2],
@ -25,8 +25,8 @@ export function dateUTC(time: number[]): Date {
time[4], time[4],
time[5], time[5],
time[6], time[6],
) )
: null; : null;
if (!d) throw new Error("wrong number of arguments"); if (!d) throw new Error("wrong number of arguments");

View file

@ -7,8 +7,8 @@ export function getJobInfo(job: Bull.Job, increment = false) {
age > 60000 age > 60000
? `${Math.floor(age / 1000 / 60)}m` ? `${Math.floor(age / 1000 / 60)}m`
: age > 10000 : age > 10000
? `${Math.floor(age / 1000)}s` ? `${Math.floor(age / 1000)}s`
: `${age}ms`; : `${age}ms`;
// onActiveとかonCompletedのattemptsMadeがなぜか0始まりなのでインクリメントする // onActiveとかonCompletedのattemptsMadeがなぜか0始まりなのでインクリメントする
const currentAttempts = job.attemptsMade + (increment ? 1 : 0); const currentAttempts = job.attemptsMade + (increment ? 1 : 0);

View file

@ -18,7 +18,7 @@ export function initialize<T>(name: string, limitPerSec = -1) {
? { ? {
max: limitPerSec, max: limitPerSec,
duration: 1000, duration: 1000,
} }
: undefined, : undefined,
settings: { settings: {
stalledInterval: 60, stalledInterval: 60,

View file

@ -38,7 +38,7 @@ export async function exportFollowing(
const mutings = job.data.excludeMuting const mutings = job.data.excludeMuting
? await Mutings.findBy({ ? await Mutings.findBy({
muterId: user.id, muterId: user.id,
}) })
: []; : [];
while (true) { while (true) {

View file

@ -48,11 +48,11 @@ export async function importBlocking(
? await Users.findOneBy({ ? await Users.findOneBy({
host: IsNull(), host: IsNull(),
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}) })
: await Users.findOneBy({ : await Users.findOneBy({
host: toPuny(host!), host: toPuny(host!),
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}); });
if (host == null && target == null) continue; if (host == null && target == null) continue;

View file

@ -46,11 +46,11 @@ export async function importFollowing(
? await Users.findOneBy({ ? await Users.findOneBy({
host: IsNull(), host: IsNull(),
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}) })
: await Users.findOneBy({ : await Users.findOneBy({
host: toPuny(host!), host: toPuny(host!),
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}); });
if (host == null && target == null) continue; if (host == null && target == null) continue;
@ -84,11 +84,11 @@ export async function importFollowing(
? await Users.findOneBy({ ? await Users.findOneBy({
host: IsNull(), host: IsNull(),
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}) })
: await Users.findOneBy({ : await Users.findOneBy({
host: toPuny(host!), host: toPuny(host!),
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}); });
if (host == null && target == null) continue; if (host == null && target == null) continue;

View file

@ -49,11 +49,11 @@ export async function importMuting(
? await Users.findOneBy({ ? await Users.findOneBy({
host: IsNull(), host: IsNull(),
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}) })
: await Users.findOneBy({ : await Users.findOneBy({
host: toPuny(host!), host: toPuny(host!),
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}); });
if (host == null && target == null) continue; if (host == null && target == null) continue;

View file

@ -68,11 +68,11 @@ export async function importUserLists(
? await Users.findOneBy({ ? await Users.findOneBy({
host: IsNull(), host: IsNull(),
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}) })
: await Users.findOneBy({ : await Users.findOneBy({
host: toPuny(host!), host: toPuny(host!),
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}); });
if (target == null) { if (target == null) {
target = await resolveUser(username, host); target = await resolveUser(username, host);

View file

@ -205,8 +205,8 @@ export async function createNote(
note.attachment = Array.isArray(note.attachment) note.attachment = Array.isArray(note.attachment)
? note.attachment ? note.attachment
: note.attachment : note.attachment
? [note.attachment] ? [note.attachment]
: []; : [];
const files = note.attachment.map( const files = note.attachment.map(
(attach) => (attach.sensitive = note.sensitive), (attach) => (attach.sensitive = note.sensitive),
) )
@ -216,7 +216,7 @@ export async function createNote(
(x) => limit(() => resolveImage(actor, x)) as Promise<DriveFile>, (x) => limit(() => resolveImage(actor, x)) as Promise<DriveFile>,
), ),
) )
).filter((image) => image != null) ).filter((image) => image != null)
: []; : [];
// Reply // Reply

View file

@ -276,26 +276,26 @@ export async function createPerson(
followersCount !== undefined followersCount !== undefined
? followersCount ? followersCount
: person.followers && : person.followers &&
typeof person.followers !== "string" && typeof person.followers !== "string" &&
isCollectionOrOrderedCollection(person.followers) isCollectionOrOrderedCollection(person.followers)
? person.followers.totalItems ? person.followers.totalItems
: undefined, : undefined,
followingCount: followingCount:
followingCount !== undefined followingCount !== undefined
? followingCount ? followingCount
: person.following && : person.following &&
typeof person.following !== "string" && typeof person.following !== "string" &&
isCollectionOrOrderedCollection(person.following) isCollectionOrOrderedCollection(person.following)
? person.following.totalItems ? person.following.totalItems
: undefined, : undefined,
notesCount: notesCount:
notesCount !== undefined notesCount !== undefined
? notesCount ? notesCount
: person.outbox && : person.outbox &&
typeof person.outbox !== "string" && typeof person.outbox !== "string" &&
isCollectionOrOrderedCollection(person.outbox) isCollectionOrOrderedCollection(person.outbox)
? person.outbox.totalItems ? person.outbox.totalItems
: undefined, : undefined,
featured: person.featured ? getApId(person.featured) : undefined, featured: person.featured ? getApId(person.featured) : undefined,
uri: person.id, uri: person.id,
tags, tags,
@ -315,8 +315,8 @@ export async function createPerson(
description: person._misskey_summary description: person._misskey_summary
? truncate(person._misskey_summary, summaryLength) ? truncate(person._misskey_summary, summaryLength)
: person.summary : person.summary
? htmlToMfm(truncate(person.summary, summaryLength), person.tag) ? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
: null, : null,
url: url, url: url,
fields, fields,
birthday: bday ? bday[0] : null, birthday: bday ? bday[0] : null,
@ -526,26 +526,26 @@ export async function updatePerson(
followersCount !== undefined followersCount !== undefined
? followersCount ? followersCount
: person.followers && : person.followers &&
typeof person.followers !== "string" && typeof person.followers !== "string" &&
isCollectionOrOrderedCollection(person.followers) isCollectionOrOrderedCollection(person.followers)
? person.followers.totalItems ? person.followers.totalItems
: undefined, : undefined,
followingCount: followingCount:
followingCount !== undefined followingCount !== undefined
? followingCount ? followingCount
: person.following && : person.following &&
typeof person.following !== "string" && typeof person.following !== "string" &&
isCollectionOrOrderedCollection(person.following) isCollectionOrOrderedCollection(person.following)
? person.following.totalItems ? person.following.totalItems
: undefined, : undefined,
notesCount: notesCount:
notesCount !== undefined notesCount !== undefined
? notesCount ? notesCount
: person.outbox && : person.outbox &&
typeof person.outbox !== "string" && typeof person.outbox !== "string" &&
isCollectionOrOrderedCollection(person.outbox) isCollectionOrOrderedCollection(person.outbox)
? person.outbox.totalItems ? person.outbox.totalItems
: undefined, : undefined,
featured: person.featured, featured: person.featured,
emojis: emojiNames, emojis: emojiNames,
name: truncate(person.name, nameLength), name: truncate(person.name, nameLength),
@ -592,8 +592,8 @@ export async function updatePerson(
description: person._misskey_summary description: person._misskey_summary
? truncate(person._misskey_summary, summaryLength) ? truncate(person._misskey_summary, summaryLength)
: person.summary : person.summary
? htmlToMfm(truncate(person.summary, summaryLength), person.tag) ? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
: null, : null,
birthday: bday ? bday[0] : null, birthday: bday ? bday[0] : null,
location: person["vcard:Address"] || null, location: person["vcard:Address"] || null,
}, },

View file

@ -22,8 +22,8 @@ export async function extractPollFromQuestion(
const expiresAt = question.endTime const expiresAt = question.endTime
? new Date(question.endTime) ? new Date(question.endTime)
: question.closed : question.closed
? new Date(question.closed) ? new Date(question.closed)
: null; : null;
if (multiple && !question.anyOf) { if (multiple && !question.anyOf) {
throw new Error("invalid question"); throw new Error("invalid question");

View file

@ -85,7 +85,7 @@ export default async function renderNote(
note.mentions.length > 0 note.mentions.length > 0
? await Users.findBy({ ? await Users.findBy({
id: In(note.mentions), id: In(note.mentions),
}) })
: []; : [];
const hashtagTags = (note.tags || []).map((tag) => renderHashtag(tag)); const hashtagTags = (note.tags || []).map((tag) => renderHashtag(tag));
@ -117,7 +117,7 @@ export default async function renderNote(
const contentMap = note.lang const contentMap = note.lang
? { ? {
[note.lang]: content, [note.lang]: content,
} }
: null; : null;
const emojis = await getEmojis(note.emojis); const emojis = await getEmojis(note.emojis);
@ -143,13 +143,13 @@ export default async function renderNote(
totalItems: poll!.votes[i], totalItems: poll!.votes[i],
}, },
})), })),
} }
: {}; : {};
const asTalk = isTalk const asTalk = isTalk
? { ? {
_misskey_talk: true, _misskey_talk: true,
} }
: {}; : {};
return { return {

View file

@ -41,9 +41,9 @@ export async function renderPerson(user: ILocalUser) {
value: field.value?.match(/^https?:/) value: field.value?.match(/^https?:/)
? `<a href="${ ? `<a href="${
new URL(field.value).href new URL(field.value).href
}" rel="me nofollow noopener" target="_blank">${ }" rel="me nofollow noopener" target="_blank">${
new URL(field.value).href new URL(field.value).href
}</a>` }</a>`
: field.value, : field.value,
}); });
} }

View file

@ -121,7 +121,7 @@ export default class Resolver {
(Array.isArray(object["@context"]) (Array.isArray(object["@context"])
? !(object["@context"] as unknown[]).includes( ? !(object["@context"] as unknown[]).includes(
"https://www.w3.org/ns/activitystreams", "https://www.w3.org/ns/activitystreams",
) )
: object["@context"] !== "https://www.w3.org/ns/activitystreams") : object["@context"] !== "https://www.w3.org/ns/activitystreams")
) { ) {
throw new Error("invalid response"); throw new Error("invalid response");

View file

@ -94,7 +94,7 @@ export default async (ctx: Router.RouterContext) => {
? `${partOf}?${url.query({ ? `${partOf}?${url.query({
page: "true", page: "true",
cursor: followings[followings.length - 1].id, cursor: followings[followings.length - 1].id,
})}` })}`
: undefined, : undefined,
); );

View file

@ -94,7 +94,7 @@ export default async (ctx: Router.RouterContext) => {
? `${partOf}?${url.query({ ? `${partOf}?${url.query({
page: "true", page: "true",
cursor: followings[followings.length - 1].id, cursor: followings[followings.length - 1].id,
})}` })}`
: undefined, : undefined,
); );

View file

@ -93,13 +93,13 @@ export default async (ctx: Router.RouterContext) => {
? `${partOf}?${url.query({ ? `${partOf}?${url.query({
page: "true", page: "true",
since_id: notes[0].id, since_id: notes[0].id,
})}` })}`
: undefined, : undefined,
notes.length notes.length
? `${partOf}?${url.query({ ? `${partOf}?${url.query({
page: "true", page: "true",
until_id: notes[notes.length - 1].id, until_id: notes[notes.length - 1].id,
})}` })}`
: undefined, : undefined,
); );

View file

@ -22,8 +22,8 @@ export default (endpoint: IEndpoint, ctx: Koa.Context) =>
const body = ctx.is("multipart/form-data") const body = ctx.is("multipart/form-data")
? (ctx.request as any).body ? (ctx.request as any).body
: ctx.method === "GET" : ctx.method === "GET"
? ctx.query ? ctx.query
: ctx.request.body; : ctx.request.body;
const reply = (x?: any, y?: ApiError) => { const reply = (x?: any, y?: ApiError) => {
if (x == null) { if (x == null) {
@ -76,8 +76,8 @@ export default (endpoint: IEndpoint, ctx: Koa.Context) =>
e.httpStatusCode e.httpStatusCode
? e.httpStatusCode ? e.httpStatusCode
: e.kind === "client" : e.kind === "client"
? 400 ? 400
: 500, : 500,
e, e,
); );
}); });

View file

@ -11,7 +11,7 @@ export async function injectPromo(timeline: Note[], user?: User | null) {
const reads = user const reads = user
? await PromoReads.findBy({ ? await PromoReads.findBy({
userId: user.id, userId: user.id,
}) })
: []; : [];
let promos = await PromoNotes.find(); let promos = await PromoNotes.find();

View file

@ -210,7 +210,7 @@ export default define(meta, paramDef, async (ps, me) => {
webpublicUrl: ps.url, webpublicUrl: ps.url,
}, },
], ],
}); });
if (file == null) { if (file == null) {
throw new ApiError(meta.errors.noSuchFile); throw new ApiError(meta.errors.noSuchFile);

View file

@ -38,16 +38,16 @@ export default define(meta, paramDef, async (ps, user) => {
item.value === null item.value === null
? "null" ? "null"
: Array.isArray(item.value) : Array.isArray(item.value)
? "array" ? "array"
: type === "number" : type === "number"
? "number" ? "number"
: type === "string" : type === "string"
? "string" ? "string"
: type === "boolean" : type === "boolean"
? "boolean" ? "boolean"
: type === "object" : type === "object"
? "object" ? "object"
: (null as never); : (null as never);
} }
return res; return res;

View file

@ -44,7 +44,7 @@ export default define(meta, paramDef, async (ps, user) => {
const groups = ps.group const groups = ps.group
? await UserGroupJoinings.findBy({ ? await UserGroupJoinings.findBy({
userId: user.id, userId: user.id,
}).then((xs) => xs.map((x) => x.userGroupId)) }).then((xs) => xs.map((x) => x.userGroupId))
: []; : [];
if (ps.group && groups.length === 0) { if (ps.group && groups.length === 0) {

View file

@ -477,7 +477,7 @@ export default define(meta, paramDef, async (ps, me) => {
place: ad.place, place: ad.place,
ratio: ad.ratio, ratio: ad.ratio,
imageUrl: ad.imageUrl, imageUrl: ad.imageUrl,
})), })),
enableEmail: instance.enableEmail, enableEmail: instance.enableEmail,
enableServiceWorker: instance.enableServiceWorker, enableServiceWorker: instance.enableServiceWorker,
@ -501,7 +501,7 @@ export default define(meta, paramDef, async (ps, me) => {
host: IsNull(), host: IsNull(),
isAdmin: true, isAdmin: true,
})) === 0, })) === 0,
} }
: {}), : {}),
}; };

View file

@ -297,7 +297,7 @@ export default define(meta, paramDef, async (ps, user) => {
choices: ps.poll.choices, choices: ps.poll.choices,
multiple: ps.poll.multiple, multiple: ps.poll.multiple,
expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null,
} }
: undefined, : undefined,
text: ps.text || undefined, text: ps.text || undefined,
lang: ps.lang, lang: ps.lang,

View file

@ -9,6 +9,7 @@ import {
UserProfiles, UserProfiles,
Polls, Polls,
NoteEdits, NoteEdits,
NoteFiles,
} from "@/models/index.js"; } from "@/models/index.js";
import type { DriveFile } from "@/models/entities/drive-file.js"; import type { DriveFile } from "@/models/entities/drive-file.js";
import type { IMentionedRemoteUsers, Note } from "@/models/entities/note.js"; import type { IMentionedRemoteUsers, Note } from "@/models/entities/note.js";
@ -34,7 +35,6 @@ import renderUpdate from "@/remote/activitypub/renderer/update.js";
import { deliverToRelays } from "@/services/relay.js"; import { deliverToRelays } from "@/services/relay.js";
// import { deliverQuestionUpdate } from "@/services/note/polls/update.js"; // import { deliverQuestionUpdate } from "@/services/note/polls/update.js";
import { langmap } from "@/misc/langmap.js"; import { langmap } from "@/misc/langmap.js";
import detectLanguage from "@/misc/detect-language.js";
export const meta = { export const meta = {
tags: ["notes"], tags: ["notes"],
@ -606,6 +606,13 @@ export default define(meta, paramDef, async (ps, user) => {
update.updatedAt = new Date(); update.updatedAt = new Date();
await Notes.update(note.id, update); await Notes.update(note.id, update);
if (update.fileIds != null) {
await NoteFiles.delete({ noteId: note.id });
await NoteFiles.insert(
update.fileIds.map((fileId) => ({ noteId: note.id, fileId })),
);
}
// Add NoteEdit history for the previous one // Add NoteEdit history for the previous one
await NoteEdits.insert({ await NoteEdits.insert({
id: genId(), id: genId(),

View file

@ -128,7 +128,7 @@ export default define(meta, paramDef, async (ps, user) => {
ps.eyeCatchingImageId === null ps.eyeCatchingImageId === null
? null ? null
: ps.eyeCatchingImageId === undefined : ps.eyeCatchingImageId === undefined
? page.eyeCatchingImageId ? page.eyeCatchingImageId
: eyeCatchingImage!.id, : eyeCatchingImage!.id,
}); });
}); });

View file

@ -81,7 +81,7 @@ export default define(meta, paramDef, async (ps, me) => {
: { : {
usernameLower: ps.username!.toLowerCase(), usernameLower: ps.username!.toLowerCase(),
host: toPunyNullable(ps.host) ?? IsNull(), host: toPunyNullable(ps.host) ?? IsNull(),
}, },
); );
if (user == null) { if (user == null) {

View file

@ -80,7 +80,7 @@ export default define(meta, paramDef, async (ps, me) => {
: { : {
usernameLower: ps.username!.toLowerCase(), usernameLower: ps.username!.toLowerCase(),
host: toPunyNullable(ps.host) ?? IsNull(), host: toPunyNullable(ps.host) ?? IsNull(),
}, },
); );
if (user == null) { if (user == null) {

View file

@ -40,7 +40,7 @@ export default define(meta, paramDef, async (ps, me) => {
...(ownedGroups.length > 0 ...(ownedGroups.length > 0
? { ? {
userGroupId: Not(In(ownedGroups.map((x) => x.id))), userGroupId: Not(In(ownedGroups.map((x) => x.id))),
} }
: {}), : {}),
}); });

View file

@ -67,10 +67,10 @@ export function apiTimelineMastodon(router: Router): void {
query.local === "true" query.local === "true"
? await client.getLocalTimeline( ? await client.getLocalTimeline(
convertTimelinesArgsId(argsToBools(limitToInt(query))), convertTimelinesArgsId(argsToBools(limitToInt(query))),
) )
: await client.getPublicTimeline( : await client.getPublicTimeline(
convertTimelinesArgsId(argsToBools(limitToInt(query))), convertTimelinesArgsId(argsToBools(limitToInt(query))),
); );
ctx.body = data.data.map((status) => convertStatus(status)); ctx.body = data.data.map((status) => convertStatus(status));
} catch (e: any) { } catch (e: any) {
apiLogger.error(inspect(e)); apiLogger.error(inspect(e));

View file

@ -129,12 +129,12 @@ export function genOpenapiSpec() {
}, },
}, },
}, },
} }
: { : {
"204": { "204": {
description: "OK (without any results)", description: "OK (without any results)",
}, },
}), }),
"400": { "400": {
description: "Client error", description: "Client error",
content: { content: {
@ -192,7 +192,7 @@ export function genOpenapiSpec() {
}, },
}, },
}, },
} }
: {}), : {}),
"500": { "500": {
description: "Internal server error", description: "Internal server error",

View file

@ -68,7 +68,7 @@ export const initializeStreamingServer = (server: http.Server) => {
}); });
}, },
1000 * 60 * 5, 1000 * 60 * 5,
) )
: null; : null;
if (user) { if (user) {
Users.update(user.id, { Users.update(user.id, {

View file

@ -195,7 +195,7 @@ export default async function (ctx: Koa.Context) {
BigInt(file.size), BigInt(file.size),
ranges, ranges,
contentType, contentType,
); );
readable.on("error", commonReadableHandlerGenerator(ctx)); readable.on("error", commonReadableHandlerGenerator(ctx));
ctx.body = readable; ctx.body = readable;

View file

@ -107,15 +107,15 @@ export default async function (
let outstr = author let outstr = author
? `${author.name}(@${author.username}@${ ? `${author.name}(@${author.username}@${
author.host ? author.host : config.host author.host ? author.host : config.host
}) ${ }) ${
note.renoteId ? "renotes" : note.replyId ? "replies" : "says" note.renoteId ? "renotes" : note.replyId ? "replies" : "says"
}: <br>` }: <br>`
: ""; : "";
const files = const files =
note.fileIds.length > 0 note.fileIds.length > 0
? await DriveFiles.findBy({ ? await DriveFiles.findBy({
id: In(note.fileIds), id: In(note.fileIds),
}) })
: []; : [];
let fileEle = ""; let fileEle = "";
for (const file of files) { for (const file of files) {

View file

@ -95,7 +95,7 @@ app.use(
`${_dirname}/../../../../../built/_client_dist_/manifest.json`, `${_dirname}/../../../../../built/_client_dist_/manifest.json`,
"utf-8", "utf-8",
), ),
)["src/init.ts"], )["src/init.ts"],
config, config,
}, },
}), }),

View file

@ -37,11 +37,11 @@ export const urlPreviewHandler = async (ctx: Koa.Context) => {
url: url, url: url,
lang: lang ?? "en-US", lang: lang ?? "en-US",
})}`, })}`,
) )
: await summaly.default(url, { : await summaly.default(url, {
followRedirects: false, followRedirects: false,
lang: lang ?? "en-US", lang: lang ?? "en-US",
}); });
logger.succ(`Got preview of ${url}: ${summary.title}`); logger.succ(`Got preview of ${url}: ${summary.title}`);
@ -83,7 +83,7 @@ function wrap(url?: string): string | null {
? `${config.url}/proxy/preview.webp?${query({ ? `${config.url}/proxy/preview.webp?${query({
url, url,
preview: "1", preview: "1",
})}` })}`
: url : url
: null; : null;
} }

View file

@ -114,10 +114,10 @@ router.get(webFingerPath, async (ctx) => {
resource.startsWith(`${config.url.toLowerCase()}/@`) resource.startsWith(`${config.url.toLowerCase()}/@`)
? resource.split("/").pop()! ? resource.split("/").pop()!
: resource.startsWith("acct:") : resource.startsWith("acct:")
? resource.slice("acct:".length) ? resource.slice("acct:".length)
: resource, : resource,
), ),
); );
const fromAcct = (acct: Acct.Acct): FindOptionsWhere<User> | number => const fromAcct = (acct: Acct.Acct): FindOptionsWhere<User> | number =>
!acct.host || acct.host === config.host.toLowerCase() !acct.host || acct.host === config.host.toLowerCase()
@ -125,7 +125,7 @@ router.get(webFingerPath, async (ctx) => {
usernameLower: acct.username, usernameLower: acct.username,
host: IsNull(), host: IsNull(),
isSuspended: false, isSuspended: false,
} }
: 422; : 422;
if (typeof ctx.query.resource !== "string") { if (typeof ctx.query.resource !== "string") {

View file

@ -97,10 +97,10 @@ type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (
type UnflattenSingleton<K extends string, V> = K extends `${infer A}.${infer B}` type UnflattenSingleton<K extends string, V> = K extends `${infer A}.${infer B}`
? { ? {
[_ in A]: UnflattenSingleton<B, V>; [_ in A]: UnflattenSingleton<B, V>;
} }
: { : {
[_ in K]: V; [_ in K]: V;
}; };
type Unflatten<T extends Record<string, any>> = UnionToIntersection< type Unflatten<T extends Record<string, any>> = UnionToIntersection<
{ {
@ -176,8 +176,8 @@ export default abstract class Chart<T extends Schema> {
v.range === "big" v.range === "big"
? "bigint" ? "bigint"
: v.range === "small" : v.range === "small"
? "smallint" ? "smallint"
: "integer"; : "integer";
if (v.uniqueIncrement) { if (v.uniqueIncrement) {
columns[uniqueTempColumnPrefix + name] = { columns[uniqueTempColumnPrefix + name] = {
type: "varchar", type: "varchar",
@ -234,8 +234,8 @@ export default abstract class Chart<T extends Schema> {
span === "hour" span === "hour"
? `__chart__${camelToSnake(name)}` ? `__chart__${camelToSnake(name)}`
: span === "day" : span === "day"
? `__chart_day__${camelToSnake(name)}` ? `__chart_day__${camelToSnake(name)}`
: (new Error("not happen") as never), : (new Error("not happen") as never),
columns: { columns: {
id: { id: {
type: "integer", type: "integer",
@ -251,7 +251,7 @@ export default abstract class Chart<T extends Schema> {
type: "varchar", type: "varchar",
length: 128, length: 128,
}, },
} }
: {}), : {}),
...Chart.convertSchemaToColumnDefinitions(schema), ...Chart.convertSchemaToColumnDefinitions(schema),
}, },
@ -335,15 +335,15 @@ export default abstract class Chart<T extends Schema> {
span === "hour" span === "hour"
? this.repositoryForHour ? this.repositoryForHour
: span === "day" : span === "day"
? this.repositoryForDay ? this.repositoryForDay
: (new Error("not happen") as never); : (new Error("not happen") as never);
return repository return repository
.findOne({ .findOne({
where: group where: group
? { ? {
group: group, group: group,
} }
: {}, : {},
order: { order: {
date: -1, date: -1,
@ -365,16 +365,16 @@ export default abstract class Chart<T extends Schema> {
span === "hour" span === "hour"
? [y, m, d, h] ? [y, m, d, h]
: span === "day" : span === "day"
? [y, m, d] ? [y, m, d]
: (new Error("not happen") as never), : (new Error("not happen") as never),
); );
const repository = const repository =
span === "hour" span === "hour"
? this.repositoryForHour ? this.repositoryForHour
: span === "day" : span === "day"
? this.repositoryForDay ? this.repositoryForDay
: (new Error("not happen") as never); : (new Error("not happen") as never);
// 現在(=今のHour or Day)のログ // 現在(=今のHour or Day)のログ
const currentLog = (await repository.findOneBy({ const currentLog = (await repository.findOneBy({
@ -729,21 +729,21 @@ export default abstract class Chart<T extends Schema> {
cursor ? dateUTC([y2, m2, d2, 0]) : dateUTC([y, m, d, 0]), cursor ? dateUTC([y2, m2, d2, 0]) : dateUTC([y, m, d, 0]),
amount - 1, amount - 1,
"day", "day",
) )
: span === "hour" : span === "hour"
? subtractTime( ? subtractTime(
cursor ? dateUTC([y2, m2, d2, h2]) : dateUTC([y, m, d, h]), cursor ? dateUTC([y2, m2, d2, h2]) : dateUTC([y, m, d, h]),
amount - 1, amount - 1,
"hour", "hour",
) )
: (new Error("not happen") as never); : (new Error("not happen") as never);
const repository = const repository =
span === "hour" span === "hour"
? this.repositoryForHour ? this.repositoryForHour
: span === "day" : span === "day"
? this.repositoryForDay ? this.repositoryForDay
: (new Error("not happen") as never); : (new Error("not happen") as never);
// ログ取得 // ログ取得
let logs = (await repository.find({ let logs = (await repository.find({
@ -764,7 +764,7 @@ export default abstract class Chart<T extends Schema> {
where: group where: group
? { ? {
group: group, group: group,
} }
: {}, : {},
order: { order: {
date: -1, date: -1,
@ -801,8 +801,8 @@ export default abstract class Chart<T extends Schema> {
span === "hour" span === "hour"
? subtractTime(dateUTC([y, m, d, h]), i, "hour") ? subtractTime(dateUTC([y, m, d, h]), i, "hour")
: span === "day" : span === "day"
? subtractTime(dateUTC([y, m, d]), i, "day") ? subtractTime(dateUTC([y, m, d]), i, "day")
: (new Error("not happen") as never); : (new Error("not happen") as never);
const log = logs.find((l) => const log = logs.find((l) =>
isTimeSame(new Date(l.date * 1000), current), isTimeSame(new Date(l.date * 1000), current),

View file

@ -583,11 +583,11 @@ export async function addFile({
file.requestHeaders = requestHeaders; file.requestHeaders = requestHeaders;
file.isSensitive = user file.isSensitive = user
? Users.isLocalUser(user) && ? Users.isLocalUser(user) &&
(instance!.markLocalFilesNsfwByDefault || profile!.alwaysMarkNsfw) (instance!.markLocalFilesNsfwByDefault || profile!.alwaysMarkNsfw)
? true ? true
: sensitive != null : sensitive != null
? sensitive ? sensitive
: false : false
: false; : false;
if (url != null) { if (url != null) {

View file

@ -9,7 +9,7 @@ export function getS3(meta: Meta) {
meta.objectStorageEndpoint != null meta.objectStorageEndpoint != null
? `${meta.objectStorageUseSsl ? "https://" : "http://"}${ ? `${meta.objectStorageUseSsl ? "https://" : "http://"}${
meta.objectStorageEndpoint meta.objectStorageEndpoint
}` }`
: `${meta.objectStorageUseSsl ? "https://" : "http://"}example.net`; : `${meta.objectStorageUseSsl ? "https://" : "http://"}example.net`;
try { try {

View file

@ -85,16 +85,16 @@ export default class Logger {
? chalk.bgRed.white("ERR ") ? chalk.bgRed.white("ERR ")
: chalk.red("ERR ") : chalk.red("ERR ")
: level === "warning" : level === "warning"
? chalk.yellow("WARN") ? chalk.yellow("WARN")
: level === "success" : level === "success"
? important ? important
? chalk.bgGreen.white("DONE") ? chalk.bgGreen.white("DONE")
: chalk.green("DONE") : chalk.green("DONE")
: level === "debug" : level === "debug"
? chalk.gray("VERB") ? chalk.gray("VERB")
: level === "info" : level === "info"
? chalk.blue("INFO") ? chalk.blue("INFO")
: null; : null;
const domains = [this.domain] const domains = [this.domain]
.concat(subDomains) .concat(subDomains)
.map((d) => .map((d) =>
@ -106,14 +106,14 @@ export default class Logger {
level === "error" level === "error"
? chalk.red(message) ? chalk.red(message)
: level === "warning" : level === "warning"
? chalk.yellow(message) ? chalk.yellow(message)
: level === "success" : level === "success"
? chalk.green(message) ? chalk.green(message)
: level === "debug" : level === "debug"
? chalk.gray(message) ? chalk.gray(message)
: level === "info" : level === "info"
? message ? message
: null; : null;
let log = `${l} ${worker}\t[${domains.join(" ")}]\t${m}`; let log = `${l} ${worker}\t[${domains.join(" ")}]\t${m}`;
if (envOption.withLogTime) log = `${chalk.gray(time)} ${log}`; if (envOption.withLogTime) log = `${chalk.gray(time)} ${log}`;
@ -130,14 +130,14 @@ export default class Logger {
level === "error" level === "error"
? this.syslogClient.error ? this.syslogClient.error
: level === "warning" : level === "warning"
? this.syslogClient.warning ? this.syslogClient.warning
: level === "success" : level === "success"
? this.syslogClient.info ? this.syslogClient.info
: level === "debug" : level === "debug"
? this.syslogClient.info ? this.syslogClient.info
: level === "info" : level === "info"
? this.syslogClient.info ? this.syslogClient.info
: (null as never); : (null as never);
send send
.bind(this.syslogClient)(message) .bind(this.syslogClient)(message)

View file

@ -679,7 +679,7 @@ async function renderNoteOrRenoteActivity(data: Option, note: Note) {
? data.renote.uri ? data.renote.uri
: `${config.url}/notes/${data.renote.id}`, : `${config.url}/notes/${data.renote.id}`,
note, note,
) )
: renderCreate(await renderNote(note, false), note); : renderCreate(await renderNote(note, false), note);
return renderActivity(content); return renderActivity(content);

View file

@ -99,11 +99,11 @@ export default async function (
note, note,
), ),
user, user,
) )
: renderDelete( : renderDelete(
renderTombstone(`${config.url}/notes/${note.id}`), renderTombstone(`${config.url}/notes/${note.id}`),
user, user,
), ),
); );
deliverToConcerned(user, note, content); deliverToConcerned(user, note, content);

View file

@ -110,7 +110,7 @@ export default async (
? `${emoji.name}@${emoji.host}` ? `${emoji.name}@${emoji.host}`
: `${emoji.name}@.`, : `${emoji.name}@.`,
url: emoji.publicUrl || emoji.originalUrl, // || emoji.originalUrl してるのは後方互換性のため url: emoji.publicUrl || emoji.originalUrl, // || emoji.originalUrl してるのは後方互換性のため
} }
: null, : null,
userId: user.id, userId: user.id,
}); });

View file

@ -34,7 +34,7 @@ export default async function (
select: ["followeeId"], select: ["followeeId"],
}) })
).map((x) => x.followeeId), ).map((x) => x.followeeId),
); );
const followingChannels = info?.followingChannels const followingChannels = info?.followingChannels
? info.followingChannels ? info.followingChannels
: new Set<string>( : new Set<string>(
@ -46,7 +46,7 @@ export default async function (
select: ["followeeId"], select: ["followeeId"],
}) })
).map((x) => x.followeeId), ).map((x) => x.followeeId),
); );
// const myAntennas = (await getAntennas()).filter((a) => a.userId === userId); // const myAntennas = (await getAntennas()).filter((a) => a.userId === userId);
const readMentions: (Note | Packed<"Note">)[] = []; const readMentions: (Note | Packed<"Note">)[] = [];

View file

@ -29,7 +29,7 @@ export async function sendEmail(
? { ? {
user: meta.smtpUser, user: meta.smtpUser,
pass: meta.smtpPass, pass: meta.smtpPass,
} }
: undefined, : undefined,
} as any); } as any);

View file

@ -33,8 +33,8 @@ class Publisher {
type == null type == null
? value ? value
: value == null : value == null
? { type: type, body: null } ? { type: type, body: null }
: { type: type, body: value }; : { type: type, body: value };
redisClient.publish( redisClient.publish(
config.host, config.host,

View file

@ -21,7 +21,7 @@ export async function validateEmailForAccount(emailAddress: string): Promise<{
validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
validateDisposable: true, // 捨てアドかどうかチェック validateDisposable: true, // 捨てアドかどうかチェック
validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
}) })
: { valid: true }; : { valid: true };
const available = exist === 0 && validated.valid; const available = exist === 0 && validated.valid;
@ -31,15 +31,15 @@ export async function validateEmailForAccount(emailAddress: string): Promise<{
reason: available reason: available
? null ? null
: exist !== 0 : exist !== 0
? "used" ? "used"
: validated.reason === "regex" : validated.reason === "regex"
? "format" ? "format"
: validated.reason === "disposable" : validated.reason === "disposable"
? "disposable" ? "disposable"
: validated.reason === "mx" : validated.reason === "mx"
? "mx" ? "mx"
: validated.reason === "smtp" : validated.reason === "smtp"
? "smtp" ? "smtp"
: null, : null,
}; };
} }

View file

@ -171,7 +171,7 @@ describe("ユーザー", () => {
email: user.email, email: user.email,
emailVerified: user.emailVerified, emailVerified: user.emailVerified,
securityKeysList: user.securityKeysList, securityKeysList: user.securityKeysList,
} }
: {}), : {}),
}); });
}; };

View file

@ -37,7 +37,7 @@ export const api = async (endpoint: string, params: any, me?: any) => {
const auth = me const auth = me
? { ? {
i: me.token, i: me.token,
} }
: {}; : {};
const res = await got<string>(`http://localhost:${port}/api/${endpoint}`, { const res = await got<string>(`http://localhost:${port}/api/${endpoint}`, {
@ -77,7 +77,7 @@ export const request = async (
const auth = me const auth = me
? { ? {
i: me.token, i: me.token,
} }
: {}; : {};
const res = await fetch(`http://localhost:${port}/api${endpoint}`, { const res = await fetch(`http://localhost:${port}/api${endpoint}`, {
@ -152,8 +152,8 @@ export const uploadFile = async (user: any, _path?: string): Promise<any> => {
_path == null _path == null
? `${_dirname}/resources/Lenna.jpg` ? `${_dirname}/resources/Lenna.jpg`
: path.isAbsolute(_path) : path.isAbsolute(_path)
? _path ? _path
: `${_dirname}/resources/${_path}`; : `${_dirname}/resources/${_path}`;
const formData = new FormData() as any; const formData = new FormData() as any;
formData.append("i", user.token); formData.append("i", user.token);

View file

@ -173,10 +173,10 @@
return c == 0 return c == 0
? Math.PI / 2 ? Math.PI / 2
: ((a = c / (this.length() * b.length())), a >= 1) : ((a = c / (this.length() * b.length())), a >= 1)
? 0 ? 0
: a <= -1 : a <= -1
? Math.PI ? Math.PI
: Math.acos(a); : Math.acos(a);
}), }),
(z.unit = function () { (z.unit = function () {
var a = this.length(); var a = this.length();
@ -226,7 +226,7 @@
this[a][1] * c[1][b] + this[a][1] * c[1][b] +
this[a][2] * c[2][b] + this[a][2] * c[2][b] +
this[a][3] * c[3][b], this[a][3] * c[3][b],
) )
: d.push(this[a][b] * c); : d.push(this[a][b] * c);
return new m(d); return new m(d);
}), }),
@ -330,14 +330,14 @@
D[a.substr(1, 2)] + D[a.substr(1, 2)] +
D[a.substr(3, 2)] + D[a.substr(3, 2)] +
D[a.substr(5, 2)])), D[a.substr(5, 2)])),
(b = I[a] + f)) (b = I[a] + f))
: a.substr(0, 4) === "rgb(" || a.substr(0, 4) === "hsl(" : a.substr(0, 4) === "rgb(" || a.substr(0, 4) === "hsl("
? (b = a.replace("(", "a(").replace(")", "," + f)) ? (b = a.replace("(", "a(").replace(")", "," + f))
: (a.substr(0, 5) === "rgba(" || a.substr(0, 5) === "hsla(") && : (a.substr(0, 5) === "rgba(" || a.substr(0, 5) === "hsla(") &&
((d = a.lastIndexOf(",") + 1), ((d = a.lastIndexOf(",") + 1),
(e = a.indexOf(")")), (e = a.indexOf(")")),
(c *= parseFloat(a.substring(d, e))), (c *= parseFloat(a.substring(d, e))),
(b = a.substr(0, d) + c.toPrecision(3) + ")")), (b = a.substr(0, d) + c.toPrecision(3) + ")")),
b b
); );
} }
@ -414,13 +414,13 @@
function y(d, a, b, f, e, c, g) { function y(d, a, b, f, e, c, g) {
c c
? (d.beginPath(), ? (d.beginPath(),
d.moveTo(a, b + e - c), d.moveTo(a, b + e - c),
d.arcTo(a, b, a + c, b, c), d.arcTo(a, b, a + c, b, c),
d.arcTo(a + f, b, a + f, b + c, c), d.arcTo(a + f, b, a + f, b + c, c),
d.arcTo(a + f, b + e, a + f - c, b + e, c), d.arcTo(a + f, b + e, a + f - c, b + e, c),
d.arcTo(a, b + e, a, b + e - c, c), d.arcTo(a, b + e, a, b + e - c, c),
d.closePath(), d.closePath(),
d[g ? "stroke" : "fill"]()) d[g ? "stroke" : "fill"]())
: d[g ? "strokeRect" : "fillRect"](a, b, f, e); : d[g ? "strokeRect" : "fillRect"](a, b, f, e);
} }
function O(a, b, c, d, e, f, g, h, i) { function O(a, b, c, d, e, f, g, h, i) {
@ -489,33 +489,33 @@
? (c < this.width ? (c < this.width
? (w += this.Align(c, this.width, this.ialign)) ? (w += this.Align(c, this.width, this.ialign))
: (v += this.Align(this.width, c, this.align)), : (v += this.Align(this.width, c, this.align)),
this.ipos == "top" this.ipos == "top"
? (r += d + this.ipad) ? (r += d + this.ipad)
: (n += this.height + this.ipad), : (n += this.height + this.ipad),
(e = g(e, c + l)), (e = g(e, c + l)),
(f += d + this.ipad)) (f += d + this.ipad))
: (d < this.height : (d < this.height
? (n += this.Align(d, this.height, this.ivalign)) ? (n += this.Align(d, this.height, this.ivalign))
: (r += this.Align(this.height, d, this.valign)), : (r += this.Align(this.height, d, this.valign)),
this.ipos == "right" this.ipos == "right"
? (w += this.width + this.ipad) ? (w += this.width + this.ipad)
: (v += c + this.ipad), : (v += c + this.ipad),
(e += c + this.ipad), (e += c + this.ipad),
(f = g(f, d + i)))), (f = g(f, d + i)))),
(o = k(e, f)), (o = k(e, f)),
!o !o
? null ? null
: ((l = i = b / 2), : ((l = i = b / 2),
(s = e - b), (s = e - b),
(u = f - b), (u = f - b),
(x = h(E, s / 2, u / 2)), (x = h(E, s / 2, u / 2)),
(a = o.getContext("2d")), (a = o.getContext("2d")),
D && ((a.fillStyle = D), y(a, l, i, s, u, x)), D && ((a.fillStyle = D), y(a, l, i, s, u, x)),
b && b &&
((a.strokeStyle = F), (a.lineWidth = b), y(a, l, i, s, u, x, !0)), ((a.strokeStyle = F), (a.lineWidth = b), y(a, l, i, s, u, x, !0)),
(m || B || C) && (m || B || C) &&
((t = k(e, f)), t && ((z = a), (a = t.getContext("2d")))), ((t = k(e, f)), t && ((z = a), (a = t.getContext("2d")))),
Y( Y(
a, a,
this.font, this.font,
G, G,
@ -528,16 +528,16 @@
this.maxWidth, this.maxWidth,
this.stringWidths, this.stringWidths,
this.align, this.align,
), ),
this.image && a.drawImage(this.image, w, n, c, d), this.image && a.drawImage(this.image, w, n, c, d),
z && z &&
((a = z), ((a = z),
A && (a.shadowColor = A), A && (a.shadowColor = A),
m && (a.shadowBlur = m), m && (a.shadowBlur = m),
(a.shadowOffsetX = q[0]), (a.shadowOffsetX = q[0]),
(a.shadowOffsetY = q[1]), (a.shadowOffsetY = q[1]),
a.drawImage(t, 0, 0)), a.drawImage(t, 0, 0)),
o) o)
); );
}); });
function H(a, c, d) { function H(a, c, d) {
@ -545,8 +545,8 @@
e; e;
return b return b
? ((e = b.getContext("2d")), ? ((e = b.getContext("2d")),
e.drawImage(a, (c - a.width) / 2, (d - a.height) / 2), e.drawImage(a, (c - a.width) / 2, (d - a.height) / 2),
b) b)
: null; : null;
} }
function S(e, b, c) { function S(e, b, c) {
@ -568,28 +568,28 @@
p; p;
return l return l
? ((c *= e), ? ((c *= e),
(r *= e), (r *= e),
(i = q = c / 2), (i = q = c / 2),
(m = g - c), (m = g - c),
(j = f - c), (j = f - c),
(d = d * e + i), (d = d * e + i),
(b = l.getContext("2d")), (b = l.getContext("2d")),
(p = h(r, m / 2, j / 2)), (p = h(r, m / 2, j / 2)),
s && ((b.fillStyle = s), y(b, i, q, m, j, p)), s && ((b.fillStyle = s), y(b, i, q, m, j, p)),
c && ((b.strokeStyle = v), (b.lineWidth = c), y(b, i, q, m, j, p, !0)), c && ((b.strokeStyle = v), (b.lineWidth = c), y(b, i, q, m, j, p, !0)),
w w
? ((o = k(g, f)), ? ((o = k(g, f)),
(a = o.getContext("2d")), (a = o.getContext("2d")),
a.drawImage(n, d, d, u, t), a.drawImage(n, d, d, u, t),
(a.globalCompositeOperation = "source-in"), (a.globalCompositeOperation = "source-in"),
(a.fillStyle = v), (a.fillStyle = v),
a.fillRect(0, 0, g, f), a.fillRect(0, 0, g, f),
(a.globalCompositeOperation = "destination-over"), (a.globalCompositeOperation = "destination-over"),
a.drawImage(l, 0, 0), a.drawImage(l, 0, 0),
(a.globalCompositeOperation = "source-over"), (a.globalCompositeOperation = "source-over"),
b.drawImage(o, 0, 0)) b.drawImage(o, 0, 0))
: b.drawImage(n, d, d, n.width, n.height), : b.drawImage(n, d, d, n.width, n.height),
{ image: l, width: g / e, height: f / e }) { image: l, width: g / e, height: f / e })
: null; : null;
} }
function at(l, f, c, d, j) { function at(l, f, c, d, j) {
@ -602,20 +602,20 @@
!e !e
? null ? null
: (f.indexOf("%") > 0 ? (b = (i * b) / 100) : (b = b * j), : (f.indexOf("%") > 0 ? (b = (i * b) / 100) : (b = b * j),
(a = e.getContext("2d")), (a = e.getContext("2d")),
(a.globalCompositeOperation = "source-over"), (a.globalCompositeOperation = "source-over"),
(a.fillStyle = "#fff"), (a.fillStyle = "#fff"),
b >= i / 2 b >= i / 2
? ((b = h(c, d) / 2), ? ((b = h(c, d) / 2),
a.beginPath(), a.beginPath(),
a.moveTo(c / 2, d / 2), a.moveTo(c / 2, d / 2),
a.arc(c / 2, d / 2, b, 0, 2 * Math.PI, !1), a.arc(c / 2, d / 2, b, 0, 2 * Math.PI, !1),
a.fill(), a.fill(),
a.closePath()) a.closePath())
: ((b = h(c / 2, d / 2, b)), y(a, 0, 0, c, d, b, !0), a.fill()), : ((b = h(c / 2, d / 2, b)), y(a, 0, 0, c, d, b, !0), a.fill()),
(a.globalCompositeOperation = "source-in"), (a.globalCompositeOperation = "source-in"),
a.drawImage(l, 0, 0, c, d), a.drawImage(l, 0, 0, c, d),
e) e)
); );
} }
function ao(q, m, i, b, h, a, c) { function ao(q, m, i, b, h, a, c) {
@ -632,11 +632,11 @@
!e !e
? null ? null
: ((d = e.getContext("2d")), : ((d = e.getContext("2d")),
h && (d.shadowColor = h), h && (d.shadowColor = h),
a && (d.shadowBlur = a * b), a && (d.shadowBlur = a * b),
c && ((d.shadowOffsetX = c[0] * b), (d.shadowOffsetY = c[1] * b)), c && ((d.shadowOffsetX = c[0] * b), (d.shadowOffsetY = c[1] * b)),
d.drawImage(q, n, o, m, i), d.drawImage(q, n, o, m, i),
{ image: e, width: j / b, height: l / b }) { image: e, width: j / b, height: l / b })
); );
} }
function ae(m, o, l) { function ae(m, o, l) {
@ -779,16 +779,16 @@
b.outlineMethod == "size" && b.outlineMethod == "size" &&
(b.outlineIncrease > 0 (b.outlineIncrease > 0
? ((a.iw += 2 * b.outlineIncrease), ? ((a.iw += 2 * b.outlineIncrease),
(a.ih += 2 * b.outlineIncrease), (a.ih += 2 * b.outlineIncrease),
(f = h * a.iw), (f = h * a.iw),
(d = h * a.ih), (d = h * a.ih),
(c = S(a.fimage, f, d)), (c = S(a.fimage, f, d)),
(a.oimage = c), (a.oimage = c),
(a.fimage = H(a.fimage, a.oimage.width, a.oimage.height))) (a.fimage = H(a.fimage, a.oimage.width, a.oimage.height)))
: ((f = h * (a.iw + 2 * b.outlineIncrease)), : ((f = h * (a.iw + 2 * b.outlineIncrease)),
(d = h * (a.ih + 2 * b.outlineIncrease)), (d = h * (a.ih + 2 * b.outlineIncrease)),
(c = S(a.fimage, f, d)), (c = S(a.fimage, f, d)),
(a.oimage = H(c, a.fimage.width, a.fimage.height)))))), (a.oimage = H(c, a.fimage.width, a.fimage.height)))))),
(a.alt = j), (a.alt = j),
a.Init(); a.Init();
} }
@ -811,7 +811,7 @@
d d
? (b = 1 * (c.getAttribute(d) || e)) ? (b = 1 * (c.getAttribute(d) || e))
: (a = i(c, "font-size")) && : (a = i(c, "font-size")) &&
(b = (b =
(a.indexOf("px") > -1 && a.replace("px", "") * 1) || (a.indexOf("px") > -1 && a.replace("px", "") * 1) ||
(a.indexOf("pt") > -1 && a.replace("pt", "") * 1.25) || (a.indexOf("pt") > -1 && a.replace("pt", "") * 1.25) ||
a * 3.3), a * 3.3),
@ -832,8 +832,8 @@
n(a.offsetX) n(a.offsetX)
? (b = { x: a.offsetX, y: a.offsetY }) ? (b = { x: a.offsetX, y: a.offsetY })
: ((d = X(c.id)), : ((d = X(c.id)),
n(a.changedTouches) && (a = a.changedTouches[0]), n(a.changedTouches) && (a = a.changedTouches[0]),
a.pageX && (b = { x: a.pageX - d.x, y: a.pageY - d.y })), a.pageX && (b = { x: a.pageX - d.x, y: a.pageY - d.y })),
b && e && f && ((b.x /= e), (b.y /= f)), b && e && f && ((b.x /= e), (b.y /= f)),
b b
); );
@ -881,11 +881,11 @@
c.changedTouches && c.changedTouches &&
(c.touches.length == 1 && b.touchState == 0 (c.touches.length == 1 && b.touchState == 0
? ((b.touchState = 1), ? ((b.touchState = 1),
b.BeginDrag(c), b.BeginDrag(c),
(d = K(c, b.canvas)) && ((b.mx = d.x), (b.my = d.y), (b.drawn = 0))) (d = K(c, b.canvas)) && ((b.mx = d.x), (b.my = d.y), (b.drawn = 0)))
: c.targetTouches.length == 2 && b.pinchZoom : c.targetTouches.length == 2 && b.pinchZoom
? ((b.touchState = 3), b.EndDrag(), b.BeginPinch(c)) ? ((b.touchState = 3), b.EndDrag(), b.BeginPinch(c))
: (b.EndDrag(), b.EndPinch(), (b.touchState = 0))); : (b.EndDrag(), b.EndPinch(), (b.touchState = 0)));
} }
function ac(c) { function ac(c) {
var d = u(c), var d = u(c),
@ -1001,10 +1001,10 @@
b[a].nodeName == "BR" b[a].nodeName == "BR"
? (this.text.push(this.line.join(" ")), (this.br = 1)) ? (this.text.push(this.line.join(" ")), (this.br = 1))
: b[a].nodeType == 3 : b[a].nodeType == 3
? this.br ? this.br
? ((this.line = [b[a].nodeValue]), (this.br = 0)) ? ((this.line = [b[a].nodeValue]), (this.br = 0))
: this.line.push(b[a].nodeValue) : this.line.push(b[a].nodeValue)
: this.Lines(b[a]); : this.Lines(b[a]);
return e || this.br || this.text.push(this.line.join(" ")), this.text; return e || this.br || this.text.push(this.line.join(" ")), this.text;
}), }),
(F.SplitWidth = function (h, e, f, g) { (F.SplitWidth = function (h, e, f, g) {
@ -1056,7 +1056,7 @@
a == "none" a == "none"
? (this.Draw = function () { ? (this.Draw = function () {
return 1; return 1;
}) })
: (this.drawFunc = this[c[1]]), : (this.drawFunc = this[c[1]]),
(this[c[0]] = this.Draw), (this[c[0]] = this.Draw),
d && ((this.RealPreDraw = this.PreDraw), (this.PreDraw = this.DrawAlt)); d && ((this.RealPreDraw = this.PreDraw), (this.PreDraw = this.DrawAlt));
@ -1089,7 +1089,7 @@
(a = ~~d % j)), (a = ~~d % j)),
a a
? (b >= a ? ((h = b - a), (g = a)) : ((f = j - a), (i = c - f)), ? (b >= a ? ((h = b - a), (g = a)) : ((f = j - a), (i = c - f)),
(e = [h, f, g, i])) (e = [h, f, g, i]))
: (e = [b, c]), : (e = [b, c]),
k.setLineDash(e); k.setLineDash(e);
}), }),
@ -1109,10 +1109,10 @@
? (d = ? (d =
(a.image.height + this.tc.outlineIncrease) / a.image.height) (a.image.height + this.tc.outlineIncrease) / a.image.height)
: (d = a.oscale), : (d = a.oscale),
(b = a.fimage || a.image), (b = a.fimage || a.image),
(c = 1 + (d - 1) * (1 - this.pulse)), (c = 1 + (d - 1) * (1 - this.pulse)),
(a.h *= c), (a.h *= c),
(a.w *= c)) (a.w *= c))
: (b = a.oimage), : (b = a.oimage),
(a.alpha = 1), (a.alpha = 1),
a.Draw(i, h, g, b), a.Draw(i, h, g, b),
@ -1125,11 +1125,11 @@
return a.oimage return a.oimage
? (this.pulse < 1 ? (this.pulse < 1
? ((a.alpha = 1 - w(this.pulse, 2)), ? ((a.alpha = 1 - w(this.pulse, 2)),
a.Draw(d, b, c, a.fimage), a.Draw(d, b, c, a.fimage),
(a.alpha = this.pulse)) (a.alpha = this.pulse))
: (a.alpha = 1), : (a.alpha = 1),
a.Draw(d, b, c, a.oimage), a.Draw(d, b, c, a.oimage),
1) 1)
: this[a.image ? "DrawColourImage" : "DrawColourText"]( : this[a.image ? "DrawColourImage" : "DrawColourText"](
d, d,
h, h,
@ -1140,7 +1140,7 @@
a, a,
b, b,
c, c,
); );
}), }),
(f.DrawColourText = function (f, h, i, j, g, e, a, b, c) { (f.DrawColourText = function (f, h, i, j, g, e, a, b, c) {
var d = a.colour; var d = a.colour;
@ -1158,24 +1158,24 @@
!v !v
? this.SetMethod("outline") ? this.SetMethod("outline")
: ((j = v.getContext("2d")), : ((j = v.getContext("2d")),
j.drawImage(f, e, d, c, b, 0, 0, c, b), j.drawImage(f, e, d, c, b, 0, 0, c, b),
a.clearRect(e, d, c, b), a.clearRect(e, d, c, b),
this.pulsate ? (i.alpha = 1 - w(this.pulse, 2)) : (i.alpha = 1), this.pulsate ? (i.alpha = 1 - w(this.pulse, 2)) : (i.alpha = 1),
i.Draw(a, r, l), i.Draw(a, r, l),
a.setTransform(1, 0, 0, 1, 0, 0), a.setTransform(1, 0, 0, 1, 0, 0),
a.save(), a.save(),
a.beginPath(), a.beginPath(),
a.rect(e, d, c, b), a.rect(e, d, c, b),
a.clip(), a.clip(),
(a.globalCompositeOperation = "source-in"), (a.globalCompositeOperation = "source-in"),
(a.fillStyle = m), (a.fillStyle = m),
a.fillRect(e, d, c, b), a.fillRect(e, d, c, b),
a.restore(), a.restore(),
(a.globalAlpha = 1), (a.globalAlpha = 1),
(a.globalCompositeOperation = "destination-over"), (a.globalCompositeOperation = "destination-over"),
a.drawImage(v, 0, 0, c, b, e, d, c, b), a.drawImage(v, 0, 0, c, b, e, d, c, b),
(a.globalCompositeOperation = "source-over"), (a.globalCompositeOperation = "source-over"),
1) 1)
); );
}), }),
(f.DrawAlt = function (b, a, c, d, f, g) { (f.DrawAlt = function (b, a, c, d, f, g) {
@ -1262,8 +1262,8 @@
return this.a.href != a.href return this.a.href != a.href
? 0 ? 0
: b.length : b.length
? this.image.src == b[0].src ? this.image.src == b[0].src
: (a.innerText || a.textContent) == this.text_original; : (a.innerText || a.textContent) == this.text_original;
}), }),
(d.SetImage = function (a) { (d.SetImage = function (a) {
this.image = this.fimage = a; this.image = this.fimage = a;
@ -1354,21 +1354,21 @@
i, i,
b * this.padding, b * this.padding,
b * this.bgRadius, b * this.bgRadius,
)) ))
: a.outlineMethod == "size" && : a.outlineMethod == "size" &&
((f = ae( ((f = ae(
this.text, this.text,
this.textFont, this.textFont,
this.textHeight + a.outlineIncrease, this.textHeight + a.outlineIncrease,
)), )),
(k = f.max.y + f.min.y), (k = f.max.y + f.min.y),
(h = (h =
b * (this.textHeight + a.outlineIncrease) + b * (this.textHeight + a.outlineIncrease) +
"px " + "px " +
this.textFont), this.textFont),
(e.font = h), (e.font = h),
(g = this.MeasureText(e)), (g = this.MeasureText(e)),
(d = new O( (d = new O(
this.text, this.text,
h, h,
g + b, g + b,
@ -1378,8 +1378,8 @@
a.textAlign, a.textAlign,
a.textVAlign, a.textVAlign,
b, b,
)), )),
this.image && this.image &&
d.SetImage( d.SetImage(
this.image, this.image,
this.iw + a.outlineIncrease, this.iw + a.outlineIncrease,
@ -1390,7 +1390,7 @@
a.imageVAlign, a.imageVAlign,
a.imageScale, a.imageScale,
), ),
(this.oimage = d.Create( (this.oimage = d.Create(
this.colour, this.colour,
this.bgColour, this.bgColour,
this.bgOutline, this.bgOutline,
@ -1400,9 +1400,9 @@
i, i,
b * this.padding, b * this.padding,
b * this.bgRadius, b * this.bgRadius,
)), )),
(this.oscale = this.oimage.width / c.width), (this.oscale = this.oimage.width / c.width),
a.outlineIncrease > 0 a.outlineIncrease > 0
? (c = H(c, this.oimage.width, this.oimage.height)) ? (c = H(c, this.oimage.width, this.oimage.height))
: (this.oimage = H(this.oimage, c.width, c.height))), : (this.oimage = H(this.oimage, c.width, c.height))),
c && c &&
@ -1440,8 +1440,8 @@
b.min_weight[a], b.min_weight[a],
b.max_weight[a], b.max_weight[a],
a, a,
), ),
this.Weight( this.Weight(
c[a], c[a],
b.ctxt, b.ctxt,
b, b,
@ -1449,7 +1449,7 @@
b.min_weight[a], b.min_weight[a],
b.max_weight[a], b.max_weight[a],
a, a,
)) ))
: this.Weight( : this.Weight(
c[a], c[a],
b.ctxt, b.ctxt,
@ -1458,7 +1458,7 @@
b.min_weight[a], b.min_weight[a],
b.max_weight[a], b.max_weight[a],
a, a,
); );
this.Measure(b.ctxt, b); this.Measure(b.ctxt, b);
}), }),
(d.Weight = function (b, i, a, d, f, h, e) { (d.Weight = function (b, i, a, d, f, h, e) {
@ -1467,13 +1467,13 @@
"colour" == d "colour" == d
? (this.colour = L(a, c, e)) ? (this.colour = L(a, c, e))
: "bgcolour" == d : "bgcolour" == d
? (this.bgColour = L(a, c, e)) ? (this.bgColour = L(a, c, e))
: "bgoutline" == d : "bgoutline" == d
? (this.bgOutline = L(a, c, e)) ? (this.bgOutline = L(a, c, e))
: "outline" == d : "outline" == d
? (this.outline.colour = L(a, c, e)) ? (this.outline.colour = L(a, c, e))
: "size" == d && : "size" == d &&
(a.weightSizeMin > 0 && a.weightSizeMax > a.weightSizeMin (a.weightSizeMin > 0 && a.weightSizeMax > a.weightSizeMin
? (this.textHeight = ? (this.textHeight =
a.weightSize * a.weightSize *
(a.weightSizeMin + (a.weightSizeMin +
@ -1504,8 +1504,8 @@
"right" == e.textAlign "right" == e.textAlign
? (d += this.w / 2 - this.line_widths[b]) ? (d += this.w / 2 - this.line_widths[b])
: "centre" == e.textAlign : "centre" == e.textAlign
? (d -= this.line_widths[b] / 2) ? (d -= this.line_widths[b] / 2)
: (d -= this.w / 2), : (d -= this.w / 2),
a.setTransform(c, 0, 0, c, c * d, c * f), a.setTransform(c, 0, 0, c, c * d, c * f),
a.fillText(this.text[b], 0, 0), a.fillText(this.text[b], 0, 0),
(f += this.textHeight); (f += this.textHeight);
@ -1712,8 +1712,8 @@
: a.Smooth), : a.Smooth),
this.shadowBlur || this.shadowOffset[0] || this.shadowOffset[1] this.shadowBlur || this.shadowOffset[0] || this.shadowOffset[1]
? ((this.ctxt.shadowColor = this.shadow), ? ((this.ctxt.shadowColor = this.shadow),
(this.shadow = this.ctxt.shadowColor), (this.shadow = this.ctxt.shadowColor),
(this.shadowAlpha = aD())) (this.shadowAlpha = aD()))
: delete this.shadow, : delete this.shadow,
this.activeAudio === !1 this.activeAudio === !1
? (e = "off") ? (e = "off")
@ -1730,17 +1730,17 @@
b.HideTags(); b.HideTags();
}, },
window, window,
); );
})(this), })(this),
(this.yaw = this.initial ? this.initial[0] * this.maxSpeed : 0), (this.yaw = this.initial ? this.initial[0] * this.maxSpeed : 0),
(this.pitch = this.initial ? this.initial[1] * this.maxSpeed : 0), (this.pitch = this.initial ? this.initial[1] * this.maxSpeed : 0),
this.tooltip this.tooltip
? ((this.ctitle = b.title), ? ((this.ctitle = b.title),
(b.title = ""), (b.title = ""),
this.tooltip == "native" this.tooltip == "native"
? (this.Tooltip = this.TooltipNative) ? (this.Tooltip = this.TooltipNative)
: ((this.Tooltip = this.TooltipDiv), : ((this.Tooltip = this.TooltipDiv),
this.ttdiv || this.ttdiv ||
((this.ttdiv = c.createElement("div")), ((this.ttdiv = c.createElement("div")),
(this.ttdiv.className = this.tooltipClass), (this.ttdiv.className = this.tooltipClass),
(this.ttdiv.style.position = "absolute"), (this.ttdiv.style.position = "absolute"),
@ -1874,18 +1874,18 @@
d.Empty() d.Empty()
? (d = null) ? (d = null)
: ((g = this.textFont || Q(i(b, "font-family"))), : ((g = this.textFont || Q(i(b, "font-family"))),
this.splitWidth && this.splitWidth &&
(f = d.SplitWidth( (f = d.SplitWidth(
this.splitWidth, this.splitWidth,
this.ctxt, this.ctxt,
g, g,
this.textHeight, this.textHeight,
)), )),
(h = (h =
this.bgColour == "tag" this.bgColour == "tag"
? i(b, "background-color") ? i(b, "background-color")
: this.bgColour), : this.bgColour),
(j = this.bgOutline == "tag" ? i(b, "color") : this.bgOutline))), (j = this.bgOutline == "tag" ? i(b, "color") : this.bgOutline))),
d || c) d || c)
) )
return ( return (
@ -1973,11 +1973,11 @@
this.shapeArgs this.shapeArgs
? (this.shapeArgs[0] = b.length) ? (this.shapeArgs[0] = b.length)
: ((l = this.shape.toString().split(/[(),]/)), : ((l = this.shape.toString().split(/[(),]/)),
(d = l.shift()), (d = l.shift()),
typeof window[d] == "function" typeof window[d] == "function"
? (this.shape = window[d]) ? (this.shape = window[d])
: (this.shape = m[d] || m.sphere), : (this.shape = m[d] || m.sphere),
(this.shapeArgs = [b.length, h, i, j].concat(l))), (this.shapeArgs = [b.length, h, i, j].concat(l))),
(f = this.shape.apply(this, this.shapeArgs)), (f = this.shape.apply(this, this.shapeArgs)),
(this.listLength = b.length); (this.listLength = b.length);
for (a = 0; a < b.length; ++a) for (a = 0; a < b.length; ++a)
@ -2189,8 +2189,8 @@
b && a && a.title b && a && a.title
? this.SetTTDiv(a.title, a) ? this.SetTTDiv(a.title, a)
: !b && this.mx != -1 && this.my != -1 && this.ctitle.length : !b && this.mx != -1 && this.my != -1 && this.ctitle.length
? this.SetTTDiv(this.ctitle) ? this.SetTTDiv(this.ctitle)
: (this.ttdiv.style.display = "none"); : (this.ttdiv.style.display = "none");
}), }),
(b.Transform = function (c, a, b) { (b.Transform = function (c, a, b) {
if (a || b) { if (a || b) {
@ -2222,8 +2222,8 @@
(this.transform = a.transform), (this.transform = a.transform),
b >= a.t b >= a.t
? ((this.fixedCallbackTag = a.tag), ? ((this.fixedCallbackTag = a.tag),
(this.fixedCallback = a.cb), (this.fixedCallback = a.cb),
(this.fixedAnim = this.yaw = this.pitch = 0)) (this.fixedAnim = this.yaw = this.pitch = 0))
: (c *= e), : (c *= e),
(d = m.Rotation(c, a.axis)), (d = m.Rotation(c, a.axis)),
(this.transform = this.transform.mul(d)), (this.transform = this.transform.mul(d)),
@ -2238,12 +2238,12 @@
c; c;
!a.frozen && d >= 0 && e >= 0 && d < g && e < h !a.frozen && d >= 0 && e >= 0 && d < g && e < h
? ((b = a.maxSpeed), ? ((b = a.maxSpeed),
(c = a.reverse ? -1 : 1), (c = a.reverse ? -1 : 1),
a.lx || (a.yaw = ((d * 2 * b) / g - b) * c * f), a.lx || (a.yaw = ((d * 2 * b) / g - b) * c * f),
a.ly || (a.pitch = ((e * 2 * b) / h - b) * -c * f), a.ly || (a.pitch = ((e * 2 * b) / h - b) * -c * f),
(a.initial = null)) (a.initial = null))
: a.initial || : a.initial ||
(a.frozen && !a.freezeDecel ? (a.yaw = a.pitch = 0) : a.Decel(a)), (a.frozen && !a.freezeDecel ? (a.yaw = a.pitch = 0) : a.Decel(a)),
this.Transform(a, a.pitch, a.yaw); this.Transform(a, a.pitch, a.yaw);
}), }),
(b.AnimateDrag = function (d, e, c) { (b.AnimateDrag = function (d, e, c) {
@ -2251,9 +2251,9 @@
b = (100 * c * a.maxSpeed) / a.max_radius / a.zoom; b = (100 * c * a.maxSpeed) / a.max_radius / a.zoom;
a.dx || a.dy a.dx || a.dy
? (a.lx || (a.yaw = (a.dx * b) / a.stretchX), ? (a.lx || (a.yaw = (a.dx * b) / a.stretchX),
a.ly || (a.pitch = (a.dy * -b) / a.stretchY), a.ly || (a.pitch = (a.dy * -b) / a.stretchY),
(a.dx = a.dy = 0), (a.dx = a.dy = 0),
(a.initial = null)) (a.initial = null))
: a.initial || a.Decel(a), : a.initial || a.Decel(a),
this.Transform(a, a.pitch, a.yaw); this.Transform(a, a.pitch, a.yaw);
}), }),
@ -2297,7 +2297,7 @@
a.tag.Clicked(b); a.tag.Clicked(b);
}, },
!0, !0,
)); ));
} catch (a) {} } catch (a) {}
}), }),
(b.Wheel = function (a) { (b.Wheel = function (a) {
@ -2382,7 +2382,7 @@
cb: f, cb: f,
tag: a, tag: a,
active: g, active: g,
}); });
}), }),
(b.TagToFront = function (a, b, c, d) { (b.TagToFront = function (a, b, c, d) {
this.RotateTag(a, 0, 0, b, c, d); this.RotateTag(a, 0, 0, b, c, d);

View file

@ -59,7 +59,7 @@
"idb-keyval": "6.2.1", "idb-keyval": "6.2.1",
"insert-text-at-cursor": "0.3.0", "insert-text-at-cursor": "0.3.0",
"json5": "2.2.3", "json5": "2.2.3",
"katex": "0.16.9", "katex": "0.16.10",
"libopenmpt-wasm": "github:TheEssem/libopenmpt-packaging#build", "libopenmpt-wasm": "github:TheEssem/libopenmpt-packaging#build",
"matter-js": "0.19.0", "matter-js": "0.19.0",
"mfm-js": "0.24.0", "mfm-js": "0.24.0",
@ -83,7 +83,7 @@
"typescript": "5.4.3", "typescript": "5.4.3",
"unicode-emoji-json": "^0.6.0", "unicode-emoji-json": "^0.6.0",
"uuid": "9.0.1", "uuid": "9.0.1",
"vite": "5.2.4", "vite": "5.2.6",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vue": "3.4.21", "vue": "3.4.21",
"vue-draggable-plus": "^0.3.5", "vue-draggable-plus": "^0.3.5",

View file

@ -251,7 +251,7 @@ export async function openAccountMenu(
}, },
], ],
}, },
] ]
: [ : [
{ {
type: "link", type: "link",
@ -260,7 +260,7 @@ export async function openAccountMenu(
avatar: me, avatar: me,
}, },
null, null,
]), ]),
...(opts.includeCurrentAccount ? [createItem(me)] : []), ...(opts.includeCurrentAccount ? [createItem(me)] : []),
...accountItemPromises, ...accountItemPromises,
...(isMobile ?? false ...(isMobile ?? false
@ -272,7 +272,7 @@ export async function openAccountMenu(
to: `/@${me.username}`, to: `/@${me.username}`,
avatar: me, avatar: me,
}, },
] ]
: [ : [
{ {
type: "parent", type: "parent",
@ -293,7 +293,7 @@ export async function openAccountMenu(
}, },
], ],
}, },
]), ]),
], ],
], ],
ev.currentTarget ?? ev.target, ev.currentTarget ?? ev.target,

View file

@ -38,11 +38,11 @@ const props = withDefaults(
defineProps<{ defineProps<{
file: entities.DriveFile; file: entities.DriveFile;
fit: string; fit: string;
showAltIndicator?: boolean showAltIndicator?: boolean;
}>(), }>(),
{ {
showAltIndicator: false, showAltIndicator: false,
} },
); );
const is = computed(() => { const is = computed(() => {

View file

@ -27,9 +27,7 @@
v-if="alt && showAltIndicator" v-if="alt && showAltIndicator"
v-tooltip.noLabel=" v-tooltip.noLabel="
`${i18n.ts.alt}: ${ `${i18n.ts.alt}: ${
alt.length > 200 alt.length > 200 ? alt.trim().slice(0, 200) + '...' : alt.trim()
? alt.trim().slice(0, 200) + '...'
: alt.trim()
}` }`
" "
></i> ></i>
@ -51,7 +49,7 @@ const props = withDefaults(
size?: number; size?: number;
cover?: boolean; cover?: boolean;
largestDimension?: "width" | "height"; largestDimension?: "width" | "height";
showAltIndicator?: boolean showAltIndicator?: boolean;
}>(), }>(),
{ {
src: null, src: null,
@ -60,7 +58,7 @@ const props = withDefaults(
title: null, title: null,
size: 64, size: 64,
cover: true, cover: true,
showAltIndicator: false showAltIndicator: false,
}, },
); );

View file

@ -291,7 +291,7 @@ import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue"; import XQuoteButton from "@/components/MkQuoteButton.vue";
import MkVisibility from "@/components/MkVisibility.vue"; import MkVisibility from "@/components/MkVisibility.vue";
import copyToClipboard from "@/scripts/copy-to-clipboard"; import copyToClipboard from "@/scripts/copy-to-clipboard";
import detectLanguage from "@/scripts/detect-language"; import { detectLanguage } from "@/scripts/language-utils";
import { url } from "@/config"; import { url } from "@/config";
import { pleaseLogin } from "@/scripts/please-login"; import { pleaseLogin } from "@/scripts/please-login";
import { focusNext, focusPrev } from "@/scripts/focus"; import { focusNext, focusPrev } from "@/scripts/focus";

View file

@ -201,7 +201,7 @@ import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XRenoteButton from "@/components/MkRenoteButton.vue"; import XRenoteButton from "@/components/MkRenoteButton.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue"; import XQuoteButton from "@/components/MkQuoteButton.vue";
import copyToClipboard from "@/scripts/copy-to-clipboard"; import copyToClipboard from "@/scripts/copy-to-clipboard";
import detectLanguage from "@/scripts/detect-language"; import { detectLanguage } from "@/scripts/language-utils";
import { url } from "@/config"; import { url } from "@/config";
import { pleaseLogin } from "@/scripts/please-login"; import { pleaseLogin } from "@/scripts/please-login";
import { getNoteMenu } from "@/scripts/get-note-menu"; import { getNoteMenu } from "@/scripts/get-note-menu";

View file

@ -329,9 +329,14 @@ import XCheatSheet from "@/components/MkCheatSheetDialog.vue";
import preprocess from "@/scripts/preprocess"; import preprocess from "@/scripts/preprocess";
import { vibrate } from "@/scripts/vibrate"; import { vibrate } from "@/scripts/vibrate";
import { langmap } from "@/scripts/langmap"; import { langmap } from "@/scripts/langmap";
import { isSupportedLang, isSameLanguage, languageContains, parentLanguage } from "@/scripts/language-utils"; import {
detectLanguage,
isSupportedLang,
isSameLanguage,
languageContains,
parentLanguage,
} from "@/scripts/language-utils";
import type { MenuItem } from "@/types/menu"; import type { MenuItem } from "@/types/menu";
import detectLanguage from "@/scripts/detect-language";
import icon from "@/scripts/icon"; import icon from "@/scripts/icon";
const modal = inject("modal"); const modal = inject("modal");
@ -1012,8 +1017,6 @@ function deleteDraft() {
localStorage.setItem("drafts", JSON.stringify(draftData)); localStorage.setItem("drafts", JSON.stringify(draftData));
} }
async function post() { async function post() {
// For text that is too short, the false positive rate may be too high, so we don't show alarm. // For text that is too short, the false positive rate may be too high, so we don't show alarm.
if (defaultStore.state.autocorrectNoteLanguage && text.value.length > 10) { if (defaultStore.state.autocorrectNoteLanguage && text.value.length > 10) {

View file

@ -142,6 +142,10 @@ function done(canceled: boolean, result?: searchQuery) {
} }
function search() { function search() {
searchWords.value = searchWords.value.trim();
searchUsers.value = searchUsers.value.trim();
searchRange.value = searchRange.value.trim();
if ( if (
searchWords.value === "" && searchWords.value === "" &&
searchUsers.value === "" && searchUsers.value === "" &&
@ -160,6 +164,8 @@ function search() {
} }
function lookup() { function lookup() {
searchWords.value = searchWords.value.trim();
if (searchWords.value === "") return; if (searchWords.value === "") return;
done(false, { done(false, {

View file

@ -149,13 +149,13 @@ export default defineComponent({
const direction = token.props.args.left const direction = token.props.args.left
? "reverse" ? "reverse"
: token.props.args.alternate : token.props.args.alternate
? "alternate" ? "alternate"
: "normal"; : "normal";
const anime = token.props.args.x const anime = token.props.args.x
? "mfm-spinX" ? "mfm-spinX"
: token.props.args.y : token.props.args.y
? "mfm-spinY" ? "mfm-spinY"
: "mfm-spin"; : "mfm-spin";
const speed = validTime(token.props.args.speed) || "1.5s"; const speed = validTime(token.props.args.speed) || "1.5s";
const delay = validTime(token.props.args.delay) || "0s"; const delay = validTime(token.props.args.delay) || "0s";
const loop = validNumber(token.props.args.loop) || "infinite"; const loop = validNumber(token.props.args.loop) || "infinite";
@ -204,8 +204,8 @@ export default defineComponent({
token.props.args.h && token.props.args.v token.props.args.h && token.props.args.v
? "scale(-1, -1)" ? "scale(-1, -1)"
: token.props.args.v : token.props.args.v
? "scaleY(-1)" ? "scaleY(-1)"
: "scaleX(-1)"; : "scaleX(-1)";
style = `transform: ${transform};`; style = `transform: ${transform};`;
break; break;
} }
@ -240,16 +240,16 @@ export default defineComponent({
const family = token.props.args.serif const family = token.props.args.serif
? "serif" ? "serif"
: token.props.args.monospace : token.props.args.monospace
? "monospace" ? "monospace"
: token.props.args.cursive : token.props.args.cursive
? "cursive" ? "cursive"
: token.props.args.fantasy : token.props.args.fantasy
? "fantasy" ? "fantasy"
: token.props.args.emoji : token.props.args.emoji
? "emoji" ? "emoji"
: token.props.args.math : token.props.args.math
? "math" ? "math"
: null; : null;
if (family) style = `font-family: ${family};`; if (family) style = `font-family: ${family};`;
break; break;
} }
@ -266,8 +266,8 @@ export default defineComponent({
const rotate = token.props.args.x const rotate = token.props.args.x
? "perspective(128px) rotateX" ? "perspective(128px) rotateX"
: token.props.args.y : token.props.args.y
? "perspective(128px) rotateY" ? "perspective(128px) rotateY"
: "rotate"; : "rotate";
const degrees = parseFloat(token.props.args.deg ?? "90"); const degrees = parseFloat(token.props.args.deg ?? "90");
style = `transform: ${rotate}(${degrees}deg); transform-origin: center center;`; style = `transform: ${rotate}(${degrees}deg); transform-origin: center center;`;
break; break;

View file

@ -63,12 +63,12 @@ export default {
direction: binding.modifiers.left direction: binding.modifiers.left
? "left" ? "left"
: binding.modifiers.right : binding.modifiers.right
? "right" ? "right"
: binding.modifiers.top : binding.modifiers.top
? "top" ? "top"
: binding.modifiers.bottom : binding.modifiers.bottom
? "bottom" ? "bottom"
: "top", : "top",
targetElement: el, targetElement: el,
}, },
{}, {},

View file

@ -190,10 +190,10 @@ function checkForSplash() {
window.location.search === "?zen" window.location.search === "?zen"
? defineAsyncComponent(() => import("@/ui/zen.vue")) ? defineAsyncComponent(() => import("@/ui/zen.vue"))
: !me : !me
? defineAsyncComponent(() => import("@/ui/visitor.vue")) ? defineAsyncComponent(() => import("@/ui/visitor.vue"))
: ui === "deck" : ui === "deck"
? defineAsyncComponent(() => import("@/ui/deck.vue")) ? defineAsyncComponent(() => import("@/ui/deck.vue"))
: defineAsyncComponent(() => import("@/ui/universal.vue")), : defineAsyncComponent(() => import("@/ui/universal.vue")),
); );
if (_DEV_) { if (_DEV_) {

View file

@ -12,7 +12,7 @@ export const instance: entities.DetailedInstanceMetadata = reactive(
? JSON.parse(instanceData) ? JSON.parse(instanceData)
: { : {
// TODO: set default values // TODO: set default values
}, },
); );
export async function fetchInstance() { export async function fetchInstance() {

View file

@ -221,7 +221,7 @@ export async function popup(
? { ? {
...events, ...events,
[disposeEvent]: dispose, [disposeEvent]: dispose,
} }
: events, : events,
id, id,
}; };
@ -500,7 +500,7 @@ export function inputDate(props: {
? { ? {
result: new Date(result.result), result: new Date(result.result),
canceled: false, canceled: false,
} }
: { canceled: true }, : { canceled: true },
); );
}, },
@ -774,8 +774,8 @@ export async function cropImage(
type AwaitType<T> = T extends Promise<infer U> type AwaitType<T> = T extends Promise<infer U>
? U ? U
: T extends (...args: any[]) => Promise<infer V> : T extends (...args: any[]) => Promise<infer V>
? V ? V
: T; : T;
let openingEmojiPicker: AwaitType<ReturnType<typeof popup>> | null = null, let openingEmojiPicker: AwaitType<ReturnType<typeof popup>> | null = null,
activeTextarea: HTMLTextAreaElement | HTMLInputElement | null = null; activeTextarea: HTMLTextAreaElement | HTMLInputElement | null = null;
export async function openEmojiPicker( export async function openEmojiPicker(

View file

@ -46,13 +46,13 @@ export class Storage<T extends StateDef> {
const deviceAccountState = isSignedIn const deviceAccountState = isSignedIn
? JSON.parse( ? JSON.parse(
localStorage.getItem(`${this.keyForLocalStorage}::${me.id}`) || "{}", localStorage.getItem(`${this.keyForLocalStorage}::${me.id}`) || "{}",
) )
: {}; : {};
const registryCache = isSignedIn const registryCache = isSignedIn
? JSON.parse( ? JSON.parse(
localStorage.getItem(`${this.keyForLocalStorage}::cache::${me.id}`) || localStorage.getItem(`${this.keyForLocalStorage}::cache::${me.id}`) ||
"{}", "{}",
) )
: {}; : {};
const state = {}; const state = {};

View file

@ -1,11 +0,0 @@
import { detect } from "tinyld";
import * as mfm from "mfm-js";
export default function detectLanguage(text: string): string {
const nodes = mfm.parse(text);
const filtered = mfm.extract(nodes, (node) => {
return node.type === "text" || node.type === "quote";
});
const purified = mfm.toString(filtered);
return detect(purified);
}

View file

@ -9,7 +9,7 @@ const isSmartphone = !isTablet && /mobile|iphone|android/.test(ua);
export const deviceKind = defaultStore.state.overridedDeviceKind export const deviceKind = defaultStore.state.overridedDeviceKind
? defaultStore.state.overridedDeviceKind ? defaultStore.state.overridedDeviceKind
: isSmartphone : isSmartphone
? "smartphone" ? "smartphone"
: isTablet : isTablet
? "tablet" ? "tablet"
: "desktop"; : "desktop";

View file

@ -54,18 +54,18 @@ export type Form = Record<string, FormItem>;
type GetItemType<Item extends FormItem> = Item["type"] extends "string" type GetItemType<Item extends FormItem> = Item["type"] extends "string"
? string ? string
: Item["type"] extends "number" : Item["type"] extends "number"
? number ? number
: Item["type"] extends "boolean" : Item["type"] extends "boolean"
? boolean ? boolean
: Item["type"] extends "radio" : Item["type"] extends "radio"
? unknown ? unknown
: Item["type"] extends "enum" : Item["type"] extends "enum"
? string ? string
: Item["type"] extends "array" : Item["type"] extends "array"
? unknown[] ? unknown[]
: Item["type"] extends "object" : Item["type"] extends "object"
? Record<string, unknown> ? Record<string, unknown>
: never; : never;
export type GetFormResultType<F extends Form> = { export type GetFormResultType<F extends Form> = {
[P in keyof F]: GetItemType<F[P]>; [P in keyof F]: GetItemType<F[P]>;

View file

@ -310,7 +310,7 @@ export function getNoteMenu(props: {
action: unclip, action: unclip,
}, },
null, null,
] ]
: []), : []),
statePromise.then((state) => statePromise.then((state) =>
state?.isFavorited state?.isFavorited
@ -318,12 +318,12 @@ export function getNoteMenu(props: {
icon: `${icon("ph-bookmark-simple")}`, icon: `${icon("ph-bookmark-simple")}`,
text: i18n.ts.unfavorite, text: i18n.ts.unfavorite,
action: () => toggleFavorite(false), action: () => toggleFavorite(false),
} }
: { : {
icon: `${icon("ph-bookmark-simple")}`, icon: `${icon("ph-bookmark-simple")}`,
text: i18n.ts.favorite, text: i18n.ts.favorite,
action: () => toggleFavorite(true), action: () => toggleFavorite(true),
}, },
), ),
{ {
icon: `${icon("ph-paperclip")}`, icon: `${icon("ph-paperclip")}`,
@ -337,13 +337,13 @@ export function getNoteMenu(props: {
icon: `${icon("ph-eye-slash")}`, icon: `${icon("ph-eye-slash")}`,
text: i18n.ts.unwatch, text: i18n.ts.unwatch,
action: () => toggleWatch(false), action: () => toggleWatch(false),
} }
: { : {
icon: `${icon("ph-eye")}`, icon: `${icon("ph-eye")}`,
text: i18n.ts.watch, text: i18n.ts.watch,
action: () => toggleWatch(true), action: () => toggleWatch(true),
}, },
) )
: undefined, : undefined,
statePromise.then((state) => statePromise.then((state) =>
state.isMutedThread state.isMutedThread
@ -351,12 +351,12 @@ export function getNoteMenu(props: {
icon: `${icon("ph-speaker-x")}`, icon: `${icon("ph-speaker-x")}`,
text: i18n.ts.unmuteThread, text: i18n.ts.unmuteThread,
action: () => toggleThreadMute(false), action: () => toggleThreadMute(false),
} }
: { : {
icon: `${icon("ph-speaker-x")}`, icon: `${icon("ph-speaker-x")}`,
text: i18n.ts.muteThread, text: i18n.ts.muteThread,
action: () => toggleThreadMute(true), action: () => toggleThreadMute(true),
}, },
), ),
isAppearAuthor isAppearAuthor
? (me.pinnedNoteIds || []).includes(appearNote.id) ? (me.pinnedNoteIds || []).includes(appearNote.id)
@ -364,12 +364,12 @@ export function getNoteMenu(props: {
icon: `${icon("ph-push-pin")}`, icon: `${icon("ph-push-pin")}`,
text: i18n.ts.unpin, text: i18n.ts.unpin,
action: () => togglePin(false), action: () => togglePin(false),
} }
: { : {
icon: `${icon("ph-push-pin")}`, icon: `${icon("ph-push-pin")}`,
text: i18n.ts.pin, text: i18n.ts.pin,
action: () => togglePin(true), action: () => togglePin(true),
} }
: undefined, : undefined,
isEdited isEdited
? { ? {
@ -383,7 +383,7 @@ export function getNoteMenu(props: {
icon: `${icon("ph-translate")}`, icon: `${icon("ph-translate")}`,
text: i18n.ts.translate, text: i18n.ts.translate,
action: translate, action: translate,
} }
: undefined, : undefined,
appearNote.url || appearNote.uri appearNote.url || appearNote.uri
? { ? {
@ -392,7 +392,7 @@ export function getNoteMenu(props: {
action: () => { action: () => {
window.open(appearNote.url || appearNote.uri, "_blank"); window.open(appearNote.url || appearNote.uri, "_blank");
}, },
} }
: undefined, : undefined,
{ {
type: "parent", type: "parent",
@ -414,14 +414,14 @@ export function getNoteMenu(props: {
icon: `${icon("ph-link-simple")}`, icon: `${icon("ph-link-simple")}`,
text: `${i18n.ts.copyLink} (${i18n.ts.origin})`, text: `${i18n.ts.copyLink} (${i18n.ts.origin})`,
action: copyOriginal, action: copyOriginal,
} }
: undefined, : undefined,
shareAvailable() shareAvailable()
? { ? {
icon: `${icon("ph-share-network")}`, icon: `${icon("ph-share-network")}`,
text: i18n.ts.share, text: i18n.ts.share,
action: share, action: share,
} }
: undefined, : undefined,
], ],
}, },
@ -457,7 +457,7 @@ export function getNoteMenu(props: {
"closed", "closed",
); );
}, },
} }
: undefined, : undefined,
isAppearAuthor isAppearAuthor
? { ? {
@ -465,7 +465,7 @@ export function getNoteMenu(props: {
text: i18n.ts.toEdit, text: i18n.ts.toEdit,
accent: true, accent: true,
action: edit, action: edit,
} }
: undefined, : undefined,
isAppearAuthor && isAppearAuthor &&
!( !(
@ -477,7 +477,7 @@ export function getNoteMenu(props: {
text: i18n.ts.makePrivate, text: i18n.ts.makePrivate,
danger: true, danger: true,
action: makePrivate, action: makePrivate,
} }
: undefined, : undefined,
isAppearAuthor isAppearAuthor
? { ? {
@ -485,7 +485,7 @@ export function getNoteMenu(props: {
text: i18n.ts.deleteAndEdit, text: i18n.ts.deleteAndEdit,
danger: true, danger: true,
action: delEdit, action: delEdit,
} }
: undefined, : undefined,
isAppearAuthor || isModerator isAppearAuthor || isModerator
? { ? {
@ -493,7 +493,7 @@ export function getNoteMenu(props: {
text: i18n.ts.delete, text: i18n.ts.delete,
danger: true, danger: true,
action: del, action: del,
} }
: undefined, : undefined,
!isAppearAuthor ? null : undefined, !isAppearAuthor ? null : undefined,
!isAppearAuthor !isAppearAuthor
@ -502,7 +502,7 @@ export function getNoteMenu(props: {
icon: `${icon("ph-user")}`, icon: `${icon("ph-user")}`,
text: i18n.ts.user, text: i18n.ts.user,
children: getUserMenu(appearNote.user), children: getUserMenu(appearNote.user),
} }
: undefined, : undefined,
].filter((x) => x !== undefined); ].filter((x) => x !== undefined);
} else { } else {
@ -514,7 +514,7 @@ export function getNoteMenu(props: {
action: () => { action: () => {
window.open(appearNote.url || appearNote.uri, "_blank"); window.open(appearNote.url || appearNote.uri, "_blank");
}, },
} }
: undefined, : undefined,
{ {
icon: `${icon("ph-clipboard-text")}`, icon: `${icon("ph-clipboard-text")}`,
@ -531,14 +531,14 @@ export function getNoteMenu(props: {
icon: `${icon("ph-link-simple")}`, icon: `${icon("ph-link-simple")}`,
text: `${i18n.ts.copyLink} (${i18n.ts.origin})`, text: `${i18n.ts.copyLink} (${i18n.ts.origin})`,
action: copyOriginal, action: copyOriginal,
} }
: undefined, : undefined,
shareAvailable() shareAvailable()
? { ? {
icon: `${icon("ph-share-network")}`, icon: `${icon("ph-share-network")}`,
text: i18n.ts.share, text: i18n.ts.share,
action: share, action: share,
} }
: undefined, : undefined,
].filter((x) => x !== undefined); ].filter((x) => x !== undefined);
} }

View file

@ -98,14 +98,14 @@ export function getUserMenu(user, router: Router = mainRouter) {
period === "indefinitely" period === "indefinitely"
? null ? null
: period === "tenMinutes" : period === "tenMinutes"
? Date.now() + 1000 * 60 * 10 ? Date.now() + 1000 * 60 * 10
: period === "oneHour" : period === "oneHour"
? Date.now() + 1000 * 60 * 60 ? Date.now() + 1000 * 60 * 60
: period === "oneDay" : period === "oneDay"
? Date.now() + 1000 * 60 * 60 * 24 ? Date.now() + 1000 * 60 * 60 * 24
: period === "oneWeek" : period === "oneWeek"
? Date.now() + 1000 * 60 * 60 * 24 * 7 ? Date.now() + 1000 * 60 * 60 * 24 * 7
: null; : null;
os.apiWithDialog("mute/create", { os.apiWithDialog("mute/create", {
userId: user.id, userId: user.id,
@ -296,7 +296,7 @@ export function getUserMenu(user, router: Router = mainRouter) {
icon: `${icon("ph-chats-teardrop")}`, icon: `${icon("ph-chats-teardrop")}`,
text: i18n.ts.startMessaging, text: i18n.ts.startMessaging,
to: `/my/messaging/${acct.toString(user)}`, to: `/my/messaging/${acct.toString(user)}`,
} }
: undefined, : undefined,
user.host != null && user.url user.host != null && user.url
? { ? {
@ -305,7 +305,7 @@ export function getUserMenu(user, router: Router = mainRouter) {
text: i18n.ts.showOnRemote, text: i18n.ts.showOnRemote,
href: user.url, href: user.url,
target: "_blank", target: "_blank",
} }
: undefined, : undefined,
null, null,
{ {
@ -318,7 +318,7 @@ export function getUserMenu(user, router: Router = mainRouter) {
icon: `${icon("ph-users-three")}`, icon: `${icon("ph-users-three")}`,
text: i18n.ts.inviteToGroup, text: i18n.ts.inviteToGroup,
action: inviteGroup, action: inviteGroup,
} }
: undefined, : undefined,
null, null,
{ {

Some files were not shown because too many files have changed in this diff Show more