Merge branch 'develop' into swn
This commit is contained in:
commit
20649f5ae1
93 changed files with 1347 additions and 746 deletions
2
.github/workflows/docker-develop.yml
vendored
2
.github/workflows/docker-develop.yml
vendored
|
@ -29,5 +29,5 @@ jobs:
|
|||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: develop
|
||||
tags: misskey/misskey:develop
|
||||
labels: develop
|
||||
|
|
10
.github/workflows/nodejs.yml
vendored
10
.github/workflows/nodejs.yml
vendored
|
@ -16,16 +16,16 @@ jobs:
|
|||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:10-alpine
|
||||
image: postgres:12.2-alpine
|
||||
ports:
|
||||
- 5432:5432
|
||||
- 54312:5432
|
||||
env:
|
||||
POSTGRES_DB: test-misskey
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
redis:
|
||||
image: redis:alpine
|
||||
image: redis:4.0-alpine
|
||||
ports:
|
||||
- 6379:6379
|
||||
- 56312:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -40,7 +40,7 @@ jobs:
|
|||
- name: Check yarn.lock
|
||||
run: git diff --exit-code yarn.lock
|
||||
- name: Copy Configure
|
||||
run: cp .circleci/misskey/*.yml .config
|
||||
run: cp test/test.yml .config
|
||||
- name: Build
|
||||
run: yarn build
|
||||
- name: Test
|
||||
|
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -12,6 +12,19 @@
|
|||
|
||||
## 12.x.x (unreleased)
|
||||
|
||||
### Improvements
|
||||
- クライアント: 自分のリアクション一覧を見れるように
|
||||
- 設定により、リアクション一覧を全員に公開することも可能
|
||||
- クライアント: ユーザー検索の精度を強化
|
||||
- クライアント: 新しいライトテーマを追加
|
||||
- API: ユーザーのリアクション一覧を取得する users/reactions を追加
|
||||
- API: users/search および users/search-by-username-and-host を強化
|
||||
|
||||
### Bugfixes
|
||||
- クライアント: テーマの管理が行えない問題を修正
|
||||
|
||||
## 12.92.0 (2021/10/16)
|
||||
|
||||
### Improvements
|
||||
- アカウント登録にメールアドレスの設定を必須にするオプション
|
||||
- クライアント: 全体的なUIのブラッシュアップ
|
||||
|
@ -23,6 +36,7 @@
|
|||
- クライアント: 新しいダークテーマを追加
|
||||
- クライアント: テーマコンパイラに hue と saturate 関数を追加
|
||||
- ActivityPub: HTML -> MFMの変換を強化
|
||||
- API: グループから抜ける users/groups/leave エンドポイントを実装
|
||||
- API: i/notifications に unreadOnly オプションを追加
|
||||
- API: ap系のエンドポイントをログイン必須化+レートリミット追加
|
||||
- MFM: Add tag syntaxes of bold <b></b> and strikethrough <s></s>
|
||||
|
|
|
@ -9,9 +9,9 @@ It will also allow the reader to use the translation tool of their preference if
|
|||
## Issues
|
||||
Before creating an issue, please check the following:
|
||||
- To avoid duplication, please search for similar issues before creating a new issue.
|
||||
- Do not use Issues as a question.
|
||||
- Issues should only be used to feature requests, suggestions, and report problems.
|
||||
- Please ask questions in the [Misskey Forum](https://forum.misskey.io/) or [Discord](https://discord.gg/Wp8gVStHW3).
|
||||
- Do not use Issues to ask questions or troubleshooting.
|
||||
- Issues should only be used to feature requests, suggestions, and bug tracking.
|
||||
- Please ask questions or troubleshooting in the [Misskey Forum](https://forum.misskey.io/) or [Discord](https://discord.gg/Wp8gVStHW3).
|
||||
|
||||
## Before implementation
|
||||
When you want to add a feature or fix a bug, **first have the design and policy reviewed in an Issue** (if it is not there, please make one). Without this step, there is a high possibility that the PR will not be merged even if it is implemented.
|
||||
|
@ -57,6 +57,17 @@ If your language is not listed in Crowdin, please open an issue.
|
|||
- Test codes are located in [`/test`](/test).
|
||||
|
||||
### Run test
|
||||
Create a config file.
|
||||
```
|
||||
cp test/test.yml .config/
|
||||
```
|
||||
Prepare DB/Redis for testing.
|
||||
```
|
||||
docker-compose -f test/docker-compose.yml up
|
||||
```
|
||||
Alternatively, prepare an empty (data can be erased) DB and edit `.config/test.yml`.
|
||||
|
||||
Run all test.
|
||||
```
|
||||
npm run test
|
||||
```
|
||||
|
|
|
@ -6,6 +6,7 @@ search: "البحث"
|
|||
notifications: "الإشعارات"
|
||||
username: "اسم المستخدم"
|
||||
password: "الكلمة السرية"
|
||||
forgotPassword: "نسيتَ كلمة السر"
|
||||
fetchingAsApObject: "جارٍ جلبه مِن الفديفرس…"
|
||||
ok: " حسناً"
|
||||
gotIt: "فهِمت"
|
||||
|
|
|
@ -81,6 +81,8 @@ somethingHappened: "Ein Fehler ist aufgetreten"
|
|||
retry: "Wiederholen"
|
||||
pageLoadError: "Laden der Seite fehlgeschlagen."
|
||||
pageLoadErrorDescription: "Dieser Fehler wird meist durch Netzwerkfehler oder den Browser-Cache verursacht. Bitte leere den Cache oder versuche es nach einiger Zeit erneut."
|
||||
serverIsDead: "Dieser Server antwortet nicht. Bitte warte einen Moment und versuche es dann erneut."
|
||||
youShouldUpgradeClient: "Bitte aktualisiere diese Seite, um eine neuere Version deines Clients zu verwenden."
|
||||
enterListName: "Name der Liste eingeben"
|
||||
privacy: "Privatsphäre"
|
||||
makeFollowManuallyApprove: "Follow-Anfragen benötigen Bestätigung"
|
||||
|
@ -545,7 +547,7 @@ invisibleNote: "Private Notiz"
|
|||
enableInfiniteScroll: "Automatisch mehr Notizen laden"
|
||||
visibility: "Sichtbarkeit"
|
||||
poll: "Umfrage"
|
||||
useCw: "Inhalt verbergen"
|
||||
useCw: "Inhaltswarnung verwenden"
|
||||
enablePlayer: "Video-Player öffnen"
|
||||
disablePlayer: "Video-Player schließen"
|
||||
expandTweet: "Tweet ausklappen"
|
||||
|
@ -764,6 +766,7 @@ middle: "Mittel"
|
|||
low: "Niedrig"
|
||||
emailNotConfiguredWarning: "Keine Email-Adresse hinterlegt"
|
||||
ratio: "Verhältnis"
|
||||
previewNoteText: "Vorschau anzeigen"
|
||||
customCss: "Benutzerdefiniertes CSS"
|
||||
customCssWarn: "Verwende diese Einstellung nur, wenn du weißt, was sie tut. Ungültige Eingaben können dazu führen, dass der Client nicht mehr normal funktioniert."
|
||||
global: "Global"
|
||||
|
@ -782,11 +785,22 @@ translatedFrom: "Aus {x} übersetzt"
|
|||
accountDeletionInProgress: "Löschung des Benutzerkontos momentan in Bearbeitung"
|
||||
usernameInfo: "Ein Name, durch den dein Benutzerkonto auf diesem Server identifiziert werden kann. Du kannst das Alphabet (a~z, A~Z), Ziffern (0~9) oder Unterstriche (_) verwenden. Benutzernamen können später nicht geändert werden."
|
||||
aiChanMode: "Ai Modus"
|
||||
keepCw: "Inhaltswarnung beibehalten"
|
||||
keepCw: "Inhaltswarnungen beibehalten"
|
||||
pubSub: "Pub/Sub Benutzerkonten"
|
||||
lastCommunication: "Letzte Kommunikation"
|
||||
resolved: "Gelöst"
|
||||
unresolved: "Ungelöst"
|
||||
itsOn: "Eingeschaltet"
|
||||
itsOff: "Ausgeschaltet"
|
||||
emailRequiredForSignup: "Angaben einer Email-Adresse als benötigt markieren"
|
||||
unread: "Ungelesen"
|
||||
filter: "Filter"
|
||||
controllPanel: "Systemsteuerung"
|
||||
manageAccounts: "Benutzerkonten verwalten"
|
||||
_signup:
|
||||
almostThere: "Fast geschafft"
|
||||
emailAddressInfo: "Bitte gib deine Email-Adresse ein."
|
||||
emailSent: "An deine Email-Adresse ({email}) wurde soeben eine Bestätigungsmail geschickt. Bitte klicke auf den enthaltenen Link, um die Erstellung deines Benutzerkontos abzuschließen."
|
||||
_accountDelete:
|
||||
accountDelete: "Benutzerkonto löschen"
|
||||
mayTakeTime: "Da die Löschung eines Benutzerkontos ein aufwendiger Prozess ist, kann dessen Dauer davon abhängen, wie viel Inhalt in diesem erstellt wurde oder wie viele Dateien hochgeladen wurden."
|
||||
|
@ -901,6 +915,8 @@ _mfm:
|
|||
fontDescription: "Setzt die Schriftart des Inhaltes fest."
|
||||
rainbow: "Regenbogen"
|
||||
rainbowDescription: "Lässt den Inhalt in Regenbogenfarben erscheinen."
|
||||
sparkle: "Glitzer"
|
||||
sparkleDescription: "Verleiht Inhalt einen glitzernden Partikeleffekt."
|
||||
_reversi:
|
||||
reversi: "Reversi"
|
||||
gameSettings: "Spieleinstellungen"
|
||||
|
@ -1024,9 +1040,9 @@ _theme:
|
|||
infoFg: "Text von Informationen"
|
||||
infoWarnBg: "Hintergrund von Warnungen"
|
||||
infoWarnFg: "Text von Warnungen"
|
||||
cwBg: "Hintergrund von verborgenen Inhalten"
|
||||
cwFg: "Text von verborgenen Inhalten"
|
||||
cwHoverBg: "Hintergrund von verborgenen Inhalten (Mouseover)"
|
||||
cwBg: "Hintergrund des Inhaltswarnungsknopfs"
|
||||
cwFg: "Text des Inhaltswarnungsknopfs"
|
||||
cwHoverBg: "Hintergrund des Inhaltswarnungsknopfs (Mouseover)"
|
||||
toastBg: "Hintergrund von Benachrichtigungen"
|
||||
toastFg: "Text von Benachrichtigungen"
|
||||
buttonBg: "Hintergrund von Schaltflächen"
|
||||
|
@ -1173,7 +1189,7 @@ _widgets:
|
|||
aiscript: "AiScript-Konsole"
|
||||
aichan: "Ai"
|
||||
_cw:
|
||||
hide: "Verbergen"
|
||||
hide: "Inhalt verbergen"
|
||||
show: "Inhalt anzeigen"
|
||||
chars: "{count} Zeichen"
|
||||
files: "{count} Datei(en)"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
_lang_: "English"
|
||||
headlineMisskey: "A network connected by notes"
|
||||
introMisskey: "Welcome! Misskey is an open source, decentralized microblogging service.\nCreate \"notes\" to share what your thoughts with everyone around you. 📡\nWith \"reactions\", you can also quickly express your feelings about everyone's notes. 👍\nLet's explore a new world! 🚀"
|
||||
introMisskey: "Welcome! Misskey is an open source, decentralized microblogging service.\nCreate \"notes\" to share your thoughts with everyone around you. 📡\nWith \"reactions\", you can also quickly express your feelings about everyone's notes. 👍\nLet's explore a new world! 🚀"
|
||||
monthAndDay: "{month}/{day}"
|
||||
search: "Search"
|
||||
notifications: "Notifications"
|
||||
|
@ -81,6 +81,8 @@ somethingHappened: "An error occurred"
|
|||
retry: "Retry"
|
||||
pageLoadError: "Failed to load page."
|
||||
pageLoadErrorDescription: "This is normally caused by network errors or the browser's cache. Try clearing the cache and then try again after waiting a little while."
|
||||
serverIsDead: "This server is not responding. Please wait for a while and try again."
|
||||
youShouldUpgradeClient: "To view this page, please refresh to update your client."
|
||||
enterListName: "Enter a list name"
|
||||
privacy: "Privacy"
|
||||
makeFollowManuallyApprove: "Follow requests require approval"
|
||||
|
@ -764,6 +766,7 @@ middle: "Medium"
|
|||
low: "Low"
|
||||
emailNotConfiguredWarning: "Email address not set."
|
||||
ratio: "Ratio"
|
||||
previewNoteText: "Show preview"
|
||||
customCss: "Custom CSS"
|
||||
customCssWarn: "This setting should only be used if you know what it does. Entering improper values may cause the client to stop functioning normally."
|
||||
global: "Global"
|
||||
|
@ -782,11 +785,22 @@ translatedFrom: "Translated from {x}"
|
|||
accountDeletionInProgress: "Account deletion is currently in progress"
|
||||
usernameInfo: "A name that identifies your account from others on this server. You can use the alphabet (a~z, A~Z), digits (0~9) or underscores (_). Usernames cannot be changed later."
|
||||
aiChanMode: "Ai Mode"
|
||||
keepCw: "Keep Content Warning"
|
||||
keepCw: "Keep Content Warnings"
|
||||
pubSub: "Pub/Sub Accounts"
|
||||
lastCommunication: "Last communication"
|
||||
resolved: "Resolved"
|
||||
unresolved: "Unresolved"
|
||||
itsOn: "Enabled"
|
||||
itsOff: "Disabled"
|
||||
emailRequiredForSignup: "Require email address for sign-up"
|
||||
unread: "Unread"
|
||||
filter: "Filter"
|
||||
controllPanel: "Control Panel"
|
||||
manageAccounts: "Manage Accounts"
|
||||
_signup:
|
||||
almostThere: "Almost there"
|
||||
emailAddressInfo: "Please enter your email address."
|
||||
emailSent: "A confirmation email has been sent to your email address ({email}). Please click the included link to complete account creation."
|
||||
_accountDelete:
|
||||
accountDelete: "Delete Account"
|
||||
mayTakeTime: "As account deletion is a resource-heavy process, it may take some time to complete depending on how much content you have created and how many files you have uploaded."
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
_lang_: "Esperanto"
|
||||
headlineMisskey: "Jen la reto konektita de notoj"
|
||||
introMisskey: "Bonvenon! Misskey estas malfermitkoda malcentraliza mikrobloga servo.\nKreu \"noto\"n por diskonigu tion kio nun okazas, aŭ por parolu pri vi. 📡\nUzu la funkcion \"reago\" por esprimu rapide vian senton pri ies noto. 👍\nBonvole esploru novan mondon. 🚀"
|
||||
monthAndDay: "{day}a/{month}"
|
||||
headlineMisskey: "Jen la reto konektata de notoj"
|
||||
introMisskey: "Bonvenon! Misskey estas malfermitkoda malcentraliza etbloga servo.\nKreu \"noto\"n por paroli vian penson al iuj ĉirkaŭ vi. 📡\nLa funkcion \"reago\" ebligas esprimi rapide vian senton pri ies noto en Fediverso. 👍\nBonvole esploru novan mondon. 🚀"
|
||||
monthAndDay: "La {day}-a de la {month}-a monato"
|
||||
search: "Serĉi"
|
||||
notifications: "Sciigoj"
|
||||
username: "Uzantnomo"
|
||||
|
@ -33,18 +33,18 @@ save: "Konservi"
|
|||
users: "Uzantoj"
|
||||
addUser: "Aldoni uzanton"
|
||||
favorite: "Preferi"
|
||||
favorites: "Preferataĵoj"
|
||||
favorites: "Preferaĵoj"
|
||||
unfavorite: "Malpreferi"
|
||||
favorited: "Aldonita al preferataĵoj"
|
||||
alreadyFavorited: "Ankoraŭ aldonita al via listo de preferaĵoj."
|
||||
cantFavorite: "Ne aldonita al preferataĵoj"
|
||||
pin: "Alpingli al la profilo"
|
||||
favorited: "Aldonita al via listo de preferaĵoj."
|
||||
alreadyFavorited: "Ĝi jam estis aldonita al via listo de preferaĵoj."
|
||||
cantFavorite: "Ne aldonita al via listo de preferaĵoj."
|
||||
pin: "Alpingli"
|
||||
unpin: "Depingli"
|
||||
copyContent: "Kopii enhavon"
|
||||
copyLink: "Kopii ligilon"
|
||||
delete: "Forviŝi"
|
||||
deleteAndEdit: "Forviŝi kaj redakti"
|
||||
deleteAndEditConfirm: "Ĉu vi certas, ke vi volas forigi kaj redakti la noton? Kun tio foriĝos reagoj, plusendaĵoj, kaj respondoj ĉiuj de ĝi."
|
||||
deleteAndEdit: "Redakti foriginte"
|
||||
deleteAndEditConfirm: "Ĉu vi certas, ke vi volas forigi kaj redakti la noton? Tio forviŝos reagojn, notojn plusendintajn, kaj respondojn ĉiujn de ĝi."
|
||||
addToList: "Aldoni al listo"
|
||||
sendMessage: "Sendi mesaĝon"
|
||||
copyUsername: "Kopii uzantnomon"
|
||||
|
@ -57,17 +57,17 @@ receiveFollowRequest: "Peto de sekvado estas ricevita"
|
|||
followRequestAccepted: "La peto de sekvado akceptita"
|
||||
mention: "Mencioj"
|
||||
mentions: "Al vi"
|
||||
directNotes: "Notoj rektaj"
|
||||
directNotes: "Rekte senditaj"
|
||||
importAndExport: "Importi/eksporti"
|
||||
import: "Importi"
|
||||
export: "Eksporti"
|
||||
files: "Dosieroj"
|
||||
download: "Elŝuti"
|
||||
driveFileDeleteConfirm: "Ĉu vi certas, ke vi volas forviŝi la dosieron \"{name}\"? Pro tio forviŝiĝos ankaŭ la notoj kiuj enhavas ĝin."
|
||||
unfollowConfirm: "Ĉu vi certas, ke vi volas ne plu sekvi {name}'(o)n?"
|
||||
unfollowConfirm: "Ĉu vi certas, ke vi volas ĉesi sekvi {name}'(o)n?"
|
||||
lists: "Listoj"
|
||||
noLists: "Neniu listo"
|
||||
note: "Notoj"
|
||||
note: "Sendi"
|
||||
notes: "Notoj"
|
||||
following: "Sekvatoj"
|
||||
followers: "Sekvantoj"
|
||||
|
@ -92,13 +92,13 @@ cantRenote: "Oni ne povas plusendi la noton."
|
|||
cantReRenote: "Plusendado ne estas plusendebla."
|
||||
quote: "Citi"
|
||||
pinnedNote: "Alpinglita noto"
|
||||
pinned: "Alpingli al la profilo"
|
||||
pinned: "Alpingli"
|
||||
you: "Vi"
|
||||
clickToShow: "Klaku por malkaŝu"
|
||||
sensitive: "Enhavo ne estas deca por laborejo (NSFW)"
|
||||
add: "Aldoni"
|
||||
reaction: "Reagoj"
|
||||
rememberNoteVisibility: "Rememoru la videblecon de la noto laste sendita"
|
||||
rememberNoteVisibility: "Rememoru videblecon de la noto laste sendita "
|
||||
attachCancel: "Deigi aldonaĵon"
|
||||
markAsSensitive: "Troviĝi NSFW"
|
||||
unmarkAsSensitive: "Ne troviĝi NSFW"
|
||||
|
@ -137,7 +137,7 @@ removeWallpaper: "Forviŝi ekranfonon. "
|
|||
searchWith: "Serĉi: {q}"
|
||||
youHaveNoLists: "Vi ne havas listojn."
|
||||
followConfirm: "Ĉu vi certas ke vi volas sekvi {name}'(o)n?"
|
||||
host: "Gastiganto"
|
||||
host: "Gastigo"
|
||||
selectUser: "Elekti uzanton"
|
||||
recipient: "Ricevonto"
|
||||
annotation: "Komentarioj"
|
||||
|
@ -254,7 +254,7 @@ unwatch: "Malobservi"
|
|||
accept: "Permesi"
|
||||
normal: "Normala"
|
||||
instanceName: "Nomo de la nodo"
|
||||
instanceDescription: "Mempriskribo de la nodo "
|
||||
instanceDescription: "Priskribo de la nodo "
|
||||
maintainerName: "Nomo de la administranto"
|
||||
maintainerEmail: "Retpoŝto de la administranto"
|
||||
tosUrl: "URL de kondiĉoj de uzado"
|
||||
|
@ -323,6 +323,7 @@ newPasswordIs: "La nova pasvorto estas {password}."
|
|||
share: "Diskonigi"
|
||||
notFound: "Ne trovita"
|
||||
cacheClear: "Malplenigi staplon"
|
||||
markAsReadAllNotifications: "Marki ĉiujn sciigojn kiel legito"
|
||||
help: "Manlibro de uzado"
|
||||
inputMessageHere: "Entajpu masaĝo tie ĉi"
|
||||
close: "Fermi"
|
||||
|
@ -344,10 +345,10 @@ quoteAttached: "Kun citaĵo"
|
|||
quoteQuestion: "Ĉu vi aldonas citaĵon?"
|
||||
noMessagesYet: "Ankoraŭ neniu mesaĝo"
|
||||
newMessageExists: "Vi ricevis novan mesaĝon."
|
||||
onlyOneFileCanBeAttached: "Vi povas aldoni nur unu dosieron po unu mesaĝo."
|
||||
onlyOneFileCanBeAttached: "Oni povas aldoni nur unu dosieron po mesaĝo."
|
||||
signinRequired: "Bonvolu ensaluti"
|
||||
invitations: "Inviti"
|
||||
invitationCode: "Kodo de invito"
|
||||
invitationCode: "Invita kodo"
|
||||
unavailable: "Ne disponebla"
|
||||
passwordMatched: "Konforma"
|
||||
passwordNotMatched: "Nekonforma"
|
||||
|
@ -417,7 +418,7 @@ enablePlayer: "Vidi videon"
|
|||
disablePlayer: "Fermi videon"
|
||||
expandTweet: "Disvolvi pepon"
|
||||
themeEditor: "Redaktilo de koloraroj"
|
||||
description: "Priskribe"
|
||||
description: "Priskribo"
|
||||
describeFile: "Priskribi la bildon"
|
||||
enterFileDescription: "Priskribu"
|
||||
author: "Aŭtoro"
|
||||
|
@ -433,7 +434,7 @@ emailServer: "Retpoŝta servilo"
|
|||
email: "Retpoŝto"
|
||||
emailAddress: "Retpoŝta adreso"
|
||||
smtpConfig: "Agordoj de SMTP servilo"
|
||||
smtpHost: "Gastiganto"
|
||||
smtpHost: "Gastigo"
|
||||
smtpPort: "Pordo"
|
||||
smtpUser: "Uzantnomo"
|
||||
smtpPass: "Pasvorto"
|
||||
|
@ -481,7 +482,7 @@ notSet: "Ne elektita"
|
|||
emailVerified: "Via retpoŝto estis kontrolita."
|
||||
noteFavoritesCount: "La nombro de notoj preferataj"
|
||||
pageLikesCount: "La nombro de paĝoj kiun la uzanto preferas"
|
||||
pageLikedCount: "La nombro de uzantoj kiuj preferas la paĝon"
|
||||
pageLikedCount: "La nombro de uzantoj, kiuj preferas paĝon de ĉi tiu uzanto"
|
||||
contact: "Kontakto"
|
||||
makeExplorable: "Videbligi konton sur la paĝo \"Esplori\""
|
||||
duplicate: "Duobligi"
|
||||
|
@ -509,7 +510,7 @@ inUse: "Uzata"
|
|||
editCode: "Redakti kodon"
|
||||
emailNotification: "Sciigoj per retpoŝto"
|
||||
inChannelSearch: "Serĉi en kanalo"
|
||||
useReactionPickerForContextMenu: "Oni malfermas reago-elektilon per dekstro-kliki"
|
||||
useReactionPickerForContextMenu: "Malfermi reago-elektilon per dekstro-klaki"
|
||||
typingUsers: "{users} nun entajpas…"
|
||||
clear: "Vakigi"
|
||||
goBack: "Reiri antaŭ"
|
||||
|
@ -540,6 +541,7 @@ troubleshooting: "Problemsolvi"
|
|||
learnMore: "Lernu pli"
|
||||
translate: "Traduki"
|
||||
translatedFrom: "Tradukita el {x}"
|
||||
controllPanel: "Ŝaltpodio"
|
||||
_docs:
|
||||
continueReading: "Legi plu"
|
||||
features: "Funkcioj"
|
||||
|
@ -614,8 +616,8 @@ _wordMute:
|
|||
mutedNotes: "Silentigitaj notoj"
|
||||
_theme:
|
||||
manage: "Administri kolorarojn"
|
||||
code: "Kodo de koloraro"
|
||||
description: "Priskribe"
|
||||
code: "Kolorara kodo"
|
||||
description: "Priskribo"
|
||||
color: "Koloro"
|
||||
darken: "Malbrileco"
|
||||
lighten: "Brileco"
|
||||
|
@ -667,8 +669,8 @@ _permissions:
|
|||
"write:blocks": "Redakti vian liston de blokitoj"
|
||||
"read:drive": "Legi vian diskon"
|
||||
"write:drive": "Ĉia operacio por skribi, forviŝi, aŭ alimaniere ŝanĝi la informon de dosiero en via disko de Misskey"
|
||||
"read:favorites": "Vidi vian liston de preferataĵoj"
|
||||
"write:favorites": "Redakti vian liston de preferataĵoj."
|
||||
"read:favorites": "Vidi vian liston de preferaĵoj"
|
||||
"write:favorites": "Redakti vian liston de preferaĵoj"
|
||||
"read:following": "Vidi la infomaciojn pri tio, kion vi sekvas"
|
||||
"write:following": "Sekvi aŭ malsekvi alian uzanton"
|
||||
"read:messaging": "Vidi vian retbabiladon"
|
||||
|
@ -715,23 +717,24 @@ _poll:
|
|||
vote: "Baloti"
|
||||
closed: "Oni jam balotis ĝin"
|
||||
_visibility:
|
||||
public: "Publika"
|
||||
publicDescription: "Via noto estos videbla de ĉiuj uzantoj"
|
||||
home: "Hejma"
|
||||
homeDescription: "Dissendi nur sur hejma templinio"
|
||||
followers: "Sekvantoj"
|
||||
followersDescription: "Nur al sekvantoj al mi"
|
||||
specified: "Rekta"
|
||||
specifiedDescription: "Publikigi nur al specifaj uzantoj"
|
||||
followers: "Nur al sekvantoj"
|
||||
followersDescription: "Publiki nur al viaj sekvantoj"
|
||||
specified: "Rekte"
|
||||
specifiedDescription: "Montri nur al specifaj uzantoj"
|
||||
localOnly: "Nur loka"
|
||||
localOnlyDescription: "Ne montri al transaj uzantoj"
|
||||
_postForm:
|
||||
replyPlaceholder: "Respondi tiun noton…"
|
||||
quotePlaceholder: "Citi tiun noton…"
|
||||
replyPlaceholder: "Respondi la noton…"
|
||||
quotePlaceholder: "Citi la noton…"
|
||||
channelPlaceholder: "Mencii en kanalo…"
|
||||
_profile:
|
||||
name: "Nomo"
|
||||
username: "Uzantnomo"
|
||||
description: "Pri mi"
|
||||
description: "Sinprezento"
|
||||
metadata: "Kromaj informoj"
|
||||
metadataEdit: "Redakti kromaj informoj"
|
||||
changeAvatar: "Ŝanĝi profilbildon"
|
||||
|
@ -746,7 +749,7 @@ _charts:
|
|||
federationInstancesTotal: "La totala nombro de nodoj kunfederantaj"
|
||||
usersTotal: "La totala nombro de la uzantoj"
|
||||
activeUsers: "La nombro de la uzantoj aktivaj"
|
||||
notesTotal: "La totala nombro de la notoj"
|
||||
notesTotal: "La totala nombro de notoj"
|
||||
filesTotal: "La totala nombro de la dosieroj"
|
||||
_timelines:
|
||||
home: "Hejma"
|
||||
|
@ -859,16 +862,21 @@ _pages:
|
|||
argVariables: "Eniga junto"
|
||||
_notification:
|
||||
fileUploaded: "La dosiero sukcese alŝutiĝis."
|
||||
youGotMention: "{name} mencis"
|
||||
youGotReply: "{name} respondis"
|
||||
youGotQuote: "{name} citis"
|
||||
youRenoted: "{name} plusendis"
|
||||
youGotPoll: "{name} balotis"
|
||||
youGotMessagingMessageFromUser: "{name} sentis mesaĝon al vi."
|
||||
youGotMessagingMessageFromGroup: "Retbabilan mesaĝon oni sendis al la grupo {name}"
|
||||
youWereFollowed: "eksekvis vin"
|
||||
youReceivedFollowRequest: "Vi ricevis peton de sekvado"
|
||||
yourFollowRequestAccepted: "Via peto por sekvado estis akceptita."
|
||||
yourFollowRequestAccepted: "Via peto de sekvado estis akceptita."
|
||||
_types:
|
||||
follow: "Sekvatoj"
|
||||
all: "Ĉio"
|
||||
follow: "Nova sekvatoj"
|
||||
mention: "Mencioj"
|
||||
reply: "Respondoj"
|
||||
renote: "Notoj plusenditaj"
|
||||
quote: "Citi"
|
||||
reaction: "Reagoj"
|
||||
|
@ -882,4 +890,4 @@ _deck:
|
|||
antenna: "Antenoj"
|
||||
list: "Listoj"
|
||||
mentions: "Al vi"
|
||||
direct: "Notoj rektaj"
|
||||
direct: "Rekte"
|
||||
|
|
|
@ -7,6 +7,7 @@ search: "Buscar"
|
|||
notifications: "Notificaciones"
|
||||
username: "Nombre de usuario"
|
||||
password: "Contraseña"
|
||||
forgotPassword: "Olvidé mi Contraseña"
|
||||
fetchingAsApObject: "Buscando en el fediverso"
|
||||
ok: "OK"
|
||||
gotIt: "Entendido"
|
||||
|
@ -279,6 +280,7 @@ emptyDrive: "El drive está vacío"
|
|||
emptyFolder: "La carpeta está vacía"
|
||||
unableToDelete: "No se puede borrar"
|
||||
inputNewFileName: "Ingrese un nuevo nombre de archivo"
|
||||
inputNewDescription: "Ingrese nueva descripción"
|
||||
inputNewFolderName: "Ingrese un nuevo nombre de la carpeta"
|
||||
circularReferenceFolder: "La carpeta de destino es una sub-carpeta de la carpeta que quieres mover."
|
||||
hasChildFilesOrFolders: "No se puede borrar esta carpeta. No está vacía."
|
||||
|
@ -310,6 +312,8 @@ monthX: "Mes {month}"
|
|||
yearX: "Año {year}"
|
||||
pages: "Páginas"
|
||||
integration: "Integración"
|
||||
connectService: "Conectar"
|
||||
disconnectService: "Desconectar"
|
||||
enableLocalTimeline: "Habilitar linea de tiempo local"
|
||||
enableGlobalTimeline: "Habilitar linea de tiempo global"
|
||||
disablingTimelinesInfo: "Aunque se desactiven estas lineas de tiempo, por conveniencia el administrador y los moderadores pueden seguir usándolos"
|
||||
|
@ -323,6 +327,7 @@ driveCapacityPerRemoteAccount: "Capacidad del drive por usuario remoto"
|
|||
inMb: "En megabytes"
|
||||
iconUrl: "URL de la imagen del avatar"
|
||||
bannerUrl: "URL de la imagen del banner"
|
||||
backgroundImageUrl: "URL de la imagen de fondo"
|
||||
basicInfo: "Información básica"
|
||||
pinnedUsers: "Usuarios fijados"
|
||||
pinnedUsersDescription: "Describir los usuarios que quiere fijar en la página \"Descubrir\" separados por una linea nueva"
|
||||
|
@ -524,6 +529,9 @@ removeAllFollowing: "Retener todos los siguientes"
|
|||
removeAllFollowingDescription: "Cancelar todos los siguientes del servidor {host}. Ejecutar en caso de que esta instancia haya dejado de existir"
|
||||
userSuspended: "Este usuario ha sido suspendido."
|
||||
userSilenced: "Este usuario ha sido silenciado."
|
||||
yourAccountSuspendedTitle: "Esta cuenta ha sido suspendida"
|
||||
yourAccountSuspendedDescription: "Esta cuenta ha sido suspendida debido a violaciones de los términos de servicio del servidor y otras razones. Para más información, póngase en contacto con el administrador. Por favor, no cree una nueva cuenta."
|
||||
menu: "Menú"
|
||||
divider: "Divisor"
|
||||
addItem: "Agregar elemento"
|
||||
rooms: "Cuartos"
|
||||
|
@ -543,6 +551,8 @@ disablePlayer: "Cerrar reproductor"
|
|||
expandTweet: "Expandir tweet"
|
||||
themeEditor: "Editor de temas"
|
||||
description: "Descripción"
|
||||
describeFile: "Añade una descripción"
|
||||
enterFileDescription: "Introducir un título"
|
||||
author: "Autor"
|
||||
leaveConfirm: "Hay modificaciones sin guardar. ¿Desea descartarlas?"
|
||||
manage: "Administrar"
|
||||
|
@ -645,29 +655,90 @@ driveFilesCount: "Cantidad de archivos en el drive"
|
|||
driveUsage: "Uso del drive"
|
||||
noCrawle: "Rechazar indexación del crawler"
|
||||
noCrawleDescription: "Pedir a los motores de búsqueda que no indexen tu perfil, notas, páginas, etc."
|
||||
lockedAccountInfo: "A menos que configures la visibilidad de tus notas como \"Sólo seguidores\", tus notas serán visibles para cualquiera, incluso si requieres que los seguidores sean aprobados manualmente."
|
||||
alwaysMarkSensitive: "Marcar los medios de comunicación como contenido sensible por defecto"
|
||||
loadRawImages: "Cargar las imágenes originales en lugar de mostrar las miniaturas"
|
||||
disableShowingAnimatedImages: "No reproducir imágenes animadas"
|
||||
verificationEmailSent: "Se le ha enviado un correo electrónico de confirmación. Por favor, acceda al enlace proporcionado en el correo electrónico para completar la configuración."
|
||||
notSet: "Sin especificar"
|
||||
emailVerified: "Su dirección de correo electrónico ha sido verificada."
|
||||
noteFavoritesCount: "Número de notas favoritas"
|
||||
pageLikesCount: "Número de favoritos en la página"
|
||||
pageLikedCount: "Número de favoritos de su página"
|
||||
reversiCount: "Numero de partidas Reversi"
|
||||
contact: "Contacto"
|
||||
useSystemFont: "Utilizar la tipografía por defecto del sistema"
|
||||
clips: "Clip"
|
||||
experimentalFeatures: "Características experimentales"
|
||||
developer: "Desarrolladores"
|
||||
makeExplorable: "Hacer visible la cuenta en \"Explorar\""
|
||||
makeExplorableDescription: "Si desactiva esta opción, su cuenta no aparecerá en la sección \"Explorar\"."
|
||||
showGapBetweenNotesInTimeline: "Mostrar un intervalo entre notas en la línea de tiempo"
|
||||
duplicate: "Duplicar"
|
||||
left: "Izquierda"
|
||||
center: "Centrar"
|
||||
wide: "Ancho"
|
||||
narrow: "Estrecho"
|
||||
reloadToApplySetting: "Esta configuración sólo se aplicará después de recargar la página. ¿Recargar ahora?"
|
||||
showTitlebar: "Mostrar la barra de título"
|
||||
clearCache: "Limpiar caché"
|
||||
onlineUsersCount: "{n} usuarios en línea"
|
||||
nUsers: "{n} Usuarios"
|
||||
nNotes: "{n} Notas"
|
||||
sendErrorReports: "Envíar informe de errores"
|
||||
sendErrorReportsDescription: "Si habilita esta opción, ayudará a mejorar la calidad de Misskey compartiendo información detallada sobre los errores cuando se produzca un problema.\nEsto incluye información como la versión de su sistema operativo, el tipo de navegador que utiliza, su historial de actividad, etc."
|
||||
myTheme: "Mi Tema"
|
||||
backgroundColor: "Fondo"
|
||||
accentColor: "Acento"
|
||||
textColor: "Texto"
|
||||
saveAs: "Guardar como…"
|
||||
advanced: "Avanzado"
|
||||
value: "Valores"
|
||||
createdAt: "Fecha de creación"
|
||||
updatedAt: "Actualizado"
|
||||
saveConfirm: "¿Guardar cambios?"
|
||||
deleteConfirm: "¿Desea eliminarlo?"
|
||||
invalidValue: "Este no es un valor válido."
|
||||
registry: "Registro"
|
||||
closeAccount: "Cerrar cuenta"
|
||||
currentVersion: "Versión actual"
|
||||
latestVersion: "Última versión"
|
||||
youAreRunningUpToDateClient: "Está utilizando la versión más reciente de su cliente."
|
||||
newVersionOfClientAvailable: "Hay una versión más nueva de su cliente disponible."
|
||||
usageAmount: "Uso"
|
||||
capacity: "Capacidad"
|
||||
inUse: "Usado"
|
||||
editCode: "Editar código"
|
||||
goBack: "Deseleccionar"
|
||||
info: "Información"
|
||||
user: "Usuarios"
|
||||
administration: "Administrar"
|
||||
expiration: "Termina el"
|
||||
middle: "Mediano"
|
||||
customCssWarn: "Este ajuste sólo debe utilizarse si se sabe lo que hace. Introducir valores inadecuados puede hacer que el cliente deje de funcionar con normalidad."
|
||||
global: "Global"
|
||||
squareAvatars: "Mostrar iconos cuadrados"
|
||||
sent: "Enviar"
|
||||
received: "Recibido"
|
||||
searchResult: "Resultados de búsqueda"
|
||||
hashtags: "Hashtag"
|
||||
troubleshooting: "Solución de problemas"
|
||||
useBlurEffect: "Utilizar efecto de desenfoque en la interfaz de usuario"
|
||||
learnMore: "Ver más"
|
||||
misskeyUpdated: "¡Misskey ha sido actualizado!"
|
||||
whatIsNew: "Mostrar cambios"
|
||||
translate: "Traducir"
|
||||
translatedFrom: "Traducido de {x}"
|
||||
accountDeletionInProgress: "La eliminación de la cuenta está en curso"
|
||||
usernameInfo: "Un nombre que identifique su cuenta de otras en este servidor. Puede utilizar el alfabeto (a~z, A~Z), dígitos (0~9) o guiones bajos (_). Los nombres de usuario no se pueden cambiar posteriormente."
|
||||
aiChanMode: "Modo Ai"
|
||||
keepCw: "Mantener la advertencia de contenido"
|
||||
pubSub: "Cuentas Pub/Sub"
|
||||
lastCommunication: "Última comunicación"
|
||||
resolved: "Resuelto"
|
||||
unresolved: "Sin resolver"
|
||||
_accountDelete:
|
||||
accountDelete: "Eliminar Cuenta"
|
||||
_docs:
|
||||
admin: "Administrar"
|
||||
_ad:
|
||||
|
|
|
@ -81,6 +81,8 @@ somethingHappened: "Une erreur est survenue"
|
|||
retry: "Réessayer"
|
||||
pageLoadError: "Le chargement de la page a échoué"
|
||||
pageLoadErrorDescription: "Cela est généralement causé par le cache du navigateur ou par un problème réseau. Veuillez vider votre cache ou attendre un peu et réessayer."
|
||||
serverIsDead: "Le serveur ne répond pas. Patientez quelques instants puis essayez à nouveau."
|
||||
youShouldUpgradeClient: "Si la page ne s'affiche pas correctement, rechargez-la pour mettre votre client à jour."
|
||||
enterListName: "Nom de la liste"
|
||||
privacy: "Confidentialité"
|
||||
makeFollowManuallyApprove: "Accepter manuellement les demandes d’abonnement"
|
||||
|
@ -136,7 +138,7 @@ settingGuide: "Configuration proposée"
|
|||
cacheRemoteFiles: "Mise en cache des fichiers distants"
|
||||
cacheRemoteFilesDescription: "Lorsque cette option est désactivée, les fichiers distants sont chargés directement depuis l’instance distante. La désactiver diminuera certes l’utilisation de l’espace de stockage local mais augmentera le trafic réseau puisque les miniatures ne seront plus générées."
|
||||
flagAsBot: "Ce compte est un robot"
|
||||
flagAsBotDescription: "Si ce compte est géré de manière automatisée , définissez cette option. Si elle est activée, elle agira comme un marqueur pour les autres développeurs afin d'éviter des chaînes d'interaction sans fin avec d'autres robots et d'ajuster les systèmes internes de Misskey pour traiter ce compte comme un robot."
|
||||
flagAsBotDescription: "Si ce compte est géré de manière automatisée, choisissez cette option. Si elle est activée, elle agira comme un marqueur pour les autres développeurs afin d'éviter des chaînes d'interaction sans fin avec d'autres robots et d'ajuster les systèmes internes de Misskey pour traiter ce compte comme un robot."
|
||||
flagAsCat: "Ce compte est un chat"
|
||||
flagAsCatDescription: "Activer l'option \" Je suis un chat \" pour ce compte."
|
||||
autoAcceptFollowed: "Accepter automatiquement les demandes d’abonnement venant d’utilisateur·rice·s que vous suivez"
|
||||
|
@ -377,7 +379,7 @@ aboutMisskey: "À propos de Misskey"
|
|||
administrator: "Administrateur"
|
||||
token: "Jeton"
|
||||
twoStepAuthentication: "Authentification à deux facteurs"
|
||||
moderator: "Modérateurs"
|
||||
moderator: "Modérateur·rice·s"
|
||||
nUsersMentioned: "{n} utilisateur·rice·s mentionné·e·s"
|
||||
securityKey: "Clé de sécurité"
|
||||
securityKeyName: "Nom de la clé"
|
||||
|
@ -495,7 +497,7 @@ objectStorageSetPublicRead: "Régler sur « public » lors de l'envoi"
|
|||
serverLogs: "Journal du serveur"
|
||||
deleteAll: "Supprimer tout"
|
||||
showFixedPostForm: "Afficher le formulaire de publication en haut du fil d'actualité"
|
||||
newNoteRecived: "Vous avez reçu une nouvelle note"
|
||||
newNoteRecived: "Voir les nouvelles notes"
|
||||
sounds: "Sons"
|
||||
listen: "Écouter"
|
||||
none: "Rien"
|
||||
|
@ -530,6 +532,7 @@ removeAllFollowingDescription: "Se désabonner de tous les comptes de {host}. Ve
|
|||
userSuspended: "Cet·te utilisateur·rice a été suspendu·e."
|
||||
userSilenced: "Cette utilisateur·trice a été mis·e en sourdine."
|
||||
yourAccountSuspendedTitle: "Ce compte est suspendu"
|
||||
yourAccountSuspendedDescription: "Ce compte est suspendu car vous avez enfreint les conditions d'utilisation de l'instance, ou pour un motif similaire. Si vous souhaitez connaître en détail les raisons de cette suspension, renseignez-vous auprès de l'administrateur·rice de votre instance. Merci de ne pas créer de nouveau compte."
|
||||
menu: "Menu"
|
||||
divider: "Séparateur"
|
||||
addItem: "Ajouter un élément"
|
||||
|
@ -786,6 +789,15 @@ pubSub: "Comptes Pub/Sub"
|
|||
lastCommunication: "Dernière communication"
|
||||
resolved: "Résolu"
|
||||
unresolved: "En attente"
|
||||
emailRequiredForSignup: "Une adresse e-mail est nécessaire pour créer un compte"
|
||||
unread: "Non lu"
|
||||
filter: "Filtre"
|
||||
controllPanel: "Panneau de contrôle"
|
||||
manageAccounts: "Gérer les comptes"
|
||||
_signup:
|
||||
almostThere: "Bientôt fini"
|
||||
emailAddressInfo: "Insérez votre adresse e-mail."
|
||||
emailSent: "Un courriel de confirmation vient d'être envoyé à l'adresse que vous avez renseignée ({email}). Cliquez sur le lien contenu dans le message pour terminer la création de votre compte."
|
||||
_accountDelete:
|
||||
accountDelete: "Supprimer le compte"
|
||||
mayTakeTime: "La suppression de compte nécessitant beaucoup de ressources, l'exécution du processus peut prendre du temps, en fonction de la quantité de contenus que vous avez créés et du nombre de fichiers que vous avez téléversés."
|
||||
|
@ -900,6 +912,8 @@ _mfm:
|
|||
fontDescription: "Il est possible de choisir la police."
|
||||
rainbow: "Arc-en-ciel"
|
||||
rainbowDescription: "Permet d'afficher le contenu en couleurs arc-en-ciel."
|
||||
sparkle: "Paillettes"
|
||||
sparkleDescription: "Ajoute un effet scintillant au contenu."
|
||||
_reversi:
|
||||
reversi: "Reversi"
|
||||
gameSettings: "Réglages de la partie"
|
||||
|
@ -1243,7 +1257,7 @@ _charts:
|
|||
federationInstancesTotal: "Nombre total d'instances fédérées"
|
||||
usersIncDec: "Variation du nombre d'utilisateur·rice·s"
|
||||
usersTotal: "Nombre des utilisateur·rice·s au total"
|
||||
activeUsers: "Utilisateur·rice·s actif·ve·s"
|
||||
activeUsers: "Nombre d'utilisateurices actif·ve·s"
|
||||
notesIncDec: "Variation du nombre des notes"
|
||||
localNotesIncDec: "Variation du nombre de notes locales"
|
||||
remoteNotesIncDec: "Variation du nombre de notes distantes"
|
||||
|
|
|
@ -780,6 +780,7 @@ translatedFrom: "Terjemahkan dari {x}"
|
|||
accountDeletionInProgress: "Penghapusan akun sedang dalam proses"
|
||||
usernameInfo: "Nama yang mengidentifikasikan akun kamu dari yang lain pada server ini. Kamu dapat menggunakan alfabet (a~z, A~Z), digit (0~9) atau garis bawah (_). Username tidak dapat diubah setelahnya."
|
||||
keepCw: "Biarkan Peringatan Konten"
|
||||
controllPanel: "Panel kontrol"
|
||||
_accountDelete:
|
||||
accountDelete: "Hapus akun"
|
||||
mayTakeTime: "Karena penghapusan akun merupakan proses yang berat dan intensif, kemungkinan dapat membutuhkan waktu untuk menyelesaikan tergantung daripada berapa banyak konten yang kamu buat dan berapa banyak berkas yang telah kamu unggah."
|
||||
|
|
|
@ -482,7 +482,7 @@ objectStorageSetPublicRead: "Imposta \"visibilità pubblica\" al momento di cari
|
|||
serverLogs: "Log del server"
|
||||
deleteAll: "Cancella cronologia"
|
||||
showFixedPostForm: "Visualizzare la finestra di pubblicazione in cima alla timeline"
|
||||
newNoteRecived: "Nuova nota ricevuta"
|
||||
newNoteRecived: "Vedi le nuove note"
|
||||
sounds: "Impostazioni suoni"
|
||||
listen: "Ascolta"
|
||||
none: "Niente"
|
||||
|
|
|
@ -797,6 +797,8 @@ unread: "未読"
|
|||
filter: "フィルタ"
|
||||
controllPanel: "コントロールパネル"
|
||||
manageAccounts: "アカウントを管理"
|
||||
makeReactionsPublic: "リアクション一覧を公開する"
|
||||
makeReactionsPublicDescription: "あなたがしたリアクション一覧を誰でも見れるようにします。"
|
||||
|
||||
_signup:
|
||||
almostThere: "ほとんど完了です"
|
||||
|
|
|
@ -787,6 +787,7 @@ pubSub: "Pub/Sub 계정"
|
|||
lastCommunication: "마지막 통신"
|
||||
resolved: "해결됨"
|
||||
unresolved: "해결되지 않음"
|
||||
controllPanel: "제어판"
|
||||
_accountDelete:
|
||||
accountDelete: "계정 삭제"
|
||||
mayTakeTime: "계정 삭제는 서버에 부하를 가하기 때문에, 작성한 콘텐츠나 업로드한 파일의 수가 많으면 완료까지 시간이 걸릴 수 있습니다."
|
||||
|
@ -901,6 +902,8 @@ _mfm:
|
|||
fontDescription: "내용의 글꼴을 지정할 수 있습니다."
|
||||
rainbow: "무지개"
|
||||
rainbowDescription: "내용을 무지개로 표시합니다."
|
||||
sparkle: "반짝반짝"
|
||||
sparkleDescription: "반짝이는 파티클 효과를 추가합니다."
|
||||
_reversi:
|
||||
reversi: "리버시"
|
||||
gameSettings: "대국 설정"
|
||||
|
|
|
@ -81,6 +81,8 @@ somethingHappened: "Что-то пошло не так"
|
|||
retry: "Повторить попытку"
|
||||
pageLoadError: "Не удалось загрузить страницу"
|
||||
pageLoadErrorDescription: "Обычно это случается из-за сбоев в сети или кэша браузера. Попробуйте очистить кэш, или подождать пару минут, а потом попытаться загрузить страницу снова."
|
||||
serverIsDead: "Ответа от сервера нет. Пожалуйста, подождите немного и повторите попытку."
|
||||
youShouldUpgradeClient: "Чтобы просмотреть эту страницу, пожалуйста, обновите ее."
|
||||
enterListName: "Название списка"
|
||||
privacy: "Конфиденциальность"
|
||||
makeFollowManuallyApprove: "Принимать подписчиков вручную"
|
||||
|
@ -529,6 +531,8 @@ removeAllFollowing: "Удалить всех подписчиков"
|
|||
removeAllFollowingDescription: "Отменить все подписки с домена {host}? Пожалуйста, применяйте это действие, если инстанс больше не существует."
|
||||
userSuspended: "Эта учётная запись заморожена"
|
||||
userSilenced: "Этот пользователь был заглушен"
|
||||
yourAccountSuspendedTitle: "Эта учетная запись заблокирована"
|
||||
yourAccountSuspendedDescription: "Эта учетная запись была заблокирована из-за нарушения условий предоставления услуг сервера. Свяжитесь с администратором, если вы хотите узнать более подробную причину. Пожалуйста, не создавайте новую учетную запись."
|
||||
menu: "Меню"
|
||||
divider: "Линия-разделитель"
|
||||
addItem: "Добавить элемент"
|
||||
|
@ -775,6 +779,13 @@ useBlurEffect: "Размытие в интерфейсе"
|
|||
learnMore: "Подробнее"
|
||||
misskeyUpdated: "Misskey обновился!"
|
||||
whatIsNew: "Что новенького?"
|
||||
translate: "Перевод"
|
||||
accountDeletionInProgress: "В настоящее время выполняется удаление учетной записи"
|
||||
usernameInfo: "Имя, которое отличает вашу учетную запись от других на этом сервере. Вы можете использовать алфавит (a~z, A~Z), цифры (0~9) или символы подчеркивания (_). Имена пользователей не могут быть изменены позже."
|
||||
aiChanMode: "ИИ режим"
|
||||
keepCw: "Сохраняйте Предупреждения о содержимом"
|
||||
controllPanel: "Панель управления"
|
||||
manageAccounts: "Управление аккаунтом"
|
||||
_docs:
|
||||
continueReading: "Читать подробнее"
|
||||
features: "Возможности"
|
||||
|
|
|
@ -81,6 +81,8 @@ somethingHappened: "出现了一些问题!"
|
|||
retry: "重试"
|
||||
pageLoadError: "页面加载失败。"
|
||||
pageLoadErrorDescription: "这通常是由于网络或浏览器缓存的原因。请清除缓存或等待片刻后重试。"
|
||||
serverIsDead: "服务器没有响应。 请稍等片刻,然后重试。"
|
||||
youShouldUpgradeClient: "请重新加载并使用新版本的客户端查看此页面。"
|
||||
enterListName: "输入列表名称"
|
||||
privacy: "隐私"
|
||||
makeFollowManuallyApprove: "关注者的关注请求需要批准"
|
||||
|
@ -764,6 +766,7 @@ middle: "中"
|
|||
low: "低"
|
||||
emailNotConfiguredWarning: "电子邮件地址未设置。"
|
||||
ratio: "比率"
|
||||
previewNoteText: "预览文本"
|
||||
customCss: "自定义 CSS"
|
||||
customCssWarn: "这些设置必须有相关的基础知识,不当的配置可能导致客户端无法正常使用!"
|
||||
global: "全局"
|
||||
|
@ -787,6 +790,17 @@ pubSub: "Pub/Sub账户"
|
|||
lastCommunication: "最近通信"
|
||||
resolved: "已解决"
|
||||
unresolved: "未解决"
|
||||
itsOn: "已开启"
|
||||
itsOff: "已关闭"
|
||||
emailRequiredForSignup: "注册账户需要电子邮件地址"
|
||||
unread: "未读"
|
||||
filter: "筛选"
|
||||
controllPanel: "控制面板"
|
||||
manageAccounts: "管理账户"
|
||||
_signup:
|
||||
almostThere: "即将完成"
|
||||
emailAddressInfo: "请输入您所使用的电子邮件地址"
|
||||
emailSent: "已将确认邮件发送至您输入的电子邮件地址 ({email})。请访问电子邮件中的链接以完成帐户创建。"
|
||||
_accountDelete:
|
||||
accountDelete: "删除帐户"
|
||||
mayTakeTime: "删除账号是一个性能损耗较大的处理,如果账号持有的内容数量和上传的文件数量较多的话,完成需要花费一段时间。"
|
||||
|
@ -901,6 +915,8 @@ _mfm:
|
|||
fontDescription: "可以设置内容所使用的字体。"
|
||||
rainbow: "彩虹"
|
||||
rainbowDescription: "用彩虹色来显示内容。"
|
||||
sparkle: "闪光"
|
||||
sparkleDescription: "添加发光粒子效果。"
|
||||
_reversi:
|
||||
reversi: "黑白棋"
|
||||
gameSettings: "对局设置"
|
||||
|
|
14
migration/1634486652000-user-public-reactions.ts
Normal file
14
migration/1634486652000-user-public-reactions.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class userPublicReactions1634486652000 implements MigrationInterface {
|
||||
name = 'userPublicReactions1634486652000'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "user_profile" ADD "publicReactions" boolean NOT NULL DEFAULT false`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "publicReactions"`);
|
||||
}
|
||||
|
||||
}
|
34
package.json
34
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <syuilotan@yahoo.co.jp>",
|
||||
"version": "12.91.0",
|
||||
"version": "12.92.0",
|
||||
"codename": "indigo",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -103,8 +103,8 @@
|
|||
"@types/webpack-stream": "3.2.12",
|
||||
"@types/websocket": "1.0.4",
|
||||
"@types/ws": "8.2.0",
|
||||
"@typescript-eslint/parser": "4.33.0",
|
||||
"@vue/compiler-sfc": "3.2.19",
|
||||
"@typescript-eslint/parser": "5.0.0",
|
||||
"@vue/compiler-sfc": "3.2.20",
|
||||
"abort-controller": "3.0.0",
|
||||
"apexcharts": "3.28.3",
|
||||
"autobind-decorator": "2.4.0",
|
||||
|
@ -114,8 +114,8 @@
|
|||
"bcryptjs": "2.4.3",
|
||||
"blurhash": "1.1.4",
|
||||
"broadcast-channel": "4.2.0",
|
||||
"bull": "3.29.2",
|
||||
"cacheable-lookup": "6.0.2",
|
||||
"bull": "3.29.3",
|
||||
"cacheable-lookup": "6.0.3",
|
||||
"cafy": "15.2.1",
|
||||
"cbor": "8.0.2",
|
||||
"chalk": "4.1.2",
|
||||
|
@ -125,11 +125,11 @@
|
|||
"concurrently": "6.3.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"crc-32": "1.2.0",
|
||||
"css-loader": "6.3.0",
|
||||
"css-loader": "6.4.0",
|
||||
"cssnano": "5.0.8",
|
||||
"dateformat": "4.5.1",
|
||||
"escape-regexp": "0.0.1",
|
||||
"eslint": "7.32.0",
|
||||
"eslint": "8.0.1",
|
||||
"eslint-plugin-vue": "7.19.1",
|
||||
"eventemitter3": "4.0.7",
|
||||
"feed": "4.2.2",
|
||||
|
@ -176,15 +176,15 @@
|
|||
"multer": "1.4.3",
|
||||
"nested-property": "4.0.0",
|
||||
"node-fetch": "2.6.1",
|
||||
"nodemailer": "6.6.5",
|
||||
"nodemailer": "6.7.0",
|
||||
"os-utils": "0.0.14",
|
||||
"parse5": "6.0.1",
|
||||
"pg": "8.7.1",
|
||||
"portscanner": "2.2.0",
|
||||
"postcss": "8.3.9",
|
||||
"postcss-loader": "6.1.1",
|
||||
"postcss-loader": "6.2.0",
|
||||
"prismjs": "1.25.0",
|
||||
"private-ip": "2.2.1",
|
||||
"private-ip": "2.3.0",
|
||||
"probe-image-size": "7.2.1",
|
||||
"promise-limit": "2.7.0",
|
||||
"pug": "3.0.2",
|
||||
|
@ -203,8 +203,8 @@
|
|||
"rimraf": "3.0.2",
|
||||
"rndstr": "1.0.0",
|
||||
"s-age": "1.1.2",
|
||||
"sass": "1.42.1",
|
||||
"sass-loader": "12.1.0",
|
||||
"sass": "1.43.2",
|
||||
"sass-loader": "12.2.0",
|
||||
"seedrandom": "3.0.5",
|
||||
"sharp": "0.29.1",
|
||||
"speakeasy": "2.0.0",
|
||||
|
@ -213,7 +213,7 @@
|
|||
"style-loader": "3.3.0",
|
||||
"summaly": "2.4.1",
|
||||
"syslog-pro": "1.0.0",
|
||||
"systeminformation": "5.9.4",
|
||||
"systeminformation": "5.9.7",
|
||||
"syuilo-password-strength": "0.0.1",
|
||||
"textarea-caret": "3.1.0",
|
||||
"three": "0.117.1",
|
||||
|
@ -221,19 +221,19 @@
|
|||
"tinycolor2": "1.4.2",
|
||||
"tmp": "0.2.1",
|
||||
"ts-loader": "9.2.6",
|
||||
"ts-node": "10.2.1",
|
||||
"ts-node": "10.3.0",
|
||||
"tsc-alias": "1.3.10",
|
||||
"tsconfig-paths": "3.11.0",
|
||||
"tslint": "6.1.3",
|
||||
"tslint-sonarts": "1.9.0",
|
||||
"twemoji-parser": "13.1.0",
|
||||
"typeorm": "0.2.38",
|
||||
"typescript": "4.4.3",
|
||||
"typescript": "4.4.4",
|
||||
"ulid": "2.3.0",
|
||||
"uuid": "8.3.2",
|
||||
"v-debounce": "0.1.2",
|
||||
"vanilla-tilt": "1.7.2",
|
||||
"vue": "3.2.19",
|
||||
"vue": "3.2.20",
|
||||
"vue-loader": "16.7.0",
|
||||
"vue-prism-editor": "2.0.0-alpha.2",
|
||||
"vue-router": "4.0.5",
|
||||
|
@ -241,7 +241,7 @@
|
|||
"vue-svg-loader": "0.17.0-beta.2",
|
||||
"vuedraggable": "4.0.1",
|
||||
"web-push": "3.4.5",
|
||||
"webpack": "5.58.0",
|
||||
"webpack": "5.58.2",
|
||||
"webpack-cli": "4.9.0",
|
||||
"websocket": "1.0.34",
|
||||
"ws": "8.2.3",
|
||||
|
|
|
@ -22,7 +22,6 @@ export default defineComponent({
|
|||
}
|
||||
},
|
||||
render() {
|
||||
const label = this.$slots.desc();
|
||||
let options = this.$slots.default();
|
||||
|
||||
// なぜかFragmentになることがあるため
|
||||
|
@ -31,7 +30,6 @@ export default defineComponent({
|
|||
return h('div', {
|
||||
class: 'novjtcto'
|
||||
}, [
|
||||
h('div', { class: 'label' }, label),
|
||||
...options.map(option => h(MkRadio, {
|
||||
key: option.key,
|
||||
value: option.props.value,
|
||||
|
@ -45,16 +43,6 @@ export default defineComponent({
|
|||
|
||||
<style lang="scss">
|
||||
.novjtcto {
|
||||
> .label {
|
||||
font-size: 0.85em;
|
||||
padding: 0 0 8px 12px;
|
||||
user-select: none;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
|
|
@ -33,10 +33,16 @@ export default defineComponent({
|
|||
|
||||
onMounted(() => {
|
||||
ro = new ResizeObserver((entries) => {
|
||||
/* iOSが対応していない
|
||||
adjust({
|
||||
width: entries[0].borderBoxSize[0].inlineSize,
|
||||
height: entries[0].borderBoxSize[0].blockSize,
|
||||
});
|
||||
*/
|
||||
adjust({
|
||||
width: root.value.offsetWidth,
|
||||
height: root.value.offsetHeight,
|
||||
});
|
||||
});
|
||||
ro.observe(root.value);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</span>
|
||||
<button class="_button" @click="$refs.modal.close()"><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
<div class="body _flat_">
|
||||
<div class="body _fitSide_">
|
||||
<keep-alive>
|
||||
<component :is="component" v-bind="props" :ref="changePage"/>
|
||||
</keep-alive>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<template #headerLeft>
|
||||
<button v-if="history.length > 0" class="_button" @click="back()" v-tooltip="$ts.goBack"><i class="fas fa-arrow-left"></i></button>
|
||||
</template>
|
||||
<div class="yrolvcoq _flat_">
|
||||
<div class="yrolvcoq _fitSide_">
|
||||
<component :is="component" v-bind="props" :ref="changePage"/>
|
||||
</div>
|
||||
</XWindow>
|
||||
|
|
|
@ -35,8 +35,8 @@ export default defineComponent({
|
|||
|
||||
> button {
|
||||
flex: 1;
|
||||
padding: 15px 12px 12px 12px;
|
||||
border-bottom: solid 3px transparent;
|
||||
padding: 10px 8px;
|
||||
border-radius: var(--radius);
|
||||
|
||||
&:disabled {
|
||||
opacity: 1 !important;
|
||||
|
@ -45,11 +45,16 @@ export default defineComponent({
|
|||
|
||||
&.active {
|
||||
color: var(--accent);
|
||||
border-bottom-color: var(--accent);
|
||||
background: var(--accentedBg);
|
||||
}
|
||||
|
||||
&:not(.active):hover {
|
||||
color: var(--fgHighlighted);
|
||||
background: var(--panelHighlight);
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
> .icon {
|
||||
|
@ -61,7 +66,7 @@ export default defineComponent({
|
|||
font-size: 80%;
|
||||
|
||||
> button {
|
||||
padding: 11px 8px 8px 8px;
|
||||
padding: 11px 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ export default defineComponent({
|
|||
}
|
||||
}
|
||||
|
||||
._flat_ .ssazuxis {
|
||||
._fitSide_ .ssazuxis {
|
||||
> header {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ export default defineComponent({
|
|||
}
|
||||
}
|
||||
|
||||
._flat_ .fpezltsf {
|
||||
._fitSide_ .fpezltsf {
|
||||
border-radius: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -382,7 +382,7 @@ export default defineComponent({
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.window-enter-active, .window-leave-active {
|
||||
transition: opacity 0.3s, transform 0.3s !important;
|
||||
transition: opacity 0.2s, transform 0.2s !important;
|
||||
}
|
||||
.window-enter-from, .window-leave-to {
|
||||
pointer-events: none;
|
||||
|
|
|
@ -65,13 +65,18 @@
|
|||
</div>
|
||||
<div v-else-if="tab === 'search'">
|
||||
<div class="_isolated">
|
||||
<MkInput v-model="query" :debounce="true" type="search">
|
||||
<MkInput v-model="searchQuery" :debounce="true" type="search">
|
||||
<template #prefix><i class="fas fa-search"></i></template>
|
||||
<template #label>{{ $ts.searchUser }}</template>
|
||||
</MkInput>
|
||||
<MkRadios v-model="searchOrigin">
|
||||
<option value="local">{{ $ts.local }}</option>
|
||||
<option value="remote">{{ $ts.remote }}</option>
|
||||
<option value="both">{{ $ts.both }}</option>
|
||||
</MkRadios>
|
||||
</div>
|
||||
|
||||
<XUserList v-if="query" class="_gap" :pagination="searchPagination" ref="search"/>
|
||||
<XUserList v-if="searchQuery" class="_gap" :pagination="searchPagination" ref="search"/>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
|
@ -83,6 +88,7 @@ import { computed, defineComponent } from 'vue';
|
|||
import XUserList from '@client/components/user-list.vue';
|
||||
import MkFolder from '@client/components/ui/folder.vue';
|
||||
import MkInput from '@client/components/form/input.vue';
|
||||
import MkRadios from '@client/components/form/radios.vue';
|
||||
import number from '@client/filters/number';
|
||||
import * as os from '@client/os';
|
||||
import * as symbols from '@client/symbols';
|
||||
|
@ -92,6 +98,7 @@ export default defineComponent({
|
|||
XUserList,
|
||||
MkFolder,
|
||||
MkInput,
|
||||
MkRadios,
|
||||
},
|
||||
|
||||
props: {
|
||||
|
@ -158,14 +165,16 @@ export default defineComponent({
|
|||
searchPagination: {
|
||||
endpoint: 'users/search',
|
||||
limit: 10,
|
||||
params: computed(() => (this.query && this.query !== '') ? {
|
||||
query: this.query
|
||||
params: computed(() => (this.searchQuery && this.searchQuery !== '') ? {
|
||||
query: this.searchQuery,
|
||||
origin: this.searchOrigin,
|
||||
} : null)
|
||||
},
|
||||
tagsLocal: [],
|
||||
tagsRemote: [],
|
||||
stats: null,
|
||||
query: null,
|
||||
searchQuery: null,
|
||||
searchOrigin: 'combined',
|
||||
num: number,
|
||||
};
|
||||
},
|
||||
|
|
|
@ -302,7 +302,7 @@ export default defineComponent({
|
|||
|
||||
> .text {
|
||||
&, ::v-deep(*) {
|
||||
color: #fff !important;
|
||||
color: var(--fgOnAccent) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
|
||||
<MkSpacer>
|
||||
<!-- TODO: MkHeaderに統合 -->
|
||||
<MkTab v-model="tab" v-if="$i">
|
||||
<option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._pages.featured }}</option>
|
||||
|
@ -29,6 +30,7 @@
|
|||
</MkPagination>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
<FormSwitch v-model="autoAcceptFollowed" :disabled="!isLocked" @update:modelValue="save()">{{ $ts.autoAcceptFollowed }}</FormSwitch>
|
||||
<template #caption>{{ $ts.lockedAccountInfo }}</template>
|
||||
</FormGroup>
|
||||
<FormSwitch v-model="publicReactions" @update:modelValue="save()">
|
||||
{{ $ts.makeReactionsPublic }}
|
||||
<template #desc>{{ $ts.makeReactionsPublicDescription }}</template>
|
||||
</FormSwitch>
|
||||
<FormSwitch v-model="hideOnlineStatus" @update:modelValue="save()">
|
||||
{{ $ts.hideOnlineStatus }}
|
||||
<template #desc>{{ $ts.hideOnlineStatusDescription }}</template>
|
||||
|
@ -64,6 +68,7 @@ export default defineComponent({
|
|||
noCrawle: false,
|
||||
isExplorable: false,
|
||||
hideOnlineStatus: false,
|
||||
publicReactions: false,
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -80,6 +85,7 @@ export default defineComponent({
|
|||
this.noCrawle = this.$i.noCrawle;
|
||||
this.isExplorable = this.$i.isExplorable;
|
||||
this.hideOnlineStatus = this.$i.hideOnlineStatus;
|
||||
this.publicReactions = this.$i.publicReactions;
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
@ -94,6 +100,7 @@ export default defineComponent({
|
|||
noCrawle: !!this.noCrawle,
|
||||
isExplorable: !!this.isExplorable,
|
||||
hideOnlineStatus: !!this.hideOnlineStatus,
|
||||
publicReactions: !!this.publicReactions,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
</optgroup>
|
||||
</FormSelect>
|
||||
<template v-if="selectedTheme">
|
||||
<FormInput readonly :value="selectedTheme.author">
|
||||
<FormInput readonly :modelValue="selectedTheme.author">
|
||||
<span>{{ $ts.author }}</span>
|
||||
</FormInput>
|
||||
<FormTextarea readonly :value="selectedTheme.desc" v-if="selectedTheme.desc">
|
||||
<FormTextarea readonly :modelValue="selectedTheme.desc" v-if="selectedTheme.desc">
|
||||
<span>{{ $ts._theme.description }}</span>
|
||||
</FormTextarea>
|
||||
<FormTextarea readonly tall :value="selectedThemeCode">
|
||||
<FormTextarea readonly tall :modelValue="selectedThemeCode">
|
||||
<span>{{ $ts._theme.code }}</span>
|
||||
<template #desc><button @click="copyThemeCode()" class="_textButton">{{ $ts.copy }}</button></template>
|
||||
</FormTextarea>
|
||||
|
@ -28,12 +28,12 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import * as JSON5 from 'json5';
|
||||
import FormTextarea from '@client/components/form/textarea.vue';
|
||||
import FormSelect from '@client/components/form/select.vue';
|
||||
import FormRadios from '@client/components/form/radios.vue';
|
||||
import FormTextarea from '@client/components/debobigego/textarea.vue';
|
||||
import FormSelect from '@client/components/debobigego/select.vue';
|
||||
import FormRadios from '@client/components/debobigego/radios.vue';
|
||||
import FormBase from '@client/components/debobigego/base.vue';
|
||||
import FormGroup from '@client/components/debobigego/group.vue';
|
||||
import FormInput from '@client/components/form/input.vue';
|
||||
import FormInput from '@client/components/debobigego/input.vue';
|
||||
import FormButton from '@client/components/debobigego/button.vue';
|
||||
import { Theme, builtinThemes } from '@client/scripts/theme';
|
||||
import copyToClipboard from '@client/scripts/copy-to-clipboard';
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import MkPagination from '@client/components/ui/pagination.vue';
|
||||
import { userPage, acct } from '@client/filters/user';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
|
@ -43,12 +42,6 @@ export default defineComponent({
|
|||
this.$refs.list.reload();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
userPage,
|
||||
|
||||
acct
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
import { defineComponent } from 'vue';
|
||||
import MkUserInfo from '@client/components/user-info.vue';
|
||||
import MkPagination from '@client/components/ui/pagination.vue';
|
||||
import { userPage, acct } from '@client/filters/user';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
|
@ -51,12 +50,6 @@ export default defineComponent({
|
|||
user() {
|
||||
this.$refs.list.reload();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
userPage,
|
||||
|
||||
acct
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
import { defineComponent } from 'vue';
|
||||
import MkGalleryPostPreview from '@client/components/gallery-post-preview.vue';
|
||||
import MkPagination from '@client/components/ui/pagination.vue';
|
||||
import { userPage, acct } from '@client/filters/user';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
|
@ -43,12 +42,6 @@ export default defineComponent({
|
|||
user() {
|
||||
this.$refs.list.reload();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
userPage,
|
||||
|
||||
acct
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="yrzkoczt" v-sticky-container>
|
||||
<MkTab v-model="with_" class="_gap tab">
|
||||
<MkTab v-model="with_" class="tab">
|
||||
<option :value="null">{{ $ts.notes }}</option>
|
||||
<option value="replies">{{ $ts.notesAndReplies }}</option>
|
||||
<option value="files">{{ $ts.withFiles }}</option>
|
||||
|
@ -60,7 +60,16 @@ export default defineComponent({
|
|||
<style lang="scss" scoped>
|
||||
.yrzkoczt {
|
||||
> .tab {
|
||||
margin: calc(var(--margin) / 2) 0;
|
||||
padding: calc(var(--margin) / 2) 0;
|
||||
background: var(--bg);
|
||||
}
|
||||
}
|
||||
|
||||
._fitSide_ .yrzkoczt {
|
||||
> .tab {
|
||||
padding-left: var(--margin);
|
||||
padding-right: var(--margin);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -181,6 +181,7 @@
|
|||
</template>
|
||||
<XFollowList v-else-if="page === 'following'" type="following" :user="user" class="_content _gap"/>
|
||||
<XFollowList v-else-if="page === 'followers'" type="followers" :user="user" class="_content _gap"/>
|
||||
<XReactions v-else-if="page === 'reactions'" :user="user" class="_gap"/>
|
||||
<XClips v-else-if="page === 'clips'" :user="user" class="_gap"/>
|
||||
<XPages v-else-if="page === 'pages'" :user="user" class="_gap"/>
|
||||
<XGallery v-else-if="page === 'gallery'" :user="user" class="_gap"/>
|
||||
|
@ -223,6 +224,7 @@ export default defineComponent({
|
|||
MkTab,
|
||||
MkInfo,
|
||||
XFollowList: defineAsyncComponent(() => import('./follow-list.vue')),
|
||||
XReactions: defineAsyncComponent(() => import('./reactions.vue')),
|
||||
XClips: defineAsyncComponent(() => import('./clips.vue')),
|
||||
XPages: defineAsyncComponent(() => import('./pages.vue')),
|
||||
XGallery: defineAsyncComponent(() => import('./gallery.vue')),
|
||||
|
@ -268,7 +270,12 @@ export default defineComponent({
|
|||
title: this.$ts.overview,
|
||||
icon: 'fas fa-home',
|
||||
onClick: () => { this.$router.push('/@' + getAcct(this.user)); },
|
||||
}, {
|
||||
}, ...(this.$i && (this.$i.id === this.user.id)) || this.user.publicReactions ? [{
|
||||
active: this.page === 'reactions',
|
||||
title: this.$ts.reaction,
|
||||
icon: 'fas fa-laugh',
|
||||
onClick: () => { this.$router.push('/@' + getAcct(this.user) + '/reactions'); },
|
||||
}] : [], {
|
||||
active: this.page === 'clips',
|
||||
title: this.$ts.clips,
|
||||
icon: 'fas fa-paperclip',
|
||||
|
@ -827,7 +834,7 @@ export default defineComponent({
|
|||
}
|
||||
}
|
||||
|
||||
._flat_ .ftskorzw.narrow {
|
||||
._fitSide_ .ftskorzw.narrow {
|
||||
> .profile {
|
||||
> .warn {
|
||||
margin: 0;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
import { defineComponent } from 'vue';
|
||||
import MkPagePreview from '@client/components/page-preview.vue';
|
||||
import MkPagination from '@client/components/ui/pagination.vue';
|
||||
import { userPage, acct } from '@client/filters/user';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
|
@ -41,12 +40,6 @@ export default defineComponent({
|
|||
user() {
|
||||
this.$refs.list.reload();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
userPage,
|
||||
|
||||
acct
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
81
src/client/pages/user/reactions.vue
Normal file
81
src/client/pages/user/reactions.vue
Normal file
|
@ -0,0 +1,81 @@
|
|||
<template>
|
||||
<div>
|
||||
<MkPagination :pagination="pagination" #default="{items}" ref="list">
|
||||
<div v-for="item in items" :key="item.id" :to="`/clips/${item.id}`" class="item _panel _gap afdcfbfb">
|
||||
<div class="header">
|
||||
<MkAvatar class="avatar" :user="user"/>
|
||||
<MkReactionIcon class="reaction" :reaction="item.type" :custom-emojis="item.note.emojis" :no-style="true"/>
|
||||
<MkTime :time="item.createdAt" class="createdAt"/>
|
||||
</div>
|
||||
<MkNote :note="item.note" @update:note="updated(note, $event)" :key="item.id"/>
|
||||
</div>
|
||||
</MkPagination>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import MkPagination from '@client/components/ui/pagination.vue';
|
||||
import MkNote from '@client/components/note.vue';
|
||||
import MkReactionIcon from '@client/components/reaction-icon.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MkPagination,
|
||||
MkNote,
|
||||
MkReactionIcon,
|
||||
},
|
||||
|
||||
props: {
|
||||
user: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
pagination: {
|
||||
endpoint: 'users/reactions',
|
||||
limit: 20,
|
||||
params: {
|
||||
userId: this.user.id,
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
user() {
|
||||
this.$refs.list.reload();
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.afdcfbfb {
|
||||
> .header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 16px;
|
||||
margin-bottom: 8px;
|
||||
border-bottom: solid 2px var(--divider);
|
||||
|
||||
> .avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
> .reaction {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
> .createdAt {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -20,6 +20,7 @@ export const builtinThemes = [
|
|||
require('@client/themes/l-apricot.json5'),
|
||||
require('@client/themes/l-rainy.json5'),
|
||||
require('@client/themes/l-vivid.json5'),
|
||||
require('@client/themes/l-sushi.json5'),
|
||||
|
||||
require('@client/themes/d-dark.json5'),
|
||||
require('@client/themes/d-persimmon.json5'),
|
||||
|
|
|
@ -380,7 +380,7 @@ hr {
|
|||
}
|
||||
}
|
||||
|
||||
._flat_ {
|
||||
._fitSide_ {
|
||||
--root-margin: 0px;
|
||||
--baseContentWidth: 100%;
|
||||
--panelBorder: none;
|
||||
|
|
18
src/client/themes/l-sushi.json5
Normal file
18
src/client/themes/l-sushi.json5
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
id: '213273e5-7d20-d5f0-6e36-1b6a4f67115c',
|
||||
|
||||
name: 'Mi Sushi Light',
|
||||
author: 'syuilo',
|
||||
|
||||
base: 'light',
|
||||
|
||||
props: {
|
||||
accent: '#e36749',
|
||||
bg: '#f0eee9',
|
||||
fg: '#5f5f5f',
|
||||
renote: '@accent',
|
||||
link: '@accent',
|
||||
mention: '@accent',
|
||||
hashtag: '#229e82',
|
||||
},
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
<header class="header" @contextmenu.prevent.stop="onContextmenu">
|
||||
<MkHeader class="title" :info="pageInfo" :center="false"/>
|
||||
</header>
|
||||
<component :is="component" v-bind="props" :ref="changePage" class="body _flat_"/>
|
||||
<component :is="component" v-bind="props" :ref="changePage" class="body _fitSide_"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</template>
|
||||
</template>
|
||||
|
||||
<router-view v-slot="{ Component }" class="_flat_">
|
||||
<router-view v-slot="{ Component }" class="_fitSide_">
|
||||
<transition>
|
||||
<keep-alive :include="['timeline']">
|
||||
<component :is="Component" :ref="changePage" @contextmenu.stop="onContextmenu"/>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<MkAvatar :user="$i" class="avatar"/><MkAcct class="acct" :user="$i"/>
|
||||
</button>
|
||||
<div class="post" @click="post">
|
||||
<MkButton class="button" primary full rounded>
|
||||
<MkButton class="button" gradate full rounded>
|
||||
<i class="fas fa-pencil-alt fa-fw"></i>
|
||||
</MkButton>
|
||||
</div>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</template>
|
||||
|
||||
<main class="main" @contextmenu.stop="onContextmenu" :style="{ background: pageInfo?.bg }">
|
||||
<div class="content" :class="{ _flat_: !fullView }">
|
||||
<div class="content" :class="{ _fitSide_: !fullView }">
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition :name="$store.state.animation ? 'page' : ''" mode="out-in" @enter="onTransition">
|
||||
<keep-alive :include="['timeline']">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<template #header><i class="fas fa-bell"></i>{{ $ts.notifications }}</template>
|
||||
<template #func><button @click="configure()" class="_button"><i class="fas fa-cog"></i></button></template>
|
||||
|
||||
<div class="_flat_">
|
||||
<div class="_fitSide_">
|
||||
<XNotifications :include-types="props.includingTypes"/>
|
||||
</div>
|
||||
</MkContainer>
|
||||
|
|
|
@ -3,5 +3,5 @@ AiScript is a scripting language for Misskey.
|
|||
|
||||
<div class="info">ℹ️ AiScript is open source and hosted in a separate repository from Misskey. </a></div>
|
||||
|
||||
## 使い方
|
||||
## Usage
|
||||
AiScript documentation such as syntax and built-in functions can be found [here](https://github.com/syuilo/aiscript/tree/master/docs).
|
||||
|
|
|
@ -4,7 +4,7 @@ MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス
|
|||
|
||||
APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。
|
||||
|
||||
## アクセストークンの取得
|
||||
## Obtain an access token
|
||||
基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。
|
||||
|
||||
* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む
|
||||
|
@ -20,7 +20,7 @@ APIを使い始めるには、まずアクセストークンを取得する必
|
|||
|
||||
#### Step 1
|
||||
|
||||
UUIDを生成する。以後これをセッションIDと呼びます。
|
||||
Generate UUID.以後これをセッションIDと呼びます。
|
||||
|
||||
> このセッションIDは毎回生成し、使いまわさないようにしてください。
|
||||
|
||||
|
@ -30,14 +30,14 @@ UUIDを生成する。以後これをセッションIDと呼びます。
|
|||
> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f`
|
||||
|
||||
表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます:
|
||||
* `name` ... アプリケーション名
|
||||
* `name` ... App name
|
||||
* > 例: `MissDeck`
|
||||
* `icon` ... アプリケーションのアイコン画像URL
|
||||
* `icon` ... App icon URL
|
||||
* > 例: `https://missdeck.example.com/icon.png`
|
||||
* `callback` ... 認証が終わった後にリダイレクトするURL
|
||||
* > 例: `https://missdeck.example.com/callback`
|
||||
* リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます
|
||||
* `permission` ... アプリケーションが要求する権限
|
||||
* `permission` ... App permissions
|
||||
* > 例: `write:notes,write:following,read:drive`
|
||||
* 要求する権限を`,`で区切って列挙します
|
||||
* どのような権限があるかは[APIリファレンス](/api-doc)で確認できます
|
||||
|
@ -46,13 +46,13 @@ UUIDを生成する。以後これをセッションIDと呼びます。
|
|||
ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。
|
||||
|
||||
レスポンスに含まれるプロパティ:
|
||||
* `token` ... ユーザーのアクセストークン
|
||||
* `user` ... ユーザーの情報
|
||||
* `token` ... User access token
|
||||
* `user` ... User info
|
||||
|
||||
[「APIの使い方」へ進む](#APIの使い方)
|
||||
|
||||
## APIの使い方
|
||||
**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。
|
||||
## API usage
|
||||
**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。There is no REST support.** アクセストークンは、`i`というパラメータ名でリクエストに含めます。
|
||||
|
||||
* [APIリファレンス](/api-doc)
|
||||
* [ストリーミングAPI](./stream)
|
||||
* [API Reference](/api-doc)
|
||||
* [Streaming API](./stream)
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
# プラグインの作成
|
||||
# New Plugin
|
||||
Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。
|
||||
|
||||
## Metadata
|
||||
プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。
|
||||
|
||||
### name
|
||||
プラグイン名
|
||||
Plugin name
|
||||
|
||||
### author
|
||||
プラグイン作者
|
||||
Plugin author
|
||||
|
||||
### version
|
||||
プラグインバージョン。数値を指定してください。
|
||||
プラグインバージョン。A number must be specified.
|
||||
|
||||
### description
|
||||
プラグインの説明
|
||||
Plugin description
|
||||
|
||||
### permissions
|
||||
プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。
|
||||
|
@ -34,7 +34,7 @@ Misskey Webクライアントのプラグイン機能を使うと、クライア
|
|||
#### default
|
||||
設定のデフォルト値
|
||||
|
||||
## APIリファレンス
|
||||
## API Reference
|
||||
AiScript標準で組み込まれているAPIは掲載しません。
|
||||
|
||||
### Mk:dialog(title text type)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Botの作成
|
||||
# Create a bot
|
||||
[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。
|
||||
|
||||
- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# ストリーミングAPI
|
||||
# Streaming API
|
||||
|
||||
ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ A feature allowing users to organize the files they have uploaded to Misskey.For
|
|||
## Notes
|
||||
Content which may include text, images, surveys and others that has been posted to Misskey.For details, see [here.](../features/note)
|
||||
|
||||
## Misskist
|
||||
## Misskeyist
|
||||
Users of Misskey.
|
||||
|
||||
## Moderator
|
||||
|
|
|
@ -34,7 +34,7 @@ A blinking light indicates unread content.In cases where this light won't go awa
|
|||
Followers-only notes cannot be renoted.
|
||||
|
||||
## Specific parts of the UI are not being displayed
|
||||
Problems like these can arise if you are using an Adblocker.Please turn these off on Misskey.
|
||||
Problems like these can arise if you are using an Adblocker. For an optimized experience on Misskey, please turn it off.
|
||||
|
||||
## Some parts of the UI are untranslated
|
||||
In most cases, this is simply a matter of the translation not having been done yet instead of being a bug.Please wait until the translation of this area has been completed. You can alternatively also [participate in translation](./misskey) yourself.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# よくある質問
|
||||
# Oftaj demandoj
|
||||
ここでは、サーバー管理者向けのよくある質問を掲載しています。
|
||||
|
||||
## デフォルトテーマを設定したい
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# プラグインの作成
|
||||
# Krei kromaĵo
|
||||
Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。
|
||||
|
||||
## Metadatumoj
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# ストリーミングAPI
|
||||
# API de Flui
|
||||
|
||||
ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Preferataĵoj
|
||||
# Preferaĵoj
|
||||
[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。
|
||||
|
||||
ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。
|
||||
|
|
|
@ -4,21 +4,21 @@
|
|||
これらのショートカットは基本的にどこでも使えます。
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Fulmoklavoj</th><th>効果</th><th>由来</th></tr>
|
||||
<tr><th>Fulmoklavoj</th><th>Rezultato</th><th>Deveno (angla)</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><kbd class="key">P</kbd>, <kbd class="key">N</kbd></td><td>Skribi novan noton</td><td><b>P</b>ost, <b>N</b>ew, <b>N</b>ote</td></tr>
|
||||
<tr><td><kbd class="key">T</kbd></td><td>タイムラインの最も新しい投稿にフォーカス</td><td><b>T</b>imeline, <b>T</b>op</td></tr>
|
||||
<tr><td><kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">N</kbd></kbd></td><td>Malfermi sekcio de sciigoj</td><td><b>N</b>otifications</td></tr>
|
||||
<tr><td><kbd class="key">S</kbd></td><td>Serĉi</td><td><b>S</b>earch</td></tr>
|
||||
<tr><td><kbd class="key">H</kbd>, <kbd class="key">?</kbd></td><td>ヘルプを表示</td><td><b>H</b>elp</td></tr>
|
||||
<tr><td><kbd class="key">H</kbd>, <kbd class="key">?</kbd></td><td>Montru helpon</td><td><b>H</b>elp</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 投稿にフォーカスされた状態
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Fulmoklavoj</th><th>効果</th><th>Deveno (angla)</th></tr>
|
||||
<tr><th>Fulmoklavoj</th><th>Rezultato</th><th>Deveno (angla)</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><kbd class="key">↑</kbd>, <kbd class="key">K</kbd>, <kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">Tab</kbd></kbd></td><td>上の投稿にフォーカスを移動</td><td>-</td></tr>
|
||||
|
@ -28,7 +28,7 @@
|
|||
<tr><td><kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">Q</kbd></kbd></td><td>Tuj plusendos (sen la fasado)</td><td>-</td></tr>
|
||||
<tr><td><kbd class="key">E</kbd>, <kbd class="key">A</kbd>, <kbd class="key">+</kbd></td><td>リアクションフォームを開く</td><td><b>E</b>mote, re<b>A</b>ction</td></tr>
|
||||
<tr><td><kbd class="key">0</kbd>-<kbd class="key">9</kbd></td><td>数字に対応したリアクションをする(対応については後述)</td><td>-</td></tr>
|
||||
<tr><td><kbd class="key">F</kbd>, <kbd class="key">B</kbd></td><td>Aldoni vian liston de preferaĵoj</td><td><b>F</b>avorite, <b>B</b>ookmark</td></tr>
|
||||
<tr><td><kbd class="key">F</kbd>, <kbd class="key">B</kbd></td><td>Aldoni al vian liston de preferaĵoj</td><td><b>F</b>avorite, <b>B</b>ookmark</td></tr>
|
||||
<tr><td><kbd class="key">Del</kbd>, <kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">D</kbd></kbd></td><td>Forviŝi la noton</td><td><b>D</b>elete</tr>
|
||||
<tr><td><kbd class="key">M</kbd>, <kbd class="key">O</kbd></td><td>Malfelmi poŝtaĵan menuon</td><td><b>M</b>ore, <b>O</b>ther</td></tr>
|
||||
<tr><td><kbd class="key">S</kbd></td><td>CWで隠された部分を表示 or 隠す</td><td><b>S</b>how, <b>S</b>ee</td></tr>
|
||||
|
@ -48,11 +48,11 @@
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
## リアクションフォーム
|
||||
## Elektilo de reago
|
||||
デフォルトで「👍」にフォーカスが当たっている状態です。
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Fulmoklavoj</th><th>効果</th><th>Deveno (angla)</th></tr>
|
||||
<tr><th>Fulmoklavoj</th><th>Rezultato</th><th>Deveno (angla)</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><kbd class="key">↑</kbd>, <kbd class="key">K</kbd></td><td>上のリアクションにフォーカスを移動</td><td>-</td></tr>
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。
|
||||
|
||||
## MFMが使用可能な場所の例
|
||||
- ノート本文
|
||||
- Teksto de notoj
|
||||
- CW注釈
|
||||
- Nomo de uzanto
|
||||
- Profilo de uzanto
|
||||
- La nomo de uzantoj
|
||||
- La sinprezento de profiloj
|
||||
|
||||
## Informoj por programistoj
|
||||
MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Notoj
|
||||
ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。
|
||||
Notoj estas centraj konceptoj en Misskey kaj enhavoj kiuj konsistas el teksto, bildoj, dosieroj, balotujo k.t.p.Ankaŭ krei notojn estas nomata "noto" same kiel ili
|
||||
|
||||
ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。
|
||||
|
||||
|
@ -7,14 +7,14 @@
|
|||
|
||||
ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。
|
||||
|
||||
## ノートを作成する
|
||||
## Skribi notojn
|
||||
ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。
|
||||
<div class="info">ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。</div>
|
||||
<div class="info">ℹ️ テキストボックス内で<kbd class="key">Ctrl + Enter</kbd>を押すことでも投稿できます。</div>
|
||||
|
||||
## Plusendi la noton
|
||||
## Plusendi noton
|
||||
既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。
|
||||
<div class="warn">⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません</div>
|
||||
<div class="warn">⚠️ Se oni sendas notojn nur al sekvantoj aŭ rekte, iliaj ne estas plusendeblaj.</div>
|
||||
|
||||
Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。
|
||||
|
||||
|
@ -31,10 +31,10 @@ Contents Warningの略で、ノートの内容を、閲覧者の操作なしに
|
|||
### Hejma
|
||||
全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。
|
||||
|
||||
### Sekvantoj
|
||||
自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。
|
||||
### Nur al sekvantoj
|
||||
Viaj notoj estos senditaj nur al viaj sekvantoj.La noto aperos sur ĉiuj templinioj de viaj sekvantoj.
|
||||
|
||||
### Rekta
|
||||
### Rekte
|
||||
指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。
|
||||
|
||||
### 「ローカルのみ」オプション
|
||||
|
@ -42,13 +42,13 @@ Contents Warningの略で、ノートの内容を、閲覧者の操作なしに
|
|||
|
||||
### 公開範囲の比較
|
||||
<table>
|
||||
<tr><th></th><th>Publika</th><th>Hejma</th><th>Sekvantoj</th><th>Rekta</th></tr>
|
||||
<tr><th></th><th>Publika</th><th>Hejma</th><th>Nur al sekvantoj</th><th>Rekte</th></tr>
|
||||
<tr><th>フォロワーのLTL/STL/GTL</th><td>✔</td><td>✔</td><td>✔</td><td></td></tr>
|
||||
<tr><th>非フォロワーのLTL/STL/GTL</th><td>✔</td><td></td><td></td><td></td></tr>
|
||||
</table>
|
||||
|
||||
## Alpingli al la profilo
|
||||
## Alpingli sur profilo
|
||||
ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。
|
||||
|
||||
## Observi
|
||||
Vi povas ricevi sciigojn pri reagoj, respondoj, ktp al noto, kiuj ne apartenas al vi. Por observu, malfermu respektivan menuon de noto, kaj elektu la "Observi" el ĝi.
|
||||
Vi povas ricevi tiuj sciigoj pri reagoj, respondoj, k.t.p al noto kiuj ne apartenas al vi estas ankaŭ ricevebla. Por komenci tion elektu la "Observi" el la menuon kuntekstan de la notoj respektivaj.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# よくある質問
|
||||
# Oftaj demandoj
|
||||
ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。
|
||||
|
||||
## iOS/Androidのアプリはありますか?
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# 用語集
|
||||
# Glosaro
|
||||
Misskeyに関する用語集です。
|
||||
|
||||
## ActivityPub
|
||||
|
@ -49,7 +49,7 @@ Ai estas oficiala maskoto de Misskey.
|
|||
## Nodo
|
||||
todo
|
||||
|
||||
## Personecigitaj emoĵioj
|
||||
## Emoĵioj personecigitaj
|
||||
サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。
|
||||
|
||||
## Ŝaltpodio
|
||||
|
@ -68,10 +68,10 @@ todo
|
|||
アカウントが使用不可に設定されている状態。
|
||||
|
||||
## Disko
|
||||
Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive)
|
||||
Funkcio ebligas al uzantoj administri dosierojn kiujn ili alŝutis al Misskey.Rigardu por sciu pli tie[.](../features/drive)
|
||||
|
||||
## Notoj
|
||||
Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。Rigardu por sciu pli tie[.](../features/note)
|
||||
Enpoŝtigaĵoj en Misskey kiuj konsistas el teksto, dosiero, balotujo, ktp.Rigardu por sciu pli tie[.](../features/note)
|
||||
|
||||
## Miskiisto
|
||||
Uzuloj de Misskey.
|
||||
|
@ -82,7 +82,7 @@ Uzuloj de Misskey.
|
|||
## Transa, Surloka
|
||||
他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。
|
||||
|
||||
## Kunfederado
|
||||
## Federado
|
||||
サーバー上で作成された情報が他のサーバーに伝わること。
|
||||
|
||||
## Loka
|
||||
|
|
|
@ -43,7 +43,7 @@ Misskeyはビジネスではなく、利用は無料であるため、収益は
|
|||
## クレジット
|
||||
Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。
|
||||
|
||||
## よくある質問
|
||||
## Oftaj demandoj
|
||||
### プロジェクトは何を目指していますか?
|
||||
強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。
|
||||
<!-- TODO: ここにロードマップへのリンク -->
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# トラブルシューティング
|
||||
# Solución de problemas
|
||||
<div class="info">ℹ️ <a href="./faq">よくある質問</a>も合わせてお役立てください。</div>
|
||||
|
||||
問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Liste des applications tierces
|
||||
## クライアント
|
||||
## Client
|
||||
todo
|
||||
|
||||
## 連携サービス
|
||||
## Services connexes
|
||||
todo
|
||||
|
|
|
@ -1,65 +1,65 @@
|
|||
# 用語集
|
||||
Misskeyに関する用語集です。
|
||||
# Glossaire
|
||||
Glossaire des termes utilisés dans Misskey.
|
||||
|
||||
## ActivityPub
|
||||
(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。
|
||||
Nom du protocole (procédé technique) utilisé par Misskey pour pouvoir fonctionner comme service décentralisé. Ce protocole permet à tous les serveurs l'ayant adopté de communiquer entre eux et de former une sorte de fédération que l'on appelle « Fédiverse ».
|
||||
|
||||
## AiScript
|
||||
(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript)
|
||||
Langage de programmation qui peut être utilisé sur Misskey. [Voir ici pour plus d'informations.](../advanced/aiscript)
|
||||
|
||||
## API
|
||||
(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api)
|
||||
(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。[Voir ici pour plus d'informations. ](../advanced/api)
|
||||
|
||||
## Bot
|
||||
(読み: ぼっと) プログラムによって動作しているアカウント。
|
||||
Anglicisme désignant un compte géré par un programme informatique (vous le trouverez parfois aussi sous le terme de « robot »).
|
||||
|
||||
## CW
|
||||
(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。
|
||||
Abréviation de « Content Warning » (qui signifie littéralement « alerte de contenu »). Fonctionnalité permettant d'assujettir l'affichage du contenu d'une note à une intervention de l'utilisateur·rice par le biais d'un bouton de masquage automatique. Principalement employée pour cacher le contenu des notes très longues, ou pour éviter de dévoiler publiquement des spoils potentiels, etc.
|
||||
|
||||
## Fediverse
|
||||
(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。
|
||||
## Fédiverse
|
||||
Nom du réseau social fédéré qui rassemble une multitude d'instances appartenant à différents services et dont fait partie Misskey.
|
||||
|
||||
## GTL
|
||||
グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline)
|
||||
## FG
|
||||
Abréviation de « Fil global ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline)
|
||||
|
||||
## HTL
|
||||
ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline)
|
||||
## FP
|
||||
Abréviation de « Fil principal ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline)
|
||||
|
||||
## LTL
|
||||
ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline)
|
||||
## FL
|
||||
Abréviation de « Fil local ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline)
|
||||
|
||||
## MFM
|
||||
(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm)
|
||||
Abréviation de « Misskey Flavored Markdown », un langage Markdown qui peut être utilisé sur Misskey. [Voir ici pour plus d'informations.](../features/mfm)
|
||||
|
||||
## NSFW
|
||||
(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。
|
||||
Abréviation de « Not Safe For Work » (qui signifie littéralement « pas sûr pour le travail »). Fonctionnalité permettant d'avertir que le contenu d'une note n'est pas approprié sur le lieu de travail et d'en assujettir l'affichage à une intervention de l'utilisateur·rice par le biais d'un bouton de masquage automatique.
|
||||
|
||||
## Renoter
|
||||
(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note)
|
||||
Il s'agit du fait de citer une note existante ou de partager une note existante dans une nouvelle note. La note créée par l'un de ces deux biais est alors appelée une « Renote ». [Voir ici pour plus d'informations.](../features/note)
|
||||
|
||||
## STL
|
||||
ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline)
|
||||
## FS
|
||||
Abréviation de « Fil social ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline)
|
||||
|
||||
## 藍
|
||||
(読み: あい) Misskeyの看板娘(公式キャラクター)です。
|
||||
## Ai
|
||||
Nom de la mascotte officielle de Misskey. (Le mot japonais, à prononcer « a-i », signifie littéralement « indigo »).
|
||||
|
||||
## アクティブユーザー
|
||||
インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。
|
||||
## Utilisateurices actif·ve·s
|
||||
Désigne les utilisateur·rice·s, parmi tou·te·s celleux inscrit·e·s sur l'instance, qui utilisent effectivement leur compte au moment présent.
|
||||
|
||||
## Instance
|
||||
todo
|
||||
|
||||
## Émojis personnalisés
|
||||
サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。
|
||||
Désigne les émojis mis à disposition par votre instance. Par opposition, les émojis disponibles par défaut (donc pas « personnalisés ») sont appelés « émojis unicode ».
|
||||
|
||||
## コントロールパネル
|
||||
インスタンスの設定画面のこと。
|
||||
## Panneau de contrôle
|
||||
Écran de contrôle des paramètres d'instance.
|
||||
|
||||
## Serveurs
|
||||
todo
|
||||
|
||||
## Mettre en sourdine
|
||||
ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence)
|
||||
ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。[Voir ici pour plus d'informations. ](../features/silence)
|
||||
|
||||
## File d’attente
|
||||
アクティビティ配送などを順番に行うためのシステム。
|
||||
|
@ -68,15 +68,15 @@ todo
|
|||
アカウントが使用不可に設定されている状態。
|
||||
|
||||
## Drive
|
||||
Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive)
|
||||
Fonctionnalité vous permettant de gérer les fichiers que vous avez téléversés sur Misskey. [Voir ici pour plus d'informations. ](../features/drive)
|
||||
|
||||
## Notes
|
||||
Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note)
|
||||
Nom des publications sur Misskey. Leur contenu peut être du texte, mais aussi des fichiers, des enquêtes, etc. [Voir ici pour plus d'informations.](../features/note)
|
||||
|
||||
## ミスキスト
|
||||
Misskeyを使う人のこと。
|
||||
## Misskeynaute
|
||||
Désigne les utilisateur·rice·s de Misskey.
|
||||
|
||||
## Modérateurs
|
||||
## Modérateur·rice·s
|
||||
スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。
|
||||
|
||||
## Distant
|
||||
|
|
|
@ -21,20 +21,20 @@ Essayez les solutions proposées ci-dessous :
|
|||
- activer l'option « Réduire les animations dans l'interface » dans les paramètres du client
|
||||
- désactiver l'option « Utiliser un effet de flou pour les modals » dans les paramètres du client
|
||||
- activer l'accélération matérielle dans les paramètres de votre navigateur
|
||||
- お使いのデバイスのスペックを上げる
|
||||
- effectuer les mises à jour de votre appareil.
|
||||
|
||||
## UIの一部の表示がおかしい(背景が透明になっている等)
|
||||
アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。
|
||||
<div class="warn">⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。</div>
|
||||
## Certaines parties de l'interface ne s'affichent pas correctement (arrière-plan transparent, etc.)
|
||||
Cela peut être lié au système de mise en cache du thème lorsqu'une mise à jour visant à améliorer l'interface a eu lieu. Pour résoudre le problème, sélectionnez la touche « Vider le cache » dans les paramètres du client.
|
||||
<div class="warn">⚠️ Attention de bien vider le cache du -client-... et pas celui du -navigateur- !</div>
|
||||
|
||||
## 通知やアンテナ等の点滅が消えない
|
||||
点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。
|
||||
## Les pastilles de notification clignotantes ne disparaissent pas
|
||||
Une pastille clignotante indique la présence de nouveau contenu que vous n'avez pas encore lu. Lorsque cette pastille ne disparaît pas, c'est généralement parce que du contenu laissé non lu a été repoussé par la réception de nouveau contenu. S'il s'avère que vous avez déjà lu le contenu dans sa totalité mais que la pastille continue tout de même de clignoter, il s'agit alors vraisemblablement d'un bug et vous pouvez forcer Misskey à tout marquer comme lu depuis vos paramètres généraux.
|
||||
|
||||
## La fonction « Renoter » ne fonctionne pas
|
||||
Les notes dont l'audience est limitée aux « Abonné·e·s uniquement » ne peuvent pas être renotées.
|
||||
|
||||
## Des éléments spécifiques de l'interface ne s'affichent pas
|
||||
広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。
|
||||
Ce type de dysfonctionnement survient lorsque vous utilisez des bloqueurs de publicité. Désactivez-les pour profiter d'une expérience optimale sur Misskey.
|
||||
|
||||
## Certaines parties de l'interface ne sont pas traduites
|
||||
La plupart du temps, cela n'est pas un bug mais simplement un problème de traduction qui n'a pas encore été faite. Merci de patienter jusqu'à ce que la traduction de la portion en question soit achevée. Vous pouvez également [aider à traduire](./misskey) Misskey.
|
||||
|
|
|
@ -50,7 +50,7 @@ MisskeyのストリーミングAPIにはチャンネルという概念があり
|
|||
}
|
||||
```
|
||||
|
||||
ここで、
|
||||
其中:
|
||||
* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。
|
||||
* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。
|
||||
* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。
|
||||
|
@ -74,7 +74,7 @@ MisskeyのストリーミングAPIにはチャンネルという概念があり
|
|||
}
|
||||
```
|
||||
|
||||
ここで、
|
||||
其中:
|
||||
* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。
|
||||
* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。
|
||||
* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。
|
||||
|
@ -96,7 +96,7 @@ MisskeyのストリーミングAPIにはチャンネルという概念があり
|
|||
}
|
||||
```
|
||||
|
||||
ここで、
|
||||
其中:
|
||||
* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。
|
||||
* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。
|
||||
* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。
|
||||
|
@ -113,7 +113,7 @@ MisskeyのストリーミングAPIにはチャンネルという概念があり
|
|||
}
|
||||
```
|
||||
|
||||
ここで、
|
||||
其中:
|
||||
* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。
|
||||
|
||||
## ストリームを経由してAPIリクエストする
|
||||
|
@ -134,7 +134,7 @@ MisskeyのストリーミングAPIにはチャンネルという概念があり
|
|||
}
|
||||
```
|
||||
|
||||
ここで、
|
||||
其中:
|
||||
* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。
|
||||
* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。
|
||||
* `data`には、エンドポイントのパラメータを含めます。
|
||||
|
@ -154,7 +154,7 @@ APIへリクエストすると、レスポンスがストリームから次の
|
|||
}
|
||||
```
|
||||
|
||||
ここで、
|
||||
其中:
|
||||
* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。
|
||||
* `body`には、レスポンスが含まれています。
|
||||
|
||||
|
@ -181,7 +181,7 @@ Misskeyは投稿のキャプチャと呼ばれる仕組みを提供していま
|
|||
}
|
||||
```
|
||||
|
||||
ここで、
|
||||
其中:
|
||||
* `id`にキャプチャしたい投稿の`id`を設定します。
|
||||
|
||||
このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。
|
||||
|
@ -202,7 +202,7 @@ Misskeyは投稿のキャプチャと呼ばれる仕組みを提供していま
|
|||
}
|
||||
```
|
||||
|
||||
ここで、
|
||||
其中:
|
||||
* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。
|
||||
* `body`内の`type`に、イベントの種類が設定されます。
|
||||
* `body`内の`body`に、イベントの詳細が設定されます。
|
||||
|
@ -285,7 +285,7 @@ Misskeyは投稿のキャプチャと呼ばれる仕組みを提供していま
|
|||
}
|
||||
```
|
||||
|
||||
ここで、
|
||||
其中:
|
||||
* `id`にキャプチャを解除したい投稿の`id`を設定します。
|
||||
|
||||
このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# 关注中
|
||||
ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。
|
||||
# 关注
|
||||
当您关注一名用户时,您可以在您的时间线上看到该用户的发帖。但是不包含该用户对其他用户的回复。 要关注一名用户,请点击该用户页面上的“关注”按钮。如果需要取消关注,请再次点击该按钮。
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# MFM
|
||||
MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。
|
||||
MFM是Misskey Flavored Markdown的缩写,是一种专用的标记语言,可以用在Misskey的任何地方。 MFM中可用的语法可以在[MFM代码速查表](/mfm-cheat-sheet)中找到。
|
||||
|
||||
## MFMが使用可能な場所の例
|
||||
- ノート本文
|
||||
## 使用 MFM 的位置示例
|
||||
- 帖子正文
|
||||
- CW注释
|
||||
- ユーザーの名前
|
||||
- ユーザーの自己紹介
|
||||
- 用户姓名
|
||||
- 用户自我介绍
|
||||
|
||||
## 開発者向け情報
|
||||
MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。
|
||||
- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装
|
||||
## 面向开发者的信息
|
||||
MFM 的解析器实现作为库发布,可以轻松地将 MFM 嵌入到客户端中。
|
||||
- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScript的解析器实现
|
||||
|
|
|
@ -2,7 +2,7 @@ import * as fs from 'fs';
|
|||
import * as stream from 'stream';
|
||||
import * as util from 'util';
|
||||
import got, * as Got from 'got';
|
||||
import { httpAgent, httpsAgent } from './fetch';
|
||||
import { httpAgent, httpsAgent, StatusError } from './fetch';
|
||||
import config from '@/config/index';
|
||||
import * as chalk from 'chalk';
|
||||
import Logger from '@/services/logger';
|
||||
|
@ -37,6 +37,7 @@ export async function downloadUrl(url: string, path: string) {
|
|||
http: httpAgent,
|
||||
https: httpsAgent,
|
||||
},
|
||||
http2: false, // default
|
||||
retry: 0,
|
||||
}).on('response', (res: Got.Response) => {
|
||||
if ((process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') && !config.proxy && res.ip) {
|
||||
|
@ -59,17 +60,17 @@ export async function downloadUrl(url: string, path: string) {
|
|||
logger.warn(`maxSize exceeded (${progress.transferred} > ${maxSize}) on downloadProgress`);
|
||||
req.destroy();
|
||||
}
|
||||
}).on('error', (e: any) => {
|
||||
if (e.name === 'HTTPError') {
|
||||
const statusCode = e.response?.statusCode;
|
||||
const statusMessage = e.response?.statusMessage;
|
||||
e.name = `StatusError`;
|
||||
e.statusCode = statusCode;
|
||||
e.message = `${statusCode} ${statusMessage}`;
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
await pipeline(req, fs.createWriteStream(path));
|
||||
} catch (e) {
|
||||
if (e instanceof Got.HTTPError) {
|
||||
throw new StatusError(`${e.response.statusCode} ${e.response.statusMessage}`, e.response.statusCode, e.response.statusMessage);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
logger.succ(`Download finished: ${chalk.cyan(url)}`);
|
||||
}
|
||||
|
|
|
@ -1,51 +1,62 @@
|
|||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
import CacheableLookup from 'cacheable-lookup';
|
||||
import fetch, { HeadersInit } from 'node-fetch';
|
||||
import fetch from 'node-fetch';
|
||||
import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent';
|
||||
import config from '@/config/index';
|
||||
import { URL } from 'url';
|
||||
|
||||
export async function getJson(url: string, accept = 'application/json, */*', timeout = 10000, headers?: HeadersInit) {
|
||||
const res = await fetch(url, {
|
||||
export async function getJson(url: string, accept = 'application/json, */*', timeout = 10000, headers?: Record<string, string>) {
|
||||
const res = await getResponse({
|
||||
url,
|
||||
method: 'GET',
|
||||
headers: Object.assign({
|
||||
'User-Agent': config.userAgent,
|
||||
Accept: accept
|
||||
}, headers || {}),
|
||||
timeout,
|
||||
agent: getAgentByUrl,
|
||||
timeout
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw {
|
||||
name: `StatusError`,
|
||||
statusCode: res.status,
|
||||
message: `${res.status} ${res.statusText}`,
|
||||
};
|
||||
}
|
||||
|
||||
return await res.json();
|
||||
}
|
||||
|
||||
export async function getHtml(url: string, accept = 'text/html, */*', timeout = 10000, headers?: HeadersInit) {
|
||||
const res = await fetch(url, {
|
||||
export async function getHtml(url: string, accept = 'text/html, */*', timeout = 10000, headers?: Record<string, string>) {
|
||||
const res = await getResponse({
|
||||
url,
|
||||
method: 'GET',
|
||||
headers: Object.assign({
|
||||
'User-Agent': config.userAgent,
|
||||
Accept: accept
|
||||
}, headers || {}),
|
||||
timeout
|
||||
});
|
||||
|
||||
return await res.text();
|
||||
}
|
||||
|
||||
export async function getResponse(args: { url: string, method: string, body?: string, headers: Record<string, string>, timeout?: number, size?: number }) {
|
||||
const timeout = args?.timeout || 10 * 1000;
|
||||
|
||||
const controller = new AbortController();
|
||||
setTimeout(() => {
|
||||
controller.abort();
|
||||
}, timeout * 6);
|
||||
|
||||
const res = await fetch(args.url, {
|
||||
method: args.method,
|
||||
headers: args.headers,
|
||||
body: args.body,
|
||||
timeout,
|
||||
size: args?.size || 10 * 1024 * 1024,
|
||||
agent: getAgentByUrl,
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw {
|
||||
name: `StatusError`,
|
||||
statusCode: res.status,
|
||||
message: `${res.status} ${res.statusText}`,
|
||||
};
|
||||
throw new StatusError(`${res.status} ${res.statusText}`, res.status, res.statusText);
|
||||
}
|
||||
|
||||
return await res.text();
|
||||
return res;
|
||||
}
|
||||
|
||||
const cache = new CacheableLookup({
|
||||
|
@ -114,3 +125,17 @@ export function getAgentByUrl(url: URL, bypassProxy = false) {
|
|||
return url.protocol == 'http:' ? httpAgent : httpsAgent;
|
||||
}
|
||||
}
|
||||
|
||||
export class StatusError extends Error {
|
||||
public statusCode: number;
|
||||
public statusMessage?: string;
|
||||
public isClientError: boolean;
|
||||
|
||||
constructor(message: string, statusCode: number, statusMessage?: string) {
|
||||
super(message);
|
||||
this.name = 'StatusError';
|
||||
this.statusCode = statusCode;
|
||||
this.statusMessage = statusMessage;
|
||||
this.isClientError = typeof this.statusCode === 'number' && this.statusCode >= 400 && this.statusCode < 500;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,11 @@ export class UserProfile {
|
|||
})
|
||||
public emailNotificationTypes: string[];
|
||||
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
public publicReactions: boolean;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 128, nullable: true,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { NoteReaction } from '@/models/entities/note-reaction';
|
||||
import { Users } from '../index';
|
||||
import { Notes, Users } from '../index';
|
||||
import { Packed } from '@/misc/schema';
|
||||
import { convertLegacyReaction } from '@/misc/reaction-lib';
|
||||
import { User } from '@/models/entities/user';
|
||||
|
@ -9,8 +9,15 @@ import { User } from '@/models/entities/user';
|
|||
export class NoteReactionRepository extends Repository<NoteReaction> {
|
||||
public async pack(
|
||||
src: NoteReaction['id'] | NoteReaction,
|
||||
me?: { id: User['id'] } | null | undefined
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
options?: {
|
||||
withNote: boolean;
|
||||
},
|
||||
): Promise<Packed<'NoteReaction'>> {
|
||||
const opts = Object.assign({
|
||||
withNote: false,
|
||||
}, options);
|
||||
|
||||
const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
|
||||
return {
|
||||
|
@ -18,6 +25,9 @@ export class NoteReactionRepository extends Repository<NoteReaction> {
|
|||
createdAt: reaction.createdAt.toISOString(),
|
||||
user: await Users.pack(reaction.userId, me),
|
||||
type: convertLegacyReaction(reaction.reaction),
|
||||
...(opts.withNote ? {
|
||||
note: await Notes.pack(reaction.noteId, me),
|
||||
} : {})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -231,6 +231,7 @@ export class UserRepository extends Repository<User> {
|
|||
}),
|
||||
pinnedPageId: profile!.pinnedPageId,
|
||||
pinnedPage: profile!.pinnedPageId ? Pages.pack(profile!.pinnedPageId, me) : null,
|
||||
publicReactions: profile!.publicReactions,
|
||||
twoFactorEnabled: profile!.twoFactorEnabled,
|
||||
usePasswordLessLogin: profile!.usePasswordLessLogin,
|
||||
securityKeys: profile!.twoFactorEnabled
|
||||
|
|
|
@ -11,6 +11,7 @@ import { toPuny } from '@/misc/convert-host';
|
|||
import { Cache } from '@/misc/cache';
|
||||
import { Instance } from '@/models/entities/instance';
|
||||
import { DeliverJobData } from '../types';
|
||||
import { StatusError } from '@/misc/fetch';
|
||||
|
||||
const logger = new Logger('deliver');
|
||||
|
||||
|
@ -68,16 +69,16 @@ export default async (job: Bull.Job<DeliverJobData>) => {
|
|||
registerOrFetchInstanceDoc(host).then(i => {
|
||||
Instances.update(i.id, {
|
||||
latestRequestSentAt: new Date(),
|
||||
latestStatus: res != null && res.hasOwnProperty('statusCode') ? res.statusCode : null,
|
||||
latestStatus: res instanceof StatusError ? res.statusCode : null,
|
||||
isNotResponding: true
|
||||
});
|
||||
|
||||
instanceChart.requestSent(i.host, false);
|
||||
});
|
||||
|
||||
if (res != null && res.hasOwnProperty('statusCode')) {
|
||||
if (res instanceof StatusError) {
|
||||
// 4xx
|
||||
if (res.statusCode >= 400 && res.statusCode < 500) {
|
||||
if (res.isClientError) {
|
||||
// HTTPステータスコード4xxはクライアントエラーであり、それはつまり
|
||||
// 何回再送しても成功することはないということなのでエラーにはしないでおく
|
||||
return `${res.statusCode} ${res.statusMessage}`;
|
||||
|
|
|
@ -14,6 +14,7 @@ import { InboxJobData } from '../types';
|
|||
import DbResolver from '@/remote/activitypub/db-resolver';
|
||||
import { resolvePerson } from '@/remote/activitypub/models/person';
|
||||
import { LdSignature } from '@/remote/activitypub/misc/ld-signature';
|
||||
import { StatusError } from '@/misc/fetch';
|
||||
|
||||
const logger = new Logger('inbox');
|
||||
|
||||
|
@ -53,7 +54,7 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => {
|
|||
authUser = await dbResolver.getAuthUserFromApId(getApId(activity.actor));
|
||||
} catch (e) {
|
||||
// 対象が4xxならスキップ
|
||||
if (e.statusCode >= 400 && e.statusCode < 500) {
|
||||
if (e instanceof StatusError && e.isClientError) {
|
||||
return `skip: Ignored deleted actors on both ends ${activity.actor} - ${e.statusCode}`;
|
||||
}
|
||||
throw `Error in actor ${activity.actor} - ${e.statusCode || e}`;
|
||||
|
|
104
src/remote/activitypub/ap-request.ts
Normal file
104
src/remote/activitypub/ap-request.ts
Normal file
|
@ -0,0 +1,104 @@
|
|||
import * as crypto from 'crypto';
|
||||
import { URL } from 'url';
|
||||
|
||||
type Request = {
|
||||
url: string;
|
||||
method: string;
|
||||
headers: Record<string, string>;
|
||||
};
|
||||
|
||||
type PrivateKey = {
|
||||
privateKeyPem: string;
|
||||
keyId: string;
|
||||
};
|
||||
|
||||
export function createSignedPost(args: { key: PrivateKey, url: string, body: string, additionalHeaders: Record<string, string> }) {
|
||||
const u = new URL(args.url);
|
||||
const digestHeader = `SHA-256=${crypto.createHash('sha256').update(args.body).digest('base64')}`;
|
||||
|
||||
const request: Request = {
|
||||
url: u.href,
|
||||
method: 'POST',
|
||||
headers: objectAssignWithLcKey({
|
||||
'Date': new Date().toUTCString(),
|
||||
'Host': u.hostname,
|
||||
'Content-Type': 'application/activity+json',
|
||||
'Digest': digestHeader,
|
||||
}, args.additionalHeaders),
|
||||
};
|
||||
|
||||
const result = signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'digest']);
|
||||
|
||||
return {
|
||||
request,
|
||||
signingString: result.signingString,
|
||||
signature: result.signature,
|
||||
signatureHeader: result.signatureHeader,
|
||||
};
|
||||
}
|
||||
|
||||
export function createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }) {
|
||||
const u = new URL(args.url);
|
||||
|
||||
const request: Request = {
|
||||
url: u.href,
|
||||
method: 'GET',
|
||||
headers: objectAssignWithLcKey({
|
||||
'Accept': 'application/activity+json, application/ld+json',
|
||||
'Date': new Date().toUTCString(),
|
||||
'Host': new URL(args.url).hostname,
|
||||
}, args.additionalHeaders),
|
||||
};
|
||||
|
||||
const result = signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'accept']);
|
||||
|
||||
return {
|
||||
request,
|
||||
signingString: result.signingString,
|
||||
signature: result.signature,
|
||||
signatureHeader: result.signatureHeader,
|
||||
};
|
||||
}
|
||||
|
||||
function signToRequest(request: Request, key: PrivateKey, includeHeaders: string[]) {
|
||||
const signingString = genSigningString(request, includeHeaders);
|
||||
const signature = crypto.sign('sha256', Buffer.from(signingString), key.privateKeyPem).toString('base64');
|
||||
const signatureHeader = `keyId="${key.keyId}",algorithm="rsa-sha256",headers="${includeHeaders.join(' ')}",signature="${signature}"`;
|
||||
|
||||
request.headers = objectAssignWithLcKey(request.headers, {
|
||||
Signature: signatureHeader
|
||||
});
|
||||
|
||||
return {
|
||||
request,
|
||||
signingString,
|
||||
signature,
|
||||
signatureHeader,
|
||||
};
|
||||
}
|
||||
|
||||
function genSigningString(request: Request, includeHeaders: string[]) {
|
||||
request.headers = lcObjectKey(request.headers);
|
||||
|
||||
const results: string[] = [];
|
||||
|
||||
for (const key of includeHeaders.map(x => x.toLowerCase())) {
|
||||
if (key === '(request-target)') {
|
||||
results.push(`(request-target): ${request.method.toLowerCase()} ${new URL(request.url).pathname}`);
|
||||
} else {
|
||||
results.push(`${key}: ${request.headers[key]}`);
|
||||
}
|
||||
}
|
||||
|
||||
return results.join('\n');
|
||||
}
|
||||
|
||||
function lcObjectKey(src: Record<string, string>) {
|
||||
const dst: Record<string, string> = {};
|
||||
for (const key of Object.keys(src).filter(x => x != '__proto__' && typeof src[x] === 'string')) dst[key.toLowerCase()] = src[key];
|
||||
return dst;
|
||||
}
|
||||
|
||||
function objectAssignWithLcKey(a: Record<string, string>, b: Record<string, string>) {
|
||||
return Object.assign(lcObjectKey(a), lcObjectKey(b));
|
||||
}
|
|
@ -8,6 +8,7 @@ import { extractDbHost } from '@/misc/convert-host';
|
|||
import { fetchMeta } from '@/misc/fetch-meta';
|
||||
import { getApLock } from '@/misc/app-lock';
|
||||
import { parseAudience } from '../../audience';
|
||||
import { StatusError } from '@/misc/fetch';
|
||||
|
||||
const logger = apLogger;
|
||||
|
||||
|
@ -41,7 +42,7 @@ export default async function(resolver: Resolver, actor: IRemoteUser, activity:
|
|||
renote = await resolveNote(targetUri);
|
||||
} catch (e) {
|
||||
// 対象が4xxならスキップ
|
||||
if (e.statusCode >= 400 && e.statusCode < 500) {
|
||||
if (e instanceof StatusError && e.isClientError) {
|
||||
logger.warn(`Ignored announce target ${targetUri} - ${e.statusCode}`);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import { createNote, fetchNote } from '../../models/note';
|
|||
import { getApId, IObject, ICreate } from '../../type';
|
||||
import { getApLock } from '@/misc/app-lock';
|
||||
import { extractDbHost } from '@/misc/convert-host';
|
||||
import { StatusError } from '@/misc/fetch';
|
||||
|
||||
/**
|
||||
* 投稿作成アクティビティを捌きます
|
||||
|
@ -32,7 +33,7 @@ export default async function(resolver: Resolver, actor: IRemoteUser, note: IObj
|
|||
await createNote(note, resolver, silent);
|
||||
return 'ok';
|
||||
} catch (e) {
|
||||
if (e.statusCode >= 400 && e.statusCode < 500) {
|
||||
if (e instanceof StatusError && e.isClientError) {
|
||||
return `skip ${e.statusCode}`;
|
||||
} else {
|
||||
throw e;
|
||||
|
|
|
@ -26,6 +26,7 @@ import { createMessage } from '@/services/messages/create';
|
|||
import { parseAudience } from '../audience';
|
||||
import { extractApMentions } from './mention';
|
||||
import DbResolver from '../db-resolver';
|
||||
import { StatusError } from '@/misc/fetch';
|
||||
|
||||
const logger = apLogger;
|
||||
|
||||
|
@ -177,7 +178,7 @@ export async function createNote(value: string | IObject, resolver?: Resolver, s
|
|||
}
|
||||
} catch (e) {
|
||||
return {
|
||||
status: e.statusCode >= 400 && e.statusCode < 500 ? 'permerror' : 'temperror'
|
||||
status: (e instanceof StatusError && e.isClientError) ? 'permerror' : 'temperror'
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,66 +1,31 @@
|
|||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
import { sign } from 'http-signature';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
import config from '@/config/index';
|
||||
import { User } from '@/models/entities/user';
|
||||
import { getAgentByUrl } from '@/misc/fetch';
|
||||
import { URL } from 'url';
|
||||
import got from 'got';
|
||||
import * as Got from 'got';
|
||||
import { getUserKeypair } from '@/misc/keypair-store';
|
||||
import { User } from '@/models/entities/user';
|
||||
import { getResponse } from '../../misc/fetch';
|
||||
import { createSignedPost, createSignedGet } from './ap-request';
|
||||
|
||||
export default async (user: { id: User['id'] }, url: string, object: any) => {
|
||||
const timeout = 10 * 1000;
|
||||
|
||||
const { protocol, hostname, port, pathname, search } = new URL(url);
|
||||
|
||||
const data = JSON.stringify(object);
|
||||
|
||||
const sha256 = crypto.createHash('sha256');
|
||||
sha256.update(data);
|
||||
const hash = sha256.digest('base64');
|
||||
const body = JSON.stringify(object);
|
||||
|
||||
const keypair = await getUserKeypair(user.id);
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const req = https.request({
|
||||
agent: getAgentByUrl(new URL(`https://example.net`)),
|
||||
protocol,
|
||||
hostname,
|
||||
port,
|
||||
method: 'POST',
|
||||
path: pathname + search,
|
||||
timeout,
|
||||
headers: {
|
||||
const req = createSignedPost({
|
||||
key: {
|
||||
privateKeyPem: keypair.privateKey,
|
||||
keyId: `${config.url}/users/${user.id}#main-key`
|
||||
},
|
||||
url,
|
||||
body,
|
||||
additionalHeaders: {
|
||||
'User-Agent': config.userAgent,
|
||||
'Content-Type': 'application/activity+json',
|
||||
'Digest': `SHA-256=${hash}`
|
||||
}
|
||||
}, res => {
|
||||
if (res.statusCode! >= 400) {
|
||||
reject(res);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
sign(req, {
|
||||
authorizationHeaderName: 'Signature',
|
||||
key: keypair.privateKey,
|
||||
keyId: `${config.url}/users/${user.id}#main-key`,
|
||||
headers: ['(request-target)', 'date', 'host', 'digest']
|
||||
});
|
||||
|
||||
req.on('timeout', () => req.abort());
|
||||
|
||||
req.on('error', e => {
|
||||
if (req.aborted) reject('timeout');
|
||||
reject(e);
|
||||
});
|
||||
|
||||
req.end(data);
|
||||
await getResponse({
|
||||
url,
|
||||
method: req.request.method,
|
||||
headers: req.request.headers,
|
||||
body,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -70,87 +35,24 @@ export default async (user: { id: User['id'] }, url: string, object: any) => {
|
|||
* @param url URL to fetch
|
||||
*/
|
||||
export async function signedGet(url: string, user: { id: User['id'] }) {
|
||||
const timeout = 10 * 1000;
|
||||
|
||||
const keypair = await getUserKeypair(user.id);
|
||||
|
||||
const req = got.get<any>(url, {
|
||||
headers: {
|
||||
'Accept': 'application/activity+json, application/ld+json',
|
||||
const req = createSignedGet({
|
||||
key: {
|
||||
privateKeyPem: keypair.privateKey,
|
||||
keyId: `${config.url}/users/${user.id}#main-key`
|
||||
},
|
||||
url,
|
||||
additionalHeaders: {
|
||||
'User-Agent': config.userAgent,
|
||||
},
|
||||
responseType: 'json',
|
||||
timeout,
|
||||
hooks: {
|
||||
beforeRequest: [
|
||||
options => {
|
||||
options.request = (url: URL, opt: http.RequestOptions, callback?: (response: any) => void) => {
|
||||
// Select custom agent by URL
|
||||
opt.agent = getAgentByUrl(url, false);
|
||||
|
||||
// Wrap original https?.request
|
||||
const requestFunc = url.protocol === 'http:' ? http.request : https.request;
|
||||
const clientRequest = requestFunc(url, opt, callback) as http.ClientRequest;
|
||||
|
||||
// HTTP-Signature
|
||||
sign(clientRequest, {
|
||||
authorizationHeaderName: 'Signature',
|
||||
key: keypair.privateKey,
|
||||
keyId: `${config.url}/users/${user.id}#main-key`,
|
||||
headers: ['(request-target)', 'host', 'date', 'accept']
|
||||
}
|
||||
});
|
||||
|
||||
return clientRequest;
|
||||
};
|
||||
},
|
||||
],
|
||||
},
|
||||
retry: 0,
|
||||
const res = await getResponse({
|
||||
url,
|
||||
method: req.request.method,
|
||||
headers: req.request.headers
|
||||
});
|
||||
|
||||
const res = await receiveResponce(req, 10 * 1024 * 1024);
|
||||
|
||||
return res.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive response (with size limit)
|
||||
* @param req Request
|
||||
* @param maxSize size limit
|
||||
*/
|
||||
export async function receiveResponce<T>(req: Got.CancelableRequest<Got.Response<T>>, maxSize: number) {
|
||||
// 応答ヘッダでサイズチェック
|
||||
req.on('response', (res: Got.Response) => {
|
||||
const contentLength = res.headers['content-length'];
|
||||
if (contentLength != null) {
|
||||
const size = Number(contentLength);
|
||||
if (size > maxSize) {
|
||||
req.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 受信中のデータでサイズチェック
|
||||
req.on('downloadProgress', (progress: Got.Progress) => {
|
||||
if (progress.transferred > maxSize) {
|
||||
req.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
// 応答取得 with ステータスコードエラーの整形
|
||||
const res = await req.catch(e => {
|
||||
if (e.name === 'HTTPError') {
|
||||
const statusCode = (e as Got.HTTPError).response.statusCode;
|
||||
const statusMessage = (e as Got.HTTPError).response.statusMessage;
|
||||
throw {
|
||||
name: `StatusError`,
|
||||
statusCode,
|
||||
message: `${statusCode} ${statusMessage}`,
|
||||
};
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
return res;
|
||||
return await res.json();
|
||||
}
|
||||
|
|
|
@ -68,6 +68,10 @@ export const meta = {
|
|||
validator: $.optional.bool,
|
||||
},
|
||||
|
||||
publicReactions: {
|
||||
validator: $.optional.bool,
|
||||
},
|
||||
|
||||
carefulBot: {
|
||||
validator: $.optional.bool,
|
||||
},
|
||||
|
@ -180,6 +184,7 @@ export default define(meta, async (ps, _user, token) => {
|
|||
if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked;
|
||||
if (typeof ps.isExplorable === 'boolean') updates.isExplorable = ps.isExplorable;
|
||||
if (typeof ps.hideOnlineStatus === 'boolean') updates.hideOnlineStatus = ps.hideOnlineStatus;
|
||||
if (typeof ps.publicReactions === 'boolean') profileUpdates.publicReactions = ps.publicReactions;
|
||||
if (typeof ps.isBot === 'boolean') updates.isBot = ps.isBot;
|
||||
if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot;
|
||||
if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;
|
||||
|
|
50
src/server/api/endpoints/users/groups/leave.ts
Normal file
50
src/server/api/endpoints/users/groups/leave.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
import $ from 'cafy';
|
||||
import { ID } from '@/misc/cafy-id';
|
||||
import define from '../../../define';
|
||||
import { ApiError } from '../../../error';
|
||||
import { UserGroups, UserGroupJoinings } from '@/models/index';
|
||||
|
||||
export const meta = {
|
||||
tags: ['groups', 'users'],
|
||||
|
||||
requireCredential: true as const,
|
||||
|
||||
kind: 'write:user-groups',
|
||||
|
||||
params: {
|
||||
groupId: {
|
||||
validator: $.type(ID),
|
||||
},
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchGroup: {
|
||||
message: 'No such group.',
|
||||
code: 'NO_SUCH_GROUP',
|
||||
id: '62780270-1f67-5dc0-daca-3eb510612e31'
|
||||
},
|
||||
|
||||
youAreOwner: {
|
||||
message: 'Your are the owner.',
|
||||
code: 'YOU_ARE_OWNER',
|
||||
id: 'b6d6e0c2-ef8a-9bb8-653d-79f4a3107c69'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, async (ps, me) => {
|
||||
// Fetch the group
|
||||
const userGroup = await UserGroups.findOne({
|
||||
id: ps.groupId,
|
||||
});
|
||||
|
||||
if (userGroup == null) {
|
||||
throw new ApiError(meta.errors.noSuchGroup);
|
||||
}
|
||||
|
||||
if (me.id === userGroup.userId) {
|
||||
throw new ApiError(meta.errors.youAreOwner);
|
||||
}
|
||||
|
||||
await UserGroupJoinings.delete({ userGroupId: userGroup.id, userId: me.id });
|
||||
});
|
79
src/server/api/endpoints/users/reactions.ts
Normal file
79
src/server/api/endpoints/users/reactions.ts
Normal file
|
@ -0,0 +1,79 @@
|
|||
import $ from 'cafy';
|
||||
import { ID } from '@/misc/cafy-id';
|
||||
import define from '../../define';
|
||||
import { NoteReactions, UserProfiles } from '@/models/index';
|
||||
import { makePaginationQuery } from '../../common/make-pagination-query';
|
||||
import { generateVisibilityQuery } from '../../common/generate-visibility-query';
|
||||
import { ApiError } from '../../error';
|
||||
|
||||
export const meta = {
|
||||
tags: ['users', 'reactions'],
|
||||
|
||||
requireCredential: false as const,
|
||||
|
||||
params: {
|
||||
userId: {
|
||||
validator: $.type(ID),
|
||||
},
|
||||
|
||||
limit: {
|
||||
validator: $.optional.num.range(1, 100),
|
||||
default: 10,
|
||||
},
|
||||
|
||||
sinceId: {
|
||||
validator: $.optional.type(ID),
|
||||
},
|
||||
|
||||
untilId: {
|
||||
validator: $.optional.type(ID),
|
||||
},
|
||||
|
||||
sinceDate: {
|
||||
validator: $.optional.num,
|
||||
},
|
||||
|
||||
untilDate: {
|
||||
validator: $.optional.num,
|
||||
},
|
||||
},
|
||||
|
||||
res: {
|
||||
type: 'array' as const,
|
||||
optional: false as const, nullable: false as const,
|
||||
items: {
|
||||
type: 'object' as const,
|
||||
optional: false as const, nullable: false as const,
|
||||
ref: 'NoteReaction',
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
reactionsNotPublic: {
|
||||
message: 'Reactions of the user is not public.',
|
||||
code: 'REACTIONS_NOT_PUBLIC',
|
||||
id: '673a7dd2-6924-1093-e0c0-e68456ceae5c'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, async (ps, me) => {
|
||||
const profile = await UserProfiles.findOneOrFail(ps.userId);
|
||||
|
||||
if (me == null || (me.id !== ps.userId && !profile.publicReactions)) {
|
||||
throw new ApiError(meta.errors.reactionsNotPublic);
|
||||
}
|
||||
|
||||
const query = makePaginationQuery(NoteReactions.createQueryBuilder('reaction'),
|
||||
ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
|
||||
.andWhere(`reaction.userId = :userId`, { userId: ps.userId })
|
||||
.leftJoinAndSelect('reaction.note', 'note');
|
||||
|
||||
generateVisibilityQuery(query, me);
|
||||
|
||||
const reactions = await query
|
||||
.take(ps.limit!)
|
||||
.getMany();
|
||||
|
||||
return await Promise.all(reactions.map(reaction => NoteReactions.pack(reaction, me, { withNote: true })));
|
||||
});
|
|
@ -1,6 +1,8 @@
|
|||
import $ from 'cafy';
|
||||
import define from '../../define';
|
||||
import { Users } from '@/models/index';
|
||||
import { Brackets } from 'typeorm';
|
||||
import { USER_ACTIVE_THRESHOLD } from '@/const';
|
||||
|
||||
export const meta = {
|
||||
tags: ['users'],
|
||||
|
@ -44,13 +46,15 @@ export const meta = {
|
|||
};
|
||||
|
||||
export default define(meta, async (ps, me) => {
|
||||
const activeThreshold = new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)); // 30日
|
||||
|
||||
if (ps.host) {
|
||||
const q = Users.createQueryBuilder('user')
|
||||
.where('user.isSuspended = FALSE')
|
||||
.andWhere('user.host LIKE :host', { host: ps.host.toLowerCase() + '%' });
|
||||
|
||||
if (ps.username) {
|
||||
q.andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' });
|
||||
q.andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' });
|
||||
}
|
||||
|
||||
q.andWhere('user.updatedAt IS NOT NULL');
|
||||
|
@ -63,9 +67,12 @@ export default define(meta, async (ps, me) => {
|
|||
let users = await Users.createQueryBuilder('user')
|
||||
.where('user.host IS NULL')
|
||||
.andWhere('user.isSuspended = FALSE')
|
||||
.andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' })
|
||||
.andWhere('user.updatedAt IS NOT NULL')
|
||||
.orderBy('user.updatedAt', 'DESC')
|
||||
.andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' })
|
||||
.andWhere(new Brackets(qb => { qb
|
||||
.where('user.updatedAt IS NULL')
|
||||
.orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
|
||||
}))
|
||||
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
|
||||
.take(ps.limit!)
|
||||
.skip(ps.offset)
|
||||
.getMany();
|
||||
|
@ -74,7 +81,7 @@ export default define(meta, async (ps, me) => {
|
|||
const otherUsers = await Users.createQueryBuilder('user')
|
||||
.where('user.host IS NOT NULL')
|
||||
.andWhere('user.isSuspended = FALSE')
|
||||
.andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' })
|
||||
.andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' })
|
||||
.andWhere('user.updatedAt IS NOT NULL')
|
||||
.orderBy('user.updatedAt', 'DESC')
|
||||
.take(ps.limit! - users.length)
|
||||
|
|
|
@ -2,6 +2,7 @@ import $ from 'cafy';
|
|||
import define from '../../define';
|
||||
import { UserProfiles, Users } from '@/models/index';
|
||||
import { User } from '@/models/entities/user';
|
||||
import { Brackets } from 'typeorm';
|
||||
|
||||
export const meta = {
|
||||
tags: ['users'],
|
||||
|
@ -23,9 +24,9 @@ export const meta = {
|
|||
default: 10,
|
||||
},
|
||||
|
||||
localOnly: {
|
||||
validator: $.optional.bool,
|
||||
default: false,
|
||||
origin: {
|
||||
validator: $.optional.str.or(['local', 'remote', 'combined']),
|
||||
default: 'combined',
|
||||
},
|
||||
|
||||
detail: {
|
||||
|
@ -46,63 +47,79 @@ export const meta = {
|
|||
};
|
||||
|
||||
export default define(meta, async (ps, me) => {
|
||||
const activeThreshold = new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)); // 30日
|
||||
|
||||
const isUsername = ps.query.startsWith('@');
|
||||
|
||||
let users: User[] = [];
|
||||
|
||||
if (isUsername) {
|
||||
users = await Users.createQueryBuilder('user')
|
||||
.where('user.host IS NULL')
|
||||
.andWhere('user.isSuspended = FALSE')
|
||||
.andWhere('user.usernameLower like :username', { username: ps.query.replace('@', '').toLowerCase() + '%' })
|
||||
.andWhere('user.updatedAt IS NOT NULL')
|
||||
.orderBy('user.updatedAt', 'DESC')
|
||||
const usernameQuery = Users.createQueryBuilder('user')
|
||||
.where('user.usernameLower LIKE :username', { username: ps.query.replace('@', '').toLowerCase() + '%' })
|
||||
.andWhere(new Brackets(qb => { qb
|
||||
.where('user.updatedAt IS NULL')
|
||||
.orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
|
||||
}))
|
||||
.andWhere('user.isSuspended = FALSE');
|
||||
|
||||
if (ps.origin === 'local') {
|
||||
usernameQuery.andWhere('user.host IS NULL');
|
||||
} else if (ps.origin === 'remote') {
|
||||
usernameQuery.andWhere('user.host IS NOT NULL');
|
||||
}
|
||||
|
||||
users = await usernameQuery
|
||||
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
|
||||
.take(ps.limit!)
|
||||
.skip(ps.offset)
|
||||
.getMany();
|
||||
} else {
|
||||
const nameQuery = Users.createQueryBuilder('user')
|
||||
.where('user.name ILIKE :query', { query: '%' + ps.query + '%' })
|
||||
.andWhere(new Brackets(qb => { qb
|
||||
.where('user.updatedAt IS NULL')
|
||||
.orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
|
||||
}))
|
||||
.andWhere('user.isSuspended = FALSE');
|
||||
|
||||
if (ps.origin === 'local') {
|
||||
nameQuery.andWhere('user.host IS NULL');
|
||||
} else if (ps.origin === 'remote') {
|
||||
nameQuery.andWhere('user.host IS NOT NULL');
|
||||
}
|
||||
|
||||
users = await nameQuery
|
||||
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
|
||||
.take(ps.limit!)
|
||||
.skip(ps.offset)
|
||||
.getMany();
|
||||
|
||||
if (users.length < ps.limit! && !ps.localOnly) {
|
||||
const otherUsers = await Users.createQueryBuilder('user')
|
||||
.where('user.host IS NOT NULL')
|
||||
.andWhere('user.isSuspended = FALSE')
|
||||
.andWhere('user.usernameLower like :username', { username: ps.query.replace('@', '').toLowerCase() + '%' })
|
||||
.andWhere('user.updatedAt IS NOT NULL')
|
||||
.orderBy('user.updatedAt', 'DESC')
|
||||
.take(ps.limit! - users.length)
|
||||
.getMany();
|
||||
|
||||
users = users.concat(otherUsers);
|
||||
}
|
||||
} else {
|
||||
if (users.length < ps.limit!) {
|
||||
const profQuery = UserProfiles.createQueryBuilder('prof')
|
||||
.select('prof.userId')
|
||||
.where('prof.userHost IS NULL')
|
||||
.andWhere('prof.description ilike :query', { query: '%' + ps.query + '%' });
|
||||
.where('prof.description ILIKE :query', { query: '%' + ps.query + '%' });
|
||||
|
||||
users = await Users.createQueryBuilder('user')
|
||||
if (ps.origin === 'local') {
|
||||
profQuery.andWhere('prof.userHost IS NULL');
|
||||
} else if (ps.origin === 'remote') {
|
||||
profQuery.andWhere('prof.userHost IS NOT NULL');
|
||||
}
|
||||
|
||||
const query = Users.createQueryBuilder('user')
|
||||
.where(`user.id IN (${ profQuery.getQuery() })`)
|
||||
.setParameters(profQuery.getParameters())
|
||||
.andWhere('user.updatedAt IS NOT NULL')
|
||||
.orderBy('user.updatedAt', 'DESC')
|
||||
.andWhere(new Brackets(qb => { qb
|
||||
.where('user.updatedAt IS NULL')
|
||||
.orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
|
||||
}))
|
||||
.andWhere('user.isSuspended = FALSE')
|
||||
.setParameters(profQuery.getParameters());
|
||||
|
||||
users = users.concat(await query
|
||||
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
|
||||
.take(ps.limit!)
|
||||
.skip(ps.offset)
|
||||
.getMany();
|
||||
|
||||
if (users.length < ps.limit! && !ps.localOnly) {
|
||||
const profQuery2 = UserProfiles.createQueryBuilder('prof')
|
||||
.select('prof.userId')
|
||||
.where('prof.userHost IS NOT NULL')
|
||||
.andWhere('prof.description ilike :query', { query: '%' + ps.query + '%' });
|
||||
|
||||
const otherUsers = await Users.createQueryBuilder('user')
|
||||
.where(`user.id IN (${ profQuery2.getQuery() })`)
|
||||
.setParameters(profQuery2.getParameters())
|
||||
.andWhere('user.updatedAt IS NOT NULL')
|
||||
.orderBy('user.updatedAt', 'DESC')
|
||||
.take(ps.limit! - users.length)
|
||||
.getMany();
|
||||
|
||||
users = users.concat(otherUsers);
|
||||
.getMany()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import { downloadUrl } from '@/misc/download-url';
|
|||
import { detectType } from '@/misc/get-file-info';
|
||||
import { convertToJpeg, convertToPngOrJpeg } from '@/services/drive/image-processor';
|
||||
import { GenerateVideoThumbnail } from '@/services/drive/generate-video-thumbnail';
|
||||
import { StatusError } from '@/misc/fetch';
|
||||
|
||||
//const _filename = fileURLToPath(import.meta.url);
|
||||
const _filename = __filename;
|
||||
|
@ -83,9 +84,9 @@ export default async function(ctx: Koa.Context) {
|
|||
ctx.set('Content-Type', image.type);
|
||||
ctx.set('Cache-Control', 'max-age=31536000, immutable');
|
||||
} catch (e) {
|
||||
serverLogger.error(e.statusCode);
|
||||
serverLogger.error(`${e}`);
|
||||
|
||||
if (typeof e.statusCode === 'number' && e.statusCode >= 400 && e.statusCode < 500) {
|
||||
if (e instanceof StatusError && e.isClientError) {
|
||||
ctx.status = e.statusCode;
|
||||
ctx.set('Cache-Control', 'max-age=86400');
|
||||
} else {
|
||||
|
|
|
@ -5,6 +5,7 @@ import { IImage, convertToPng, convertToJpeg } from '@/services/drive/image-proc
|
|||
import { createTemp } from '@/misc/create-temp';
|
||||
import { downloadUrl } from '@/misc/download-url';
|
||||
import { detectType } from '@/misc/get-file-info';
|
||||
import { StatusError } from '@/misc/fetch';
|
||||
|
||||
export async function proxyMedia(ctx: Koa.Context) {
|
||||
const url = 'url' in ctx.query ? ctx.query.url : 'https://' + ctx.params.url;
|
||||
|
@ -37,9 +38,9 @@ export async function proxyMedia(ctx: Koa.Context) {
|
|||
ctx.set('Cache-Control', 'max-age=31536000, immutable');
|
||||
ctx.body = image.data;
|
||||
} catch (e) {
|
||||
serverLogger.error(e);
|
||||
serverLogger.error(`${e}`);
|
||||
|
||||
if (typeof e.statusCode === 'number' && e.statusCode >= 400 && e.statusCode < 500) {
|
||||
if (e instanceof StatusError && e.isClientError) {
|
||||
ctx.status = e.statusCode;
|
||||
} else {
|
||||
ctx.status = 500;
|
||||
|
|
55
test/ap-request.ts
Normal file
55
test/ap-request.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
import * as assert from 'assert';
|
||||
import { genRsaKeyPair } from '../src/misc/gen-key-pair';
|
||||
import { createSignedPost, createSignedGet } from '../src/remote/activitypub/ap-request';
|
||||
const httpSignature = require('http-signature');
|
||||
|
||||
export const buildParsedSignature = (signingString: string, signature: string, algorithm: string) => {
|
||||
return {
|
||||
scheme: 'Signature',
|
||||
params: {
|
||||
keyId: 'KeyID', // dummy, not used for verify
|
||||
algorithm: algorithm,
|
||||
headers: [ '(request-target)', 'date', 'host', 'digest' ], // dummy, not used for verify
|
||||
signature: signature,
|
||||
},
|
||||
signingString: signingString,
|
||||
algorithm: algorithm?.toUpperCase(),
|
||||
keyId: 'KeyID', // dummy, not used for verify
|
||||
};
|
||||
};
|
||||
|
||||
describe('ap-request', () => {
|
||||
it('createSignedPost with verify', async () => {
|
||||
const keypair = await genRsaKeyPair();
|
||||
const key = { keyId: 'x', 'privateKeyPem': keypair.privateKey };
|
||||
const url = 'https://example.com/inbox';
|
||||
const activity = { a: 1 };
|
||||
const body = JSON.stringify(activity);
|
||||
const headers = {
|
||||
'User-Agent': 'UA'
|
||||
};
|
||||
|
||||
const req = createSignedPost({ key, url, body, additionalHeaders: headers });
|
||||
|
||||
const parsed = buildParsedSignature(req.signingString, req.signature, 'rsa-sha256');
|
||||
|
||||
const result = httpSignature.verifySignature(parsed, keypair.publicKey);
|
||||
assert.deepStrictEqual(result, true);
|
||||
});
|
||||
|
||||
it('createSignedGet with verify', async () => {
|
||||
const keypair = await genRsaKeyPair();
|
||||
const key = { keyId: 'x', 'privateKeyPem': keypair.privateKey };
|
||||
const url = 'https://example.com/outbox';
|
||||
const headers = {
|
||||
'User-Agent': 'UA'
|
||||
};
|
||||
|
||||
const req = createSignedGet({ key, url, additionalHeaders: headers });
|
||||
|
||||
const parsed = buildParsedSignature(req.signingString, req.signature, 'rsa-sha256');
|
||||
|
||||
const result = httpSignature.verifySignature(parsed, keypair.publicKey);
|
||||
assert.deepStrictEqual(result, true);
|
||||
});
|
||||
});
|
15
test/docker-compose.yml
Normal file
15
test/docker-compose.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
version: "3"
|
||||
|
||||
services:
|
||||
redistest:
|
||||
image: redis:4.0-alpine
|
||||
ports:
|
||||
- "127.0.0.1:56312:6379"
|
||||
|
||||
dbtest:
|
||||
image: postgres:12.2-alpine
|
||||
ports:
|
||||
- "127.0.0.1:54312:5432"
|
||||
environment:
|
||||
POSTGRES_DB: "test-misskey"
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
12
test/test.yml
Normal file
12
test/test.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
url: 'http://misskey.local'
|
||||
port: 61812
|
||||
db:
|
||||
host: localhost
|
||||
port: 54312
|
||||
db: test-misskey
|
||||
user: postgres
|
||||
pass: ''
|
||||
redis:
|
||||
host: localhost
|
||||
port: 56312
|
||||
id: aid
|
475
yarn.lock
475
yarn.lock
|
@ -2,13 +2,6 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@7.12.11":
|
||||
version "7.12.11"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
|
||||
integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.10.4"
|
||||
|
||||
"@babel/code-frame@^7.0.0":
|
||||
version "7.12.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
|
||||
|
@ -21,7 +14,7 @@
|
|||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
|
||||
integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
|
||||
|
||||
"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13":
|
||||
"@babel/highlight@^7.12.13":
|
||||
version "7.12.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c"
|
||||
integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==
|
||||
|
@ -61,10 +54,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b"
|
||||
integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==
|
||||
|
||||
"@cspotcode/source-map-support@0.6.1":
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz#118511f316e2e87ee4294761868e254d3da47960"
|
||||
integrity sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==
|
||||
"@cspotcode/source-map-support@0.7.0":
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5"
|
||||
integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==
|
||||
dependencies:
|
||||
"@cspotcode/source-map-consumer" "0.8.0"
|
||||
|
||||
|
@ -131,14 +124,14 @@
|
|||
pump "^3.0.0"
|
||||
secure-json-parse "^2.1.0"
|
||||
|
||||
"@eslint/eslintrc@^0.4.3":
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
||||
integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==
|
||||
"@eslint/eslintrc@^1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.3.tgz#41f08c597025605f672251dcc4e8be66b5ed7366"
|
||||
integrity sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.1.1"
|
||||
espree "^7.3.0"
|
||||
debug "^4.3.2"
|
||||
espree "^9.0.0"
|
||||
globals "^13.9.0"
|
||||
ignore "^4.0.6"
|
||||
import-fresh "^3.2.1"
|
||||
|
@ -158,10 +151,10 @@
|
|||
dependencies:
|
||||
"@hapi/hoek" "^9.0.0"
|
||||
|
||||
"@humanwhocodes/config-array@^0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"
|
||||
integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==
|
||||
"@humanwhocodes/config-array@^0.6.0":
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.6.0.tgz#b5621fdb3b32309d2d16575456cbc277fa8f021a"
|
||||
integrity sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==
|
||||
dependencies:
|
||||
"@humanwhocodes/object-schema" "^1.2.0"
|
||||
debug "^4.1.1"
|
||||
|
@ -1189,144 +1182,144 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71"
|
||||
integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg==
|
||||
|
||||
"@typescript-eslint/parser@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899"
|
||||
integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==
|
||||
"@typescript-eslint/parser@5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.0.0.tgz#50d1be2e0def82d73e863cceba74aeeac9973592"
|
||||
integrity sha512-B6D5rmmQ14I1fdzs71eL3DAuvnPHTY/t7rQABrL9BLnx/H51Un8ox1xqYAchs0/V2trcoyxB1lMJLlrwrJCDgw==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "4.33.0"
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
"@typescript-eslint/typescript-estree" "4.33.0"
|
||||
"@typescript-eslint/scope-manager" "5.0.0"
|
||||
"@typescript-eslint/types" "5.0.0"
|
||||
"@typescript-eslint/typescript-estree" "5.0.0"
|
||||
debug "^4.3.1"
|
||||
|
||||
"@typescript-eslint/scope-manager@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3"
|
||||
integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==
|
||||
"@typescript-eslint/scope-manager@5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.0.0.tgz#aea0fb0e2480c1169a02e89d9005ac3f2835713f"
|
||||
integrity sha512-5RFjdA/ain/MDUHYXdF173btOKncIrLuBmA9s6FJhzDrRAyVSA+70BHg0/MW6TE+UiKVyRtX91XpVS0gVNwVDQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
"@typescript-eslint/visitor-keys" "4.33.0"
|
||||
"@typescript-eslint/types" "5.0.0"
|
||||
"@typescript-eslint/visitor-keys" "5.0.0"
|
||||
|
||||
"@typescript-eslint/types@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72"
|
||||
integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==
|
||||
"@typescript-eslint/types@5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.0.0.tgz#25d93f6d269b2d25fdc51a0407eb81ccba60eb0f"
|
||||
integrity sha512-dU/pKBUpehdEqYuvkojmlv0FtHuZnLXFBn16zsDmlFF3LXkOpkAQ2vrKc3BidIIve9EMH2zfTlxqw9XM0fFN5w==
|
||||
|
||||
"@typescript-eslint/typescript-estree@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609"
|
||||
integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==
|
||||
"@typescript-eslint/typescript-estree@5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.0.0.tgz#bc20f413c6e572c7309dbe5fa3be027984952af3"
|
||||
integrity sha512-V/6w+PPQMhinWKSn+fCiX5jwvd1vRBm7AX7SJQXEGQtwtBvjMPjaU3YTQ1ik2UF1u96X7tsB96HMnulG3eLi9Q==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
"@typescript-eslint/visitor-keys" "4.33.0"
|
||||
"@typescript-eslint/types" "5.0.0"
|
||||
"@typescript-eslint/visitor-keys" "5.0.0"
|
||||
debug "^4.3.1"
|
||||
globby "^11.0.3"
|
||||
is-glob "^4.0.1"
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd"
|
||||
integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==
|
||||
"@typescript-eslint/visitor-keys@5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.0.0.tgz#b789f7cd105e59bee5c0983a353942a5a48f56df"
|
||||
integrity sha512-yRyd2++o/IrJdyHuYMxyFyBhU762MRHQ/bAGQeTnN3pGikfh+nEmM61XTqaDH1XDp53afZ+waXrk0ZvenoZ6xw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
"@typescript-eslint/types" "5.0.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
|
||||
"@ungap/promise-all-settled@1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
|
||||
integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
|
||||
|
||||
"@vue/compiler-core@3.2.19":
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.19.tgz#b537dd377ce51fdb64e9b30ebfbff7cd70a64cb9"
|
||||
integrity sha512-8dOPX0YOtaXol0Zf2cfLQ4NU/yHYl2H7DCKsLEZ7gdvPK6ZSEwGLJ7IdghhY2YEshEpC5RB9QKdC5I07z8Dtjg==
|
||||
"@vue/compiler-core@3.2.20":
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.20.tgz#af5a3c5237818835b0d0be837eb5885a8d21c160"
|
||||
integrity sha512-vcEXlKXoPwBXFP5aUTHN9GTZaDfwCofa9Yu9bbW2C5O/QSa9Esdt7OG4+0RRd3EHEMxUvEdj4RZrd/KpQeiJbA==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.15.0"
|
||||
"@vue/shared" "3.2.19"
|
||||
"@vue/shared" "3.2.20"
|
||||
estree-walker "^2.0.2"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-dom@3.2.19":
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.19.tgz#0607bc90de6af55fde73b09b3c4d0bf8cb597ed8"
|
||||
integrity sha512-WzQoE8rfkFjPtIioc7SSgTsnz9g2oG61DU8KHnzPrRS7fW/lji6H2uCYJfp4Z6kZE8GjnHc1Ljwl3/gxDes0cw==
|
||||
"@vue/compiler-dom@3.2.20":
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.20.tgz#8e0ef354449c0faf41519b00bfc2045eae01dcb5"
|
||||
integrity sha512-QnI77ec/JtV7R0YBbcVayYTDCRcI9OCbxiUQK6izVyqQO0658n0zQuoNwe+bYgtqnvGAIqTR3FShTd5y4oOjdg==
|
||||
dependencies:
|
||||
"@vue/compiler-core" "3.2.19"
|
||||
"@vue/shared" "3.2.19"
|
||||
"@vue/compiler-core" "3.2.20"
|
||||
"@vue/shared" "3.2.20"
|
||||
|
||||
"@vue/compiler-sfc@3.2.19":
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.19.tgz#d412195a98ebd49b84602f171719294a1d9549be"
|
||||
integrity sha512-pLlbgkO1UHTO02MSpa/sFOXUwIDxSMiKZ1ozE5n71CY4DM+YmI+G3gT/ZHZ46WBId7f3VTF/D8pGwMygcQbrQA==
|
||||
"@vue/compiler-sfc@3.2.20":
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.20.tgz#2d7668e76f066c566dd7c09c15c9acce4e876e0a"
|
||||
integrity sha512-03aZo+6tQKiFLfunHKSPZvdK4Jsn/ftRCyaro8AQIWkuxJbvSosbKK6HTTn+D2c3nPScG155akJoxKENw7rftQ==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.15.0"
|
||||
"@vue/compiler-core" "3.2.19"
|
||||
"@vue/compiler-dom" "3.2.19"
|
||||
"@vue/compiler-ssr" "3.2.19"
|
||||
"@vue/ref-transform" "3.2.19"
|
||||
"@vue/shared" "3.2.19"
|
||||
"@vue/compiler-core" "3.2.20"
|
||||
"@vue/compiler-dom" "3.2.20"
|
||||
"@vue/compiler-ssr" "3.2.20"
|
||||
"@vue/ref-transform" "3.2.20"
|
||||
"@vue/shared" "3.2.20"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.25.7"
|
||||
postcss "^8.1.10"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@vue/compiler-ssr@3.2.19":
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.19.tgz#3e91ecf70f8f961c5f63eacd2139bcdab9a7a07c"
|
||||
integrity sha512-oLon0Cn3O7WEYzzmzZavGoqXH+199LT+smdjBT3Uf3UX4HwDNuBFCmvL0TsqV9SQnIgKvBRbQ7lhbpnd4lqM3w==
|
||||
"@vue/compiler-ssr@3.2.20":
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.20.tgz#9cceb6261d9932cb5568202610c1c28f86c5e521"
|
||||
integrity sha512-rzzVVYivm+EjbfiGQvNeyiYZWzr6Hkej97RZLZvcumacQlnKv9176Xo9rRyeWwFbBlxmtNdrVMslRXtipMXk2w==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.2.19"
|
||||
"@vue/shared" "3.2.19"
|
||||
"@vue/compiler-dom" "3.2.20"
|
||||
"@vue/shared" "3.2.20"
|
||||
|
||||
"@vue/reactivity@3.2.19":
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.19.tgz#fc6e0f0106f295226835cfed5ff5f84d927bea65"
|
||||
integrity sha512-FtachoYs2SnyrWup5UikP54xDX6ZJ1s5VgHcJp4rkGoutU3Ry61jhs+nCX7J64zjX992Mh9gGUC0LqTs8q9vCA==
|
||||
"@vue/reactivity@3.2.20":
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.20.tgz#81fe1c368e7f20bc0ec1dec1045bbee253582de8"
|
||||
integrity sha512-nSmoLojUTk+H8HNTAkrUduB4+yIUBK2HPihJo2uXVSH4Spry6oqN6lFzE5zpLK+F27Sja+UqR9R1+/kIOsHV5w==
|
||||
dependencies:
|
||||
"@vue/shared" "3.2.19"
|
||||
"@vue/shared" "3.2.20"
|
||||
|
||||
"@vue/ref-transform@3.2.19":
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.19.tgz#cf0f986486bb26838fbd09749e927bab19745600"
|
||||
integrity sha512-03wwUnoIAeKti5IGGx6Vk/HEBJ+zUcm5wrUM3+PQsGf7IYnXTbeIfHHpx4HeSeWhnLAjqZjADQwW8uA4rBmVbg==
|
||||
"@vue/ref-transform@3.2.20":
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.20.tgz#2a59ec90caf8e5c7336776a0900bff0a8b81c090"
|
||||
integrity sha512-Y42d3PGlYZ1lXcF3dbd3+qU/C/a3wYEZ949fyOI5ptzkjDWlkfU6vn74fmOjsLjEcjs10BXK2qO99FqQIK2r1Q==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.15.0"
|
||||
"@vue/compiler-core" "3.2.19"
|
||||
"@vue/shared" "3.2.19"
|
||||
"@vue/compiler-core" "3.2.20"
|
||||
"@vue/shared" "3.2.20"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.25.7"
|
||||
|
||||
"@vue/runtime-core@3.2.19":
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.19.tgz#807715b7f4728abb84fa4a8efdbe37d8ddb4c6d3"
|
||||
integrity sha512-qArZSWKxWsgKfxk9BelZ32nY0MZ31CAW2kUUyVJyxh4cTfHaXGbjiQB5JgsvKc49ROMNffv9t3/qjasQqAH+RQ==
|
||||
"@vue/runtime-core@3.2.20":
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.20.tgz#8f63e956a3f88fb772541443c45a7701211012cb"
|
||||
integrity sha512-d1xfUGhZPfiZzAN7SatStD4vRtT8deJSXib2+Cz3x0brjMWKxe32asQc154FF1E2fFgMCHtnfd4A90bQEzV4GQ==
|
||||
dependencies:
|
||||
"@vue/reactivity" "3.2.19"
|
||||
"@vue/shared" "3.2.19"
|
||||
"@vue/reactivity" "3.2.20"
|
||||
"@vue/shared" "3.2.20"
|
||||
|
||||
"@vue/runtime-dom@3.2.19":
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.19.tgz#7e8bf645754703e360fa132e4be9113edf2377bb"
|
||||
integrity sha512-hIRboxXwafeHhbZEkZYNV0MiJXPNf4fP0X6hM2TJb0vssz8BKhD9cF92BkRgZztTQevecbhk0gu4uAPJ3dxL9A==
|
||||
"@vue/runtime-dom@3.2.20":
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.20.tgz#8aa56ae6c30f9cd4a71ca0e9ec3c4bdc67148d15"
|
||||
integrity sha512-4TCvZMLhESWCFHFYgqN4QmMA/onnINAlUovhopjlS8ST27G1A8Z0tyxPzLoXLa+b5JrOpbMPheEMPvdKExTJig==
|
||||
dependencies:
|
||||
"@vue/runtime-core" "3.2.19"
|
||||
"@vue/shared" "3.2.19"
|
||||
"@vue/runtime-core" "3.2.20"
|
||||
"@vue/shared" "3.2.20"
|
||||
csstype "^2.6.8"
|
||||
|
||||
"@vue/server-renderer@3.2.19":
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.19.tgz#870bcec9f7cdaee0c2187a169b6e636ab4362fb1"
|
||||
integrity sha512-A9FNT7fgQJXItwdzWREntAgWKVtKYuXHBKGev/H4+ByTu8vB7gQXGcim01QxaJshdNg4dYuH2tEBZXCNCNx+/w==
|
||||
"@vue/server-renderer@3.2.20":
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.20.tgz#705e07ae9425132b2b6227d308a51a13f4d4ec81"
|
||||
integrity sha512-viIbZGep9XabnrRcaxWIi00cOh1x21QYm2upIL5W0zqzTJ54VdTzpI+zi1osNp+VfRQDTHpV2U7H3Kn4ljYJvg==
|
||||
dependencies:
|
||||
"@vue/compiler-ssr" "3.2.19"
|
||||
"@vue/shared" "3.2.19"
|
||||
"@vue/compiler-ssr" "3.2.20"
|
||||
"@vue/shared" "3.2.20"
|
||||
|
||||
"@vue/shared@3.2.19":
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.19.tgz#111ec3da18337d86274446984c49925b1b2b2dd7"
|
||||
integrity sha512-Knqhx7WieLdVgwCAZgTVrDCXZ50uItuecLh9JdLC8O+a5ayaSyIQYveUK3hCRNC7ws5zalHmZwfdLMGaS8r4Ew==
|
||||
"@vue/shared@3.2.20":
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.20.tgz#53746961f731a8ea666e3316271e944238dc31db"
|
||||
integrity sha512-FbpX+hD5BvXCQerEYO7jtAGHlhAkhTQ4KIV73kmLWNlawWhTiVuQxizgVb0BOkX5oG9cIRZ42EG++d/k/Efp0w==
|
||||
|
||||
"@webassemblyjs/ast@1.11.0":
|
||||
version "1.11.0"
|
||||
|
@ -1655,7 +1648,7 @@ acorn-walk@^8.1.1:
|
|||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.1.1.tgz#3ddab7f84e4a7e2313f6c414c5b7dac85f4e3ebc"
|
||||
integrity sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==
|
||||
|
||||
acorn@^7.1.1, acorn@^7.4.0:
|
||||
acorn@^7.1.1:
|
||||
version "7.4.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||
|
@ -1675,6 +1668,11 @@ acorn@^8.4.1:
|
|||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c"
|
||||
integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==
|
||||
|
||||
acorn@^8.5.0:
|
||||
version "8.5.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2"
|
||||
integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==
|
||||
|
||||
agent-base@6:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||
|
@ -1714,16 +1712,6 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.5.5:
|
|||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ajv@^8.0.1:
|
||||
version "8.5.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b"
|
||||
integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
json-schema-traverse "^1.0.0"
|
||||
require-from-string "^2.0.2"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
alphanum-sort@^1.0.1, alphanum-sort@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
|
||||
|
@ -2422,10 +2410,10 @@ builtin-modules@^1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
|
||||
integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
|
||||
|
||||
bull@3.29.2:
|
||||
version "3.29.2"
|
||||
resolved "https://registry.yarnpkg.com/bull/-/bull-3.29.2.tgz#30051fd14c7214b1e90c212585674f77fd982650"
|
||||
integrity sha512-zWHyza/ElwVvJUqIEDJdUhGKd1V9EHjituUL7sJAmJoxS9Z7QMhYcMOWcgbUlWPgtiKN1g9ZlOtFAoq7C4/SQw==
|
||||
bull@3.29.3:
|
||||
version "3.29.3"
|
||||
resolved "https://registry.yarnpkg.com/bull/-/bull-3.29.3.tgz#5b0059b172685b0d6f011d56214e1898ff3a7a0b"
|
||||
integrity sha512-MOqV1dKLy1YQgP9m3lFolyMxaU+1+o4afzYYf0H4wNM+x/S0I1QPQfkgGlLiH00EyFrvSmeubeCYFP47rTfpjg==
|
||||
dependencies:
|
||||
cron-parser "^2.13.0"
|
||||
debuglog "^1.0.0"
|
||||
|
@ -2497,10 +2485,10 @@ cache-content-type@^1.0.0:
|
|||
mime-types "^2.1.18"
|
||||
ylru "^1.2.0"
|
||||
|
||||
cacheable-lookup@6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.0.2.tgz#8df03d6239c91bb9f6394700d7ba4a100abbad67"
|
||||
integrity sha512-9RJkUl1k/A1dFhaRfrEUdISvvou0WKx8LboMO0j1BpsqgAuolwZgwaEtn0dmFMk5HQxpFtHF1bHCnIQMywUpvw==
|
||||
cacheable-lookup@6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.0.3.tgz#61d6171f6818fab230666b11f7cf3f5a48df7818"
|
||||
integrity sha512-xdwIK7MEC8NpRIt0dx2PL7pTRKaSmDb+zirzuM+cJTRWDfwfVu4XyASkODIU4XbjsyFHKo/tDOPSs64Z3yfFWg==
|
||||
|
||||
cacheable-lookup@^5.0.3:
|
||||
version "5.0.3"
|
||||
|
@ -3325,10 +3313,10 @@ css-declaration-sorter@^6.0.3:
|
|||
dependencies:
|
||||
timsort "^0.3.0"
|
||||
|
||||
css-loader@6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.3.0.tgz#334d3500ff0a0c14cfbd4b0670088dbb5b5c1530"
|
||||
integrity sha512-9NGvHOR+L6ps13Ilw/b216++Q8q+5RpJcVufCdW9S/9iCzs4KBDNa8qnA/n3FK/sSfWmH35PAIK/cfPi7LOSUg==
|
||||
css-loader@6.4.0:
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.4.0.tgz#01c57ea776024e18ca193428dcad3ff6b42a0130"
|
||||
integrity sha512-Dlt6qfsxI/w1vU0r8qDd4BtMPxWqJeY5qQU7SmmZfvbpe6Xl18McO4GhyaMLns24Y2VNPiZwJPQ8JSbg4qvQLw==
|
||||
dependencies:
|
||||
icss-utils "^5.1.0"
|
||||
postcss "^8.2.15"
|
||||
|
@ -4280,6 +4268,14 @@ eslint-scope@5.1.1, eslint-scope@^5.1.1:
|
|||
esrecurse "^4.3.0"
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-scope@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-6.0.0.tgz#9cf45b13c5ac8f3d4c50f46a5121f61b3e318978"
|
||||
integrity sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==
|
||||
dependencies:
|
||||
esrecurse "^4.3.0"
|
||||
estraverse "^5.2.0"
|
||||
|
||||
eslint-utils@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
|
||||
|
@ -4287,7 +4283,14 @@ eslint-utils@^2.1.0:
|
|||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0:
|
||||
eslint-utils@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
|
||||
integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
|
||||
eslint-visitor-keys@^1.1.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
|
||||
integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
|
||||
|
@ -4297,37 +4300,41 @@ eslint-visitor-keys@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
|
||||
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
|
||||
|
||||
eslint@7.32.0:
|
||||
version "7.32.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d"
|
||||
integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==
|
||||
eslint-visitor-keys@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186"
|
||||
integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==
|
||||
|
||||
eslint@8.0.1:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.0.1.tgz#3610e7fe4a05c2154669515ca60835a76a19f700"
|
||||
integrity sha512-LsgcwZgQ72vZ+SMp4K6pAnk2yFDWL7Ti4pJaRvsZ0Hsw2h8ZjUIW38a9AFn2cZXdBMlScMFYYgsSp4ttFI/0bA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "7.12.11"
|
||||
"@eslint/eslintrc" "^0.4.3"
|
||||
"@humanwhocodes/config-array" "^0.5.0"
|
||||
"@eslint/eslintrc" "^1.0.3"
|
||||
"@humanwhocodes/config-array" "^0.6.0"
|
||||
ajv "^6.10.0"
|
||||
chalk "^4.0.0"
|
||||
cross-spawn "^7.0.2"
|
||||
debug "^4.0.1"
|
||||
debug "^4.3.2"
|
||||
doctrine "^3.0.0"
|
||||
enquirer "^2.3.5"
|
||||
escape-string-regexp "^4.0.0"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^2.1.0"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
espree "^7.3.1"
|
||||
eslint-scope "^6.0.0"
|
||||
eslint-utils "^3.0.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
espree "^9.0.0"
|
||||
esquery "^1.4.0"
|
||||
esutils "^2.0.2"
|
||||
fast-deep-equal "^3.1.3"
|
||||
file-entry-cache "^6.0.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
glob-parent "^5.1.2"
|
||||
glob-parent "^6.0.1"
|
||||
globals "^13.6.0"
|
||||
ignore "^4.0.6"
|
||||
import-fresh "^3.0.0"
|
||||
imurmurhash "^0.1.4"
|
||||
is-glob "^4.0.0"
|
||||
js-yaml "^3.13.1"
|
||||
js-yaml "^4.1.0"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.4.1"
|
||||
lodash.merge "^4.6.2"
|
||||
|
@ -4335,11 +4342,10 @@ eslint@7.32.0:
|
|||
natural-compare "^1.4.0"
|
||||
optionator "^0.9.1"
|
||||
progress "^2.0.0"
|
||||
regexpp "^3.1.0"
|
||||
regexpp "^3.2.0"
|
||||
semver "^7.2.1"
|
||||
strip-ansi "^6.0.0"
|
||||
strip-json-comments "^3.1.0"
|
||||
table "^6.0.9"
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
|
@ -4357,14 +4363,14 @@ espree@^6.2.1:
|
|||
acorn-jsx "^5.2.0"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
espree@^7.3.0, espree@^7.3.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6"
|
||||
integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==
|
||||
espree@^9.0.0:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-9.0.0.tgz#e90a2965698228502e771c7a58489b1a9d107090"
|
||||
integrity sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==
|
||||
dependencies:
|
||||
acorn "^7.4.0"
|
||||
acorn "^8.5.0"
|
||||
acorn-jsx "^5.3.1"
|
||||
eslint-visitor-keys "^1.3.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
|
||||
esprima@^2.6.0:
|
||||
version "2.7.3"
|
||||
|
@ -5043,12 +5049,12 @@ glob-parent@^5.1.0, glob-parent@~5.1.0:
|
|||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob-parent@^5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||
glob-parent@^6.0.1:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
|
||||
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
is-glob "^4.0.3"
|
||||
|
||||
glob-stream@^6.1.0:
|
||||
version "6.1.0"
|
||||
|
@ -5763,7 +5769,7 @@ ip-cidr@3.0.4:
|
|||
ip-address "^7.1.0"
|
||||
jsbn "^1.1.0"
|
||||
|
||||
ip-regex@^4.3.0:
|
||||
ip-regex@^4.0.0, ip-regex@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5"
|
||||
integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==
|
||||
|
@ -5773,6 +5779,11 @@ ip@^1.1.5:
|
|||
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
||||
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
|
||||
|
||||
ipaddr.js@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0"
|
||||
integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==
|
||||
|
||||
is-absolute-url@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
|
||||
|
@ -5951,6 +5962,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
|
|||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-glob@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-installed-globally@~0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520"
|
||||
|
@ -5959,6 +5977,13 @@ is-installed-globally@~0.4.0:
|
|||
global-dirs "^3.0.0"
|
||||
is-path-inside "^3.0.2"
|
||||
|
||||
is-ip@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8"
|
||||
integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==
|
||||
dependencies:
|
||||
ip-regex "^4.0.0"
|
||||
|
||||
is-lambda@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5"
|
||||
|
@ -6241,7 +6266,7 @@ js-yaml@4.0.0:
|
|||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
js-yaml@4.1.0, js-yaml@^4.0.0:
|
||||
js-yaml@4.1.0, js-yaml@^4.0.0, js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||
|
@ -6838,11 +6863,6 @@ lodash.bind@^4.1.4:
|
|||
resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35"
|
||||
integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=
|
||||
|
||||
lodash.clonedeep@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
||||
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
|
||||
|
||||
lodash.defaults@^4.0.1, lodash.defaults@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
|
||||
|
@ -6923,11 +6943,6 @@ lodash.sortby@^4.7.0:
|
|||
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
|
||||
|
||||
lodash.truncate@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
|
||||
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
|
||||
|
||||
lodash.uniq@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
|
@ -7560,10 +7575,10 @@ node-releases@^1.1.70, node-releases@^1.1.71:
|
|||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb"
|
||||
integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==
|
||||
|
||||
nodemailer@6.6.5:
|
||||
version "6.6.5"
|
||||
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.6.5.tgz#f9f6953cee5cfe82cbea152eeddacf7a0442049a"
|
||||
integrity sha512-C/v856DBijUzHcHIgGpQoTrfsH3suKIRAGliIzCstatM2cAa+MYX3LuyCrABiO/cdJTxgBBHXxV1ztiqUwst5A==
|
||||
nodemailer@6.7.0:
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.0.tgz#86614722c4e0c33d1b5b02aecb90d6d629932b0d"
|
||||
integrity sha512-AtiTVUFHLiiDnMQ43zi0YgkzHOEWUkhDgPlBXrsDzJiJvB29Alo4OKxHQ0ugF3gRqRQIneCLtZU3yiUo7pItZw==
|
||||
|
||||
nofilter@^2.0.3:
|
||||
version "2.0.3"
|
||||
|
@ -8398,10 +8413,10 @@ postcss-filter-plugins@^2.0.0:
|
|||
dependencies:
|
||||
postcss "^5.0.4"
|
||||
|
||||
postcss-loader@6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.1.1.tgz#58dd0a3accd9bc87cc52eff75244db578d11301a"
|
||||
integrity sha512-lBmJMvRh1D40dqpWKr9Rpygwxn8M74U9uaCSeYGNKLGInbk9mXBt1ultHf2dH9Ghk6Ue4UXlXWwGMH9QdUJ5ug==
|
||||
postcss-loader@6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.0.tgz#714370a3f567141cf4cadcdf9575f5234d186bc5"
|
||||
integrity sha512-H9hv447QjQJVDbHj3OUdciyAXY3v5+UDduzEytAlZCVHCpNAAg/mCSwhYYqZr9BiGYhmYspU8QXxZwiHTLn3yA==
|
||||
dependencies:
|
||||
cosmiconfig "^7.0.0"
|
||||
klona "^2.0.4"
|
||||
|
@ -8911,12 +8926,14 @@ prismjs@1.25.0:
|
|||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756"
|
||||
integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==
|
||||
|
||||
private-ip@2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/private-ip/-/private-ip-2.2.1.tgz#4fe167d04e12eca5c67cdcbd3224e86b38c79253"
|
||||
integrity sha512-jN1WT/br/VNW9xEcwHr6DjtOKxQ5qOIqmh7o+co2TWgq56pZJw99iO3UT1tWdfgsQiyK9FqG4ji3ykwpjFqITA==
|
||||
private-ip@2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/private-ip/-/private-ip-2.3.0.tgz#aa07bf623c60ea75ee5d140814f492648c001717"
|
||||
integrity sha512-3lTFzg+Z1Q2VNQChw8AW2c5LM7getyUJ67SqeWtvnkUO4gihjbf5oIEK4+jAQ4v1sCqOVV7r+GzKrgowW/W3tw==
|
||||
dependencies:
|
||||
ip-regex "^4.3.0"
|
||||
ipaddr.js "^2.0.1"
|
||||
is-ip "^3.1.0"
|
||||
netmask "^2.0.2"
|
||||
|
||||
probe-image-size@7.2.1:
|
||||
|
@ -9411,10 +9428,10 @@ regex-not@^1.0.0, regex-not@^1.0.2:
|
|||
extend-shallow "^3.0.2"
|
||||
safe-regex "^1.1.0"
|
||||
|
||||
regexpp@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
|
||||
integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
|
||||
regexpp@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
|
||||
|
||||
remove-bom-buffer@^3.0.0:
|
||||
version "3.0.0"
|
||||
|
@ -9739,18 +9756,18 @@ safe-regex@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
sass-loader@12.1.0:
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.1.0.tgz#b73324622231009da6fba61ab76013256380d201"
|
||||
integrity sha512-FVJZ9kxVRYNZTIe2xhw93n3xJNYZADr+q69/s98l9nTCrWASo+DR2Ot0s5xTKQDDEosUkatsGeHxcH4QBp5bSg==
|
||||
sass-loader@12.2.0:
|
||||
version "12.2.0"
|
||||
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.2.0.tgz#b370010fb0ababae2ef9c6c89e05d6c6debc6042"
|
||||
integrity sha512-qducnp5vSV+8A8MZxuH6zV0MUg4MOVISScl2wDTCAn/2WJX+9Auxh92O/rnkdR2bvi5QxZBafnzkzRrWGZvm7w==
|
||||
dependencies:
|
||||
klona "^2.0.4"
|
||||
neo-async "^2.6.2"
|
||||
|
||||
sass@1.42.1:
|
||||
version "1.42.1"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.42.1.tgz#5ab17bebc1cb1881ad2e0c9a932c66ad64e441e2"
|
||||
integrity sha512-/zvGoN8B7dspKc5mC6HlaygyCBRvnyzzgD5khiaCfglWztY99cYoiTUksVx11NlnemrcfH5CEaCpsUKoW0cQqg==
|
||||
sass@1.43.2:
|
||||
version "1.43.2"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.43.2.tgz#c02501520c624ad6622529a8b3724eb08da82d65"
|
||||
integrity sha512-DncYhjl3wBaPMMJR0kIUaH3sF536rVrOcqqVGmTZHQRRzj7LQlyGV7Mb8aCKFyILMr5VsPHwRYtyKpnKYlmQSQ==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
|
||||
|
@ -10620,28 +10637,16 @@ syslog-pro@1.0.0:
|
|||
dependencies:
|
||||
moment "^2.22.2"
|
||||
|
||||
systeminformation@5.9.4:
|
||||
version "5.9.4"
|
||||
resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.9.4.tgz#1f0e29e0aa376dec8f69cc517eeefc5cdcda411a"
|
||||
integrity sha512-FOsiTn0CyJZoj9kIhla11ndsMzbbwwuriul81wpqIBt9IpbxHZ6P/oZCphIFgJrwqjTnme0Qp1HDzIkUD9Xr/g==
|
||||
systeminformation@5.9.7:
|
||||
version "5.9.7"
|
||||
resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.9.7.tgz#8a5041d3aa1518e962b17740e20a3c75ff390e6d"
|
||||
integrity sha512-Vcmc8HaWPMFM4DoasuKN2lpvIwS2AqaoPuEGZc4HCT6tlRJH+IQ5GhA2BrUgjpBDJjFMj2Bti6qLOzP3T1arCw==
|
||||
|
||||
syuilo-password-strength@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/syuilo-password-strength/-/syuilo-password-strength-0.0.1.tgz#08f71a8f0ecb77db649f3d9a6424510d9d945f52"
|
||||
integrity sha1-CPcajw7Ld9tknz2aZCRRDZ2UX1I=
|
||||
|
||||
table@^6.0.9:
|
||||
version "6.7.1"
|
||||
resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2"
|
||||
integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==
|
||||
dependencies:
|
||||
ajv "^8.0.1"
|
||||
lodash.clonedeep "^4.5.0"
|
||||
lodash.truncate "^4.4.2"
|
||||
slice-ansi "^4.0.0"
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
tapable@^2.1.1, tapable@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
|
||||
|
@ -10972,12 +10977,12 @@ ts-loader@9.2.6:
|
|||
micromatch "^4.0.0"
|
||||
semver "^7.3.4"
|
||||
|
||||
ts-node@10.2.1:
|
||||
version "10.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.2.1.tgz#4cc93bea0a7aba2179497e65bb08ddfc198b3ab5"
|
||||
integrity sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==
|
||||
ts-node@10.3.0:
|
||||
version "10.3.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.3.0.tgz#a797f2ed3ff50c9a5d814ce400437cb0c1c048b4"
|
||||
integrity sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==
|
||||
dependencies:
|
||||
"@cspotcode/source-map-support" "0.6.1"
|
||||
"@cspotcode/source-map-support" "0.7.0"
|
||||
"@tsconfig/node10" "^1.0.7"
|
||||
"@tsconfig/node12" "^1.0.7"
|
||||
"@tsconfig/node14" "^1.0.0"
|
||||
|
@ -11187,10 +11192,10 @@ typeorm@0.2.38:
|
|||
yargs "^17.0.1"
|
||||
zen-observable-ts "^1.0.0"
|
||||
|
||||
typescript@4.4.3:
|
||||
version "4.4.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324"
|
||||
integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==
|
||||
typescript@4.4.4:
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c"
|
||||
integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==
|
||||
|
||||
uc.micro@^1.0.1, uc.micro@^1.0.5:
|
||||
version "1.0.6"
|
||||
|
@ -11558,16 +11563,16 @@ vue-svg-loader@0.17.0-beta.2:
|
|||
semver "^7.3.2"
|
||||
svgo "^1.3.2"
|
||||
|
||||
vue@3.2.19:
|
||||
version "3.2.19"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.19.tgz#da2c80a6a0271c7097fee9e31692adfd9d569c8f"
|
||||
integrity sha512-6KAMdIfAtlK+qohTIUE4urwAv4A3YRuo8uAbByApUmiB0CziGAAPs6qVugN6oHPia8YIafHB/37K0O6KZ7sGmA==
|
||||
vue@3.2.20:
|
||||
version "3.2.20"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.20.tgz#940f8aa8bf3e3be78243ca582bad41fcd45ae3e6"
|
||||
integrity sha512-81JjEP4OGk9oO8+CU0h2nFPGgJBm9mNa3kdCX2k6FuRdrWrC+CNe+tOnuIeTg8EWwQuI+wwdra5Q7vSzp7p4Iw==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.2.19"
|
||||
"@vue/compiler-sfc" "3.2.19"
|
||||
"@vue/runtime-dom" "3.2.19"
|
||||
"@vue/server-renderer" "3.2.19"
|
||||
"@vue/shared" "3.2.19"
|
||||
"@vue/compiler-dom" "3.2.20"
|
||||
"@vue/compiler-sfc" "3.2.20"
|
||||
"@vue/runtime-dom" "3.2.20"
|
||||
"@vue/server-renderer" "3.2.20"
|
||||
"@vue/shared" "3.2.20"
|
||||
|
||||
vuedraggable@4.0.1:
|
||||
version "4.0.1"
|
||||
|
@ -11679,10 +11684,10 @@ webpack-sources@^3.2.0:
|
|||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.0.tgz#b16973bcf844ebcdb3afde32eda1c04d0b90f89d"
|
||||
integrity sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw==
|
||||
|
||||
webpack@5.58.0:
|
||||
version "5.58.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.58.0.tgz#9ec621cf8534f23c25e779e7c35dfde1211d5ccb"
|
||||
integrity sha512-xc2k5MLbR1iah24Z5xUm1nBh1PZXEdUnrX6YkTSOScq/VWbl5JCLREXJzGYqEAUbIO8tZI+Dzv82lGtnuUnVCQ==
|
||||
webpack@5.58.2:
|
||||
version "5.58.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.58.2.tgz#6b4af12fc9bd5cbedc00dc0a2fc2b9592db16b44"
|
||||
integrity sha512-3S6e9Vo1W2ijk4F4PPWRIu6D/uGgqaPmqw+av3W3jLDujuNkdxX5h5c+RQ6GkjVR+WwIPOfgY8av+j5j4tMqJw==
|
||||
dependencies:
|
||||
"@types/eslint-scope" "^3.7.0"
|
||||
"@types/estree" "^0.0.50"
|
||||
|
|
Loading…
Reference in a new issue