Merge branch 'notification-read-api' into swn

This commit is contained in:
tamaina
2021-11-13 12:27:54 +09:00
52 changed files with 621 additions and 452 deletions

View File

@@ -70,7 +70,6 @@
"cssnano": "5.0.10",
"date-fns": "2.25.0",
"dateformat": "4.5.1",
"deep-email-validator": "0.1.18",
"escape-regexp": "0.0.1",
"eslint": "8.2.0",
"eslint-plugin-vue": "8.0.3",

View File

@@ -94,12 +94,7 @@
<template v-else><i class="fas fa-reply"></i></template>
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
</button>
<button v-if="canRenote" @click="renote()" class="button _button" ref="renoteButton">
<i class="fas fa-retweet"></i><p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
</button>
<button v-else class="button _button">
<i class="fas fa-ban"></i>
</button>
<XRenoteButton class="button" :note="appearNote" :count="appearNote.renoteCount" ref="renoteButton"/>
<button v-if="appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton">
<i class="fas fa-plus"></i>
</button>
@@ -136,6 +131,7 @@ import XReactionsViewer from './reactions-viewer.vue';
import XMediaList from './media-list.vue';
import XCwButton from './cw-button.vue';
import XPoll from './poll.vue';
import XRenoteButton from './renote-button.vue';
import { pleaseLogin } from '@/scripts/please-login';
import { focusPrev, focusNext } from '@/scripts/focus';
import { url } from '@/config';
@@ -157,6 +153,7 @@ export default defineComponent({
XMediaList,
XCwButton,
XPoll,
XRenoteButton,
MkUrlPreview: defineAsyncComponent(() => import('@/components/url-preview.vue')),
MkInstanceTicker: defineAsyncComponent(() => import('@/components/instance-ticker.vue')),
},
@@ -197,7 +194,7 @@ export default defineComponent({
return {
'r': () => this.reply(true),
'e|a|plus': () => this.react(true),
'q': () => this.renote(true),
'q': () => this.$refs.renoteButton.renote(true),
'f|b': this.favorite,
'delete|ctrl+d': this.del,
'ctrl+q': this.renoteDirectly,
@@ -238,10 +235,6 @@ export default defineComponent({
return this.$i && (this.$i.id === this.note.userId);
},
canRenote(): boolean {
return ['public', 'home'].includes(this.appearNote.visibility) || this.isMyNote;
},
reactionsCount(): number {
return this.appearNote.reactions
? sum(Object.values(this.appearNote.reactions))
@@ -459,30 +452,6 @@ export default defineComponent({
});
},
renote(viaKeyboard = false) {
pleaseLogin();
this.blur();
os.popupMenu([{
text: this.$ts.renote,
icon: 'fas fa-retweet',
action: () => {
os.api('notes/create', {
renoteId: this.appearNote.id
});
}
}, {
text: this.$ts.quote,
icon: 'fas fa-quote-right',
action: () => {
os.post({
renote: this.appearNote,
});
}
}], this.$refs.renoteButton, {
viaKeyboard
});
},
renoteDirectly() {
os.apiWithDialog('notes/create', {
renoteId: this.appearNote.id

View File

@@ -78,12 +78,7 @@
<template v-else><i class="fas fa-reply"></i></template>
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
</button>
<button v-if="canRenote" @click="renote()" class="button _button" ref="renoteButton">
<i class="fas fa-retweet"></i><p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
</button>
<button v-else class="button _button">
<i class="fas fa-ban"></i>
</button>
<XRenoteButton class="button" :note="appearNote" :count="appearNote.renoteCount" ref="renoteButton"/>
<button v-if="appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton">
<i class="fas fa-plus"></i>
</button>
@@ -119,6 +114,7 @@ import XReactionsViewer from './reactions-viewer.vue';
import XMediaList from './media-list.vue';
import XCwButton from './cw-button.vue';
import XPoll from './poll.vue';
import XRenoteButton from './renote-button.vue';
import { pleaseLogin } from '@/scripts/please-login';
import { focusPrev, focusNext } from '@/scripts/focus';
import { url } from '@/config';
@@ -139,6 +135,7 @@ export default defineComponent({
XMediaList,
XCwButton,
XPoll,
XRenoteButton,
MkUrlPreview: defineAsyncComponent(() => import('@/components/url-preview.vue')),
MkInstanceTicker: defineAsyncComponent(() => import('@/components/instance-ticker.vue')),
},
@@ -184,7 +181,7 @@ export default defineComponent({
return {
'r': () => this.reply(true),
'e|a|plus': () => this.react(true),
'q': () => this.renote(true),
'q': () => this.$refs.renoteButton.renote(true),
'f|b': this.favorite,
'delete|ctrl+d': this.del,
'ctrl+q': this.renoteDirectly,
@@ -225,10 +222,6 @@ export default defineComponent({
return this.$i && (this.$i.id === this.note.userId);
},
canRenote(): boolean {
return ['public', 'home'].includes(this.appearNote.visibility) || this.isMyNote;
},
reactionsCount(): number {
return this.appearNote.reactions
? sum(Object.values(this.appearNote.reactions))
@@ -435,30 +428,6 @@ export default defineComponent({
});
},
renote(viaKeyboard = false) {
pleaseLogin();
this.blur();
os.popupMenu([{
text: this.$ts.renote,
icon: 'fas fa-retweet',
action: () => {
os.api('notes/create', {
renoteId: this.appearNote.id
});
}
}, {
text: this.$ts.quote,
icon: 'fas fa-quote-right',
action: () => {
os.post({
renote: this.appearNote,
});
}
}], this.$refs.renoteButton, {
viaKeyboard
});
},
renoteDirectly() {
os.apiWithDialog('notes/create', {
renoteId: this.appearNote.id

View File

@@ -69,6 +69,7 @@
<script lang="ts">
import { defineComponent, ref, onMounted, onUnmounted, watch } from 'vue';
import * as misskey from 'misskey-js';
import { getNoteSummary } from '@/scripts/get-note-summary';
import XReactionIcon from './reaction-icon.vue';
import MkFollowButton from './follow-button.vue';
@@ -77,6 +78,7 @@ import notePage from '@/filters/note';
import { userPage } from '@/filters/user';
import { i18n } from '@/i18n';
import * as os from '@/os';
import { useTooltip } from '@/scripts/use-tooltip';
export default defineComponent({
components: {
@@ -105,7 +107,7 @@ export default defineComponent({
const reactionRef = ref(null);
onMounted(() => {
let readObserver: IntersectionObserver = null;
let readObserver: IntersectionObserver | null = null;
let connection = null;
if (!props.notification.isRead) {
@@ -156,50 +158,17 @@ export default defineComponent({
os.api('users/groups/invitations/reject', { invitationId: props.notification.invitation.id });
};
let isReactionHovering = false;
let reactionTooltipTimeoutId;
const onReactionMouseover = () => {
if (isReactionHovering) return;
isReactionHovering = true;
reactionTooltipTimeoutId = setTimeout(openReactionTooltip, 300);
};
const onReactionMouseleave = () => {
if (!isReactionHovering) return;
isReactionHovering = false;
clearTimeout(reactionTooltipTimeoutId);
closeReactionTooltip();
};
let changeReactionTooltipShowingState: () => void;
const openReactionTooltip = () => {
closeReactionTooltip();
if (!isReactionHovering) return;
const showing = ref(true);
const { onMouseover: onReactionMouseover, onMouseleave: onReactionMouseleave } = useTooltip((showing) => {
os.popup(XReactionTooltip, {
showing,
reaction: props.notification.reaction ? props.notification.reaction.replace(/^:(\w+):$/, ':$1@.:') : props.notification.reaction,
emojis: props.notification.note.emojis,
source: reactionRef.value.$el,
}, {}, 'closed');
changeReactionTooltipShowingState = () => {
showing.value = false;
};
};
const closeReactionTooltip = () => {
if (changeReactionTooltipShowingState != null) {
changeReactionTooltipShowingState();
changeReactionTooltipShowingState = null;
}
};
});
return {
getNoteSummary: (text: string) => getNoteSummary(text, i18n),
getNoteSummary: (note: misskey.entities.Note) => getNoteSummary(note, i18n),
followRequestDone,
groupInviteDone,
notePage,

View File

@@ -278,8 +278,8 @@ export default defineComponent({
this.text += ' ';
}
if (this.reply && this.reply.user.host != null) {
this.text = `@${this.reply.user.username}@${toASCII(this.reply.user.host)} `;
if (this.reply && (this.reply.user.username != this.$i.username || (this.reply.user.host != null && this.reply.user.host != host))) {
this.text = `@${this.reply.user.username}${this.reply.user.host != null ? '@' + toASCII(this.reply.user.host) : ''} `;
}
if (this.reply && this.reply.text != null) {

View File

@@ -9,12 +9,14 @@
<template v-if="users.length <= 10">
<b v-for="u in users" :key="u.id" style="margin-right: 12px;">
<MkAvatar :user="u" style="width: 24px; height: 24px; margin-right: 2px;"/>
<br/>
<MkUserName :user="u" :nowrap="false" style="line-height: 24px;"/>
</b>
</template>
<template v-if="10 < users.length">
<b v-for="u in users" :key="u.id" style="margin-right: 12px;">
<MkAvatar :user="u" style="width: 24px; height: 24px; margin-right: 2px;"/>
<br/>
<MkUserName :user="u" :nowrap="false" style="line-height: 24px;"/>
</b>
<span slot="omitted">+{{ count - 10 }}</span>
@@ -64,7 +66,6 @@ export default defineComponent({
display: flex;
> .reaction {
flex: 1;
max-width: 100px;
text-align: center;
@@ -80,12 +81,13 @@ export default defineComponent({
}
> .users {
display: flex;
flex: 1;
min-width: 0;
font-size: 0.9em;
border-left: solid 0.5px var(--divider);
padding-left: 10px;
margin-left: 10px;
margin-left: 10px;
}
}
</style>

View File

@@ -2,13 +2,13 @@
<button
class="hkzvhatu _button"
:class="{ reacted: note.myReaction == reaction, canToggle }"
@click="toggleReaction(reaction)"
@click="toggleReaction()"
v-if="count > 0"
@touchstart.passive="onMouseover"
@mouseover="onMouseover"
@mouseleave="onMouseleave"
@touchend="onMouseleave"
ref="reaction"
ref="buttonRef"
v-particle="canToggle"
>
<XReactionIcon :reaction="reaction" :custom-emojis="note.emojis"/>
@@ -17,15 +17,18 @@
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { computed, defineComponent, onMounted, ref, watch } from 'vue';
import XDetails from '@/components/reactions-viewer.details.vue';
import XReactionIcon from '@/components/reaction-icon.vue';
import * as os from '@/os';
import { useTooltip } from '@/scripts/use-tooltip';
import { $i } from '@/account';
export default defineComponent({
components: {
XReactionIcon
},
props: {
reaction: {
type: String,
@@ -44,101 +47,78 @@ export default defineComponent({
required: true,
},
},
data() {
return {
close: null,
detailsTimeoutId: null,
isHovering: false
};
},
computed: {
canToggle(): boolean {
return !this.reaction.match(/@\w/) && this.$i;
},
},
watch: {
count(newCount, oldCount) {
if (oldCount < newCount) this.anime();
if (this.close != null) this.openDetails();
},
},
mounted() {
if (!this.isInitial) this.anime();
},
methods: {
toggleReaction() {
if (!this.canToggle) return;
const oldReaction = this.note.myReaction;
setup(props) {
const buttonRef = ref<HTMLElement>();
const canToggle = computed(() => !props.reaction.match(/@\w/) && $i);
const toggleReaction = () => {
if (!canToggle.value) return;
const oldReaction = props.note.myReaction;
if (oldReaction) {
os.api('notes/reactions/delete', {
noteId: this.note.id
noteId: props.note.id
}).then(() => {
if (oldReaction !== this.reaction) {
if (oldReaction !== props.reaction) {
os.api('notes/reactions/create', {
noteId: this.note.id,
reaction: this.reaction
noteId: props.note.id,
reaction: props.reaction
});
}
});
} else {
os.api('notes/reactions/create', {
noteId: this.note.id,
reaction: this.reaction
noteId: props.note.id,
reaction: props.reaction
});
}
},
onMouseover() {
if (this.isHovering) return;
this.isHovering = true;
this.detailsTimeoutId = setTimeout(this.openDetails, 300);
},
onMouseleave() {
if (!this.isHovering) return;
this.isHovering = false;
clearTimeout(this.detailsTimeoutId);
this.closeDetails();
},
openDetails() {
os.api('notes/reactions', {
noteId: this.note.id,
type: this.reaction,
limit: 11
}).then((reactions: any[]) => {
const users = reactions
.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())
.map(x => x.user);
};
this.closeDetails();
if (!this.isHovering) return;
const showing = ref(true);
os.popup(XDetails, {
showing,
reaction: this.reaction,
emojis: this.note.emojis,
users,
count: this.count,
source: this.$refs.reaction
}, {}, 'closed');
this.close = () => {
showing.value = false;
};
});
},
closeDetails() {
if (this.close != null) {
this.close();
this.close = null;
}
},
anime() {
const anime = () => {
if (document.hidden) return;
// TODO
},
}
// TODO: 新しくリアクションが付いたことが視覚的に分かりやすいアニメーション
};
watch(() => props.count, (newCount, oldCount) => {
if (oldCount < newCount) anime();
});
onMounted(() => {
if (!props.isInitial) anime();
});
const { onMouseover, onMouseleave } = useTooltip(async (showing) => {
const reactions = await os.api('notes/reactions', {
noteId: props.note.id,
type: props.reaction,
limit: 11
});
const users = reactions
.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())
.map(x => x.user);
os.popup(XDetails, {
showing,
reaction: props.reaction,
emojis: props.note.emojis,
users,
count: props.count,
source: buttonRef.value
}, {}, 'closed');
});
return {
buttonRef,
canToggle,
toggleReaction,
onMouseover,
onMouseleave,
};
},
});
</script>

View File

@@ -0,0 +1,121 @@
<template>
<button v-if="canRenote"
class="eddddedb _button canRenote"
@click="renote()"
@touchstart.passive="onMouseover"
@mouseover="onMouseover"
@mouseleave="onMouseleave"
@touchend="onMouseleave"
ref="buttonRef"
>
<i class="fas fa-retweet"></i>
<p class="count" v-if="count > 0">{{ count }}</p>
</button>
<button v-else class="eddddedb _button">
<i class="fas fa-ban"></i>
</button>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
import XDetails from '@/components/renote.details.vue';
import { pleaseLogin } from '@/scripts/please-login';
import * as os from '@/os';
import { $i } from '@/account';
import { useTooltip } from '@/scripts/use-tooltip';
import { i18n } from '@/i18n';
export default defineComponent({
props: {
count: {
type: Number,
required: true,
},
note: {
type: Object,
required: true,
},
},
setup(props) {
const buttonRef = ref<HTMLElement>();
const canRenote = computed(() => ['public', 'home'].includes(props.note.visibility) || props.note.userId === $i.id);
const { onMouseover, onMouseleave } = useTooltip(async (showing) => {
const renotes = await os.api('notes/renotes', {
noteId: props.note.id,
limit: 11
});
const users = renotes
.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())
.map(x => x.user);
if (users.length < 1) return;
os.popup(XDetails, {
showing,
users,
count: props.count,
source: buttonRef.value
}, {}, 'closed');
});
const renote = (viaKeyboard = false) => {
pleaseLogin();
os.popupMenu([{
text: i18n.locale.renote,
icon: 'fas fa-retweet',
action: () => {
os.api('notes/create', {
renoteId: props.note.id
});
}
}, {
text: i18n.locale.quote,
icon: 'fas fa-quote-right',
action: () => {
os.post({
renote: props.note,
});
}
}], buttonRef.value, {
viaKeyboard
});
};
return {
buttonRef,
canRenote,
renote,
onMouseover,
onMouseleave,
};
},
});
</script>
<style lang="scss" scoped>
.eddddedb {
display: inline-block;
height: 32px;
margin: 2px;
padding: 0 6px;
border-radius: 4px;
&:not(.canRenote) {
cursor: default;
}
&.renoted {
background: var(--accent);
}
> .count {
display: inline;
margin-left: 8px;
opacity: 0.7;
}
}
</style>

View File

@@ -0,0 +1,46 @@
<template>
<MkTooltip :source="source" ref="tooltip" @closed="$emit('closed')" :max-width="340">
<div class="renoteTooltip">
<b v-for="u in users" :key="u.id">
<MkAvatar :user="u" style="width: 24px; height: 24px;"/><br/>
<MkUserName :user="u" :nowrap="false" style="line-height: 24px;"/>
</b>
<span v-if="users.length < count" slot="omitted">+{{ count - users.length }}</span>
</div>
</MkTooltip>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import MkTooltip from './ui/tooltip.vue';
export default defineComponent({
components: {
MkTooltip,
},
props: {
users: {
type: Array,
required: true,
},
count: {
type: Number,
required: true,
},
source: {
required: true,
}
},
emits: ['closed'],
})
</script>
<style lang="scss" scoped>
.renoteTooltip {
display: flex;
flex: 1;
min-width: 0;
font-size: 0.9em;
gap: 12px;
}
</style>

View File

@@ -0,0 +1,44 @@
import { Ref, ref } from 'vue';
export function useTooltip(onShow: (showing: Ref<boolean>) => void) {
let isHovering = false;
let timeoutId: number;
let changeShowingState: (() => void) | null;
const open = () => {
close();
if (!isHovering) return;
const showing = ref(true);
onShow(showing);
changeShowingState = () => {
showing.value = false;
};
};
const close = () => {
if (changeShowingState != null) {
changeShowingState();
changeShowingState = null;
}
};
const onMouseover = () => {
if (isHovering) return;
isHovering = true;
timeoutId = window.setTimeout(open, 300);
};
const onMouseleave = () => {
if (!isHovering) return;
isHovering = false;
window.clearTimeout(timeoutId);
close();
};
return {
onMouseover,
onMouseleave,
};
}

View File

@@ -206,8 +206,8 @@ export default defineComponent({
this.text += ' ';
}
if (this.reply && this.reply.user.host != null) {
this.text = `@${this.reply.user.username}@${toASCII(this.reply.user.host)} `;
if (this.reply && (this.reply.user.username != this.$i.username || (this.reply.user.host != null && this.reply.user.host != host))) {
this.text = `@${this.reply.user.username}${this.reply.user.host != null ? '@' + toASCII(this.reply.user.host) : ''} `;
}
if (this.reply && this.reply.text != null) {

View File

@@ -397,11 +397,6 @@
resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc"
integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==
"@types/disposable-email-domains@^1.0.1":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@types/disposable-email-domains/-/disposable-email-domains-1.0.2.tgz#0280f6b38fa7f14e54b056a434135ecd254483b1"
integrity sha512-SDKwyYTjk3y5aZBxxc38yRecpJPjsqn57STz1bNxYYlv4k11bBe7QB8w4llXDTmQXKT1mFvgGmJv+8Zdu3YmJw==
"@types/escape-regexp@0.0.0":
version "0.0.0"
resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.0.tgz#bff0225f9ef30d0dbdbe0e2a24283ee5342990c3"
@@ -1479,13 +1474,6 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
axios@^0.19.2:
version "0.19.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
dependencies:
follow-redirects "1.5.10"
axios@^0.21.1:
version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
@@ -1628,13 +1616,6 @@ browserslist@^4.16.6:
escalade "^3.1.1"
node-releases "^1.1.71"
bs-logger@0.x:
version "0.2.6"
resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8"
integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==
dependencies:
fast-json-stable-stringify "2.x"
buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
@@ -1663,11 +1644,6 @@ buffer-fill@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
buffer-from@1.x:
version "1.1.2"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
buffer-from@^1.0.0, buffer-from@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@@ -2350,13 +2326,6 @@ debug@4.3.2, debug@^4.3.2:
dependencies:
ms "2.1.2"
debug@=3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@^3.1.0:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
@@ -2388,18 +2357,6 @@ decompress-response@^6.0.0:
dependencies:
mimic-response "^3.1.0"
deep-email-validator@0.1.18:
version "0.1.18"
resolved "https://registry.yarnpkg.com/deep-email-validator/-/deep-email-validator-0.1.18.tgz#a072a93f28e11863cc6b9ca3ae964e0e45b3ece8"
integrity sha512-eo2WEUidQvppg6Qdek8iwOqmXvaxRJ2D2VJKbIOwUgLZNFveDDdJMBsFc+yq0S+lILEUcmzrJRrCWbyoe7QUzQ==
dependencies:
"@types/disposable-email-domains" "^1.0.1"
axios "^0.19.2"
disposable-email-domains "^1.0.53"
lodash "^4.17.15"
mailcheck "^1.1.1"
ts-jest "^25.2.1"
deep-is@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
@@ -2454,11 +2411,6 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"
disposable-email-domains@^1.0.53:
version "1.0.58"
resolved "https://registry.yarnpkg.com/disposable-email-domains/-/disposable-email-domains-1.0.58.tgz#ac9c879c02c4f0898bfb6c0c80b959c0b0b7bc51"
integrity sha512-frnNCPqTjk6t/sosPoco6EIFHbP9SazHQkeltJNfZeUyNgewaVf+kFjEfVkVDVd436Vln43YElJPb8JozhBs7Q==
doctrine@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
@@ -3013,7 +2965,7 @@ fast-glob@^3.1.1:
micromatch "^4.0.2"
picomatch "^2.2.1"
fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0:
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
@@ -3134,13 +3086,6 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067"
integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==
follow-redirects@1.5.10:
version "1.5.10"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
dependencies:
debug "=3.1.0"
follow-redirects@^1.10.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
@@ -3952,7 +3897,7 @@ json5-loader@4.0.1:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
json5@2.2.0, json5@2.x:
json5@2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
@@ -4153,7 +4098,7 @@ lodash.isfinite@^3.3.2:
resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3"
integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=
lodash.memoize@4.x, lodash.memoize@^4.1.2:
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
@@ -4173,7 +4118,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21:
lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -4222,12 +4167,7 @@ magic-string@^0.25.7:
dependencies:
sourcemap-codec "^1.4.4"
mailcheck@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/mailcheck/-/mailcheck-1.1.1.tgz#d87cf6ba0b64ba512199dbf93f1489f479591e34"
integrity sha1-2Hz2ugtkulEhmdv5PxSJ9HlZHjQ=
make-error@1.x, make-error@^1.1.1:
make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
@@ -4279,14 +4219,6 @@ mfm-js@0.20.0:
dependencies:
twemoji-parser "13.1.x"
micromatch@4.x:
version "4.0.4"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
dependencies:
braces "^3.0.1"
picomatch "^2.2.3"
micromatch@^4.0.0, micromatch@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
@@ -4353,7 +4285,7 @@ misskey-js@0.0.10:
eventemitter3 "^4.0.7"
reconnecting-websocket "^4.4.0"
mkdirp@0.x, mkdirp@~0.5.1:
mkdirp@~0.5.1:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@@ -4754,11 +4686,6 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
picomatch@^2.2.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
pify@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -5605,11 +5532,6 @@ seedrandom@3.0.5:
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7"
integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==
semver@6.x:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.2.1, semver@^7.3.2, semver@^7.3.4:
version "7.3.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
@@ -6114,22 +6036,6 @@ tree-kill@^1.2.2:
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
ts-jest@^25.2.1:
version "25.5.1"
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.5.1.tgz#2913afd08f28385d54f2f4e828be4d261f4337c7"
integrity sha512-kHEUlZMK8fn8vkxDjwbHlxXRB9dHYpyzqKIGDNxbzs+Rz+ssNDSDNusEK8Fk/sDd4xE6iKoQLfFkFVaskmTJyw==
dependencies:
bs-logger "0.x"
buffer-from "1.x"
fast-json-stable-stringify "2.x"
json5 "2.x"
lodash.memoize "4.x"
make-error "1.x"
micromatch "4.x"
mkdirp "0.x"
semver "6.x"
yargs-parser "18.x"
ts-loader@9.2.6:
version "9.2.6"
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74"
@@ -6734,14 +6640,6 @@ yaml@^1.10.2:
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yargs-parser@18.x:
version "18.1.3"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
dependencies:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs-parser@20.2.4, yargs-parser@^20.2.2:
version "20.2.4"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"