Merge branch 'misskey-dev:develop' into sonic
This commit is contained in:
commit
0805cb281d
59 changed files with 1394 additions and 355 deletions
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
|
@ -16,7 +16,7 @@ jobs:
|
||||||
submodules: true
|
submodules: true
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 12.x
|
node-version: 16.x
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: '**/node_modules'
|
path: '**/node_modules'
|
||||||
|
|
29
CHANGELOG.md
29
CHANGELOG.md
|
@ -10,15 +10,34 @@
|
||||||
You should also include the user name that made the change.
|
You should also include the user name that made the change.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## 12.x.x (unreleased)
|
## 12.109.1 (2022/04/02)
|
||||||
|
|
||||||
### Improvements
|
### Known issues
|
||||||
- Bull Dashboardを組み込み、ジョブキューの確認や操作を行えるように @syuilo
|
- two-factor authentication is not working
|
||||||
- Check that installed Node.js version fulfills version requirement @ThatOneCalculator
|
|
||||||
- Server: performance improvements @syuilo
|
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
- API: Renoteが行えない問題を修正
|
||||||
|
|
||||||
|
## 12.109.0 (2022/04/02)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- Webhooks @syuilo
|
||||||
|
- Bull Dashboardを組み込み、ジョブキューの確認や操作を行えるように @syuilo
|
||||||
|
- Bull Dashboardを開くには、最初だけ一旦ログアウトしてから再度管理者権限を持つアカウントでログインする必要があります
|
||||||
|
- Check that installed Node.js version fulfills version requirement @ThatOneCalculator
|
||||||
|
- Server: overall performance improvements @syuilo
|
||||||
|
- Federation: avoid duplicate activity delivery @Johann150
|
||||||
|
- Federation: limit federation of reactions on direct notes @Johann150
|
||||||
|
- Client: タッチパッド・タッチスクリーンでのデッキの操作性を向上 @tamaina
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- email address validation was not working @ybw2016v
|
||||||
- API: fix endpoint endpoint @Johann150
|
- API: fix endpoint endpoint @Johann150
|
||||||
|
- API: fix admin/meta endpoint @syuilo
|
||||||
|
- API: improved validation and documentation for endpoints that accept different variants of input @Johann150
|
||||||
|
- API: `notes/create`: The `mediaIds` property is now deprecated. @Johann150
|
||||||
|
- Use `fileIds` instead, it has the same behaviour.
|
||||||
|
- Client: URIエンコーディングが異常でdecodeURIComponentが失敗するとURLが表示できなくなる問題を修正 @tamaina
|
||||||
|
|
||||||
## 12.108.1 (2022/03/12)
|
## 12.108.1 (2022/03/12)
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@ Also, you might receive comments on your Issue/PR in Japanese, but you do not ne
|
||||||
The accuracy of machine translation into Japanese is not high, so it will be easier for us to understand if you write it in the original language.
|
The accuracy of machine translation into Japanese is not high, so it will be easier for us to understand if you write it in the original language.
|
||||||
It will also allow the reader to use the translation tool of their preference if necessary.
|
It will also allow the reader to use the translation tool of their preference if necessary.
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
See [ROADMAP.md](./ROADMAP.md)
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
Before creating an issue, please check the following:
|
Before creating an issue, please check the following:
|
||||||
- To avoid duplication, please search for similar issues before creating a new issue.
|
- To avoid duplication, please search for similar issues before creating a new issue.
|
||||||
|
|
36
ROADMAP.md
Normal file
36
ROADMAP.md
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Roadmap
|
||||||
|
The order of individual tasks is a guide only and is subject to change depending on the situation.
|
||||||
|
Also, the later tasks are more indefinite and are subject to change as development progresses.
|
||||||
|
|
||||||
|
## (1) Improve maintainability \<current phase\>
|
||||||
|
This is the phase we are at now. We need to make a high-maintenance environment that can withstand future development.
|
||||||
|
|
||||||
|
- Make the number of type errors zero (backend)
|
||||||
|
- Probably need to switch some libraries to others that make it difficult to reduce type errors
|
||||||
|
- e.g. koa to fastify https://github.com/misskey-dev/misskey/issues/7537
|
||||||
|
- Improve CI
|
||||||
|
- Fix tests
|
||||||
|
- mocha, jest, etc. do not support the combination of `TypeScript + ESM + Path alias`, and the tests currently do not work.
|
||||||
|
- Fix random test failures - https://github.com/misskey-dev/misskey/issues/7985 and https://github.com/misskey-dev/misskey/issues/7986
|
||||||
|
- Add more tests
|
||||||
|
- May need to implement a mechanism that allows for DI
|
||||||
|
- Improve documentation
|
||||||
|
|
||||||
|
## (2) Improve functionality
|
||||||
|
Once Phase 1 is complete and an environment conducive to the development of a stable system is in place, the implementation of new functions can begin gradually.
|
||||||
|
|
||||||
|
- OAuth2 support https://github.com/misskey-dev/misskey/issues/8262
|
||||||
|
- GraphQL support?
|
||||||
|
|
||||||
|
## (3) Improve scalability
|
||||||
|
Once the development of the feature has settled down, this may be an opportunity to make larger modifications.
|
||||||
|
|
||||||
|
- Rewriting in Rust?
|
||||||
|
|
||||||
|
## (4) Change the world
|
||||||
|
It is time to promote Misskey and change the world.
|
||||||
|
|
||||||
|
- Become more major than services such as Twitter and become critical infrastructure for the world
|
||||||
|
- MiOS will be developed and integrated into various systems - What is MiOS?
|
||||||
|
- Letting Ai-chan interfere with the real world
|
||||||
|
- Make Misskey a member of GAFA; Misskey's office must be a reinforced concrete brutalist building with a courtyard.
|
|
@ -189,7 +189,7 @@ clearCachedFiles: "امسح التخزين المؤقت"
|
||||||
clearCachedFilesConfirm: "أتريد حذف التخزين المؤقت للملفات البعيدة؟"
|
clearCachedFilesConfirm: "أتريد حذف التخزين المؤقت للملفات البعيدة؟"
|
||||||
blockedInstances: "المثلاء المحجوبون"
|
blockedInstances: "المثلاء المحجوبون"
|
||||||
blockedInstancesDescription: "قائمة بالمثلاء التي تريد حظرها بحيث كل نطاق في سطر لوحده. بعد إدراجهم لن يتمكنوا من التفاعل مع هذا المثيل."
|
blockedInstancesDescription: "قائمة بالمثلاء التي تريد حظرها بحيث كل نطاق في سطر لوحده. بعد إدراجهم لن يتمكنوا من التفاعل مع هذا المثيل."
|
||||||
muteAndBlock: "تم كتمها / تم حجبها"
|
muteAndBlock: "المكتومون والمحجوبون"
|
||||||
mutedUsers: "الحسابات المكتومة"
|
mutedUsers: "الحسابات المكتومة"
|
||||||
blockedUsers: "الحسابات المحجوبة"
|
blockedUsers: "الحسابات المحجوبة"
|
||||||
noUsers: "ليس هناك مستخدمون"
|
noUsers: "ليس هناك مستخدمون"
|
||||||
|
@ -490,7 +490,7 @@ none: "لا شيء"
|
||||||
showInPage: "اعرض في الصفحة"
|
showInPage: "اعرض في الصفحة"
|
||||||
popout: "منبثقة"
|
popout: "منبثقة"
|
||||||
volume: "مستوى الصوت"
|
volume: "مستوى الصوت"
|
||||||
masterVolume: "القرص الرئيسي"
|
masterVolume: "حجم الصوت الرئيس"
|
||||||
details: "التفاصيل"
|
details: "التفاصيل"
|
||||||
chooseEmoji: "اختر إيموجي"
|
chooseEmoji: "اختر إيموجي"
|
||||||
unableToProcess: "يتعذر إكمال العملية"
|
unableToProcess: "يتعذر إكمال العملية"
|
||||||
|
@ -521,6 +521,7 @@ divider: "فاصل"
|
||||||
addItem: "إضافة عنصر"
|
addItem: "إضافة عنصر"
|
||||||
relays: "المُرَحلات"
|
relays: "المُرَحلات"
|
||||||
addRelay: "إضافة مُرحّل"
|
addRelay: "إضافة مُرحّل"
|
||||||
|
inboxUrl: "رابط صندوق الوارد"
|
||||||
addedRelays: "المرحلات المضافة"
|
addedRelays: "المرحلات المضافة"
|
||||||
serviceworkerInfo: "يجب أن يفعل لإرسال الإشعارات."
|
serviceworkerInfo: "يجب أن يفعل لإرسال الإشعارات."
|
||||||
deletedNote: "ملاحظة محذوفة"
|
deletedNote: "ملاحظة محذوفة"
|
||||||
|
@ -533,6 +534,8 @@ enablePlayer: "افتح مشغل الفيديو"
|
||||||
disablePlayer: "أغلق مشغل الفيديو"
|
disablePlayer: "أغلق مشغل الفيديو"
|
||||||
themeEditor: "مصمم القوالب"
|
themeEditor: "مصمم القوالب"
|
||||||
description: "الوصف"
|
description: "الوصف"
|
||||||
|
describeFile: "أضف تعليقًا توضيحيًا"
|
||||||
|
enterFileDescription: "أدخل تعليقًا توضيحيًا"
|
||||||
author: "الكاتب"
|
author: "الكاتب"
|
||||||
leaveConfirm: "لديك تغييرات غير محفوظة. أتريد المتابعة دون حفظها؟"
|
leaveConfirm: "لديك تغييرات غير محفوظة. أتريد المتابعة دون حفظها؟"
|
||||||
manage: "إدارة "
|
manage: "إدارة "
|
||||||
|
@ -564,6 +567,9 @@ smtpPass: "الكلمة السرية"
|
||||||
emptyToDisableSmtpAuth: "اترك اسم المستخدم وكلمة المرور فارغين لتعطيل التحقق من SMTP"
|
emptyToDisableSmtpAuth: "اترك اسم المستخدم وكلمة المرور فارغين لتعطيل التحقق من SMTP"
|
||||||
smtpSecureInfo: "عطل هذا الخيار عند استخدام STARTTLS"
|
smtpSecureInfo: "عطل هذا الخيار عند استخدام STARTTLS"
|
||||||
wordMute: "حظر الكلمات"
|
wordMute: "حظر الكلمات"
|
||||||
|
regexpError: "خطأ في التعبير النمطي"
|
||||||
|
instanceMute: "المثلاء المكتومون"
|
||||||
|
userSaysSomething: "كتب {name} شيءً"
|
||||||
makeActive: "تفعيل"
|
makeActive: "تفعيل"
|
||||||
display: "المظهر"
|
display: "المظهر"
|
||||||
copy: "نسخ"
|
copy: "نسخ"
|
||||||
|
@ -590,10 +596,16 @@ reportAbuse: "أبلغ"
|
||||||
reportAbuseOf: "أبلغ عن {name}"
|
reportAbuseOf: "أبلغ عن {name}"
|
||||||
fillAbuseReportDescription: "أكتب بالتفصيل سبب البلاغ، إذا كنت تبلغ عن ملاحظة أرفق رابط لها."
|
fillAbuseReportDescription: "أكتب بالتفصيل سبب البلاغ، إذا كنت تبلغ عن ملاحظة أرفق رابط لها."
|
||||||
abuseReported: "أُرسل البلاغ، شكرًا لك"
|
abuseReported: "أُرسل البلاغ، شكرًا لك"
|
||||||
|
reporter: "المُبلّغ"
|
||||||
|
reporteeOrigin: "أصل البلاغ"
|
||||||
|
reporterOrigin: "أصل المُبلّغ"
|
||||||
|
forwardReport: "وجّه البلاغ إلى المثيل البعيد"
|
||||||
|
forwardReportIsAnonymous: "في المثيل البعيد سيظهر المبلّغ كحساب مجهول."
|
||||||
send: "أرسل"
|
send: "أرسل"
|
||||||
abuseMarkAsResolved: "علّم البلاغ كمحلول"
|
abuseMarkAsResolved: "علّم البلاغ كمحلول"
|
||||||
openInNewTab: "افتح في لسان جديد"
|
openInNewTab: "افتح في لسان جديد"
|
||||||
defaultNavigationBehaviour: "سلوك الملاحة الافتراضي"
|
defaultNavigationBehaviour: "سلوك الملاحة الافتراضي"
|
||||||
|
editTheseSettingsMayBreakAccount: "تعديل هذه الإعدادات قد يسبب عطبًا لحسابك"
|
||||||
instanceTicker: "معلومات المثيل الأصلي للملاحظات"
|
instanceTicker: "معلومات المثيل الأصلي للملاحظات"
|
||||||
waitingFor: "في انتظار {x}"
|
waitingFor: "في انتظار {x}"
|
||||||
random: "عشوائي"
|
random: "عشوائي"
|
||||||
|
@ -624,10 +636,15 @@ no: "لا"
|
||||||
driveFilesCount: "عدد الملفات في قرص التخزين"
|
driveFilesCount: "عدد الملفات في قرص التخزين"
|
||||||
driveUsage: "المستغل من قرص التخزين"
|
driveUsage: "المستغل من قرص التخزين"
|
||||||
noCrawleDescription: "يطلب من محركات البحث ألّا يُفهرسوا ملفك الشخصي وملاحظات وصفحاتك وما شابه."
|
noCrawleDescription: "يطلب من محركات البحث ألّا يُفهرسوا ملفك الشخصي وملاحظات وصفحاتك وما شابه."
|
||||||
|
alwaysMarkSensitive: "علّم افتراضيًا جميع ملاحظاتي كذات محتوى حساس"
|
||||||
|
loadRawImages: "حمّل الصور الأصلية بدلًا من المصغرات"
|
||||||
disableShowingAnimatedImages: "لا تشغّل الصور المتحركة"
|
disableShowingAnimatedImages: "لا تشغّل الصور المتحركة"
|
||||||
|
verificationEmailSent: "أُرسل بريد التحقق. أنقر على الرابط المضمن لإكمال التحقق."
|
||||||
notSet: "لم يعيّن"
|
notSet: "لم يعيّن"
|
||||||
emailVerified: "تُحقّق من بريدك الإلكتروني"
|
emailVerified: "تُحقّق من بريدك الإلكتروني"
|
||||||
noteFavoritesCount: "عدد الملاحظات المفضلة"
|
noteFavoritesCount: "عدد الملاحظات المفضلة"
|
||||||
|
pageLikesCount: "عدد الصفحات التي أعجبت بها"
|
||||||
|
pageLikedCount: "عدد صفحاتك المُعجب بها"
|
||||||
contact: "التواصل"
|
contact: "التواصل"
|
||||||
useSystemFont: "استخدم الخط الافتراضية للنظام"
|
useSystemFont: "استخدم الخط الافتراضية للنظام"
|
||||||
clips: "مشابك"
|
clips: "مشابك"
|
||||||
|
@ -635,6 +652,7 @@ experimentalFeatures: "ميّزات اختبارية"
|
||||||
developer: "المطور"
|
developer: "المطور"
|
||||||
makeExplorable: "أظهر الحساب في صفحة \"استكشاف\""
|
makeExplorable: "أظهر الحساب في صفحة \"استكشاف\""
|
||||||
makeExplorableDescription: "بتعطيل هذا الخيار لن يظهر حسابك في صفحة \"استكشاف\""
|
makeExplorableDescription: "بتعطيل هذا الخيار لن يظهر حسابك في صفحة \"استكشاف\""
|
||||||
|
showGapBetweenNotesInTimeline: "أظهر فجوات بين المشاركات في الخيط الزمني"
|
||||||
wide: "عريض"
|
wide: "عريض"
|
||||||
narrow: "رفيع"
|
narrow: "رفيع"
|
||||||
reloadToApplySetting: "سيُطبق هذا الإعداد بعد إعادة تحميل الصفحة، أتريد إعادة تحميلها الآن؟"
|
reloadToApplySetting: "سيُطبق هذا الإعداد بعد إعادة تحميل الصفحة، أتريد إعادة تحميلها الآن؟"
|
||||||
|
@ -782,6 +800,7 @@ tenMinutes: "10 دقائق"
|
||||||
oneHour: "ساعة"
|
oneHour: "ساعة"
|
||||||
oneDay: "يوم"
|
oneDay: "يوم"
|
||||||
oneWeek: "أسبوع"
|
oneWeek: "أسبوع"
|
||||||
|
failedToFetchAccountInformation: "تعذر جلب معلومات الحساب"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "هذا البريد الإلكتروني مستخدم"
|
used: "هذا البريد الإلكتروني مستخدم"
|
||||||
format: "صيغة البريد الإلكتروني غير صالحة"
|
format: "صيغة البريد الإلكتروني غير صالحة"
|
||||||
|
@ -860,6 +879,7 @@ _mfm:
|
||||||
centerDescription: "يمركز المحتوى في الوَسَط."
|
centerDescription: "يمركز المحتوى في الوَسَط."
|
||||||
quote: "اقتبس"
|
quote: "اقتبس"
|
||||||
emoji: "إيموجي مخصص"
|
emoji: "إيموجي مخصص"
|
||||||
|
emojiDescription: "إحاطة اسم الإيموجي بنقطتي تفسير سيستبدله بصورة الإيموجي."
|
||||||
search: "البحث"
|
search: "البحث"
|
||||||
flip: "اقلب"
|
flip: "اقلب"
|
||||||
flipDescription: "يقلب المحتوى عموديًا أو أفقيًا"
|
flipDescription: "يقلب المحتوى عموديًا أو أفقيًا"
|
||||||
|
@ -871,15 +891,27 @@ _mfm:
|
||||||
jumpDescription: "يمنح للمحتوى حركة قفز."
|
jumpDescription: "يمنح للمحتوى حركة قفز."
|
||||||
bounce: "تأثير (ارتداد)"
|
bounce: "تأثير (ارتداد)"
|
||||||
bounceDescription: "يمنح للمحتوى حركة ارتدادية"
|
bounceDescription: "يمنح للمحتوى حركة ارتدادية"
|
||||||
|
shake: "تأثير (اهتزاز)"
|
||||||
|
shakeDescription: "يمنح المحتوى حركة اهتزازية."
|
||||||
|
spin: "تأثير (دوران)"
|
||||||
|
spinDescription: "يمنح المحتوى حركة دورانية."
|
||||||
x2: "كبير"
|
x2: "كبير"
|
||||||
|
x2Description: "يُكبر المحتوى"
|
||||||
x3: "كبير جداً"
|
x3: "كبير جداً"
|
||||||
|
x3Description: "يُضخم المحتوى"
|
||||||
|
x4: "هائل"
|
||||||
|
x4Description: "يُضخم المحتوى أكثر مما سبق."
|
||||||
blur: "طمس"
|
blur: "طمس"
|
||||||
|
blurDescription: "يطمس المحتوى، لكن بالتمرير فوقه سيظهر بوضوح."
|
||||||
font: "الخط"
|
font: "الخط"
|
||||||
|
fontDescription: "الخط المستخدم لعرض المحتوى."
|
||||||
rainbow: "قوس قزح"
|
rainbow: "قوس قزح"
|
||||||
rainbowDescription: "اجعل المحتوى يظهر بألوان الطيف"
|
rainbowDescription: "اجعل المحتوى يظهر بألوان الطيف"
|
||||||
rotate: "تدوير"
|
rotate: "تدوير"
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
|
none: "لا تظهره بتاتًا"
|
||||||
remote: "أظهر للمستخدمين البِعاد"
|
remote: "أظهر للمستخدمين البِعاد"
|
||||||
|
always: "أظهره دائمًا"
|
||||||
_serverDisconnectedBehavior:
|
_serverDisconnectedBehavior:
|
||||||
reload: "إعادة تحميل تلقائية"
|
reload: "إعادة تحميل تلقائية"
|
||||||
dialog: "أظهر مربع حوار التحذيرات"
|
dialog: "أظهر مربع حوار التحذيرات"
|
||||||
|
@ -899,12 +931,18 @@ _menuDisplay:
|
||||||
hide: "إخفاء"
|
hide: "إخفاء"
|
||||||
_wordMute:
|
_wordMute:
|
||||||
muteWords: "الكلمات المحظورة"
|
muteWords: "الكلمات المحظورة"
|
||||||
|
muteWordsDescription: "افصل بينهم بمسافة لاستخدام معامل \"و\" أو بسطر لاستخدام معامل \"أو\"."
|
||||||
muteWordsDescription2: "احصر الكلمات المفتاحية بين بين شرطتين مائلتين لاستخدامها كتعابير نمطية"
|
muteWordsDescription2: "احصر الكلمات المفتاحية بين بين شرطتين مائلتين لاستخدامها كتعابير نمطية"
|
||||||
softDescription: "اخف الملاحظات التي تستوف الشروط من الخيط الزمني."
|
softDescription: "اخف الملاحظات التي تستوف الشروط من الخيط الزمني."
|
||||||
hardDescription: "اخف الملاحظات التي تستوف الشروط من الخيط الزمني.بالإضافة إلى أن هذه الملاحظات ستبقى مخفية حتى وإن تغيرت الشروط."
|
hardDescription: "اخف الملاحظات التي تستوف الشروط من الخيط الزمني.بالإضافة إلى أن هذه الملاحظات ستبقى مخفية حتى وإن تغيرت الشروط."
|
||||||
soft: "لينة"
|
soft: "لينة"
|
||||||
hard: "قاسية"
|
hard: "قاسية"
|
||||||
mutedNotes: "الملاحظات المكتومة"
|
mutedNotes: "الملاحظات المكتومة"
|
||||||
|
_instanceMute:
|
||||||
|
instanceMuteDescription: "هذه سيحجب كل ملاحظات الخوادم المحجوبة ومشاركاتها والردود على تلك الملاحظات حتى وإن كانت من خادم غير محجوب."
|
||||||
|
instanceMuteDescription2: "مدخلة لكل سطر"
|
||||||
|
title: "يخفي ملاحظات الخوادم المسرودة."
|
||||||
|
heading: "قائمة الخوادم المحجوبة"
|
||||||
_theme:
|
_theme:
|
||||||
explore: "استكشف قوالب المظهر"
|
explore: "استكشف قوالب المظهر"
|
||||||
install: "تنصيب قالب"
|
install: "تنصيب قالب"
|
||||||
|
|
|
@ -478,8 +478,8 @@ promote: "Werbung schalten"
|
||||||
numberOfDays: "Anzahl der Tage"
|
numberOfDays: "Anzahl der Tage"
|
||||||
hideThisNote: "Diese Notiz verstecken"
|
hideThisNote: "Diese Notiz verstecken"
|
||||||
showFeaturedNotesInTimeline: "Beliebte Notizen in der Chronik anzeigen"
|
showFeaturedNotesInTimeline: "Beliebte Notizen in der Chronik anzeigen"
|
||||||
objectStorage: "Objektspeicher"
|
objectStorage: "Object Storage"
|
||||||
useObjectStorage: "Objektspeicher verwenden"
|
useObjectStorage: "Object Storage verwenden"
|
||||||
objectStorageBaseUrl: "Basis-URL"
|
objectStorageBaseUrl: "Basis-URL"
|
||||||
objectStorageBaseUrlDesc: "Die als Referenz verwendete URL. Verwendest du einen CDN oder Proxy, gib dessen URL an. Für S3 verwende 'https://<bucket>.s3.amazonaws.com'. Für GCS o.ä. verwende 'https://storage.googleapis.com/<bucket>'."
|
objectStorageBaseUrlDesc: "Die als Referenz verwendete URL. Verwendest du einen CDN oder Proxy, gib dessen URL an. Für S3 verwende 'https://<bucket>.s3.amazonaws.com'. Für GCS o.ä. verwende 'https://storage.googleapis.com/<bucket>'."
|
||||||
objectStorageBucket: "Bucket"
|
objectStorageBucket: "Bucket"
|
||||||
|
@ -827,7 +827,7 @@ overridedDeviceKind: "Gerätetyp"
|
||||||
smartphone: "Smartphone"
|
smartphone: "Smartphone"
|
||||||
tablet: "Tablet"
|
tablet: "Tablet"
|
||||||
auto: "Automatisch"
|
auto: "Automatisch"
|
||||||
themeColor: "Instanzfarbe"
|
themeColor: "Farbe der Instanz-Information"
|
||||||
size: "Größe"
|
size: "Größe"
|
||||||
numberOfColumn: "Spaltenanzahl"
|
numberOfColumn: "Spaltenanzahl"
|
||||||
searchByGoogle: "Googlen"
|
searchByGoogle: "Googlen"
|
||||||
|
@ -840,6 +840,8 @@ tenMinutes: "10 Minuten"
|
||||||
oneHour: "Eine Stunde"
|
oneHour: "Eine Stunde"
|
||||||
oneDay: "Einen Tag"
|
oneDay: "Einen Tag"
|
||||||
oneWeek: "Eine Woche"
|
oneWeek: "Eine Woche"
|
||||||
|
reflectMayTakeTime: "Es kann etwas dauern, bis sich dies widerspiegelt."
|
||||||
|
failedToFetchAccountInformation: "Benutzerkontoinformationen konnten nicht abgefragt werden"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Diese Email-Adresse wird bereits verwendet"
|
used: "Diese Email-Adresse wird bereits verwendet"
|
||||||
format: "Das Format dieser Email-Adresse ist ungültig"
|
format: "Das Format dieser Email-Adresse ist ungültig"
|
||||||
|
|
|
@ -827,7 +827,7 @@ overridedDeviceKind: "Device type"
|
||||||
smartphone: "Smartphone"
|
smartphone: "Smartphone"
|
||||||
tablet: "Tablet"
|
tablet: "Tablet"
|
||||||
auto: "Auto"
|
auto: "Auto"
|
||||||
themeColor: "Theme Color"
|
themeColor: "Instance Ticker Color"
|
||||||
size: "Size"
|
size: "Size"
|
||||||
numberOfColumn: "Number of columns"
|
numberOfColumn: "Number of columns"
|
||||||
searchByGoogle: "Google"
|
searchByGoogle: "Google"
|
||||||
|
@ -840,6 +840,8 @@ tenMinutes: "10 minutes"
|
||||||
oneHour: "One hour"
|
oneHour: "One hour"
|
||||||
oneDay: "One day"
|
oneDay: "One day"
|
||||||
oneWeek: "One week"
|
oneWeek: "One week"
|
||||||
|
reflectMayTakeTime: "It may take some time for this to be reflected."
|
||||||
|
failedToFetchAccountInformation: "Could not fetch account information"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "This email address is already being used"
|
used: "This email address is already being used"
|
||||||
format: "The format of this email address is invalid"
|
format: "The format of this email address is invalid"
|
||||||
|
|
|
@ -7,7 +7,7 @@ search: "Serĉi"
|
||||||
notifications: "Sciigoj"
|
notifications: "Sciigoj"
|
||||||
username: "Uzantnomo"
|
username: "Uzantnomo"
|
||||||
password: "Pasvorto"
|
password: "Pasvorto"
|
||||||
forgotPassword: "Ĉu vi forgesis pasvorton?"
|
forgotPassword: "Ĉu vi forgesis vian pasvorton?"
|
||||||
fetchingAsApObject: "Informpetado de la Fediverso…"
|
fetchingAsApObject: "Informpetado de la Fediverso…"
|
||||||
ok: "Okej"
|
ok: "Okej"
|
||||||
gotIt: "Kompreni"
|
gotIt: "Kompreni"
|
||||||
|
@ -71,7 +71,7 @@ lists: "Listoj"
|
||||||
noLists: "Neniu listo"
|
noLists: "Neniu listo"
|
||||||
note: "Noti"
|
note: "Noti"
|
||||||
notes: "Notoj"
|
notes: "Notoj"
|
||||||
following: "Sekvatoj"
|
following: "Sekvi"
|
||||||
followers: "Sekvantoj"
|
followers: "Sekvantoj"
|
||||||
followsYou: "Sekvas vin"
|
followsYou: "Sekvas vin"
|
||||||
createList: "Krei liston"
|
createList: "Krei liston"
|
||||||
|
@ -138,7 +138,7 @@ cacheRemoteFiles: "Stapli forajn dosierojn"
|
||||||
flagAsBot: "Marki kiel esti uzanto de roboto"
|
flagAsBot: "Marki kiel esti uzanto de roboto"
|
||||||
flagAsCat: "Marki kiel esti kato"
|
flagAsCat: "Marki kiel esti kato"
|
||||||
flagAsCatDescription: "Flagu por montri ke la konton havas kato."
|
flagAsCatDescription: "Flagu por montri ke la konton havas kato."
|
||||||
flagShowTimelineReplies: "Montri respondon de notoj en templinio."
|
flagShowTimelineReplies: "Montri la respondojn en la templinio"
|
||||||
autoAcceptFollowed: "Aŭtomate akcepti la peton de sekvado far uzantoj kiujn vi sekvas"
|
autoAcceptFollowed: "Aŭtomate akcepti la peton de sekvado far uzantoj kiujn vi sekvas"
|
||||||
addAccount: "Aldoni konton"
|
addAccount: "Aldoni konton"
|
||||||
loginFailed: "Saluto malsukcesis"
|
loginFailed: "Saluto malsukcesis"
|
||||||
|
@ -239,7 +239,7 @@ agreeTo: "Mi akceptas {0}"
|
||||||
tos: "Kondiĉoj de uzado"
|
tos: "Kondiĉoj de uzado"
|
||||||
start: "Komenciĝi"
|
start: "Komenciĝi"
|
||||||
home: "Hejma"
|
home: "Hejma"
|
||||||
remoteUserCaution: "Pro fora uzanto, la infomoj ne estas tuto."
|
remoteUserCaution: "La informoj eblas nekompletaj ĉar estas fora uzanto."
|
||||||
activity: "Aktiveco"
|
activity: "Aktiveco"
|
||||||
images: "Bildoj"
|
images: "Bildoj"
|
||||||
birthday: "Naskiĝdato"
|
birthday: "Naskiĝdato"
|
||||||
|
@ -412,7 +412,7 @@ usernameInvalidFormat: "La uzantnomo povas enhavi minusklajn kaj majusklajn lite
|
||||||
tooShort: "Tro mallonga"
|
tooShort: "Tro mallonga"
|
||||||
tooLong: "Tro longa"
|
tooLong: "Tro longa"
|
||||||
weakPassword: "Malforta pasvorto"
|
weakPassword: "Malforta pasvorto"
|
||||||
normalPassword: "Normala pasvorto"
|
normalPassword: "Meza pasvorto"
|
||||||
strongPassword: "Forta pasvorto"
|
strongPassword: "Forta pasvorto"
|
||||||
passwordMatched: "Konforma"
|
passwordMatched: "Konforma"
|
||||||
passwordNotMatched: "Nekonforma"
|
passwordNotMatched: "Nekonforma"
|
||||||
|
@ -493,11 +493,11 @@ deletedNote: "Forviŝita noto"
|
||||||
invisibleNote: "Malpublikigita noto"
|
invisibleNote: "Malpublikigita noto"
|
||||||
enableInfiniteScroll: "Ebligi infinitan rulumon"
|
enableInfiniteScroll: "Ebligi infinitan rulumon"
|
||||||
visibility: "Videbleco"
|
visibility: "Videbleco"
|
||||||
poll: "Enketo"
|
poll: "Balot-enketo"
|
||||||
useCw: "Kaŝi enhavo"
|
useCw: "Kaŝi enhavo"
|
||||||
enablePlayer: "Vidigi la filmeton"
|
enablePlayer: "Vidigi la filmeton"
|
||||||
disablePlayer: "Malfermi la filmeton"
|
disablePlayer: "Malfermi la filmeton"
|
||||||
expandTweet: "Disvolvi pepon"
|
expandTweet: "Disvolvi la pepon"
|
||||||
themeEditor: "Redaktilo de koloraroj"
|
themeEditor: "Redaktilo de koloraroj"
|
||||||
description: "Priskribo"
|
description: "Priskribo"
|
||||||
describeFile: "Priskribi la bildon"
|
describeFile: "Priskribi la bildon"
|
||||||
|
@ -506,7 +506,7 @@ author: "Aŭtoro"
|
||||||
manage: "Bonteni"
|
manage: "Bonteni"
|
||||||
plugins: "Kromaĵoj"
|
plugins: "Kromaĵoj"
|
||||||
deck: "Kartaro"
|
deck: "Kartaro"
|
||||||
useFullReactionPicker: "Uzi la tuton de la elektilon de reagoj"
|
useFullReactionPicker: "Uzi la tuton de la elektilo de reagoj"
|
||||||
width: "Larĝeco"
|
width: "Larĝeco"
|
||||||
height: "Alteco"
|
height: "Alteco"
|
||||||
large: "Granda"
|
large: "Granda"
|
||||||
|
@ -530,6 +530,7 @@ smtpPort: "Pordo"
|
||||||
smtpUser: "Uzantnomo"
|
smtpUser: "Uzantnomo"
|
||||||
smtpPass: "Pasvorto"
|
smtpPass: "Pasvorto"
|
||||||
wordMute: "Silentigi specifajn vortojn"
|
wordMute: "Silentigi specifajn vortojn"
|
||||||
|
instanceMute: "Nodoj silentigitaj"
|
||||||
userSaysSomething: "{name} diras ion"
|
userSaysSomething: "{name} diras ion"
|
||||||
makeActive: "Aktivigi"
|
makeActive: "Aktivigi"
|
||||||
display: "Vidi"
|
display: "Vidi"
|
||||||
|
@ -548,7 +549,11 @@ regenerateLoginToken: "Regeneri la aŭtentikigan pecon"
|
||||||
fileIdOrUrl: "Dosiera identigilo aŭ URL"
|
fileIdOrUrl: "Dosiera identigilo aŭ URL"
|
||||||
behavior: "Konduto"
|
behavior: "Konduto"
|
||||||
sample: "Ekzemplo"
|
sample: "Ekzemplo"
|
||||||
|
abuseReports: "Raportoj"
|
||||||
|
reportAbuse: "Raportoj"
|
||||||
|
reportAbuseOf: "raporti {name}n"
|
||||||
reporter: "Informanto"
|
reporter: "Informanto"
|
||||||
|
reporterOrigin: "Raportanto"
|
||||||
send: "Sendi"
|
send: "Sendi"
|
||||||
openInNewTab: "Malfermi en nova langeto"
|
openInNewTab: "Malfermi en nova langeto"
|
||||||
editTheseSettingsMayBreakAccount: "Redakti tiujn agordojn povas damaĝi vian konton."
|
editTheseSettingsMayBreakAccount: "Redakti tiujn agordojn povas damaĝi vian konton."
|
||||||
|
@ -634,6 +639,7 @@ offline: "Forkonektita"
|
||||||
notRecommended: "Evitindaj"
|
notRecommended: "Evitindaj"
|
||||||
instanceBlocking: "Bloki specifajn nodojn"
|
instanceBlocking: "Bloki specifajn nodojn"
|
||||||
selectAccount: "Elekti konton"
|
selectAccount: "Elekti konton"
|
||||||
|
switchAccount: "Ŝanĝi konton"
|
||||||
user: "Uzantoj"
|
user: "Uzantoj"
|
||||||
administration: "Bontenado"
|
administration: "Bontenado"
|
||||||
accounts: "Kontoj"
|
accounts: "Kontoj"
|
||||||
|
@ -644,6 +650,7 @@ shareWithNote: "Kundividi en noto"
|
||||||
ads: "Reklamaĵo"
|
ads: "Reklamaĵo"
|
||||||
expiration: "Limtempo"
|
expiration: "Limtempo"
|
||||||
memo: "Memorigilo"
|
memo: "Memorigilo"
|
||||||
|
priority: "Prioritato"
|
||||||
high: "Alta"
|
high: "Alta"
|
||||||
middle: "Meza"
|
middle: "Meza"
|
||||||
low: "Malalta"
|
low: "Malalta"
|
||||||
|
@ -677,6 +684,7 @@ unmuteThread: "Malsilentigi la mesaĝaron"
|
||||||
ffVisibility: "Videbleco de viaj sekvatoj/sekvantoj"
|
ffVisibility: "Videbleco de viaj sekvatoj/sekvantoj"
|
||||||
ffVisibilityDescription: "Oni permesas agordi tiuln kiuj povas vidi la homojn kiujn vi sekvas, kaj la homojn kiuj sekvas vin."
|
ffVisibilityDescription: "Oni permesas agordi tiuln kiuj povas vidi la homojn kiujn vi sekvas, kaj la homojn kiuj sekvas vin."
|
||||||
continueThread: "Pli vidi la mesaĝaron"
|
continueThread: "Pli vidi la mesaĝaron"
|
||||||
|
deleteAccountConfirm: "La konto estos forviŝita. Ĉu vi daŭrigas fari?"
|
||||||
incorrectPassword: "Nevalida pasvorto"
|
incorrectPassword: "Nevalida pasvorto"
|
||||||
voteConfirm: "Ĉu vi voĉdonas {choice}n?"
|
voteConfirm: "Ĉu vi voĉdonas {choice}n?"
|
||||||
hide: "Kaŝi"
|
hide: "Kaŝi"
|
||||||
|
@ -684,14 +692,19 @@ leaveGroup: "Eliĝi el la grupo"
|
||||||
leaveGroupConfirm: "Ĉu vi certas ke vi volas eliĝi el la grupo {name}?"
|
leaveGroupConfirm: "Ĉu vi certas ke vi volas eliĝi el la grupo {name}?"
|
||||||
welcomeBackWithName: "Bonrevenon, {name}!"
|
welcomeBackWithName: "Bonrevenon, {name}!"
|
||||||
clickToFinishEmailVerification: "Volu klaki [{ok}] por fini konfirmon de via retadreso."
|
clickToFinishEmailVerification: "Volu klaki [{ok}] por fini konfirmon de via retadreso."
|
||||||
|
overridedDeviceKind: "tipo de aparato"
|
||||||
smartphone: "Saĝtelefono"
|
smartphone: "Saĝtelefono"
|
||||||
tablet: "Platkomputilo"
|
tablet: "Platkomputilo"
|
||||||
auto: "Aŭtomate"
|
auto: "Aŭtomate"
|
||||||
|
size: "Grandeco"
|
||||||
searchByGoogle: "Serĉi en Google-Serĉo"
|
searchByGoogle: "Serĉi en Google-Serĉo"
|
||||||
tenMinutes: "10 minutoj"
|
mutePeriod: "Daŭro de silentigo"
|
||||||
oneHour: "1 horo"
|
indefinitely: "Sen limdato"
|
||||||
oneDay: "1 tago"
|
tenMinutes: "Je 10 minutoj"
|
||||||
oneWeek: "1 semajno"
|
oneHour: "Je 1 horo"
|
||||||
|
oneDay: "Je 1 tago"
|
||||||
|
oneWeek: "Je 1 semajno"
|
||||||
|
failedToFetchAccountInformation: "Malsukcesas akiri informon de konto"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "La retpoŝto jam estas uzita."
|
used: "La retpoŝto jam estas uzita."
|
||||||
format: "Nevalida formato."
|
format: "Nevalida formato."
|
||||||
|
@ -834,7 +847,6 @@ _ago:
|
||||||
_time:
|
_time:
|
||||||
second: "sek"
|
second: "sek"
|
||||||
minute: "min"
|
minute: "min"
|
||||||
hour: "hor"
|
|
||||||
day: "Tago"
|
day: "Tago"
|
||||||
_tutorial:
|
_tutorial:
|
||||||
title: "Uzado de Misskey"
|
title: "Uzado de Misskey"
|
||||||
|
@ -893,16 +905,15 @@ _cw:
|
||||||
chars: "{count} literoj"
|
chars: "{count} literoj"
|
||||||
files: "{count} dosiero(j)"
|
files: "{count} dosiero(j)"
|
||||||
_poll:
|
_poll:
|
||||||
choiceN: "Ebla voĉdono {n}"
|
choiceN: "Balotilo {n}"
|
||||||
noMore: "Oni ne povas aldoni pli"
|
noMore: "Oni ne povas aldoni pli"
|
||||||
canMultipleVote: "Permesi plurelekton"
|
canMultipleVote: "Permesi plurelekton"
|
||||||
expiration: "Limtempo"
|
expiration: "Limtempo"
|
||||||
deadlineTime: "hor"
|
infinite: "Por ĉiam"
|
||||||
duration: "Daŭro"
|
|
||||||
votesCount: "{n} voĉoj"
|
votesCount: "{n} voĉoj"
|
||||||
totalVotes: "Sume {n} voĉoj"
|
totalVotes: "Sume {n} voĉoj"
|
||||||
vote: "Voĉdoni"
|
vote: "Voĉdoni"
|
||||||
showResult: "Vidi la rezultojn"
|
showResult: "Vidi rezultojn"
|
||||||
voted: "Voĉdonita"
|
voted: "Voĉdonita"
|
||||||
closed: "Finita"
|
closed: "Finita"
|
||||||
_visibility:
|
_visibility:
|
||||||
|
@ -923,7 +934,7 @@ _postForm:
|
||||||
_placeholders:
|
_placeholders:
|
||||||
a: "Kiel vi fartas?"
|
a: "Kiel vi fartas?"
|
||||||
b: "Kio okazis ĉirkaŭ vi?"
|
b: "Kio okazis ĉirkaŭ vi?"
|
||||||
c: "Kio estas sur via penso?"
|
c: "Kion vi pensas?"
|
||||||
d: "Kion vi volas diri?"
|
d: "Kion vi volas diri?"
|
||||||
e: "Komencu skribi tie"
|
e: "Komencu skribi tie"
|
||||||
_profile:
|
_profile:
|
||||||
|
@ -1115,6 +1126,7 @@ _notification:
|
||||||
youReceivedFollowRequest: "Vi ricevis peton de sekvado"
|
youReceivedFollowRequest: "Vi ricevis peton de sekvado"
|
||||||
yourFollowRequestAccepted: "Via peto de sekvado estis akceptita."
|
yourFollowRequestAccepted: "Via peto de sekvado estis akceptita."
|
||||||
youWereInvitedToGroup: "Invitita al grupo"
|
youWereInvitedToGroup: "Invitita al grupo"
|
||||||
|
pollEnded: "La rezulto de la balot-enketo estas disponebla"
|
||||||
_types:
|
_types:
|
||||||
all: "Ĉio"
|
all: "Ĉio"
|
||||||
follow: "Novaj sekvantoj"
|
follow: "Novaj sekvantoj"
|
||||||
|
@ -1123,7 +1135,8 @@ _notification:
|
||||||
renote: "Plusendoj"
|
renote: "Plusendoj"
|
||||||
quote: "Citi"
|
quote: "Citi"
|
||||||
reaction: "Reagoj"
|
reaction: "Reagoj"
|
||||||
pollVote: "Voĉdonoj en balotoj"
|
pollVote: "Voĉdonoj en balot-enketo"
|
||||||
|
pollEnded: "Enketo finiĝis"
|
||||||
receiveFollowRequest: "Ricevi peton de sekvado"
|
receiveFollowRequest: "Ricevi peton de sekvado"
|
||||||
followRequestAccepted: "Akceptita peto de sekvado"
|
followRequestAccepted: "Akceptita peto de sekvado"
|
||||||
groupInvited: "Invitita al grupo"
|
groupInvited: "Invitita al grupo"
|
||||||
|
|
|
@ -1216,7 +1216,7 @@ _poll:
|
||||||
votesCount: "{n} votes"
|
votesCount: "{n} votes"
|
||||||
totalVotes: "{n} votes au total"
|
totalVotes: "{n} votes au total"
|
||||||
vote: "Voter"
|
vote: "Voter"
|
||||||
showResult: "Voir les résultats"
|
showResult: "Voir résultats"
|
||||||
voted: "Déjà voté"
|
voted: "Déjà voté"
|
||||||
closed: "Terminé"
|
closed: "Terminé"
|
||||||
remainingDays: "{d} jours, {h} heures restantes"
|
remainingDays: "{d} jours, {h} heures restantes"
|
||||||
|
|
|
@ -592,6 +592,7 @@ smtpSecure: "Gunakan SSL/TLS implisit untuk koneksi SMTP"
|
||||||
smtpSecureInfo: "Matikan ini ketika menggunakan STARTTLS"
|
smtpSecureInfo: "Matikan ini ketika menggunakan STARTTLS"
|
||||||
testEmail: "Tes pengiriman surel"
|
testEmail: "Tes pengiriman surel"
|
||||||
wordMute: "Bisukan kata"
|
wordMute: "Bisukan kata"
|
||||||
|
regexpError: "Kesalahan ekspresi reguler"
|
||||||
instanceMute: "Bisuka instansi"
|
instanceMute: "Bisuka instansi"
|
||||||
userSaysSomething: "{name} mengatakan sesuatu"
|
userSaysSomething: "{name} mengatakan sesuatu"
|
||||||
makeActive: "Aktifkan"
|
makeActive: "Aktifkan"
|
||||||
|
@ -825,8 +826,20 @@ overridedDeviceKind: "Tipe perangkat"
|
||||||
smartphone: "Ponsel"
|
smartphone: "Ponsel"
|
||||||
tablet: "Tablet"
|
tablet: "Tablet"
|
||||||
auto: "Otomatis"
|
auto: "Otomatis"
|
||||||
|
themeColor: "Warna Tema"
|
||||||
|
size: "Ukuran"
|
||||||
|
numberOfColumn: "Jumlah per kolom"
|
||||||
searchByGoogle: "Penelusuran"
|
searchByGoogle: "Penelusuran"
|
||||||
|
instanceDefaultLightTheme: "Bawaan instan tema terang"
|
||||||
|
instanceDefaultDarkTheme: "Bawaan instan tema gelap"
|
||||||
|
instanceDefaultThemeDescription: "Masukkan kode tema di format obyek."
|
||||||
|
mutePeriod: "Batas waktu bisu"
|
||||||
indefinitely: "Selamanya"
|
indefinitely: "Selamanya"
|
||||||
|
tenMinutes: "10 Menit"
|
||||||
|
oneHour: "1 Jam"
|
||||||
|
oneDay: "1 Hari"
|
||||||
|
oneWeek: "1 Bulan"
|
||||||
|
failedToFetchAccountInformation: "Gagal untuk mendapatkan informasi akun"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Alamat surel ini telah digunakan"
|
used: "Alamat surel ini telah digunakan"
|
||||||
format: "Format tidak valid."
|
format: "Format tidak valid."
|
||||||
|
@ -1599,6 +1612,7 @@ _notification:
|
||||||
youReceivedFollowRequest: "Kamu menerima permintaan mengikuti"
|
youReceivedFollowRequest: "Kamu menerima permintaan mengikuti"
|
||||||
yourFollowRequestAccepted: "Permintaan mengikuti kamu telah diterima"
|
yourFollowRequestAccepted: "Permintaan mengikuti kamu telah diterima"
|
||||||
youWereInvitedToGroup: "Telah diundang ke grup"
|
youWereInvitedToGroup: "Telah diundang ke grup"
|
||||||
|
pollEnded: "Hasil Kuesioner telah keluar"
|
||||||
_types:
|
_types:
|
||||||
all: "Semua"
|
all: "Semua"
|
||||||
follow: "Ikuti"
|
follow: "Ikuti"
|
||||||
|
@ -1608,6 +1622,7 @@ _notification:
|
||||||
quote: "Kutip"
|
quote: "Kutip"
|
||||||
reaction: "Reaksi"
|
reaction: "Reaksi"
|
||||||
pollVote: "Memilih di angket"
|
pollVote: "Memilih di angket"
|
||||||
|
pollEnded: "Jajak pendapat berakhir"
|
||||||
receiveFollowRequest: "Permintaan mengikuti diterima"
|
receiveFollowRequest: "Permintaan mengikuti diterima"
|
||||||
followRequestAccepted: "Permintaan mengikuti disetujui"
|
followRequestAccepted: "Permintaan mengikuti disetujui"
|
||||||
groupInvited: "Diundang ke grup"
|
groupInvited: "Diundang ke grup"
|
||||||
|
|
|
@ -119,6 +119,23 @@ unblock: "Deblokkeren"
|
||||||
suspend: "Opschorten"
|
suspend: "Opschorten"
|
||||||
unsuspend: "Heractiveren"
|
unsuspend: "Heractiveren"
|
||||||
blockConfirm: "Weet je zeker dat je dit account wil blokkeren?"
|
blockConfirm: "Weet je zeker dat je dit account wil blokkeren?"
|
||||||
|
unblockConfirm: "Ben je zeker dat je deze account wil blokkeren?"
|
||||||
|
suspendConfirm: "Ben je zeker dat je deze account wil suspenderen?"
|
||||||
|
unsuspendConfirm: "Ben je zeker dat je deze account wil opnieuw aanstellen?"
|
||||||
|
flagAsBot: "Markeer dit account als een robot."
|
||||||
|
flagAsBotDescription: "Als dit account van een programma wordt beheerd, zet deze vlag aan. Het aanzetten helpt andere ontwikkelaars om bijvoorbeeld onbedoelde feedback loops te doorbreken of om Misskey meer geschikt te maken."
|
||||||
|
flagAsCat: "Markeer dit account als een kat."
|
||||||
|
flagAsCatDescription: "Zet deze vlag aan als je wilt aangeven dat dit account een kat is."
|
||||||
|
flagShowTimelineReplies: "Toon antwoorden op de tijdlijn."
|
||||||
|
flagShowTimelineRepliesDescription: "Als je dit vlag aanzet, toont de tijdlijn ook antwoorden op andere en niet alleen jouw eigen notities."
|
||||||
|
autoAcceptFollowed: "Accepteer verzoeken om jezelf te volgen vanzelf als je de verzoeker al volgt."
|
||||||
|
addAccount: "Account toevoegen"
|
||||||
|
loginFailed: "Aanmelding mislukt."
|
||||||
|
showOnRemote: "Toon op de externe instantie."
|
||||||
|
general: "Algemeen"
|
||||||
|
wallpaper: "Achtergrond"
|
||||||
|
setWallpaper: "Achtergrond instellen"
|
||||||
|
removeWallpaper: "Achtergrond verwijderen"
|
||||||
searchWith: "Zoeken: {q}"
|
searchWith: "Zoeken: {q}"
|
||||||
youHaveNoLists: "Je hebt geen lijsten"
|
youHaveNoLists: "Je hebt geen lijsten"
|
||||||
followConfirm: "Weet je zeker dat je {name} wilt volgen?"
|
followConfirm: "Weet je zeker dat je {name} wilt volgen?"
|
||||||
|
@ -205,6 +222,8 @@ resetAreYouSure: "Resetten?"
|
||||||
saved: "Opgeslagen"
|
saved: "Opgeslagen"
|
||||||
messaging: "Chat"
|
messaging: "Chat"
|
||||||
upload: "Uploaden"
|
upload: "Uploaden"
|
||||||
|
keepOriginalUploading: "Origineel beeld behouden."
|
||||||
|
keepOriginalUploadingDescription: "Bewaar de originele versie bij het uploaden van afbeeldingen. Indien uitgeschakeld, wordt bij het uploaden een alternatieve versie voor webpublicatie genereert."
|
||||||
fromDrive: "Van schijf"
|
fromDrive: "Van schijf"
|
||||||
fromUrl: "Van URL"
|
fromUrl: "Van URL"
|
||||||
uploadFromUrl: "Uploaden vanaf een URL"
|
uploadFromUrl: "Uploaden vanaf een URL"
|
||||||
|
@ -245,9 +264,36 @@ renameFile: "Wijzig bestandsnaam"
|
||||||
folderName: "Mapnaam"
|
folderName: "Mapnaam"
|
||||||
createFolder: "Map aanmaken"
|
createFolder: "Map aanmaken"
|
||||||
renameFolder: "Map hernoemen"
|
renameFolder: "Map hernoemen"
|
||||||
|
deleteFolder: "Map verwijderen"
|
||||||
|
addFile: "Bestand toevoegen"
|
||||||
|
emptyDrive: "Jouw Drive is leeg."
|
||||||
|
emptyFolder: "Deze map is leeg"
|
||||||
|
unableToDelete: "Kan niet worden verwijderd"
|
||||||
|
inputNewFileName: "Voer een nieuwe naam in"
|
||||||
|
copyUrl: "URL kopiëren"
|
||||||
|
rename: "Hernoemen"
|
||||||
|
avatar: "Avatar"
|
||||||
|
banner: "Banner"
|
||||||
nsfw: "NSFW"
|
nsfw: "NSFW"
|
||||||
|
whenServerDisconnected: "Wanneer de verbinding met de server wordt onderbroken"
|
||||||
|
disconnectedFromServer: "Verbinding met de server onderbroken."
|
||||||
|
inMb: "in megabytes"
|
||||||
pinnedNotes: "Vastgemaakte notitie"
|
pinnedNotes: "Vastgemaakte notitie"
|
||||||
userList: "Lijsten"
|
userList: "Lijsten"
|
||||||
|
aboutMisskey: "Over Misskey"
|
||||||
|
administrator: "Beheerder"
|
||||||
|
token: "Token"
|
||||||
|
securityKeyName: "Sleutelnaam"
|
||||||
|
registerSecurityKey: "Zekerheids-Sleutel registreren"
|
||||||
|
lastUsed: "Laatst gebruikt"
|
||||||
|
unregister: "Uitschrijven"
|
||||||
|
passwordLessLogin: "Inloggen zonder wachtwoord"
|
||||||
|
resetPassword: "Wachtwoord terugzetten"
|
||||||
|
newPasswordIs: "Het nieuwe wachtwoord is „{password}”."
|
||||||
|
reduceUiAnimation: "Verminder beweging in de UI"
|
||||||
|
share: "Delen"
|
||||||
|
notFound: "Niet gevonden"
|
||||||
|
cacheClear: "Cache verwijderen"
|
||||||
smtpHost: "Server"
|
smtpHost: "Server"
|
||||||
smtpUser: "Gebruikersnaam"
|
smtpUser: "Gebruikersnaam"
|
||||||
smtpPass: "Wachtwoord"
|
smtpPass: "Wachtwoord"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
_lang_: "Português"
|
_lang_: "Português"
|
||||||
headlineMisskey: "Rede conectada por notas"
|
headlineMisskey: "Rede conectada por notas"
|
||||||
|
introMisskey: "Bem-vindo! Misskey é um serviço de microblogue descentralizado de código aberto.\nCria \"notas\" e partilha o que te ocorre com todos à tua volta. 📡\nCom \"reações\" podes também expressar logo o que sentes às notas de todos. 👍\nExploremos um novo mundo! 🚀"
|
||||||
monthAndDay: "{day}/{month}"
|
monthAndDay: "{day}/{month}"
|
||||||
search: "Pesquisar"
|
search: "Pesquisar"
|
||||||
notifications: "Notificações"
|
notifications: "Notificações"
|
||||||
|
@ -22,6 +23,7 @@ otherSettings: "Outras configurações"
|
||||||
openInWindow: "Abrir numa janela"
|
openInWindow: "Abrir numa janela"
|
||||||
profile: "Perfil"
|
profile: "Perfil"
|
||||||
timeline: "Timeline"
|
timeline: "Timeline"
|
||||||
|
noAccountDescription: "Este usuário não tem uma descrição."
|
||||||
login: "Iniciar sessão"
|
login: "Iniciar sessão"
|
||||||
loggingIn: "Iniciando sessão…"
|
loggingIn: "Iniciando sessão…"
|
||||||
logout: "Sair"
|
logout: "Sair"
|
||||||
|
@ -29,8 +31,12 @@ signup: "Registrar-se"
|
||||||
uploading: "Enviando…"
|
uploading: "Enviando…"
|
||||||
save: "Guardar"
|
save: "Guardar"
|
||||||
users: "Usuários"
|
users: "Usuários"
|
||||||
|
addUser: "Adicionar usuário"
|
||||||
favorite: "Favoritar"
|
favorite: "Favoritar"
|
||||||
favorites: "Favoritar"
|
favorites: "Favoritar"
|
||||||
|
unfavorite: "Remover dos favoritos"
|
||||||
|
favorited: "Adicionado aos favoritos."
|
||||||
|
alreadyFavorited: "Já adicionado aos favoritos."
|
||||||
showMore: "Ver mais"
|
showMore: "Ver mais"
|
||||||
youGotNewFollower: "Você tem um novo seguidor"
|
youGotNewFollower: "Você tem um novo seguidor"
|
||||||
followRequestAccepted: "Pedido de seguir aceito"
|
followRequestAccepted: "Pedido de seguir aceito"
|
||||||
|
|
|
@ -449,6 +449,45 @@ groupInvited: "Ai fost invitat într-un grup"
|
||||||
aboutX: "Despre {x}"
|
aboutX: "Despre {x}"
|
||||||
useOsNativeEmojis: "Folosește emojiuri native OS-ului"
|
useOsNativeEmojis: "Folosește emojiuri native OS-ului"
|
||||||
disableDrawer: "Nu folosi meniuri în stil sertar"
|
disableDrawer: "Nu folosi meniuri în stil sertar"
|
||||||
|
youHaveNoGroups: "Nu ai niciun grup"
|
||||||
|
joinOrCreateGroup: "Primește o invitație într-un grup sau creează unul nou."
|
||||||
|
noHistory: "Nu există istoric"
|
||||||
|
signinHistory: "Istoric autentificări"
|
||||||
|
disableAnimatedMfm: "Dezactivează MFM cu animații"
|
||||||
|
doing: "Se procesează..."
|
||||||
|
category: "Categorie"
|
||||||
|
tags: "Etichete"
|
||||||
|
docSource: "Sursa acestui document"
|
||||||
|
createAccount: "Creează un cont"
|
||||||
|
existingAccount: "Cont existent"
|
||||||
|
regenerate: "Regenerează"
|
||||||
|
fontSize: "Mărimea fontului"
|
||||||
|
noFollowRequests: "Nu ai nicio cerere de urmărire în așteptare"
|
||||||
|
openImageInNewTab: "Deschide imaginile în taburi noi"
|
||||||
|
dashboard: "Panou de control"
|
||||||
|
local: "Local"
|
||||||
|
remote: "Extern"
|
||||||
|
total: "Total"
|
||||||
|
weekOverWeekChanges: "Schimbări până săptămâna trecută"
|
||||||
|
dayOverDayChanges: "Schimbări până ieri"
|
||||||
|
appearance: "Aspect"
|
||||||
|
clientSettings: "Setări client"
|
||||||
|
accountSettings: "Setări cont"
|
||||||
|
promotion: "Promovat"
|
||||||
|
promote: "Promovează"
|
||||||
|
numberOfDays: "Numărul zilelor"
|
||||||
|
hideThisNote: "Ascunde această notă"
|
||||||
|
showFeaturedNotesInTimeline: "Arată notele recomandate în cronologii"
|
||||||
|
objectStorage: "Object Storage"
|
||||||
|
useObjectStorage: "Folosește Object Storage"
|
||||||
|
objectStorageBaseUrl: "URL de bază"
|
||||||
|
objectStorageBucket: "Bucket"
|
||||||
|
objectStorageBucketDesc: "Te rog specifică numele bucket-ului furnizorului tău."
|
||||||
|
objectStoragePrefix: "Prefix"
|
||||||
|
objectStoragePrefixDesc: "Fișierele vor fi stocate sub directoare cu acest prefix."
|
||||||
|
objectStorageEndpoint: "Endpoint"
|
||||||
|
objectStorageRegion: "Regiune"
|
||||||
|
objectStorageUseSSL: "Folosește SSl"
|
||||||
sounds: "Sunete"
|
sounds: "Sunete"
|
||||||
listen: "Ascultă"
|
listen: "Ascultă"
|
||||||
none: "Nimic"
|
none: "Nimic"
|
||||||
|
@ -471,6 +510,18 @@ sort: "Sortează"
|
||||||
ascendingOrder: "Crescător"
|
ascendingOrder: "Crescător"
|
||||||
descendingOrder: "Descrescător"
|
descendingOrder: "Descrescător"
|
||||||
scratchpad: "Scratchpad"
|
scratchpad: "Scratchpad"
|
||||||
|
scratchpadDescription: "Scratchpad-ul oferă un mediu de experimentare în AiScript. Poți scrie, executa și verifica rezultatele acestuia interacționând cu Misskey în el."
|
||||||
|
output: "Ieșire"
|
||||||
|
script: "Script"
|
||||||
|
disablePagesScript: "Dezactivează AiScript în Pagini"
|
||||||
|
updateRemoteUser: "Actualizează informațiile utilizatorului extern"
|
||||||
|
deleteAllFiles: "Șterge toate fișierele"
|
||||||
|
deleteAllFilesConfirm: "Ești sigur că vrei să ștergi toate fișierele?"
|
||||||
|
removeAllFollowing: "Dezurmărește toți utilizatorii urmăriți"
|
||||||
|
removeAllFollowingDescription: "Asta va dez-urmări toate conturile din {host}. Te rog execută asta numai dacă instanța, de ex., nu mai există."
|
||||||
|
userSuspended: "Acest utilizator a fost suspendat."
|
||||||
|
userSilenced: "Acest utilizator a fost setat silențios."
|
||||||
|
yourAccountSuspendedTitle: "Acest cont a fost suspendat"
|
||||||
smtpHost: "Gazdă"
|
smtpHost: "Gazdă"
|
||||||
smtpUser: "Nume de utilizator"
|
smtpUser: "Nume de utilizator"
|
||||||
smtpPass: "Parolă"
|
smtpPass: "Parolă"
|
||||||
|
|
|
@ -839,6 +839,8 @@ tenMinutes: "10 minút"
|
||||||
oneHour: "1 hodina"
|
oneHour: "1 hodina"
|
||||||
oneDay: "1 deň"
|
oneDay: "1 deň"
|
||||||
oneWeek: "1 týždeň"
|
oneWeek: "1 týždeň"
|
||||||
|
reflectMayTakeTime: "Zmeny môžu chvíľu trvať kým sa prejavia."
|
||||||
|
failedToFetchAccountInformation: "Nepodarilo sa načítať informácie o účte."
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "Táto emailová adresa sa už používa"
|
used: "Táto emailová adresa sa už používa"
|
||||||
format: "Formát emailovej adresy je nesprávny"
|
format: "Formát emailovej adresy je nesprávny"
|
||||||
|
|
|
@ -8,12 +8,12 @@ notifications: "通知"
|
||||||
username: "用户名"
|
username: "用户名"
|
||||||
password: "密码"
|
password: "密码"
|
||||||
forgotPassword: "忘记密码"
|
forgotPassword: "忘记密码"
|
||||||
fetchingAsApObject: "联合查询"
|
fetchingAsApObject: "在联邦宇宙查询中..."
|
||||||
ok: "OK"
|
ok: "OK"
|
||||||
gotIt: "我明白了"
|
gotIt: "我明白了"
|
||||||
cancel: "取消"
|
cancel: "取消"
|
||||||
enterUsername: "输入用户名"
|
enterUsername: "输入用户名"
|
||||||
renotedBy: "由 {user} 转推"
|
renotedBy: "由 {user} 转贴"
|
||||||
noNotes: "没有帖文"
|
noNotes: "没有帖文"
|
||||||
noNotifications: "无通知"
|
noNotifications: "无通知"
|
||||||
instance: "实例"
|
instance: "实例"
|
||||||
|
@ -69,7 +69,7 @@ exportRequested: "导出请求已提交,这可能需要花一些时间,导
|
||||||
importRequested: "导入请求已提交,这可能需要花一点时间。"
|
importRequested: "导入请求已提交,这可能需要花一点时间。"
|
||||||
lists: "列表"
|
lists: "列表"
|
||||||
noLists: "列表为空"
|
noLists: "列表为空"
|
||||||
note: "帖子"
|
note: "发帖"
|
||||||
notes: "帖子"
|
notes: "帖子"
|
||||||
following: "关注中"
|
following: "关注中"
|
||||||
followers: "关注者"
|
followers: "关注者"
|
||||||
|
@ -85,7 +85,7 @@ serverIsDead: "服务器没有响应。 请稍等片刻,然后重试。"
|
||||||
youShouldUpgradeClient: "请重新加载并使用新版本的客户端查看此页面。"
|
youShouldUpgradeClient: "请重新加载并使用新版本的客户端查看此页面。"
|
||||||
enterListName: "输入列表名称"
|
enterListName: "输入列表名称"
|
||||||
privacy: "隐私"
|
privacy: "隐私"
|
||||||
makeFollowManuallyApprove: "关注者的关注请求需要批准"
|
makeFollowManuallyApprove: "关注请求需要批准"
|
||||||
defaultNoteVisibility: "默认可见性"
|
defaultNoteVisibility: "默认可见性"
|
||||||
follow: "关注"
|
follow: "关注"
|
||||||
followRequest: "关注申请"
|
followRequest: "关注申请"
|
||||||
|
@ -143,7 +143,7 @@ flagAsCat: "将这个账户设定为一只猫"
|
||||||
flagAsCatDescription: "如果您想表明此帐户是一只猫,请打开此标志。"
|
flagAsCatDescription: "如果您想表明此帐户是一只猫,请打开此标志。"
|
||||||
flagShowTimelineReplies: "在时间线上显示帖子的回复"
|
flagShowTimelineReplies: "在时间线上显示帖子的回复"
|
||||||
flagShowTimelineRepliesDescription: "启用时,时间线除了显示用户的帖子外,还会显示其他用户对帖子的回复。"
|
flagShowTimelineRepliesDescription: "启用时,时间线除了显示用户的帖子外,还会显示其他用户对帖子的回复。"
|
||||||
autoAcceptFollowed: "自动允许关注"
|
autoAcceptFollowed: "自动允许关注者的关注"
|
||||||
addAccount: "添加账户"
|
addAccount: "添加账户"
|
||||||
loginFailed: "登录失败"
|
loginFailed: "登录失败"
|
||||||
showOnRemote: "转到所在实例显示"
|
showOnRemote: "转到所在实例显示"
|
||||||
|
@ -162,7 +162,7 @@ recipient: "收件人"
|
||||||
annotation: "注解"
|
annotation: "注解"
|
||||||
federation: "联合"
|
federation: "联合"
|
||||||
instances: "实例"
|
instances: "实例"
|
||||||
registeredAt: "初次观察"
|
registeredAt: "初次观测"
|
||||||
latestRequestSentAt: "上次发送的请求"
|
latestRequestSentAt: "上次发送的请求"
|
||||||
latestRequestReceivedAt: "上次收到的请求"
|
latestRequestReceivedAt: "上次收到的请求"
|
||||||
latestStatus: "最后状态"
|
latestStatus: "最后状态"
|
||||||
|
@ -254,7 +254,7 @@ agreeTo: "{0}人同意"
|
||||||
tos: "服务条款"
|
tos: "服务条款"
|
||||||
start: "开始"
|
start: "开始"
|
||||||
home: "首页"
|
home: "首页"
|
||||||
remoteUserCaution: "由于是远程用户,信息不完整。"
|
remoteUserCaution: "由于此用户来自其它实例,显示的信息可能不完整。"
|
||||||
activity: "活动"
|
activity: "活动"
|
||||||
images: "图片"
|
images: "图片"
|
||||||
birthday: "生日"
|
birthday: "生日"
|
||||||
|
@ -372,7 +372,7 @@ recentlyUpdatedUsers: "最近投稿的用户"
|
||||||
recentlyRegisteredUsers: "最近登录的用户"
|
recentlyRegisteredUsers: "最近登录的用户"
|
||||||
recentlyDiscoveredUsers: "最近发现的用户"
|
recentlyDiscoveredUsers: "最近发现的用户"
|
||||||
exploreUsersCount: "有{count}个用户"
|
exploreUsersCount: "有{count}个用户"
|
||||||
exploreFediverse: "探索Fediverse"
|
exploreFediverse: "探索联邦宇宙"
|
||||||
popularTags: "热门标签"
|
popularTags: "热门标签"
|
||||||
userList: "列表"
|
userList: "列表"
|
||||||
about: "关于"
|
about: "关于"
|
||||||
|
@ -561,7 +561,7 @@ manage: "管理"
|
||||||
plugins: "插件"
|
plugins: "插件"
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
undeck: "取消Deck"
|
undeck: "取消Deck"
|
||||||
useBlurEffectForModal: "模态框使用模糊效果"
|
useBlurEffectForModal: "对话框使用模糊效果"
|
||||||
useFullReactionPicker: "使用全功能的回应工具栏"
|
useFullReactionPicker: "使用全功能的回应工具栏"
|
||||||
width: "宽度"
|
width: "宽度"
|
||||||
height: "高度"
|
height: "高度"
|
||||||
|
@ -840,6 +840,8 @@ tenMinutes: "10分钟"
|
||||||
oneHour: "1小时"
|
oneHour: "1小时"
|
||||||
oneDay: "1天"
|
oneDay: "1天"
|
||||||
oneWeek: "1周"
|
oneWeek: "1周"
|
||||||
|
reflectMayTakeTime: "可能需要一些时间才能体现出效果。"
|
||||||
|
failedToFetchAccountInformation: "获取账户信息失败"
|
||||||
_emailUnavailable:
|
_emailUnavailable:
|
||||||
used: "已经被使用过"
|
used: "已经被使用过"
|
||||||
format: "无效的格式"
|
format: "无效的格式"
|
||||||
|
@ -904,7 +906,7 @@ _nsfw:
|
||||||
_mfm:
|
_mfm:
|
||||||
cheatSheet: "MFM代码速查表"
|
cheatSheet: "MFM代码速查表"
|
||||||
intro: "MFM是一种在Misskey中的各个位置使用的专用标记语言。在这里您可以看到MFM中可用的语法列表。"
|
intro: "MFM是一种在Misskey中的各个位置使用的专用标记语言。在这里您可以看到MFM中可用的语法列表。"
|
||||||
dummy: "通过Misskey扩展Fediverse的世界"
|
dummy: "通过Misskey扩展联邦宇宙的世界"
|
||||||
mention: "提及"
|
mention: "提及"
|
||||||
mentionDescription: "可以使用 @+用户名 来指示特定用户"
|
mentionDescription: "可以使用 @+用户名 来指示特定用户"
|
||||||
hashtag: "话题标签"
|
hashtag: "话题标签"
|
||||||
|
@ -967,7 +969,7 @@ _mfm:
|
||||||
rotateDescription: "旋转指定的角度。"
|
rotateDescription: "旋转指定的角度。"
|
||||||
_instanceTicker:
|
_instanceTicker:
|
||||||
none: "不显示"
|
none: "不显示"
|
||||||
remote: "仅显示远程用户的"
|
remote: "仅远程用户"
|
||||||
always: "始终显示"
|
always: "始终显示"
|
||||||
_serverDisconnectedBehavior:
|
_serverDisconnectedBehavior:
|
||||||
reload: "自动重载"
|
reload: "自动重载"
|
||||||
|
@ -1051,7 +1053,7 @@ _theme:
|
||||||
mention: "提及"
|
mention: "提及"
|
||||||
mentionMe: "提及"
|
mentionMe: "提及"
|
||||||
renote: "转发"
|
renote: "转发"
|
||||||
modalBg: "模态框背景"
|
modalBg: "对话框背景"
|
||||||
divider: "分割线"
|
divider: "分割线"
|
||||||
scrollbarHandle: "滚动条"
|
scrollbarHandle: "滚动条"
|
||||||
scrollbarHandleHover: "滚动条(悬停)"
|
scrollbarHandleHover: "滚动条(悬停)"
|
||||||
|
@ -1238,7 +1240,7 @@ _visibility:
|
||||||
publicDescription: "您的帖子将出现在全局时间线上"
|
publicDescription: "您的帖子将出现在全局时间线上"
|
||||||
home: "首页"
|
home: "首页"
|
||||||
homeDescription: "仅发送至首页的时间线"
|
homeDescription: "仅发送至首页的时间线"
|
||||||
followers: "关注者"
|
followers: "仅关注者"
|
||||||
followersDescription: "仅发送至关注者"
|
followersDescription: "仅发送至关注者"
|
||||||
specified: "指定用户"
|
specified: "指定用户"
|
||||||
specifiedDescription: "仅发送至指定用户"
|
specifiedDescription: "仅发送至指定用户"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "12.108.1",
|
"version": "12.109.1",
|
||||||
"codename": "indigo",
|
"codename": "indigo",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -41,9 +41,9 @@
|
||||||
"js-yaml": "4.1.0"
|
"js-yaml": "4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/parser": "5.16.0",
|
"@typescript-eslint/parser": "5.17.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"cypress": "9.5.2",
|
"cypress": "9.5.3",
|
||||||
"start-server-and-test": "1.14.0",
|
"start-server-and-test": "1.14.0",
|
||||||
"typescript": "4.6.3"
|
"typescript": "4.6.3"
|
||||||
}
|
}
|
||||||
|
|
19
packages/backend/migration/1648548247382-webhook.js
Normal file
19
packages/backend/migration/1648548247382-webhook.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
export class webhook1648548247382 {
|
||||||
|
name = 'webhook1648548247382'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`CREATE TABLE "webhook" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "on" character varying(128) array NOT NULL DEFAULT '{}', "url" character varying(1024) NOT NULL, "secret" character varying(1024) NOT NULL, "active" boolean NOT NULL DEFAULT true, CONSTRAINT "PK_e6765510c2d078db49632b59020" PRIMARY KEY ("id")); COMMENT ON COLUMN "webhook"."createdAt" IS 'The created date of the Antenna.'; COMMENT ON COLUMN "webhook"."userId" IS 'The owner ID.'; COMMENT ON COLUMN "webhook"."name" IS 'The name of the Antenna.'`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_f272c8c8805969e6a6449c77b3" ON "webhook" ("userId") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_8063a0586ed1dfbe86e982d961" ON "webhook" ("on") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_5a056076f76b2efe08216ba655" ON "webhook" ("active") `);
|
||||||
|
await queryRunner.query(`ALTER TABLE "webhook" ADD CONSTRAINT "FK_f272c8c8805969e6a6449c77b3c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "webhook" DROP CONSTRAINT "FK_f272c8c8805969e6a6449c77b3c"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_5a056076f76b2efe08216ba655"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_8063a0586ed1dfbe86e982d961"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_f272c8c8805969e6a6449c77b3"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "webhook"`);
|
||||||
|
}
|
||||||
|
}
|
14
packages/backend/migration/1648816172177-webhook-2.js
Normal file
14
packages/backend/migration/1648816172177-webhook-2.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
export class webhook21648816172177 {
|
||||||
|
name = 'webhook21648816172177'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "webhook" ADD "latestSentAt" TIMESTAMP WITH TIME ZONE`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "webhook" ADD "latestStatus" integer`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "webhook" DROP COLUMN "latestStatus"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "webhook" DROP COLUMN "latestSentAt"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json",
|
"build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json",
|
||||||
"watch": "node watch.mjs",
|
"watch": "node watch.mjs",
|
||||||
"lint": "eslint --quiet src/**/*.ts",
|
"lint": "eslint --quiet 'src/**/*.ts'",
|
||||||
"mocha": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
|
"mocha": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
|
||||||
"test": "npm run mocha"
|
"test": "npm run mocha"
|
||||||
},
|
},
|
||||||
|
@ -65,15 +65,15 @@
|
||||||
"@types/web-push": "3.3.2",
|
"@types/web-push": "3.3.2",
|
||||||
"@types/websocket": "1.0.5",
|
"@types/websocket": "1.0.5",
|
||||||
"@types/ws": "8.5.3",
|
"@types/ws": "8.5.3",
|
||||||
"@typescript-eslint/eslint-plugin": "5.16.0",
|
"@typescript-eslint/eslint-plugin": "5.17.0",
|
||||||
"@typescript-eslint/parser": "5.16.0",
|
"@typescript-eslint/parser": "5.17.0",
|
||||||
"@bull-board/koa": "3.10.1",
|
"@bull-board/koa": "3.10.2",
|
||||||
"abort-controller": "3.0.0",
|
"abort-controller": "3.0.0",
|
||||||
"ajv": "8.11.0",
|
"ajv": "8.11.0",
|
||||||
"archiver": "5.3.0",
|
"archiver": "5.3.0",
|
||||||
"autobind-decorator": "2.4.0",
|
"autobind-decorator": "2.4.0",
|
||||||
"autwh": "0.1.0",
|
"autwh": "0.1.0",
|
||||||
"aws-sdk": "2.1100.0",
|
"aws-sdk": "2.1105.0",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"blurhash": "1.1.5",
|
"blurhash": "1.1.5",
|
||||||
"broadcast-channel": "4.10.0",
|
"broadcast-channel": "4.10.0",
|
||||||
|
@ -89,12 +89,12 @@
|
||||||
"date-fns": "2.28.0",
|
"date-fns": "2.28.0",
|
||||||
"deep-email-validator": "0.1.21",
|
"deep-email-validator": "0.1.21",
|
||||||
"escape-regexp": "0.0.1",
|
"escape-regexp": "0.0.1",
|
||||||
"eslint": "8.11.0",
|
"eslint": "8.12.0",
|
||||||
"eslint-plugin-import": "2.25.4",
|
"eslint-plugin-import": "2.25.4",
|
||||||
"feed": "4.2.2",
|
"feed": "4.2.2",
|
||||||
"file-type": "17.1.1",
|
"file-type": "17.1.1",
|
||||||
"fluent-ffmpeg": "2.1.2",
|
"fluent-ffmpeg": "2.1.2",
|
||||||
"got": "12.0.2",
|
"got": "12.0.3",
|
||||||
"hpagent": "0.1.2",
|
"hpagent": "0.1.2",
|
||||||
"http-signature": "1.3.6",
|
"http-signature": "1.3.6",
|
||||||
"ip-cidr": "3.0.4",
|
"ip-cidr": "3.0.4",
|
||||||
|
@ -165,9 +165,9 @@
|
||||||
"ts-loader": "9.2.8",
|
"ts-loader": "9.2.8",
|
||||||
"ts-node": "10.7.0",
|
"ts-node": "10.7.0",
|
||||||
"tsc-alias": "1.4.1",
|
"tsc-alias": "1.4.1",
|
||||||
"tsconfig-paths": "3.14.0",
|
"tsconfig-paths": "3.14.1",
|
||||||
"twemoji-parser": "14.0.0",
|
"twemoji-parser": "14.0.0",
|
||||||
"typeorm": "0.3.3",
|
"typeorm": "0.3.4",
|
||||||
"typescript": "4.6.3",
|
"typescript": "4.6.3",
|
||||||
"ulid": "2.3.0",
|
"ulid": "2.3.0",
|
||||||
"unzipper": "0.10.11",
|
"unzipper": "0.10.11",
|
||||||
|
@ -178,7 +178,7 @@
|
||||||
"xev": "2.0.1"
|
"xev": "2.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@redocly/openapi-core": "1.0.0-beta.90",
|
"@redocly/openapi-core": "1.0.0-beta.91",
|
||||||
"@types/fluent-ffmpeg": "2.1.20",
|
"@types/fluent-ffmpeg": "2.1.20",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"execa": "6.1.0"
|
"execa": "6.1.0"
|
||||||
|
|
|
@ -73,6 +73,7 @@ import { PasswordResetRequest } from '@/models/entities/password-reset-request.j
|
||||||
import { UserPending } from '@/models/entities/user-pending.js';
|
import { UserPending } from '@/models/entities/user-pending.js';
|
||||||
|
|
||||||
import { entities as charts } from '@/services/chart/entities.js';
|
import { entities as charts } from '@/services/chart/entities.js';
|
||||||
|
import { Webhook } from '@/models/entities/webhook.js';
|
||||||
|
|
||||||
const sqlLogger = dbLogger.createSubLogger('sql', 'gray', false);
|
const sqlLogger = dbLogger.createSubLogger('sql', 'gray', false);
|
||||||
|
|
||||||
|
@ -171,6 +172,7 @@ export const entities = [
|
||||||
Ad,
|
Ad,
|
||||||
PasswordResetRequest,
|
PasswordResetRequest,
|
||||||
UserPending,
|
UserPending,
|
||||||
|
Webhook,
|
||||||
...charts,
|
...charts,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,14 @@ export async function fetchMeta(noCache = false): Promise<Meta> {
|
||||||
|
|
||||||
return await db.transaction(async transactionalEntityManager => {
|
return await db.transaction(async transactionalEntityManager => {
|
||||||
// 過去のバグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する
|
// 過去のバグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する
|
||||||
const meta = await transactionalEntityManager.findOne(Meta, {
|
const metas = await transactionalEntityManager.find(Meta, {
|
||||||
order: {
|
order: {
|
||||||
id: 'DESC',
|
id: 'DESC',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const meta = metas[0];
|
||||||
|
|
||||||
if (meta) {
|
if (meta) {
|
||||||
cache = meta;
|
cache = meta;
|
||||||
return meta;
|
return meta;
|
||||||
|
|
49
packages/backend/src/misc/webhook-cache.ts
Normal file
49
packages/backend/src/misc/webhook-cache.ts
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import { Webhooks } from '@/models/index.js';
|
||||||
|
import { Webhook } from '@/models/entities/webhook.js';
|
||||||
|
import { subsdcriber } from '../db/redis.js';
|
||||||
|
|
||||||
|
let webhooksFetched = false;
|
||||||
|
let webhooks: Webhook[] = [];
|
||||||
|
|
||||||
|
export async function getActiveWebhooks() {
|
||||||
|
if (!webhooksFetched) {
|
||||||
|
webhooks = await Webhooks.findBy({
|
||||||
|
active: true,
|
||||||
|
});
|
||||||
|
webhooksFetched = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return webhooks;
|
||||||
|
}
|
||||||
|
|
||||||
|
subsdcriber.on('message', async (_, data) => {
|
||||||
|
const obj = JSON.parse(data);
|
||||||
|
|
||||||
|
if (obj.channel === 'internal') {
|
||||||
|
const { type, body } = obj.message;
|
||||||
|
switch (type) {
|
||||||
|
case 'webhookCreated':
|
||||||
|
if (body.active) {
|
||||||
|
webhooks.push(body);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'webhookUpdated':
|
||||||
|
if (body.active) {
|
||||||
|
const i = webhooks.findIndex(a => a.id === body.id);
|
||||||
|
if (i > -1) {
|
||||||
|
webhooks[i] = body;
|
||||||
|
} else {
|
||||||
|
webhooks.push(body);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
webhooks = webhooks.filter(a => a.id !== body.id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'webhookDeleted':
|
||||||
|
webhooks = webhooks.filter(a => a.id !== body.id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
73
packages/backend/src/models/entities/webhook.ts
Normal file
73
packages/backend/src/models/entities/webhook.ts
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
|
||||||
|
import { User } from './user.js';
|
||||||
|
import { id } from '../id.js';
|
||||||
|
|
||||||
|
export const webhookEventTypes = ['mention', 'unfollow', 'follow', 'followed', 'note', 'reply', 'renote', 'reaction'] as const;
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class Webhook {
|
||||||
|
@PrimaryColumn(id())
|
||||||
|
public id: string;
|
||||||
|
|
||||||
|
@Column('timestamp with time zone', {
|
||||||
|
comment: 'The created date of the Antenna.',
|
||||||
|
})
|
||||||
|
public createdAt: Date;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column({
|
||||||
|
...id(),
|
||||||
|
comment: 'The owner ID.',
|
||||||
|
})
|
||||||
|
public userId: User['id'];
|
||||||
|
|
||||||
|
@ManyToOne(type => User, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn()
|
||||||
|
public user: User | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 128,
|
||||||
|
comment: 'The name of the Antenna.',
|
||||||
|
})
|
||||||
|
public name: string;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 128, array: true, default: '{}',
|
||||||
|
})
|
||||||
|
public on: (typeof webhookEventTypes)[number][];
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 1024,
|
||||||
|
})
|
||||||
|
public url: string;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 1024,
|
||||||
|
})
|
||||||
|
public secret: string;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column('boolean', {
|
||||||
|
default: true,
|
||||||
|
})
|
||||||
|
public active: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直近のリクエスト送信日時
|
||||||
|
*/
|
||||||
|
@Column('timestamp with time zone', {
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
public latestSentAt: Date | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直近のリクエスト送信時のHTTPステータスコード
|
||||||
|
*/
|
||||||
|
@Column('integer', {
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
public latestStatus: number | null;
|
||||||
|
}
|
|
@ -64,6 +64,7 @@ import { Ad } from './entities/ad.js';
|
||||||
import { PasswordResetRequest } from './entities/password-reset-request.js';
|
import { PasswordResetRequest } from './entities/password-reset-request.js';
|
||||||
import { UserPending } from './entities/user-pending.js';
|
import { UserPending } from './entities/user-pending.js';
|
||||||
import { InstanceRepository } from './repositories/instance.js';
|
import { InstanceRepository } from './repositories/instance.js';
|
||||||
|
import { Webhook } from './entities/webhook.js';
|
||||||
|
|
||||||
export const Announcements = db.getRepository(Announcement);
|
export const Announcements = db.getRepository(Announcement);
|
||||||
export const AnnouncementReads = db.getRepository(AnnouncementRead);
|
export const AnnouncementReads = db.getRepository(AnnouncementRead);
|
||||||
|
@ -125,5 +126,6 @@ export const Channels = (ChannelRepository);
|
||||||
export const ChannelFollowings = db.getRepository(ChannelFollowing);
|
export const ChannelFollowings = db.getRepository(ChannelFollowing);
|
||||||
export const ChannelNotePinings = db.getRepository(ChannelNotePining);
|
export const ChannelNotePinings = db.getRepository(ChannelNotePining);
|
||||||
export const RegistryItems = db.getRepository(RegistryItem);
|
export const RegistryItems = db.getRepository(RegistryItem);
|
||||||
|
export const Webhooks = db.getRepository(Webhook);
|
||||||
export const Ads = db.getRepository(Ad);
|
export const Ads = db.getRepository(Ad);
|
||||||
export const PasswordResetRequests = db.getRepository(PasswordResetRequest);
|
export const PasswordResetRequests = db.getRepository(PasswordResetRequest);
|
||||||
|
|
|
@ -8,13 +8,15 @@ import processInbox from './processors/inbox.js';
|
||||||
import processDb from './processors/db/index.js';
|
import processDb from './processors/db/index.js';
|
||||||
import processObjectStorage from './processors/object-storage/index.js';
|
import processObjectStorage from './processors/object-storage/index.js';
|
||||||
import processSystemQueue from './processors/system/index.js';
|
import processSystemQueue from './processors/system/index.js';
|
||||||
|
import processWebhookDeliver from './processors/webhook-deliver.js';
|
||||||
import { endedPollNotification } from './processors/ended-poll-notification.js';
|
import { endedPollNotification } from './processors/ended-poll-notification.js';
|
||||||
import { queueLogger } from './logger.js';
|
import { queueLogger } from './logger.js';
|
||||||
import { DriveFile } from '@/models/entities/drive-file.js';
|
import { DriveFile } from '@/models/entities/drive-file.js';
|
||||||
import { getJobInfo } from './get-job-info.js';
|
import { getJobInfo } from './get-job-info.js';
|
||||||
import { systemQueue, dbQueue, deliverQueue, inboxQueue, objectStorageQueue, endedPollNotificationQueue } from './queues.js';
|
import { systemQueue, dbQueue, deliverQueue, inboxQueue, objectStorageQueue, endedPollNotificationQueue, webhookDeliverQueue } from './queues.js';
|
||||||
import { ThinUser } from './types.js';
|
import { ThinUser } from './types.js';
|
||||||
import { IActivity } from '@/remote/activitypub/type.js';
|
import { IActivity } from '@/remote/activitypub/type.js';
|
||||||
|
import { Webhook } from '@/models/entities/webhook.js';
|
||||||
|
|
||||||
function renderError(e: Error): any {
|
function renderError(e: Error): any {
|
||||||
return {
|
return {
|
||||||
|
@ -26,6 +28,7 @@ function renderError(e: Error): any {
|
||||||
|
|
||||||
const systemLogger = queueLogger.createSubLogger('system');
|
const systemLogger = queueLogger.createSubLogger('system');
|
||||||
const deliverLogger = queueLogger.createSubLogger('deliver');
|
const deliverLogger = queueLogger.createSubLogger('deliver');
|
||||||
|
const webhookLogger = queueLogger.createSubLogger('webhook');
|
||||||
const inboxLogger = queueLogger.createSubLogger('inbox');
|
const inboxLogger = queueLogger.createSubLogger('inbox');
|
||||||
const dbLogger = queueLogger.createSubLogger('db');
|
const dbLogger = queueLogger.createSubLogger('db');
|
||||||
const objectStorageLogger = queueLogger.createSubLogger('objectStorage');
|
const objectStorageLogger = queueLogger.createSubLogger('objectStorage');
|
||||||
|
@ -70,6 +73,14 @@ objectStorageQueue
|
||||||
.on('error', (job: any, err: Error) => objectStorageLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
.on('error', (job: any, err: Error) => objectStorageLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||||
.on('stalled', (job) => objectStorageLogger.warn(`stalled id=${job.id}`));
|
.on('stalled', (job) => objectStorageLogger.warn(`stalled id=${job.id}`));
|
||||||
|
|
||||||
|
webhookDeliverQueue
|
||||||
|
.on('waiting', (jobId) => webhookLogger.debug(`waiting id=${jobId}`))
|
||||||
|
.on('active', (job) => webhookLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`))
|
||||||
|
.on('completed', (job, result) => webhookLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`))
|
||||||
|
.on('failed', (job, err) => webhookLogger.warn(`failed(${err}) ${getJobInfo(job)} to=${job.data.to}`))
|
||||||
|
.on('error', (job: any, err: Error) => webhookLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||||
|
.on('stalled', (job) => webhookLogger.warn(`stalled ${getJobInfo(job)} to=${job.data.to}`));
|
||||||
|
|
||||||
export function deliver(user: ThinUser, content: unknown, to: string | null) {
|
export function deliver(user: ThinUser, content: unknown, to: string | null) {
|
||||||
if (content == null) return null;
|
if (content == null) return null;
|
||||||
if (to == null) return null;
|
if (to == null) return null;
|
||||||
|
@ -251,12 +262,32 @@ export function createCleanRemoteFilesJob() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function webhookDeliver(webhook: Webhook, content: unknown) {
|
||||||
|
const data = {
|
||||||
|
content,
|
||||||
|
webhookId: webhook.id,
|
||||||
|
to: webhook.url,
|
||||||
|
secret: webhook.secret,
|
||||||
|
};
|
||||||
|
|
||||||
|
return webhookDeliverQueue.add(data, {
|
||||||
|
attempts: 4,
|
||||||
|
timeout: 1 * 60 * 1000, // 1min
|
||||||
|
backoff: {
|
||||||
|
type: 'apBackoff',
|
||||||
|
},
|
||||||
|
removeOnComplete: true,
|
||||||
|
removeOnFail: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export default function() {
|
export default function() {
|
||||||
if (envOption.onlyServer) return;
|
if (envOption.onlyServer) return;
|
||||||
|
|
||||||
deliverQueue.process(config.deliverJobConcurrency || 128, processDeliver);
|
deliverQueue.process(config.deliverJobConcurrency || 128, processDeliver);
|
||||||
inboxQueue.process(config.inboxJobConcurrency || 16, processInbox);
|
inboxQueue.process(config.inboxJobConcurrency || 16, processInbox);
|
||||||
endedPollNotificationQueue.process(endedPollNotification);
|
endedPollNotificationQueue.process(endedPollNotification);
|
||||||
|
webhookDeliverQueue.process(64, processWebhookDeliver);
|
||||||
processDb(dbQueue);
|
processDb(dbQueue);
|
||||||
processObjectStorage(objectStorageQueue);
|
processObjectStorage(objectStorageQueue);
|
||||||
|
|
||||||
|
|
56
packages/backend/src/queue/processors/webhook-deliver.ts
Normal file
56
packages/backend/src/queue/processors/webhook-deliver.ts
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import { URL } from 'node:url';
|
||||||
|
import Bull from 'bull';
|
||||||
|
import Logger from '@/services/logger.js';
|
||||||
|
import { WebhookDeliverJobData } from '../types.js';
|
||||||
|
import { getResponse, StatusError } from '@/misc/fetch.js';
|
||||||
|
import { Webhooks } from '@/models/index.js';
|
||||||
|
import config from '@/config/index.js';
|
||||||
|
|
||||||
|
const logger = new Logger('webhook');
|
||||||
|
|
||||||
|
let latest: string | null = null;
|
||||||
|
|
||||||
|
export default async (job: Bull.Job<WebhookDeliverJobData>) => {
|
||||||
|
try {
|
||||||
|
if (latest !== (latest = JSON.stringify(job.data.content, null, 2))) {
|
||||||
|
logger.debug(`delivering ${latest}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await getResponse({
|
||||||
|
url: job.data.to,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'User-Agent': 'Misskey-Hooks',
|
||||||
|
'X-Misskey-Host': config.host,
|
||||||
|
'X-Misskey-Hook-Id': job.data.webhookId,
|
||||||
|
'X-Misskey-Hook-Secret': job.data.secret,
|
||||||
|
},
|
||||||
|
body: JSON.stringify(job.data.content),
|
||||||
|
});
|
||||||
|
|
||||||
|
Webhooks.update({ id: job.data.webhookId }, {
|
||||||
|
latestSentAt: new Date(),
|
||||||
|
latestStatus: res.status,
|
||||||
|
});
|
||||||
|
|
||||||
|
return 'Success';
|
||||||
|
} catch (res) {
|
||||||
|
Webhooks.update({ id: job.data.webhookId }, {
|
||||||
|
latestSentAt: new Date(),
|
||||||
|
latestStatus: res instanceof StatusError ? res.statusCode : 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res instanceof StatusError) {
|
||||||
|
// 4xx
|
||||||
|
if (res.isClientError) {
|
||||||
|
return `${res.statusCode} ${res.statusMessage}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5xx etc.
|
||||||
|
throw `${res.statusCode} ${res.statusMessage}`;
|
||||||
|
} else {
|
||||||
|
// DNS error, socket error, timeout ...
|
||||||
|
throw res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,6 +1,6 @@
|
||||||
import config from '@/config/index.js';
|
import config from '@/config/index.js';
|
||||||
import { initialize as initializeQueue } from './initialize.js';
|
import { initialize as initializeQueue } from './initialize.js';
|
||||||
import { DeliverJobData, InboxJobData, DbJobData, ObjectStorageJobData, EndedPollNotificationJobData } from './types.js';
|
import { DeliverJobData, InboxJobData, DbJobData, ObjectStorageJobData, EndedPollNotificationJobData, WebhookDeliverJobData } from './types.js';
|
||||||
|
|
||||||
export const systemQueue = initializeQueue<Record<string, unknown>>('system');
|
export const systemQueue = initializeQueue<Record<string, unknown>>('system');
|
||||||
export const endedPollNotificationQueue = initializeQueue<EndedPollNotificationJobData>('endedPollNotification');
|
export const endedPollNotificationQueue = initializeQueue<EndedPollNotificationJobData>('endedPollNotification');
|
||||||
|
@ -8,6 +8,7 @@ export const deliverQueue = initializeQueue<DeliverJobData>('deliver', config.de
|
||||||
export const inboxQueue = initializeQueue<InboxJobData>('inbox', config.inboxJobPerSec || 16);
|
export const inboxQueue = initializeQueue<InboxJobData>('inbox', config.inboxJobPerSec || 16);
|
||||||
export const dbQueue = initializeQueue<DbJobData>('db');
|
export const dbQueue = initializeQueue<DbJobData>('db');
|
||||||
export const objectStorageQueue = initializeQueue<ObjectStorageJobData>('objectStorage');
|
export const objectStorageQueue = initializeQueue<ObjectStorageJobData>('objectStorage');
|
||||||
|
export const webhookDeliverQueue = initializeQueue<WebhookDeliverJobData>('webhookDeliver', 64);
|
||||||
|
|
||||||
export const queues = [
|
export const queues = [
|
||||||
systemQueue,
|
systemQueue,
|
||||||
|
@ -16,4 +17,5 @@ export const queues = [
|
||||||
inboxQueue,
|
inboxQueue,
|
||||||
dbQueue,
|
dbQueue,
|
||||||
objectStorageQueue,
|
objectStorageQueue,
|
||||||
|
webhookDeliverQueue,
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { DriveFile } from '@/models/entities/drive-file.js';
|
import { DriveFile } from '@/models/entities/drive-file.js';
|
||||||
import { Note } from '@/models/entities/note';
|
import { Note } from '@/models/entities/note';
|
||||||
import { User } from '@/models/entities/user.js';
|
import { User } from '@/models/entities/user.js';
|
||||||
|
import { Webhook } from '@/models/entities/webhook';
|
||||||
import { IActivity } from '@/remote/activitypub/type.js';
|
import { IActivity } from '@/remote/activitypub/type.js';
|
||||||
import httpSignature from 'http-signature';
|
import httpSignature from 'http-signature';
|
||||||
|
|
||||||
|
@ -46,6 +47,13 @@ export type EndedPollNotificationJobData = {
|
||||||
noteId: Note['id'];
|
noteId: Note['id'];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type WebhookDeliverJobData = {
|
||||||
|
content: unknown;
|
||||||
|
webhookId: Webhook['id'];
|
||||||
|
to: string;
|
||||||
|
secret: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type ThinUser = {
|
export type ThinUser = {
|
||||||
id: User['id'];
|
id: User['id'];
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,9 +79,13 @@ export default class DeliverManager {
|
||||||
|
|
||||||
const inboxes = new Set<string>();
|
const inboxes = new Set<string>();
|
||||||
|
|
||||||
// build inbox list
|
/*
|
||||||
for (const recipe of this.recipes) {
|
build inbox list
|
||||||
if (isFollowers(recipe)) {
|
|
||||||
|
Process follower recipes first to avoid duplication when processing
|
||||||
|
direct recipes later.
|
||||||
|
*/
|
||||||
|
if (this.recipes.some(r => isFollowers(r))) {
|
||||||
// followers deliver
|
// followers deliver
|
||||||
// TODO: SELECT DISTINCT ON ("followerSharedInbox") "followerSharedInbox" みたいな問い合わせにすればよりパフォーマンス向上できそう
|
// TODO: SELECT DISTINCT ON ("followerSharedInbox") "followerSharedInbox" みたいな問い合わせにすればよりパフォーマンス向上できそう
|
||||||
// ただ、sharedInboxがnullなリモートユーザーも稀におり、その対応ができなさそう?
|
// ただ、sharedInboxがnullなリモートユーザーも稀におり、その対応ができなさそう?
|
||||||
|
@ -103,13 +107,18 @@ export default class DeliverManager {
|
||||||
const inbox = following.followerSharedInbox || following.followerInbox;
|
const inbox = following.followerSharedInbox || following.followerInbox;
|
||||||
inboxes.add(inbox);
|
inboxes.add(inbox);
|
||||||
}
|
}
|
||||||
} else if (isDirect(recipe)) {
|
|
||||||
// direct deliver
|
|
||||||
const inbox = recipe.to.inbox;
|
|
||||||
if (inbox) inboxes.add(inbox);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.recipes.filter((recipe): recipe is IDirectRecipe => {
|
||||||
|
// followers recipes have already been processed
|
||||||
|
isDirect(recipe)
|
||||||
|
// check that shared inbox has not been added yet
|
||||||
|
&& !(recipe.to.sharedInbox && inboxes.has(recipe.to.sharedInbox))
|
||||||
|
// check that they actually have an inbox
|
||||||
|
&& recipe.to.inbox
|
||||||
|
})
|
||||||
|
.forEach(recipe => inboxes.add(recipe.to.inbox));
|
||||||
|
|
||||||
// deliver
|
// deliver
|
||||||
for (const inbox of inboxes) {
|
for (const inbox of inboxes) {
|
||||||
deliver(this.actor, this.activity, inbox);
|
deliver(this.actor, this.activity, inbox);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Schema } from '@/misc/schema.js';
|
import { Schema } from '@/misc/schema.js';
|
||||||
|
|
||||||
|
import * as ep___admin_meta from './endpoints/admin/meta.js';
|
||||||
import * as ep___admin_abuseUserReports from './endpoints/admin/abuse-user-reports.js';
|
import * as ep___admin_abuseUserReports from './endpoints/admin/abuse-user-reports.js';
|
||||||
import * as ep___admin_accounts_create from './endpoints/admin/accounts/create.js';
|
import * as ep___admin_accounts_create from './endpoints/admin/accounts/create.js';
|
||||||
import * as ep___admin_accounts_delete from './endpoints/admin/accounts/delete.js';
|
import * as ep___admin_accounts_delete from './endpoints/admin/accounts/delete.js';
|
||||||
|
@ -201,6 +202,11 @@ import * as ep___i_unpin from './endpoints/i/unpin.js';
|
||||||
import * as ep___i_updateEmail from './endpoints/i/update-email.js';
|
import * as ep___i_updateEmail from './endpoints/i/update-email.js';
|
||||||
import * as ep___i_update from './endpoints/i/update.js';
|
import * as ep___i_update from './endpoints/i/update.js';
|
||||||
import * as ep___i_userGroupInvites from './endpoints/i/user-group-invites.js';
|
import * as ep___i_userGroupInvites from './endpoints/i/user-group-invites.js';
|
||||||
|
import * as ep___i_webhooks_create from './endpoints/i/webhooks/create.js';
|
||||||
|
import * as ep___i_webhooks_show from './endpoints/i/webhooks/show.js';
|
||||||
|
import * as ep___i_webhooks_list from './endpoints/i/webhooks/list.js';
|
||||||
|
import * as ep___i_webhooks_update from './endpoints/i/webhooks/update.js';
|
||||||
|
import * as ep___i_webhooks_delete from './endpoints/i/webhooks/delete.js';
|
||||||
import * as ep___messaging_history from './endpoints/messaging/history.js';
|
import * as ep___messaging_history from './endpoints/messaging/history.js';
|
||||||
import * as ep___messaging_messages from './endpoints/messaging/messages.js';
|
import * as ep___messaging_messages from './endpoints/messaging/messages.js';
|
||||||
import * as ep___messaging_messages_create from './endpoints/messaging/messages/create.js';
|
import * as ep___messaging_messages_create from './endpoints/messaging/messages/create.js';
|
||||||
|
@ -304,6 +310,7 @@ import * as ep___users_show from './endpoints/users/show.js';
|
||||||
import * as ep___users_stats from './endpoints/users/stats.js';
|
import * as ep___users_stats from './endpoints/users/stats.js';
|
||||||
|
|
||||||
const eps = [
|
const eps = [
|
||||||
|
['admin/meta', ep___admin_meta],
|
||||||
['admin/abuse-user-reports', ep___admin_abuseUserReports],
|
['admin/abuse-user-reports', ep___admin_abuseUserReports],
|
||||||
['admin/accounts/create', ep___admin_accounts_create],
|
['admin/accounts/create', ep___admin_accounts_create],
|
||||||
['admin/accounts/delete', ep___admin_accounts_delete],
|
['admin/accounts/delete', ep___admin_accounts_delete],
|
||||||
|
@ -505,6 +512,11 @@ const eps = [
|
||||||
['i/update-email', ep___i_updateEmail],
|
['i/update-email', ep___i_updateEmail],
|
||||||
['i/update', ep___i_update],
|
['i/update', ep___i_update],
|
||||||
['i/user-group-invites', ep___i_userGroupInvites],
|
['i/user-group-invites', ep___i_userGroupInvites],
|
||||||
|
['i/webhooks/create', ep___i_webhooks_create],
|
||||||
|
['i/webhooks/list', ep___i_webhooks_list],
|
||||||
|
['i/webhooks/show', ep___i_webhooks_show],
|
||||||
|
['i/webhooks/update', ep___i_webhooks_update],
|
||||||
|
['i/webhooks/delete', ep___i_webhooks_delete],
|
||||||
['messaging/history', ep___messaging_history],
|
['messaging/history', ep___messaging_history],
|
||||||
['messaging/messages', ep___messaging_messages],
|
['messaging/messages', ep___messaging_messages],
|
||||||
['messaging/messages/create', ep___messaging_messages_create],
|
['messaging/messages/create', ep___messaging_messages_create],
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import define from '../../../define.js';
|
import define from '../../../define.js';
|
||||||
import { Users } from '@/models/index.js';
|
import { Users } from '@/models/index.js';
|
||||||
|
import { publishInternalEvent } from '@/services/stream.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import define from '../../../define.js';
|
||||||
|
import { genId } from '@/misc/gen-id.js';
|
||||||
|
import { Webhooks } from '@/models/index.js';
|
||||||
|
import { publishInternalEvent } from '@/services/stream.js';
|
||||||
|
import { webhookEventTypes } from '@/models/entities/webhook.js';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
tags: ['webhooks'],
|
||||||
|
|
||||||
|
requireCredential: true,
|
||||||
|
|
||||||
|
kind: 'write:account',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const paramDef = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
name: { type: 'string', minLength: 1, maxLength: 100 },
|
||||||
|
url: { type: 'string', minLength: 1, maxLength: 1024 },
|
||||||
|
secret: { type: 'string', minLength: 1, maxLength: 1024 },
|
||||||
|
on: { type: 'array', items: {
|
||||||
|
type: 'string', enum: webhookEventTypes,
|
||||||
|
} },
|
||||||
|
},
|
||||||
|
required: ['name', 'url', 'secret', 'on'],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
const webhook = await Webhooks.insert({
|
||||||
|
id: genId(),
|
||||||
|
createdAt: new Date(),
|
||||||
|
userId: user.id,
|
||||||
|
name: ps.name,
|
||||||
|
url: ps.url,
|
||||||
|
secret: ps.secret,
|
||||||
|
on: ps.on,
|
||||||
|
}).then(x => Webhooks.findOneByOrFail(x.identifiers[0]));
|
||||||
|
|
||||||
|
publishInternalEvent('webhookCreated', webhook);
|
||||||
|
|
||||||
|
return webhook;
|
||||||
|
});
|
|
@ -0,0 +1,44 @@
|
||||||
|
import define from '../../../define.js';
|
||||||
|
import { ApiError } from '../../../error.js';
|
||||||
|
import { Webhooks } from '@/models/index.js';
|
||||||
|
import { publishInternalEvent } from '@/services/stream.js';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
tags: ['webhooks'],
|
||||||
|
|
||||||
|
requireCredential: true,
|
||||||
|
|
||||||
|
kind: 'write:account',
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
noSuchWebhook: {
|
||||||
|
message: 'No such webhook.',
|
||||||
|
code: 'NO_SUCH_WEBHOOK',
|
||||||
|
id: 'bae73e5a-5522-4965-ae19-3a8688e71d82',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const paramDef = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
webhookId: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
required: ['webhookId'],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
const webhook = await Webhooks.findOneBy({
|
||||||
|
id: ps.webhookId,
|
||||||
|
userId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (webhook == null) {
|
||||||
|
throw new ApiError(meta.errors.noSuchWebhook);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Webhooks.delete(webhook.id);
|
||||||
|
|
||||||
|
publishInternalEvent('webhookDeleted', webhook);
|
||||||
|
});
|
25
packages/backend/src/server/api/endpoints/i/webhooks/list.ts
Normal file
25
packages/backend/src/server/api/endpoints/i/webhooks/list.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import define from '../../../define.js';
|
||||||
|
import { Webhooks } from '@/models/index.js';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
tags: ['webhooks', 'account'],
|
||||||
|
|
||||||
|
requireCredential: true,
|
||||||
|
|
||||||
|
kind: 'read:account',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const paramDef = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {},
|
||||||
|
required: [],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
export default define(meta, paramDef, async (ps, me) => {
|
||||||
|
const webhooks = await Webhooks.findBy({
|
||||||
|
userId: me.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
return webhooks;
|
||||||
|
});
|
41
packages/backend/src/server/api/endpoints/i/webhooks/show.ts
Normal file
41
packages/backend/src/server/api/endpoints/i/webhooks/show.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import define from '../../../define.js';
|
||||||
|
import { ApiError } from '../../../error.js';
|
||||||
|
import { Webhooks } from '@/models/index.js';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
tags: ['webhooks'],
|
||||||
|
|
||||||
|
requireCredential: true,
|
||||||
|
|
||||||
|
kind: 'read:account',
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
noSuchWebhook: {
|
||||||
|
message: 'No such webhook.',
|
||||||
|
code: 'NO_SUCH_WEBHOOK',
|
||||||
|
id: '50f614d9-3047-4f7e-90d8-ad6b2d5fb098',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const paramDef = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
webhookId: { type: 'string', format: 'misskey:id' },
|
||||||
|
},
|
||||||
|
required: ['webhookId'],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
const webhook = await Webhooks.findOneBy({
|
||||||
|
id: ps.webhookId,
|
||||||
|
userId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (webhook == null) {
|
||||||
|
throw new ApiError(meta.errors.noSuchWebhook);
|
||||||
|
}
|
||||||
|
|
||||||
|
return webhook;
|
||||||
|
});
|
|
@ -0,0 +1,59 @@
|
||||||
|
import define from '../../../define.js';
|
||||||
|
import { ApiError } from '../../../error.js';
|
||||||
|
import { Webhooks } from '@/models/index.js';
|
||||||
|
import { publishInternalEvent } from '@/services/stream.js';
|
||||||
|
import { webhookEventTypes } from '@/models/entities/webhook.js';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
tags: ['webhooks'],
|
||||||
|
|
||||||
|
requireCredential: true,
|
||||||
|
|
||||||
|
kind: 'write:account',
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
noSuchWebhook: {
|
||||||
|
message: 'No such webhook.',
|
||||||
|
code: 'NO_SUCH_WEBHOOK',
|
||||||
|
id: 'fb0fea69-da18-45b1-828d-bd4fd1612518',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const paramDef = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
webhookId: { type: 'string', format: 'misskey:id' },
|
||||||
|
name: { type: 'string', minLength: 1, maxLength: 100 },
|
||||||
|
url: { type: 'string', minLength: 1, maxLength: 1024 },
|
||||||
|
secret: { type: 'string', minLength: 1, maxLength: 1024 },
|
||||||
|
on: { type: 'array', items: {
|
||||||
|
type: 'string', enum: webhookEventTypes,
|
||||||
|
} },
|
||||||
|
active: { type: 'boolean' },
|
||||||
|
},
|
||||||
|
required: ['webhookId', 'name', 'url', 'secret', 'on', 'active'],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-default-export
|
||||||
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
const webhook = await Webhooks.findOneBy({
|
||||||
|
id: ps.webhookId,
|
||||||
|
userId: user.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (webhook == null) {
|
||||||
|
throw new ApiError(meta.errors.noSuchWebhook);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Webhooks.update(webhook.id, {
|
||||||
|
name: ps.name,
|
||||||
|
url: ps.url,
|
||||||
|
secret: ps.secret,
|
||||||
|
on: ps.on,
|
||||||
|
active: ps.active,
|
||||||
|
});
|
||||||
|
|
||||||
|
publishInternalEvent('webhookUpdated', webhook);
|
||||||
|
});
|
|
@ -15,6 +15,7 @@ import { AbuseUserReport } from '@/models/entities/abuse-user-report.js';
|
||||||
import { Signin } from '@/models/entities/signin.js';
|
import { Signin } from '@/models/entities/signin.js';
|
||||||
import { Page } from '@/models/entities/page.js';
|
import { Page } from '@/models/entities/page.js';
|
||||||
import { Packed } from '@/misc/schema.js';
|
import { Packed } from '@/misc/schema.js';
|
||||||
|
import { Webhook } from '@/models/entities/webhook';
|
||||||
|
|
||||||
//#region Stream type-body definitions
|
//#region Stream type-body definitions
|
||||||
export interface InternalStreamTypes {
|
export interface InternalStreamTypes {
|
||||||
|
@ -23,6 +24,9 @@ export interface InternalStreamTypes {
|
||||||
userChangeModeratorState: { id: User['id']; isModerator: User['isModerator']; };
|
userChangeModeratorState: { id: User['id']; isModerator: User['isModerator']; };
|
||||||
userTokenRegenerated: { id: User['id']; oldToken: User['token']; newToken: User['token']; };
|
userTokenRegenerated: { id: User['id']; oldToken: User['token']; newToken: User['token']; };
|
||||||
remoteUserUpdated: { id: User['id']; };
|
remoteUserUpdated: { id: User['id']; };
|
||||||
|
webhookCreated: Webhook;
|
||||||
|
webhookDeleted: Webhook;
|
||||||
|
webhookUpdated: Webhook;
|
||||||
antennaCreated: Antenna;
|
antennaCreated: Antenna;
|
||||||
antennaDeleted: Antenna;
|
antennaDeleted: Antenna;
|
||||||
antennaUpdated: Antenna;
|
antennaUpdated: Antenna;
|
||||||
|
|
|
@ -10,6 +10,8 @@ import { Blockings, Users, FollowRequests, Followings, UserListJoinings, UserLis
|
||||||
import { perUserFollowingChart } from '@/services/chart/index.js';
|
import { perUserFollowingChart } from '@/services/chart/index.js';
|
||||||
import { genId } from '@/misc/gen-id.js';
|
import { genId } from '@/misc/gen-id.js';
|
||||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||||
|
import { getActiveWebhooks } from '@/misc/webhook-cache.js';
|
||||||
|
import { webhookDeliver } from '@/queue/index.js';
|
||||||
|
|
||||||
export default async function(blocker: User, blockee: User) {
|
export default async function(blocker: User, blockee: User) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
@ -57,9 +59,17 @@ async function cancelRequest(follower: User, followee: User) {
|
||||||
if (Users.isLocalUser(follower)) {
|
if (Users.isLocalUser(follower)) {
|
||||||
Users.pack(followee, follower, {
|
Users.pack(followee, follower, {
|
||||||
detail: true,
|
detail: true,
|
||||||
}).then(packed => {
|
}).then(async packed => {
|
||||||
publishUserEvent(follower.id, 'unfollow', packed);
|
publishUserEvent(follower.id, 'unfollow', packed);
|
||||||
publishMainStream(follower.id, 'unfollow', packed);
|
publishMainStream(follower.id, 'unfollow', packed);
|
||||||
|
|
||||||
|
const webhooks = (await getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('unfollow'));
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
webhookDeliver(webhook, {
|
||||||
|
type: 'unfollow',
|
||||||
|
user: packed,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,9 +112,17 @@ async function unFollow(follower: User, followee: User) {
|
||||||
if (Users.isLocalUser(follower)) {
|
if (Users.isLocalUser(follower)) {
|
||||||
Users.pack(followee, follower, {
|
Users.pack(followee, follower, {
|
||||||
detail: true,
|
detail: true,
|
||||||
}).then(packed => {
|
}).then(async packed => {
|
||||||
publishUserEvent(follower.id, 'unfollow', packed);
|
publishUserEvent(follower.id, 'unfollow', packed);
|
||||||
publishMainStream(follower.id, 'unfollow', packed);
|
publishMainStream(follower.id, 'unfollow', packed);
|
||||||
|
|
||||||
|
const webhooks = (await getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('unfollow'));
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
webhookDeliver(webhook, {
|
||||||
|
type: 'unfollow',
|
||||||
|
user: packed,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ import { genId } from '@/misc/gen-id.js';
|
||||||
import { createNotification } from '../create-notification.js';
|
import { createNotification } from '../create-notification.js';
|
||||||
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
|
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
|
||||||
import { Packed } from '@/misc/schema.js';
|
import { Packed } from '@/misc/schema.js';
|
||||||
|
import { getActiveWebhooks } from '@/misc/webhook-cache.js';
|
||||||
|
import { webhookDeliver } from '@/queue/index.js';
|
||||||
|
|
||||||
const logger = new Logger('following/create');
|
const logger = new Logger('following/create');
|
||||||
|
|
||||||
|
@ -89,15 +91,33 @@ export async function insertFollowingDoc(followee: { id: User['id']; host: User[
|
||||||
if (Users.isLocalUser(follower)) {
|
if (Users.isLocalUser(follower)) {
|
||||||
Users.pack(followee.id, follower, {
|
Users.pack(followee.id, follower, {
|
||||||
detail: true,
|
detail: true,
|
||||||
}).then(packed => {
|
}).then(async packed => {
|
||||||
publishUserEvent(follower.id, 'follow', packed as Packed<"UserDetailedNotMe">);
|
publishUserEvent(follower.id, 'follow', packed as Packed<"UserDetailedNotMe">);
|
||||||
publishMainStream(follower.id, 'follow', packed as Packed<"UserDetailedNotMe">);
|
publishMainStream(follower.id, 'follow', packed as Packed<"UserDetailedNotMe">);
|
||||||
|
|
||||||
|
const webhooks = (await getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('follow'));
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
webhookDeliver(webhook, {
|
||||||
|
type: 'follow',
|
||||||
|
user: packed,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish followed event
|
// Publish followed event
|
||||||
if (Users.isLocalUser(followee)) {
|
if (Users.isLocalUser(followee)) {
|
||||||
Users.pack(follower.id, followee).then(packed => publishMainStream(followee.id, 'followed', packed));
|
Users.pack(follower.id, followee).then(async packed => {
|
||||||
|
publishMainStream(followee.id, 'followed', packed)
|
||||||
|
|
||||||
|
const webhooks = (await getActiveWebhooks()).filter(x => x.userId === followee.id && x.on.includes('followed'));
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
webhookDeliver(webhook, {
|
||||||
|
type: 'followed',
|
||||||
|
user: packed,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 通知を作成
|
// 通知を作成
|
||||||
createNotification(followee.id, 'follow', {
|
createNotification(followee.id, 'follow', {
|
||||||
|
|
|
@ -3,12 +3,13 @@ import { renderActivity } from '@/remote/activitypub/renderer/index.js';
|
||||||
import renderFollow from '@/remote/activitypub/renderer/follow.js';
|
import renderFollow from '@/remote/activitypub/renderer/follow.js';
|
||||||
import renderUndo from '@/remote/activitypub/renderer/undo.js';
|
import renderUndo from '@/remote/activitypub/renderer/undo.js';
|
||||||
import renderReject from '@/remote/activitypub/renderer/reject.js';
|
import renderReject from '@/remote/activitypub/renderer/reject.js';
|
||||||
import { deliver } from '@/queue/index.js';
|
import { deliver, webhookDeliver } from '@/queue/index.js';
|
||||||
import Logger from '../logger.js';
|
import Logger from '../logger.js';
|
||||||
import { registerOrFetchInstanceDoc } from '../register-or-fetch-instance-doc.js';
|
import { registerOrFetchInstanceDoc } from '../register-or-fetch-instance-doc.js';
|
||||||
import { User } from '@/models/entities/user.js';
|
import { User } from '@/models/entities/user.js';
|
||||||
import { Followings, Users, Instances } from '@/models/index.js';
|
import { Followings, Users, Instances } from '@/models/index.js';
|
||||||
import { instanceChart, perUserFollowingChart } from '@/services/chart/index.js';
|
import { instanceChart, perUserFollowingChart } from '@/services/chart/index.js';
|
||||||
|
import { getActiveWebhooks } from '@/misc/webhook-cache.js';
|
||||||
|
|
||||||
const logger = new Logger('following/delete');
|
const logger = new Logger('following/delete');
|
||||||
|
|
||||||
|
@ -31,9 +32,17 @@ export default async function(follower: { id: User['id']; host: User['host']; ur
|
||||||
if (!silent && Users.isLocalUser(follower)) {
|
if (!silent && Users.isLocalUser(follower)) {
|
||||||
Users.pack(followee.id, follower, {
|
Users.pack(followee.id, follower, {
|
||||||
detail: true,
|
detail: true,
|
||||||
}).then(packed => {
|
}).then(async packed => {
|
||||||
publishUserEvent(follower.id, 'unfollow', packed);
|
publishUserEvent(follower.id, 'unfollow', packed);
|
||||||
publishMainStream(follower.id, 'unfollow', packed);
|
publishMainStream(follower.id, 'unfollow', packed);
|
||||||
|
|
||||||
|
const webhooks = (await getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('unfollow'));
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
webhookDeliver(webhook, {
|
||||||
|
type: 'unfollow',
|
||||||
|
user: packed,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { renderActivity } from '@/remote/activitypub/renderer/index.js';
|
import { renderActivity } from '@/remote/activitypub/renderer/index.js';
|
||||||
import renderFollow from '@/remote/activitypub/renderer/follow.js';
|
import renderFollow from '@/remote/activitypub/renderer/follow.js';
|
||||||
import renderReject from '@/remote/activitypub/renderer/reject.js';
|
import renderReject from '@/remote/activitypub/renderer/reject.js';
|
||||||
import { deliver } from '@/queue/index.js';
|
import { deliver, webhookDeliver } from '@/queue/index.js';
|
||||||
import { publishMainStream, publishUserEvent } from '@/services/stream.js';
|
import { publishMainStream, publishUserEvent } from '@/services/stream.js';
|
||||||
import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js';
|
import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js';
|
||||||
import { Users, FollowRequests, Followings } from '@/models/index.js';
|
import { Users, FollowRequests, Followings } from '@/models/index.js';
|
||||||
import { decrementFollowing } from './delete.js';
|
import { decrementFollowing } from './delete.js';
|
||||||
|
import { getActiveWebhooks } from '@/misc/webhook-cache.js';
|
||||||
|
|
||||||
type Local = ILocalUser | {
|
type Local = ILocalUser | {
|
||||||
id: ILocalUser['id'];
|
id: ILocalUser['id'];
|
||||||
|
@ -111,4 +112,12 @@ async function publishUnfollow(followee: Both, follower: Local) {
|
||||||
|
|
||||||
publishUserEvent(follower.id, 'unfollow', packedFollowee);
|
publishUserEvent(follower.id, 'unfollow', packedFollowee);
|
||||||
publishMainStream(follower.id, 'unfollow', packedFollowee);
|
publishMainStream(follower.id, 'unfollow', packedFollowee);
|
||||||
|
|
||||||
|
const webhooks = (await getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('unfollow'));
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
webhookDeliver(webhook, {
|
||||||
|
type: 'unfollow',
|
||||||
|
user: packedFollowee,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,9 +55,11 @@ import { Channel } from '@/models/entities/channel.js';
|
||||||
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
|
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
|
||||||
import { getAntennas } from '@/misc/antenna-cache.js';
|
import { getAntennas } from '@/misc/antenna-cache.js';
|
||||||
import { endedPollNotificationQueue } from '@/queue/queues.js';
|
import { endedPollNotificationQueue } from '@/queue/queues.js';
|
||||||
|
import { webhookDeliver } from '@/queue/index.js';
|
||||||
import { Cache } from '@/misc/cache.js';
|
import { Cache } from '@/misc/cache.js';
|
||||||
import { UserProfile } from '@/models/entities/user-profile.js';
|
import { UserProfile } from '@/models/entities/user-profile.js';
|
||||||
import { db } from '@/db/postgre.js';
|
import { db } from '@/db/postgre.js';
|
||||||
|
import { getActiveWebhooks } from '@/misc/webhook-cache.js';
|
||||||
|
|
||||||
const mutedWordsCache = new Cache<{ userId: UserProfile['userId']; mutedWords: UserProfile['mutedWords']; }[]>(1000 * 60 * 5);
|
const mutedWordsCache = new Cache<{ userId: UserProfile['userId']; mutedWords: UserProfile['mutedWords']; }[]>(1000 * 60 * 5);
|
||||||
|
|
||||||
|
@ -365,6 +367,16 @@ export default async (user: { id: User['id']; username: User['username']; host:
|
||||||
|
|
||||||
publishNotesStream(noteObj);
|
publishNotesStream(noteObj);
|
||||||
|
|
||||||
|
getActiveWebhooks().then(webhooks => {
|
||||||
|
webhooks = webhooks.filter(x => x.userId === user.id && x.on.includes('note'));
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
webhookDeliver(webhook, {
|
||||||
|
type: 'note',
|
||||||
|
note: noteObj,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const nm = new NotificationManager(user, note);
|
const nm = new NotificationManager(user, note);
|
||||||
const nmRelatedPromises = [];
|
const nmRelatedPromises = [];
|
||||||
|
|
||||||
|
@ -385,6 +397,14 @@ export default async (user: { id: User['id']; username: User['username']; host:
|
||||||
if (!threadMuted) {
|
if (!threadMuted) {
|
||||||
nm.push(data.reply.userId, 'reply');
|
nm.push(data.reply.userId, 'reply');
|
||||||
publishMainStream(data.reply.userId, 'reply', noteObj);
|
publishMainStream(data.reply.userId, 'reply', noteObj);
|
||||||
|
|
||||||
|
const webhooks = (await getActiveWebhooks()).filter(x => x.userId === data.reply!.userId && x.on.includes('reply'));
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
webhookDeliver(webhook, {
|
||||||
|
type: 'reply',
|
||||||
|
note: noteObj,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,6 +424,14 @@ export default async (user: { id: User['id']; username: User['username']; host:
|
||||||
// Publish event
|
// Publish event
|
||||||
if ((user.id !== data.renote.userId) && data.renote.userHost === null) {
|
if ((user.id !== data.renote.userId) && data.renote.userHost === null) {
|
||||||
publishMainStream(data.renote.userId, 'renote', noteObj);
|
publishMainStream(data.renote.userId, 'renote', noteObj);
|
||||||
|
|
||||||
|
const webhooks = (await getActiveWebhooks()).filter(x => x.userId === data.renote!.userId && x.on.includes('renote'));
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
webhookDeliver(webhook, {
|
||||||
|
type: 'renote',
|
||||||
|
note: noteObj,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,6 +660,14 @@ async function createMentionedEvents(mentionedUsers: MinimumUser[], note: Note,
|
||||||
|
|
||||||
publishMainStream(u.id, 'mention', detailPackedNote);
|
publishMainStream(u.id, 'mention', detailPackedNote);
|
||||||
|
|
||||||
|
const webhooks = (await getActiveWebhooks()).filter(x => x.userId === u.id && x.on.includes('mention'));
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
webhookDeliver(webhook, {
|
||||||
|
type: 'mention',
|
||||||
|
note: detailPackedNote,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Create notification
|
// Create notification
|
||||||
nm.push(u.id, 'mention');
|
nm.push(u.id, 'mention');
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,16 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note,
|
||||||
const reactee = await Users.findOneBy({ id: note.userId });
|
const reactee = await Users.findOneBy({ id: note.userId });
|
||||||
dm.addDirectRecipe(reactee as IRemoteUser);
|
dm.addDirectRecipe(reactee as IRemoteUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (['public', 'home', 'followers'].includes(note.visibility)) {
|
||||||
dm.addFollowersRecipe();
|
dm.addFollowersRecipe();
|
||||||
|
} else if (note.visibility === 'specified') {
|
||||||
|
const visibleUsers = await Promise.all(note.visibleUserIds.map(id => Users.findOneBy({ id })));
|
||||||
|
for (const u of visibleUsers.filter(u => u && Users.isRemoteUser(u))) {
|
||||||
|
dm.addDirectRecipe(u as IRemoteUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dm.execute();
|
dm.execute();
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
|
@ -35,20 +35,20 @@
|
||||||
lodash "^4.17.19"
|
lodash "^4.17.19"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@bull-board/api@3.10.1":
|
"@bull-board/api@3.10.2":
|
||||||
version "3.10.1"
|
version "3.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/@bull-board/api/-/api-3.10.1.tgz#c9608d501c887abcfa8f1907bc3dedee179bdea3"
|
resolved "https://registry.yarnpkg.com/@bull-board/api/-/api-3.10.2.tgz#382450b703c671bb64eeb4d76f139b5e172d1fde"
|
||||||
integrity sha512-ZYjNBdoBQu+UVbLAHQuEhJL96C+i7vYioc2n7FL/XoVea44XIw2WiKFcFxq0LnActPErja26QyZBQht23ph1lg==
|
integrity sha512-jufgsRvAZpUoq/IbmNhwRPQKav6oFUTMjgq0Z200cvNgyFkVDexPhNKNrXdhxaKhBOass4CWvgyQQntDlvCaoQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
redis-info "^3.0.8"
|
redis-info "^3.0.8"
|
||||||
|
|
||||||
"@bull-board/koa@3.10.1":
|
"@bull-board/koa@3.10.2":
|
||||||
version "3.10.1"
|
version "3.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/@bull-board/koa/-/koa-3.10.1.tgz#205641ae9721ec71303c4f16dc27eca1f71ca131"
|
resolved "https://registry.yarnpkg.com/@bull-board/koa/-/koa-3.10.2.tgz#b50049355913eb049471169faec278d30bb44559"
|
||||||
integrity sha512-+mxdnu7idjd75WqUklJbPzrQU6NJzgQCT+BLKCyqOBsWzpfEwaac6QaIXOiuPwgwG2VjH90HWIcWr+2BQB9c1w==
|
integrity sha512-SJu+yoE/823sjif003X7030Cj8FmbQ+shUN3LPcUlQ9+0tIQ6ao0+FifJ4uhFnp1CN6FWpn+DCAf4vlC771PNQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@bull-board/api" "3.10.1"
|
"@bull-board/api" "3.10.2"
|
||||||
"@bull-board/ui" "3.10.1"
|
"@bull-board/ui" "3.10.2"
|
||||||
ejs "^3.1.6"
|
ejs "^3.1.6"
|
||||||
koa "^2.13.1"
|
koa "^2.13.1"
|
||||||
koa-mount "^4.0.0"
|
koa-mount "^4.0.0"
|
||||||
|
@ -56,12 +56,12 @@
|
||||||
koa-static "^5.0.0"
|
koa-static "^5.0.0"
|
||||||
koa-views "^7.0.1"
|
koa-views "^7.0.1"
|
||||||
|
|
||||||
"@bull-board/ui@3.10.1":
|
"@bull-board/ui@3.10.2":
|
||||||
version "3.10.1"
|
version "3.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/@bull-board/ui/-/ui-3.10.1.tgz#edf7c7752a78d9829f7a944bb87a0e70812b749f"
|
resolved "https://registry.yarnpkg.com/@bull-board/ui/-/ui-3.10.2.tgz#ab6400b1cbd459604b9e8afeaef9e3cc235d1dd9"
|
||||||
integrity sha512-K2qEAvTuyHZxUdK31HaBb9sdTFSOSKAZkxsl/LeiT4FGNF/h54iYGmWF9+HSFytggcnGdM0XnK3wLihCaIQAOQ==
|
integrity sha512-XFFbnJjZZDoMxntNdmgJoyTlEvMcCfNqeC/QPiqTJU0X/k0cxWDx36tw83PKjN+lKxPjzN/WNpTebYZPKV78Yg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@bull-board/api" "3.10.1"
|
"@bull-board/api" "3.10.2"
|
||||||
|
|
||||||
"@cspotcode/source-map-consumer@0.8.0":
|
"@cspotcode/source-map-consumer@0.8.0":
|
||||||
version "0.8.0"
|
version "0.8.0"
|
||||||
|
@ -244,10 +244,10 @@
|
||||||
require-from-string "^2.0.2"
|
require-from-string "^2.0.2"
|
||||||
uri-js "^4.2.2"
|
uri-js "^4.2.2"
|
||||||
|
|
||||||
"@redocly/openapi-core@1.0.0-beta.90":
|
"@redocly/openapi-core@1.0.0-beta.91":
|
||||||
version "1.0.0-beta.90"
|
version "1.0.0-beta.91"
|
||||||
resolved "https://registry.yarnpkg.com/@redocly/openapi-core/-/openapi-core-1.0.0-beta.90.tgz#edf53b23314368e190b005e1958c1f4a7dfaa2c3"
|
resolved "https://registry.yarnpkg.com/@redocly/openapi-core/-/openapi-core-1.0.0-beta.91.tgz#58dbd8c3cad9ef82f2437c6bbeb6a14dd1bc537d"
|
||||||
integrity sha512-MvkME+AWCBexyJyNp/sVFRUBjxCSk5CQ+CAozkwm0t/HusXp9G+kH26+e9giD6Fms129smr1qp3pCAUbwJZzZA==
|
integrity sha512-8RhZGn5jSoy3oZE0sAdXxhPPHrqKgy2JVJzLqjgX9LDjNf7cXOTYOXkXIkjv1tfZHFBV/H7c08rRLEdxnzn0dg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@redocly/ajv" "^8.6.4"
|
"@redocly/ajv" "^8.6.4"
|
||||||
"@types/node" "^14.11.8"
|
"@types/node" "^14.11.8"
|
||||||
|
@ -850,14 +850,14 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@5.16.0":
|
"@typescript-eslint/eslint-plugin@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz#78f246dd8d1b528fc5bfca99a8a64d4023a3d86d"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz#704eb4e75039000531255672bf1c85ee85cf1d67"
|
||||||
integrity sha512-SJoba1edXvQRMmNI505Uo4XmGbxCK9ARQpkvOd00anxzri9RNQk0DDCxD+LIl+jYhkzOJiOMMKYEHnHEODjdCw==
|
integrity sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/scope-manager" "5.16.0"
|
"@typescript-eslint/scope-manager" "5.17.0"
|
||||||
"@typescript-eslint/type-utils" "5.16.0"
|
"@typescript-eslint/type-utils" "5.17.0"
|
||||||
"@typescript-eslint/utils" "5.16.0"
|
"@typescript-eslint/utils" "5.17.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
functional-red-black-tree "^1.0.1"
|
functional-red-black-tree "^1.0.1"
|
||||||
ignore "^5.1.8"
|
ignore "^5.1.8"
|
||||||
|
@ -865,69 +865,69 @@
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/parser@5.16.0":
|
"@typescript-eslint/parser@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.16.0.tgz#e4de1bde4b4dad5b6124d3da227347616ed55508"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.17.0.tgz#7def77d5bcd8458d12d52909118cf3f0a45f89d5"
|
||||||
integrity sha512-fkDq86F0zl8FicnJtdXakFs4lnuebH6ZADDw6CYQv0UZeIjHvmEw87m9/29nk2Dv5Lmdp0zQ3zDQhiMWQf/GbA==
|
integrity sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/scope-manager" "5.16.0"
|
"@typescript-eslint/scope-manager" "5.17.0"
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/typescript-estree" "5.16.0"
|
"@typescript-eslint/typescript-estree" "5.17.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager@5.16.0":
|
"@typescript-eslint/scope-manager@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.16.0.tgz#7e7909d64bd0c4d8aef629cdc764b9d3e1d3a69a"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz#4cea7d0e0bc0e79eb60cad431c89120987c3f952"
|
||||||
integrity sha512-P+Yab2Hovg8NekLIR/mOElCDPyGgFZKhGoZA901Yax6WR6HVeGLbsqJkZ+Cvk5nts/dAlFKm8PfL43UZnWdpIQ==
|
integrity sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/visitor-keys" "5.16.0"
|
"@typescript-eslint/visitor-keys" "5.17.0"
|
||||||
|
|
||||||
"@typescript-eslint/type-utils@5.16.0":
|
"@typescript-eslint/type-utils@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.16.0.tgz#b482bdde1d7d7c0c7080f7f2f67ea9580b9e0692"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.17.0.tgz#1c4549d68c89877662224aabb29fbbebf5fc9672"
|
||||||
integrity sha512-SKygICv54CCRl1Vq5ewwQUJV/8padIWvPgCxlWPGO/OgQLCijY9G7lDu6H+mqfQtbzDNlVjzVWQmeqbLMBLEwQ==
|
integrity sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/utils" "5.16.0"
|
"@typescript-eslint/utils" "5.17.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/types@5.16.0":
|
"@typescript-eslint/types@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.16.0.tgz#5827b011982950ed350f075eaecb7f47d3c643ee"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.17.0.tgz#861ec9e669ffa2aa9b873dd4d28d9b1ce26d216f"
|
||||||
integrity sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==
|
integrity sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@5.16.0":
|
"@typescript-eslint/typescript-estree@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.16.0.tgz#32259459ec62f5feddca66adc695342f30101f61"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz#a7cba7dfc8f9cc2ac78c18584e684507df4f2488"
|
||||||
integrity sha512-SE4VfbLWUZl9MR+ngLSARptUv2E8brY0luCdgmUevU6arZRY/KxYoLI/3V/yxaURR8tLRN7bmZtJdgmzLHI6pQ==
|
integrity sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/visitor-keys" "5.16.0"
|
"@typescript-eslint/visitor-keys" "5.17.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
globby "^11.0.4"
|
globby "^11.0.4"
|
||||||
is-glob "^4.0.3"
|
is-glob "^4.0.3"
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/utils@5.16.0":
|
"@typescript-eslint/utils@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.16.0.tgz#42218b459d6d66418a4eb199a382bdc261650679"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.17.0.tgz#549a9e1d491c6ccd3624bc3c1b098f5cfb45f306"
|
||||||
integrity sha512-iYej2ER6AwmejLWMWzJIHy3nPJeGDuCqf8Jnb+jAQVoPpmWzwQOfa9hWVB8GIQE5gsCv/rfN4T+AYb/V06WseQ==
|
integrity sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/json-schema" "^7.0.9"
|
"@types/json-schema" "^7.0.9"
|
||||||
"@typescript-eslint/scope-manager" "5.16.0"
|
"@typescript-eslint/scope-manager" "5.17.0"
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/typescript-estree" "5.16.0"
|
"@typescript-eslint/typescript-estree" "5.17.0"
|
||||||
eslint-scope "^5.1.1"
|
eslint-scope "^5.1.1"
|
||||||
eslint-utils "^3.0.0"
|
eslint-utils "^3.0.0"
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys@5.16.0":
|
"@typescript-eslint/visitor-keys@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.16.0.tgz#f27dc3b943e6317264c7492e390c6844cd4efbbb"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz#52daae45c61b0211b4c81b53a71841911e479128"
|
||||||
integrity sha512-jqxO8msp5vZDhikTwq9ubyMHqZ67UIvawohr4qF3KhlpL7gzSjOd+8471H3nh5LyABkaI85laEKKU8SnGUK5/g==
|
integrity sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
eslint-visitor-keys "^3.0.0"
|
eslint-visitor-keys "^3.0.0"
|
||||||
|
|
||||||
"@ungap/promise-all-settled@1.1.2":
|
"@ungap/promise-all-settled@1.1.2":
|
||||||
|
@ -1271,10 +1271,10 @@ autwh@0.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
oauth "0.9.15"
|
oauth "0.9.15"
|
||||||
|
|
||||||
aws-sdk@2.1100.0:
|
aws-sdk@2.1105.0:
|
||||||
version "2.1100.0"
|
version "2.1105.0"
|
||||||
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1100.0.tgz#20bbabc12fbc316067ba02af66bf371a455af9e3"
|
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1105.0.tgz#3e63129f2aca254f1d6d5a1580b988bb786e98fa"
|
||||||
integrity sha512-StLSQCYFmFPxjoMntIb+8jUZ0vzmq3xkrwG5e/4qU1bSGWCmhhjvz6c+4j38AnIy8MFV1+tV8RArbhLUEV2dGw==
|
integrity sha512-YZ6IbKvtiw8noD/Iuyp3hXNX5NmhJ2xSU4598pZr55CfnIQ0oU5ZwtQqLPG8E07ouA363/moCYddIAVGYSkQ+A==
|
||||||
dependencies:
|
dependencies:
|
||||||
buffer "4.9.2"
|
buffer "4.9.2"
|
||||||
events "1.1.1"
|
events "1.1.1"
|
||||||
|
@ -2715,10 +2715,10 @@ eslint-visitor-keys@^3.3.0:
|
||||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
||||||
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
||||||
|
|
||||||
eslint@8.11.0:
|
eslint@8.12.0:
|
||||||
version "8.11.0"
|
version "8.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.11.0.tgz#88b91cfba1356fc10bb9eb592958457dfe09fb37"
|
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.12.0.tgz#c7a5bd1cfa09079aae64c9076c07eada66a46e8e"
|
||||||
integrity sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==
|
integrity sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint/eslintrc" "^1.2.1"
|
"@eslint/eslintrc" "^1.2.1"
|
||||||
"@humanwhocodes/config-array" "^0.9.2"
|
"@humanwhocodes/config-array" "^0.9.2"
|
||||||
|
@ -3042,9 +3042,9 @@ fluent-ffmpeg@2.1.2:
|
||||||
which "^1.1.1"
|
which "^1.1.1"
|
||||||
|
|
||||||
follow-redirects@^1.14.4:
|
follow-redirects@^1.14.4:
|
||||||
version "1.14.7"
|
version "1.14.8"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
|
||||||
integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
|
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==
|
||||||
|
|
||||||
form-data-encoder@1.7.1:
|
form-data-encoder@1.7.1:
|
||||||
version "1.7.1"
|
version "1.7.1"
|
||||||
|
@ -3316,10 +3316,10 @@ got@11.5.1:
|
||||||
p-cancelable "^2.0.0"
|
p-cancelable "^2.0.0"
|
||||||
responselike "^2.0.0"
|
responselike "^2.0.0"
|
||||||
|
|
||||||
got@12.0.2:
|
got@12.0.3:
|
||||||
version "12.0.2"
|
version "12.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/got/-/got-12.0.2.tgz#8ce4c3baa50bb18a0858d2539caa0fac19e109bf"
|
resolved "https://registry.yarnpkg.com/got/-/got-12.0.3.tgz#c7314daab26d42039e624adbf98f6d442e5de749"
|
||||||
integrity sha512-Zi4yHiqCgaorUbknr/RHFBsC3XqjSodaw0F3qxlqAqyj+OGYZl37/uy01R0qz++KANKQYdY5FHJ0okXZpEzwWQ==
|
integrity sha512-hmdcXi/S0gcAtDg4P8j/rM7+j3o1Aq6bXhjxkDhRY2ipe7PHpvx/14DgTY2czHOLaGeU8VRvRecidwfu9qdFug==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@sindresorhus/is" "^4.6.0"
|
"@sindresorhus/is" "^4.6.0"
|
||||||
"@szmarczak/http-timer" "^5.0.1"
|
"@szmarczak/http-timer" "^5.0.1"
|
||||||
|
@ -4718,7 +4718,7 @@ minimatch@^3.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5:
|
minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6:
|
||||||
version "1.2.6"
|
version "1.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||||
|
@ -4918,16 +4918,11 @@ nano-time@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
big-integer "^1.6.16"
|
big-integer "^1.6.16"
|
||||||
|
|
||||||
nanoid@3.3.1:
|
nanoid@3.3.1, nanoid@^3.1.30:
|
||||||
version "3.3.1"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35"
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35"
|
||||||
integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
|
integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
|
||||||
|
|
||||||
nanoid@^3.1.30:
|
|
||||||
version "3.1.30"
|
|
||||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
|
|
||||||
integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==
|
|
||||||
|
|
||||||
napi-build-utils@^1.0.1:
|
napi-build-utils@^1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
|
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
|
||||||
|
@ -6826,14 +6821,14 @@ tsc-alias@1.4.1:
|
||||||
mylas "^2.1.4"
|
mylas "^2.1.4"
|
||||||
normalize-path "^3.0.0"
|
normalize-path "^3.0.0"
|
||||||
|
|
||||||
tsconfig-paths@3.14.0:
|
tsconfig-paths@3.14.1:
|
||||||
version "3.14.0"
|
version "3.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.0.tgz#4fcc48f9ccea8826c41b9ca093479de7f5018976"
|
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"
|
||||||
integrity sha512-cg/1jAZoL57R39+wiw4u/SCC6Ic9Q5NqjBOb+9xISedOYurfog9ZNmKJSxAnb2m/5Bq4lE9lhUcau33Ml8DM0g==
|
integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/json5" "^0.0.29"
|
"@types/json5" "^0.0.29"
|
||||||
json5 "^1.0.1"
|
json5 "^1.0.1"
|
||||||
minimist "^1.2.0"
|
minimist "^1.2.6"
|
||||||
strip-bom "^3.0.0"
|
strip-bom "^3.0.0"
|
||||||
|
|
||||||
tsconfig-paths@^3.12.0:
|
tsconfig-paths@^3.12.0:
|
||||||
|
@ -6944,10 +6939,10 @@ typedarray@^0.0.6:
|
||||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||||
|
|
||||||
typeorm@0.3.3:
|
typeorm@0.3.4:
|
||||||
version "0.3.3"
|
version "0.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.3.tgz#ada8d01c16a65bababd08222c81c682afa941f45"
|
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.4.tgz#6608f7efb15c40f3fa2863cefb45ff78a208c40c"
|
||||||
integrity sha512-01gesp6ikGMLGUxBDzEn4qcIiVW3gWzZsUPE6ETqzSRuHL4pCAWHvTPELN1agirBJrZNxhxiVFUXCmnPXYNfrg==
|
integrity sha512-6v3HH12viDhIQwQDod/B0Plt1o7IYIVDxP7zwatD6fzN+IDdqTTinW/sWNw84Edpbhh2t7XILTaQEqj0NXFP/Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@sqltools/formatter" "^1.2.2"
|
"@sqltools/formatter" "^1.2.2"
|
||||||
app-root-path "^3.0.0"
|
app-root-path "^3.0.0"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"watch": "webpack --watch",
|
"watch": "webpack --watch",
|
||||||
"build": "webpack",
|
"build": "webpack",
|
||||||
"lint": "eslint --quiet src/**/*.{ts,vue}"
|
"lint": "eslint --quiet 'src/**/*.{ts,vue}'"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"chokidar": "^3.3.1",
|
"chokidar": "^3.3.1",
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
"@types/webpack-stream": "3.2.12",
|
"@types/webpack-stream": "3.2.12",
|
||||||
"@types/websocket": "1.0.5",
|
"@types/websocket": "1.0.5",
|
||||||
"@types/ws": "8.5.3",
|
"@types/ws": "8.5.3",
|
||||||
"@typescript-eslint/parser": "5.16.0",
|
"@typescript-eslint/parser": "5.17.0",
|
||||||
"@vue/compiler-sfc": "3.2.31",
|
"@vue/compiler-sfc": "3.2.31",
|
||||||
"abort-controller": "3.0.0",
|
"abort-controller": "3.0.0",
|
||||||
"autobind-decorator": "2.4.0",
|
"autobind-decorator": "2.4.0",
|
||||||
|
@ -49,10 +49,10 @@
|
||||||
"compare-versions": "4.1.3",
|
"compare-versions": "4.1.3",
|
||||||
"content-disposition": "0.5.4",
|
"content-disposition": "0.5.4",
|
||||||
"css-loader": "6.7.1",
|
"css-loader": "6.7.1",
|
||||||
"cssnano": "5.1.5",
|
"cssnano": "5.1.6",
|
||||||
"date-fns": "2.28.0",
|
"date-fns": "2.28.0",
|
||||||
"escape-regexp": "0.0.1",
|
"escape-regexp": "0.0.1",
|
||||||
"eslint": "8.11.0",
|
"eslint": "8.12.0",
|
||||||
"eslint-plugin-vue": "8.5.0",
|
"eslint-plugin-vue": "8.5.0",
|
||||||
"eventemitter3": "4.0.7",
|
"eventemitter3": "4.0.7",
|
||||||
"feed": "4.2.2",
|
"feed": "4.2.2",
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
"ms": "2.1.3",
|
"ms": "2.1.3",
|
||||||
"nested-property": "4.0.0",
|
"nested-property": "4.0.0",
|
||||||
"parse5": "6.0.1",
|
"parse5": "6.0.1",
|
||||||
"photoswipe": "git+https://github.com/dimsemenov/photoswipe#v5-beta",
|
"photoswipe": "5.2.2",
|
||||||
"portscanner": "2.2.0",
|
"portscanner": "2.2.0",
|
||||||
"postcss": "8.4.12",
|
"postcss": "8.4.12",
|
||||||
"postcss-loader": "6.2.1",
|
"postcss-loader": "6.2.1",
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
"reflect-metadata": "0.1.13",
|
"reflect-metadata": "0.1.13",
|
||||||
"rndstr": "1.0.0",
|
"rndstr": "1.0.0",
|
||||||
"s-age": "1.1.2",
|
"s-age": "1.1.2",
|
||||||
"sass": "1.49.9",
|
"sass": "1.49.10",
|
||||||
"sass-loader": "12.6.0",
|
"sass-loader": "12.6.0",
|
||||||
"seedrandom": "3.0.5",
|
"seedrandom": "3.0.5",
|
||||||
"strict-event-emitter-types": "2.0.0",
|
"strict-event-emitter-types": "2.0.0",
|
||||||
|
@ -117,9 +117,9 @@
|
||||||
"ws": "8.5.0"
|
"ws": "8.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "5.16.0",
|
"@typescript-eslint/eslint-plugin": "5.17.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"cypress": "9.5.2",
|
"cypress": "9.5.3",
|
||||||
"eslint-plugin-import": "2.25.4",
|
"eslint-plugin-import": "2.25.4",
|
||||||
"start-server-and-test": "1.14.0"
|
"start-server-and-test": "1.14.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ export default defineComponent({
|
||||||
margin-right: 0.75em;
|
margin-right: 0.75em;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
opacity: 0.8;
|
color: var(--fgTransparentWeak);
|
||||||
|
|
||||||
&:empty {
|
&:empty {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<MkModal ref="modal" v-slot="{ type, maxHeight }" :prefer-type="preferedModalType" :anchor="{ x: 'right', y: 'center' }" :transparent-bg="true" :src="src" @click="modal.close()" @closed="emit('closed')">
|
<MkModal ref="modal" v-slot="{ type, maxHeight }" :prefer-type="preferedModalType" :anchor="anchor" :transparent-bg="true" :src="src" @click="modal.close()" @closed="emit('closed')">
|
||||||
<div class="szkkfdyq _popup _shadow" :class="{ asDrawer: type === 'drawer' }" :style="{ maxHeight: maxHeight ? maxHeight + 'px' : '' }">
|
<div class="szkkfdyq _popup _shadow" :class="{ asDrawer: type === 'drawer' }" :style="{ maxHeight: maxHeight ? maxHeight + 'px' : '' }">
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<template v-for="item in items">
|
<template v-for="item in items">
|
||||||
|
@ -44,7 +44,9 @@ import { deviceKind } from '@/scripts/device-kind';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
src?: HTMLElement;
|
src?: HTMLElement;
|
||||||
|
anchor?: { x: string; y: string; };
|
||||||
}>(), {
|
}>(), {
|
||||||
|
anchor: () => ({ x: 'right', y: 'center' }),
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import * as misskey from 'misskey-js';
|
import * as misskey from 'misskey-js';
|
||||||
import PhotoSwipeLightbox from 'photoswipe/dist/photoswipe-lightbox.esm.js';
|
import PhotoSwipeLightbox from 'photoswipe/lightbox';
|
||||||
import PhotoSwipe from 'photoswipe/dist/photoswipe.esm.js';
|
import PhotoSwipe from 'photoswipe';
|
||||||
import 'photoswipe/dist/photoswipe.css';
|
import 'photoswipe/style.css';
|
||||||
import XBanner from './media-banner.vue';
|
import XBanner from './media-banner.vue';
|
||||||
import XImage from './media-image.vue';
|
import XImage from './media-image.vue';
|
||||||
import XVideo from './media-video.vue';
|
import XVideo from './media-video.vue';
|
||||||
|
|
|
@ -148,6 +148,11 @@ const menuDef = computed(() => [{
|
||||||
text: 'API',
|
text: 'API',
|
||||||
to: '/settings/api',
|
to: '/settings/api',
|
||||||
active: page.value === 'api',
|
active: page.value === 'api',
|
||||||
|
}, {
|
||||||
|
icon: 'fas fa-bolt',
|
||||||
|
text: 'Webhook',
|
||||||
|
to: '/settings/webhook',
|
||||||
|
active: page.value === 'webhook',
|
||||||
}, {
|
}, {
|
||||||
icon: 'fas fa-ellipsis-h',
|
icon: 'fas fa-ellipsis-h',
|
||||||
text: i18n.ts.other,
|
text: i18n.ts.other,
|
||||||
|
@ -192,6 +197,9 @@ const component = computed(() => {
|
||||||
case 'security': return defineAsyncComponent(() => import('./security.vue'));
|
case 'security': return defineAsyncComponent(() => import('./security.vue'));
|
||||||
case '2fa': return defineAsyncComponent(() => import('./2fa.vue'));
|
case '2fa': return defineAsyncComponent(() => import('./2fa.vue'));
|
||||||
case 'api': return defineAsyncComponent(() => import('./api.vue'));
|
case 'api': return defineAsyncComponent(() => import('./api.vue'));
|
||||||
|
case 'webhook': return defineAsyncComponent(() => import('./webhook.vue'));
|
||||||
|
case 'webhook/new': return defineAsyncComponent(() => import('./webhook.new.vue'));
|
||||||
|
case 'webhook/edit': return defineAsyncComponent(() => import('./webhook.edit.vue'));
|
||||||
case 'apps': return defineAsyncComponent(() => import('./apps.vue'));
|
case 'apps': return defineAsyncComponent(() => import('./apps.vue'));
|
||||||
case 'other': return defineAsyncComponent(() => import('./other.vue'));
|
case 'other': return defineAsyncComponent(() => import('./other.vue'));
|
||||||
case 'general': return defineAsyncComponent(() => import('./general.vue'));
|
case 'general': return defineAsyncComponent(() => import('./general.vue'));
|
||||||
|
|
89
packages/client/src/pages/settings/webhook.edit.vue
Normal file
89
packages/client/src/pages/settings/webhook.edit.vue
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<template>
|
||||||
|
<div class="_formRoot">
|
||||||
|
<FormInput v-model="name" class="_formBlock">
|
||||||
|
<template #label>Name</template>
|
||||||
|
</FormInput>
|
||||||
|
|
||||||
|
<FormInput v-model="url" type="url" class="_formBlock">
|
||||||
|
<template #label>URL</template>
|
||||||
|
</FormInput>
|
||||||
|
|
||||||
|
<FormInput v-model="secret" class="_formBlock">
|
||||||
|
<template #prefix><i class="fas fa-lock"></i></template>
|
||||||
|
<template #label>Secret</template>
|
||||||
|
</FormInput>
|
||||||
|
|
||||||
|
<FormSection>
|
||||||
|
<template #label>Events</template>
|
||||||
|
|
||||||
|
<FormSwitch v-model="event_follow" class="_formBlock">Follow</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_followed" class="_formBlock">Followed</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_note" class="_formBlock">Note</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_reply" class="_formBlock">Reply</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_renote" class="_formBlock">Renote</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_reaction" class="_formBlock">Reaction</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_mention" class="_formBlock">Mention</FormSwitch>
|
||||||
|
</FormSection>
|
||||||
|
|
||||||
|
<FormSwitch v-model="active" class="_formBlock">Active</FormSwitch>
|
||||||
|
|
||||||
|
<div class="_formBlock" style="display: flex; gap: var(--margin); flex-wrap: wrap;">
|
||||||
|
<FormButton primary inline @click="save"><i class="fas fa-check"></i> {{ i18n.ts.save }}</FormButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { } from 'vue';
|
||||||
|
import FormInput from '@/components/form/input.vue';
|
||||||
|
import FormSection from '@/components/form/section.vue';
|
||||||
|
import FormSwitch from '@/components/form/switch.vue';
|
||||||
|
import FormButton from '@/components/ui/button.vue';
|
||||||
|
import * as os from '@/os';
|
||||||
|
import * as symbols from '@/symbols';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
|
const webhook = await os.api('i/webhooks/show', {
|
||||||
|
webhookId: new URLSearchParams(window.location.search).get('id')
|
||||||
|
});
|
||||||
|
|
||||||
|
let name = $ref(webhook.name);
|
||||||
|
let url = $ref(webhook.url);
|
||||||
|
let secret = $ref(webhook.secret);
|
||||||
|
let active = $ref(webhook.active);
|
||||||
|
|
||||||
|
let event_follow = $ref(webhook.on.includes('follow'));
|
||||||
|
let event_followed = $ref(webhook.on.includes('followed'));
|
||||||
|
let event_note = $ref(webhook.on.includes('note'));
|
||||||
|
let event_reply = $ref(webhook.on.includes('reply'));
|
||||||
|
let event_renote = $ref(webhook.on.includes('renote'));
|
||||||
|
let event_reaction = $ref(webhook.on.includes('reaction'));
|
||||||
|
let event_mention = $ref(webhook.on.includes('mention'));
|
||||||
|
|
||||||
|
async function save(): Promise<void> {
|
||||||
|
const events = [];
|
||||||
|
if (event_follow) events.push('follow');
|
||||||
|
if (event_followed) events.push('followed');
|
||||||
|
if (event_note) events.push('note');
|
||||||
|
if (event_reply) events.push('reply');
|
||||||
|
if (event_renote) events.push('renote');
|
||||||
|
if (event_reaction) events.push('reaction');
|
||||||
|
if (event_mention) events.push('mention');
|
||||||
|
|
||||||
|
os.apiWithDialog('i/webhooks/update', {
|
||||||
|
name,
|
||||||
|
url,
|
||||||
|
secret,
|
||||||
|
on: events,
|
||||||
|
active,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
[symbols.PAGE_INFO]: {
|
||||||
|
title: 'Edit webhook',
|
||||||
|
icon: 'fas fa-bolt',
|
||||||
|
bg: 'var(--bg)',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
81
packages/client/src/pages/settings/webhook.new.vue
Normal file
81
packages/client/src/pages/settings/webhook.new.vue
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<template>
|
||||||
|
<div class="_formRoot">
|
||||||
|
<FormInput v-model="name" class="_formBlock">
|
||||||
|
<template #label>Name</template>
|
||||||
|
</FormInput>
|
||||||
|
|
||||||
|
<FormInput v-model="url" type="url" class="_formBlock">
|
||||||
|
<template #label>URL</template>
|
||||||
|
</FormInput>
|
||||||
|
|
||||||
|
<FormInput v-model="secret" class="_formBlock">
|
||||||
|
<template #prefix><i class="fas fa-lock"></i></template>
|
||||||
|
<template #label>Secret</template>
|
||||||
|
</FormInput>
|
||||||
|
|
||||||
|
<FormSection>
|
||||||
|
<template #label>Events</template>
|
||||||
|
|
||||||
|
<FormSwitch v-model="event_follow" class="_formBlock">Follow</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_followed" class="_formBlock">Followed</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_note" class="_formBlock">Note</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_reply" class="_formBlock">Reply</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_renote" class="_formBlock">Renote</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_reaction" class="_formBlock">Reaction</FormSwitch>
|
||||||
|
<FormSwitch v-model="event_mention" class="_formBlock">Mention</FormSwitch>
|
||||||
|
</FormSection>
|
||||||
|
|
||||||
|
<div class="_formBlock" style="display: flex; gap: var(--margin); flex-wrap: wrap;">
|
||||||
|
<FormButton primary inline @click="create"><i class="fas fa-check"></i> {{ i18n.ts.create }}</FormButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { } from 'vue';
|
||||||
|
import FormInput from '@/components/form/input.vue';
|
||||||
|
import FormSection from '@/components/form/section.vue';
|
||||||
|
import FormSwitch from '@/components/form/switch.vue';
|
||||||
|
import FormButton from '@/components/ui/button.vue';
|
||||||
|
import * as os from '@/os';
|
||||||
|
import * as symbols from '@/symbols';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
|
let name = $ref('');
|
||||||
|
let url = $ref('');
|
||||||
|
let secret = $ref('');
|
||||||
|
|
||||||
|
let event_follow = $ref(true);
|
||||||
|
let event_followed = $ref(true);
|
||||||
|
let event_note = $ref(true);
|
||||||
|
let event_reply = $ref(true);
|
||||||
|
let event_renote = $ref(true);
|
||||||
|
let event_reaction = $ref(true);
|
||||||
|
let event_mention = $ref(true);
|
||||||
|
|
||||||
|
async function create(): Promise<void> {
|
||||||
|
const events = [];
|
||||||
|
if (event_follow) events.push('follow');
|
||||||
|
if (event_followed) events.push('followed');
|
||||||
|
if (event_note) events.push('note');
|
||||||
|
if (event_reply) events.push('reply');
|
||||||
|
if (event_renote) events.push('renote');
|
||||||
|
if (event_reaction) events.push('reaction');
|
||||||
|
if (event_mention) events.push('mention');
|
||||||
|
|
||||||
|
os.apiWithDialog('i/webhooks/create', {
|
||||||
|
name,
|
||||||
|
url,
|
||||||
|
secret,
|
||||||
|
on: events,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
[symbols.PAGE_INFO]: {
|
||||||
|
title: 'Create new webhook',
|
||||||
|
icon: 'fas fa-bolt',
|
||||||
|
bg: 'var(--bg)',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
52
packages/client/src/pages/settings/webhook.vue
Normal file
52
packages/client/src/pages/settings/webhook.vue
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<template>
|
||||||
|
<div class="_formRoot">
|
||||||
|
<FormSection>
|
||||||
|
<FormLink :to="`/settings/webhook/new`">
|
||||||
|
Create webhook
|
||||||
|
</FormLink>
|
||||||
|
</FormSection>
|
||||||
|
|
||||||
|
<FormSection>
|
||||||
|
<MkPagination :pagination="pagination">
|
||||||
|
<template v-slot="{items}">
|
||||||
|
<FormLink v-for="webhook in items" :key="webhook.id" :to="`/settings/webhook/edit?id=${webhook.id}`" class="_formBlock">
|
||||||
|
<template #icon>
|
||||||
|
<i v-if="webhook.active === false" class="fas fa-circle-pause"></i>
|
||||||
|
<i v-else-if="webhook.latestStatus === null" class="far fa-circle"></i>
|
||||||
|
<i v-else-if="[200, 201, 204].includes(webhook.latestStatus)" class="fas fa-check" :style="{ color: 'var(--success)' }"></i>
|
||||||
|
<i v-else class="fas fa-triangle-exclamation" :style="{ color: 'var(--error)' }"></i>
|
||||||
|
</template>
|
||||||
|
{{ webhook.name || webhook.url }}
|
||||||
|
<template #suffix>
|
||||||
|
<MkTime v-if="webhook.latestSentAt" :time="webhook.latestSentAt"></MkTime>
|
||||||
|
</template>
|
||||||
|
</FormLink>
|
||||||
|
</template>
|
||||||
|
</MkPagination>
|
||||||
|
</FormSection>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { } from 'vue';
|
||||||
|
import MkPagination from '@/components/ui/pagination.vue';
|
||||||
|
import FormSection from '@/components/form/section.vue';
|
||||||
|
import FormLink from '@/components/form/link.vue';
|
||||||
|
import { userPage } from '@/filters/user';
|
||||||
|
import * as os from '@/os';
|
||||||
|
import * as symbols from '@/symbols';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
|
const pagination = {
|
||||||
|
endpoint: 'i/webhooks/list' as const,
|
||||||
|
limit: 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
[symbols.PAGE_INFO]: {
|
||||||
|
title: 'Webhook',
|
||||||
|
icon: 'fas fa-bolt',
|
||||||
|
bg: 'var(--bg)',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -103,6 +103,7 @@ export default defineComponent({
|
||||||
more(ev) {
|
more(ev) {
|
||||||
os.popup(import('@/components/launch-pad.vue'), {
|
os.popup(import('@/components/launch-pad.vue'), {
|
||||||
src: ev.currentTarget ?? ev.target,
|
src: ev.currentTarget ?? ev.target,
|
||||||
|
anchor: { x: 'center', y: 'bottom' },
|
||||||
}, {
|
}, {
|
||||||
}, 'closed');
|
}, 'closed');
|
||||||
},
|
},
|
||||||
|
|
|
@ -121,9 +121,9 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
more(ev) {
|
more(ev) {
|
||||||
os.popup(import('@/components/launch-pad.vue'), {}, {
|
os.popup(import('@/components/launch-pad.vue'), {
|
||||||
src: ev.currentTarget ?? ev.target,
|
src: ev.currentTarget ?? ev.target,
|
||||||
}, 'closed');
|
}, {}, 'closed');
|
||||||
},
|
},
|
||||||
|
|
||||||
openAccountMenu:(ev) => {
|
openAccountMenu:(ev) => {
|
||||||
|
|
|
@ -128,8 +128,8 @@ if (deckStore.state.navWindow) {
|
||||||
document.documentElement.style.overflowY = 'hidden';
|
document.documentElement.style.overflowY = 'hidden';
|
||||||
document.documentElement.style.scrollBehavior = 'auto';
|
document.documentElement.style.scrollBehavior = 'auto';
|
||||||
window.addEventListener('wheel', (ev) => {
|
window.addEventListener('wheel', (ev) => {
|
||||||
if (getScrollContainer(ev.target as HTMLElement) == null) {
|
if (getScrollContainer(ev.target as HTMLElement) == null && ev.deltaX === 0) {
|
||||||
document.documentElement.scrollLeft += ev.deltaY > 0 ? 96 : -96;
|
document.documentElement.scrollLeft += ev.deltaY;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
loadDeck();
|
loadDeck();
|
||||||
|
|
|
@ -372,9 +372,9 @@ function onDrop(e) {
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
height: calc(100% - var(--deckColumnHeaderHeight));
|
height: calc(100% - var(--deckColumnHeaderHeight));
|
||||||
overflow: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden; // Safari does not supports clip
|
||||||
overscroll-behavior: contain;
|
overflow-x: clip;
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
|
@ -538,14 +538,14 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@5.16.0":
|
"@typescript-eslint/eslint-plugin@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz#78f246dd8d1b528fc5bfca99a8a64d4023a3d86d"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz#704eb4e75039000531255672bf1c85ee85cf1d67"
|
||||||
integrity sha512-SJoba1edXvQRMmNI505Uo4XmGbxCK9ARQpkvOd00anxzri9RNQk0DDCxD+LIl+jYhkzOJiOMMKYEHnHEODjdCw==
|
integrity sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/scope-manager" "5.16.0"
|
"@typescript-eslint/scope-manager" "5.17.0"
|
||||||
"@typescript-eslint/type-utils" "5.16.0"
|
"@typescript-eslint/type-utils" "5.17.0"
|
||||||
"@typescript-eslint/utils" "5.16.0"
|
"@typescript-eslint/utils" "5.17.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
functional-red-black-tree "^1.0.1"
|
functional-red-black-tree "^1.0.1"
|
||||||
ignore "^5.1.8"
|
ignore "^5.1.8"
|
||||||
|
@ -553,69 +553,69 @@
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/parser@5.16.0":
|
"@typescript-eslint/parser@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.16.0.tgz#e4de1bde4b4dad5b6124d3da227347616ed55508"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.17.0.tgz#7def77d5bcd8458d12d52909118cf3f0a45f89d5"
|
||||||
integrity sha512-fkDq86F0zl8FicnJtdXakFs4lnuebH6ZADDw6CYQv0UZeIjHvmEw87m9/29nk2Dv5Lmdp0zQ3zDQhiMWQf/GbA==
|
integrity sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/scope-manager" "5.16.0"
|
"@typescript-eslint/scope-manager" "5.17.0"
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/typescript-estree" "5.16.0"
|
"@typescript-eslint/typescript-estree" "5.17.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager@5.16.0":
|
"@typescript-eslint/scope-manager@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.16.0.tgz#7e7909d64bd0c4d8aef629cdc764b9d3e1d3a69a"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz#4cea7d0e0bc0e79eb60cad431c89120987c3f952"
|
||||||
integrity sha512-P+Yab2Hovg8NekLIR/mOElCDPyGgFZKhGoZA901Yax6WR6HVeGLbsqJkZ+Cvk5nts/dAlFKm8PfL43UZnWdpIQ==
|
integrity sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/visitor-keys" "5.16.0"
|
"@typescript-eslint/visitor-keys" "5.17.0"
|
||||||
|
|
||||||
"@typescript-eslint/type-utils@5.16.0":
|
"@typescript-eslint/type-utils@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.16.0.tgz#b482bdde1d7d7c0c7080f7f2f67ea9580b9e0692"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.17.0.tgz#1c4549d68c89877662224aabb29fbbebf5fc9672"
|
||||||
integrity sha512-SKygICv54CCRl1Vq5ewwQUJV/8padIWvPgCxlWPGO/OgQLCijY9G7lDu6H+mqfQtbzDNlVjzVWQmeqbLMBLEwQ==
|
integrity sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/utils" "5.16.0"
|
"@typescript-eslint/utils" "5.17.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/types@5.16.0":
|
"@typescript-eslint/types@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.16.0.tgz#5827b011982950ed350f075eaecb7f47d3c643ee"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.17.0.tgz#861ec9e669ffa2aa9b873dd4d28d9b1ce26d216f"
|
||||||
integrity sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==
|
integrity sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@5.16.0":
|
"@typescript-eslint/typescript-estree@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.16.0.tgz#32259459ec62f5feddca66adc695342f30101f61"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz#a7cba7dfc8f9cc2ac78c18584e684507df4f2488"
|
||||||
integrity sha512-SE4VfbLWUZl9MR+ngLSARptUv2E8brY0luCdgmUevU6arZRY/KxYoLI/3V/yxaURR8tLRN7bmZtJdgmzLHI6pQ==
|
integrity sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/visitor-keys" "5.16.0"
|
"@typescript-eslint/visitor-keys" "5.17.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
globby "^11.0.4"
|
globby "^11.0.4"
|
||||||
is-glob "^4.0.3"
|
is-glob "^4.0.3"
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/utils@5.16.0":
|
"@typescript-eslint/utils@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.16.0.tgz#42218b459d6d66418a4eb199a382bdc261650679"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.17.0.tgz#549a9e1d491c6ccd3624bc3c1b098f5cfb45f306"
|
||||||
integrity sha512-iYej2ER6AwmejLWMWzJIHy3nPJeGDuCqf8Jnb+jAQVoPpmWzwQOfa9hWVB8GIQE5gsCv/rfN4T+AYb/V06WseQ==
|
integrity sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/json-schema" "^7.0.9"
|
"@types/json-schema" "^7.0.9"
|
||||||
"@typescript-eslint/scope-manager" "5.16.0"
|
"@typescript-eslint/scope-manager" "5.17.0"
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/typescript-estree" "5.16.0"
|
"@typescript-eslint/typescript-estree" "5.17.0"
|
||||||
eslint-scope "^5.1.1"
|
eslint-scope "^5.1.1"
|
||||||
eslint-utils "^3.0.0"
|
eslint-utils "^3.0.0"
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys@5.16.0":
|
"@typescript-eslint/visitor-keys@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.16.0.tgz#f27dc3b943e6317264c7492e390c6844cd4efbbb"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz#52daae45c61b0211b4c81b53a71841911e479128"
|
||||||
integrity sha512-jqxO8msp5vZDhikTwq9ubyMHqZ67UIvawohr4qF3KhlpL7gzSjOd+8471H3nh5LyABkaI85laEKKU8SnGUK5/g==
|
integrity sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
eslint-visitor-keys "^3.0.0"
|
eslint-visitor-keys "^3.0.0"
|
||||||
|
|
||||||
"@ungap/promise-all-settled@1.1.2":
|
"@ungap/promise-all-settled@1.1.2":
|
||||||
|
@ -1064,12 +1064,7 @@ ansi-escapes@^4.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
type-fest "^0.21.3"
|
type-fest "^0.21.3"
|
||||||
|
|
||||||
ansi-regex@^5.0.0:
|
ansi-regex@^5.0.0, ansi-regex@^5.0.1:
|
||||||
version "5.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
|
||||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
|
||||||
|
|
||||||
ansi-regex@^5.0.1:
|
|
||||||
version "5.0.1"
|
version "5.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||||
|
@ -1693,12 +1688,10 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
||||||
shebang-command "^2.0.0"
|
shebang-command "^2.0.0"
|
||||||
which "^2.0.1"
|
which "^2.0.1"
|
||||||
|
|
||||||
css-declaration-sorter@^6.0.3:
|
css-declaration-sorter@^6.2.2:
|
||||||
version "6.0.3"
|
version "6.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz#9dfd8ea0df4cc7846827876fafb52314890c21a9"
|
resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz#bfd2f6f50002d6a3ae779a87d3a0c5d5b10e0f02"
|
||||||
integrity sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw==
|
integrity sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg==
|
||||||
dependencies:
|
|
||||||
timsort "^0.3.0"
|
|
||||||
|
|
||||||
css-loader@6.7.1:
|
css-loader@6.7.1:
|
||||||
version "6.7.1"
|
version "6.7.1"
|
||||||
|
@ -1779,12 +1772,12 @@ cssesc@^3.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||||
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
|
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
|
||||||
|
|
||||||
cssnano-preset-default@^5.2.5:
|
cssnano-preset-default@^5.2.6:
|
||||||
version "5.2.5"
|
version "5.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.5.tgz#267ded811a3e1664d78707f5355fcd89feeb38ac"
|
resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.6.tgz#3a2a17b7bccdbf27dbc6d4b9a8ae2c1f1720d50c"
|
||||||
integrity sha512-WopL7PzN7sos3X8B54/QGl+CZUh1f0qN4ds+y2d5EPwRSSc3jsitVw81O+Uyop0pXyOfPfZxnc+LmA8w/Ki/WQ==
|
integrity sha512-QwnYv/ZuNH0eWOxs3ME7w5uXXdWZKKXVGn1c6P877nPLl7SR8pAQQNe1CKbcPc+qpIbb2cq554Cv3QYG0MxTSQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
css-declaration-sorter "^6.0.3"
|
css-declaration-sorter "^6.2.2"
|
||||||
cssnano-utils "^3.1.0"
|
cssnano-utils "^3.1.0"
|
||||||
postcss-calc "^8.2.3"
|
postcss-calc "^8.2.3"
|
||||||
postcss-colormin "^5.3.0"
|
postcss-colormin "^5.3.0"
|
||||||
|
@ -1819,12 +1812,12 @@ cssnano-utils@^3.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861"
|
resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861"
|
||||||
integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==
|
integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==
|
||||||
|
|
||||||
cssnano@5.1.5:
|
cssnano@5.1.6:
|
||||||
version "5.1.5"
|
version "5.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.5.tgz#5f3f519538c7f1c182c527096892243db3e17397"
|
resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.6.tgz#8133722e93049ac5c284bbe5c32cbf7fc829ceca"
|
||||||
integrity sha512-VZO1e+bRRVixMeia1zKagrv0lLN1B/r/u12STGNNUFxnp97LIFgZHQa0JxqlwEkvzUyA9Oz/WnCTAFkdEbONmg==
|
integrity sha512-A7oX6Vxgpc/VzyKDTLEFpv6M0n06foVSWPAb+Xg0k6ikgSaI04SnGUKOQeBdvrXZCqhp3xdlii0cp+bUCgbCRQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
cssnano-preset-default "^5.2.5"
|
cssnano-preset-default "^5.2.6"
|
||||||
lilconfig "^2.0.3"
|
lilconfig "^2.0.3"
|
||||||
yaml "^1.10.2"
|
yaml "^1.10.2"
|
||||||
|
|
||||||
|
@ -1847,10 +1840,10 @@ csstype@^2.6.8:
|
||||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.13.tgz#a6893015b90e84dd6e85d0e3b442a1e84f2dbe0f"
|
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.13.tgz#a6893015b90e84dd6e85d0e3b442a1e84f2dbe0f"
|
||||||
integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==
|
integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==
|
||||||
|
|
||||||
cypress@9.5.2:
|
cypress@9.5.3:
|
||||||
version "9.5.2"
|
version "9.5.3"
|
||||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.5.2.tgz#8fb6ee4a890fbc35620800810bf6fb11995927bd"
|
resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.5.3.tgz#7c56b50fc1f1aa69ef10b271d895aeb4a1d7999e"
|
||||||
integrity sha512-gYiQYvJozMzDOriUV1rCt6CeRM/pRK4nhwGJj3nJQyX2BoUdTCVwp30xDMKc771HiNVhBtgj5o5/iBdVDVXQUg==
|
integrity sha512-ItelIVmqMTnKYbo1JrErhsGgQGjWOxCpHT1TfMvwnIXKXN/OSlPjEK7rbCLYDZhejQL99PmUqul7XORI24Ik0A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@cypress/request" "^2.88.10"
|
"@cypress/request" "^2.88.10"
|
||||||
"@cypress/xvfb" "^1.2.4"
|
"@cypress/xvfb" "^1.2.4"
|
||||||
|
@ -1884,7 +1877,7 @@ cypress@9.5.2:
|
||||||
listr2 "^3.8.3"
|
listr2 "^3.8.3"
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
log-symbols "^4.0.0"
|
log-symbols "^4.0.0"
|
||||||
minimist "^1.2.5"
|
minimist "^1.2.6"
|
||||||
ospath "^1.2.2"
|
ospath "^1.2.2"
|
||||||
pretty-bytes "^5.6.0"
|
pretty-bytes "^5.6.0"
|
||||||
proxy-from-env "1.0.0"
|
proxy-from-env "1.0.0"
|
||||||
|
@ -2378,10 +2371,10 @@ eslint-visitor-keys@^3.3.0:
|
||||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
||||||
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
||||||
|
|
||||||
eslint@8.11.0:
|
eslint@8.12.0:
|
||||||
version "8.11.0"
|
version "8.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.11.0.tgz#88b91cfba1356fc10bb9eb592958457dfe09fb37"
|
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.12.0.tgz#c7a5bd1cfa09079aae64c9076c07eada66a46e8e"
|
||||||
integrity sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==
|
integrity sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint/eslintrc" "^1.2.1"
|
"@eslint/eslintrc" "^1.2.1"
|
||||||
"@humanwhocodes/config-array" "^0.9.2"
|
"@humanwhocodes/config-array" "^0.9.2"
|
||||||
|
@ -3852,12 +3845,7 @@ minimatch@^3.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
minimist@^1.2.0, minimist@^1.2.5:
|
minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
|
||||||
version "1.2.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
|
||||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
|
||||||
|
|
||||||
minimist@^1.2.6:
|
|
||||||
version "1.2.6"
|
version "1.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||||
|
@ -3935,16 +3923,11 @@ nano-time@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
big-integer "^1.6.16"
|
big-integer "^1.6.16"
|
||||||
|
|
||||||
nanoid@3.3.1, nanoid@^3.3.1:
|
nanoid@3.3.1, nanoid@^3.1.20, nanoid@^3.3.1:
|
||||||
version "3.3.1"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35"
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35"
|
||||||
integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
|
integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
|
||||||
|
|
||||||
nanoid@^3.1.20:
|
|
||||||
version "3.1.20"
|
|
||||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788"
|
|
||||||
integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==
|
|
||||||
|
|
||||||
natural-compare@^1.4.0:
|
natural-compare@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||||
|
@ -4279,9 +4262,10 @@ performance-now@^2.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||||
|
|
||||||
"photoswipe@git+https://github.com/dimsemenov/photoswipe#v5-beta":
|
photoswipe@5.2.2:
|
||||||
version "5.1.7"
|
version "5.2.2"
|
||||||
resolved "git+https://github.com/dimsemenov/photoswipe#60040164333bd257409669e715e4327afdb3aec7"
|
resolved "https://registry.yarnpkg.com/photoswipe/-/photoswipe-5.2.2.tgz#3960b953c504a67d1b074f60a31229ada2ed5c07"
|
||||||
|
integrity sha512-es0AEX4zgzzcrr8ztdPWRODSARCLqCm/5H/aSwFtZwovokGtzBf/y/HXJxHMnNx6h4650DkKVIVFYILXJhmMhw==
|
||||||
|
|
||||||
picocolors@^1.0.0:
|
picocolors@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
|
@ -5000,10 +4984,10 @@ sass-loader@12.6.0:
|
||||||
klona "^2.0.4"
|
klona "^2.0.4"
|
||||||
neo-async "^2.6.2"
|
neo-async "^2.6.2"
|
||||||
|
|
||||||
sass@1.49.9:
|
sass@1.49.10:
|
||||||
version "1.49.9"
|
version "1.49.10"
|
||||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.9.tgz#b15a189ecb0ca9e24634bae5d1ebc191809712f9"
|
resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.10.tgz#7b83cee0f03bbba443111b3f94944fde2b0c7a6b"
|
||||||
integrity sha512-YlYWkkHP9fbwaFRZQRXgDi3mXZShslVmmo+FVK3kHLUELHHEYrCmL1x6IUjC7wLS6VuJSAFXRQS/DxdsC4xL1A==
|
integrity sha512-w37zfWJwKu4I78U4z63u1mmgoncq+v3iOB4yzQMPyAPVHHawaQSnu9C9ysGQnZEhW609jkcLioJcMCqm75JMdg==
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar ">=3.0.0 <4.0.0"
|
chokidar ">=3.0.0 <4.0.0"
|
||||||
immutable "^4.0.0"
|
immutable "^4.0.0"
|
||||||
|
@ -5479,11 +5463,6 @@ through@2, through@^2.3.8, through@~2.3, through@~2.3.1:
|
||||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||||
|
|
||||||
timsort@^0.3.0:
|
|
||||||
version "0.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
|
||||||
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
|
||||||
|
|
||||||
tinycolor2@1.4.2:
|
tinycolor2@1.4.2:
|
||||||
version "1.4.2"
|
version "1.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
|
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
|
||||||
|
|
80
yarn.lock
80
yarn.lock
|
@ -194,48 +194,48 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
"@typescript-eslint/parser@5.16.0":
|
"@typescript-eslint/parser@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.16.0.tgz#e4de1bde4b4dad5b6124d3da227347616ed55508"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.17.0.tgz#7def77d5bcd8458d12d52909118cf3f0a45f89d5"
|
||||||
integrity sha512-fkDq86F0zl8FicnJtdXakFs4lnuebH6ZADDw6CYQv0UZeIjHvmEw87m9/29nk2Dv5Lmdp0zQ3zDQhiMWQf/GbA==
|
integrity sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/scope-manager" "5.16.0"
|
"@typescript-eslint/scope-manager" "5.17.0"
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/typescript-estree" "5.16.0"
|
"@typescript-eslint/typescript-estree" "5.17.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager@5.16.0":
|
"@typescript-eslint/scope-manager@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.16.0.tgz#7e7909d64bd0c4d8aef629cdc764b9d3e1d3a69a"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz#4cea7d0e0bc0e79eb60cad431c89120987c3f952"
|
||||||
integrity sha512-P+Yab2Hovg8NekLIR/mOElCDPyGgFZKhGoZA901Yax6WR6HVeGLbsqJkZ+Cvk5nts/dAlFKm8PfL43UZnWdpIQ==
|
integrity sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/visitor-keys" "5.16.0"
|
"@typescript-eslint/visitor-keys" "5.17.0"
|
||||||
|
|
||||||
"@typescript-eslint/types@5.16.0":
|
"@typescript-eslint/types@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.16.0.tgz#5827b011982950ed350f075eaecb7f47d3c643ee"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.17.0.tgz#861ec9e669ffa2aa9b873dd4d28d9b1ce26d216f"
|
||||||
integrity sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==
|
integrity sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@5.16.0":
|
"@typescript-eslint/typescript-estree@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.16.0.tgz#32259459ec62f5feddca66adc695342f30101f61"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz#a7cba7dfc8f9cc2ac78c18584e684507df4f2488"
|
||||||
integrity sha512-SE4VfbLWUZl9MR+ngLSARptUv2E8brY0luCdgmUevU6arZRY/KxYoLI/3V/yxaURR8tLRN7bmZtJdgmzLHI6pQ==
|
integrity sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
"@typescript-eslint/visitor-keys" "5.16.0"
|
"@typescript-eslint/visitor-keys" "5.17.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
globby "^11.0.4"
|
globby "^11.0.4"
|
||||||
is-glob "^4.0.3"
|
is-glob "^4.0.3"
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys@5.16.0":
|
"@typescript-eslint/visitor-keys@5.17.0":
|
||||||
version "5.16.0"
|
version "5.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.16.0.tgz#f27dc3b943e6317264c7492e390c6844cd4efbbb"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz#52daae45c61b0211b4c81b53a71841911e479128"
|
||||||
integrity sha512-jqxO8msp5vZDhikTwq9ubyMHqZ67UIvawohr4qF3KhlpL7gzSjOd+8471H3nh5LyABkaI85laEKKU8SnGUK5/g==
|
integrity sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.16.0"
|
"@typescript-eslint/types" "5.17.0"
|
||||||
eslint-visitor-keys "^3.0.0"
|
eslint-visitor-keys "^3.0.0"
|
||||||
|
|
||||||
aggregate-error@^3.0.0:
|
aggregate-error@^3.0.0:
|
||||||
|
@ -1084,10 +1084,10 @@ csso@~2.3.1:
|
||||||
clap "^1.0.9"
|
clap "^1.0.9"
|
||||||
source-map "^0.5.3"
|
source-map "^0.5.3"
|
||||||
|
|
||||||
cypress@9.5.2:
|
cypress@9.5.3:
|
||||||
version "9.5.2"
|
version "9.5.3"
|
||||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.5.2.tgz#8fb6ee4a890fbc35620800810bf6fb11995927bd"
|
resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.5.3.tgz#7c56b50fc1f1aa69ef10b271d895aeb4a1d7999e"
|
||||||
integrity sha512-gYiQYvJozMzDOriUV1rCt6CeRM/pRK4nhwGJj3nJQyX2BoUdTCVwp30xDMKc771HiNVhBtgj5o5/iBdVDVXQUg==
|
integrity sha512-ItelIVmqMTnKYbo1JrErhsGgQGjWOxCpHT1TfMvwnIXKXN/OSlPjEK7rbCLYDZhejQL99PmUqul7XORI24Ik0A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@cypress/request" "^2.88.10"
|
"@cypress/request" "^2.88.10"
|
||||||
"@cypress/xvfb" "^1.2.4"
|
"@cypress/xvfb" "^1.2.4"
|
||||||
|
@ -1121,7 +1121,7 @@ cypress@9.5.2:
|
||||||
listr2 "^3.8.3"
|
listr2 "^3.8.3"
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
log-symbols "^4.0.0"
|
log-symbols "^4.0.0"
|
||||||
minimist "^1.2.5"
|
minimist "^1.2.6"
|
||||||
ospath "^1.2.2"
|
ospath "^1.2.2"
|
||||||
pretty-bytes "^5.6.0"
|
pretty-bytes "^5.6.0"
|
||||||
proxy-from-env "1.0.0"
|
proxy-from-env "1.0.0"
|
||||||
|
@ -1618,9 +1618,9 @@ flush-write-stream@^1.0.2:
|
||||||
readable-stream "^2.3.6"
|
readable-stream "^2.3.6"
|
||||||
|
|
||||||
follow-redirects@^1.10.0:
|
follow-redirects@^1.10.0:
|
||||||
version "1.14.1"
|
version "1.14.8"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
|
||||||
integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==
|
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==
|
||||||
|
|
||||||
for-in@^1.0.1, for-in@^1.0.2:
|
for-in@^1.0.1, for-in@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
@ -2678,10 +2678,10 @@ minimatch@^3.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
minimist@^1.2.5:
|
minimist@^1.2.5, minimist@^1.2.6:
|
||||||
version "1.2.5"
|
version "1.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||||
|
|
||||||
mixin-deep@^1.2.0:
|
mixin-deep@^1.2.0:
|
||||||
version "1.3.2"
|
version "1.3.2"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue