From 5a3c6575dd5d97dc0dc193771b80898fca4cfdc0 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Tue, 17 Oct 2023 20:56:17 +0900 Subject: [PATCH 01/12] =?UTF-8?q?=E6=96=B0=E8=A6=8F=E3=81=AB=E3=83=95?= =?UTF-8?q?=E3=82=A9=E3=83=AD=E3=83=BC=E3=81=97=E3=81=9F=E4=BA=BA=E3=81=AE?= =?UTF-8?q?withReplies=E3=82=92true=E3=81=AB=E3=81=99=E3=82=8B=E6=A9=9F?= =?UTF-8?q?=E8=83=BD=E3=82=92=E8=BF=BD=E5=8A=A0=20(#12048)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add defaultWithReplies to MiUser * feat: use defaultWithReplies when creating MiFollowing * feat: update defaultWithReplies from API * feat: return defaultWithReplies as a part of $i * feat(frontend): configure defaultWithReplies * docs(changelog): 新規にフォローした人のをデフォルトでTL二追加できるように * fix: typo * style: fix lint failure * chore: improve UI text * chore: make optional params of UserFollowingService.follow() object * chore: UserFollowingService.follow() accept withReplies * chore: add withReplies to MiFollowRequest * chore: process withReplies for follow request * feat: accept withReplies on 'following/create' endpoint * feat: store defaultWithReplies in client store * Revert "feat: return defaultWithReplies as a part of $i" This reverts commit f2cc4fe6 * Revert "feat: update defaultWithReplies from API" This reverts commit 95e3cee6 * Revert "feat: add defaultWithReplies to MiUser" This reverts commit 9f5ab14d7063532de2b049bc2ed40a15658168f5. * feat: configuring withReplies in import-following * feat(frontend): configure withReplies * fix(frontend): incorrectly showRepliesToOthersInTimeline can be shown * fix(backend): withReplies of following/create not working * fix(frontend): importFollowing error * fix: withReplies is not working with follow import * fix(frontend): use v-model * style: fix lint --------- Co-authored-by: Sayamame-beans <61457993+sayamame-beans@users.noreply.github.com> Co-authored-by: syuilo --- CHANGELOG.md | 1 + locales/index.d.ts | 2 ++ locales/ja-JP.yml | 2 ++ .../1697441463087-FollowRequestWithReplies.js | 17 ++++++++++++++++ packages/backend/src/core/QueueService.ts | 10 ++++++---- .../backend/src/core/UserFollowingService.ts | 20 +++++++++++++++---- .../src/core/activitypub/ApInboxService.ts | 2 +- packages/backend/src/models/FollowRequest.ts | 5 +++++ .../ImportFollowingProcessorService.ts | 6 +++--- .../RelationshipProcessorService.ts | 8 ++++++-- packages/backend/src/queue/types.ts | 3 +++ .../server/api/endpoints/following/create.ts | 3 ++- .../api/endpoints/i/import-following.ts | 3 ++- .../src/components/MkFollowButton.vue | 10 ++++++++++ .../frontend/src/components/MkUserPopup.vue | 2 +- packages/frontend/src/pages/follow.vue | 3 +++ packages/frontend/src/pages/gallery/post.vue | 2 +- .../frontend/src/pages/settings/general.vue | 2 ++ .../src/pages/settings/import-export.vue | 10 +++++++++- packages/frontend/src/pages/user/home.vue | 5 +++-- packages/frontend/src/store.ts | 4 ++++ packages/misskey-js/etc/misskey-js.api.md | 3 ++- packages/misskey-js/src/api.types.ts | 5 ++++- 23 files changed, 105 insertions(+), 23 deletions(-) create mode 100644 packages/backend/migration/1697441463087-FollowRequestWithReplies.js diff --git a/CHANGELOG.md b/CHANGELOG.md index af68dabcd6..87c9967c46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - Feat: アンテナでローカルの投稿のみ収集できるようになりました - Feat: サーバーサイレンス機能が追加されました - Enhance: 依存関係の更新 +- Enhance: 新規にフォローした人のをデフォルトでTLに追加できるように ### Client - Enhance: TLの返信表示オプションを記憶するように diff --git a/locales/index.d.ts b/locales/index.d.ts index 483c470be8..363032eaa2 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -537,6 +537,7 @@ export interface Locale { "deleteAll": string; "showFixedPostForm": string; "showFixedPostFormInChannel": string; + "withRepliesByDefaultForNewlyFollowed": string; "newNoteRecived": string; "sounds": string; "sound": string; @@ -2054,6 +2055,7 @@ export interface Locale { "userLists": string; "excludeMutingUsers": string; "excludeInactiveUsers": string; + "withReplies": string; }; "_charts": { "federation": string; diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 725d1e7a87..bc539d17dd 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -534,6 +534,7 @@ serverLogs: "サーバーログ" deleteAll: "全て削除" showFixedPostForm: "タイムライン上部に投稿フォームを表示する" showFixedPostFormInChannel: "タイムライン上部に投稿フォームを表示する(チャンネル)" +withRepliesByDefaultForNewlyFollowed: "フォローする際、デフォルトで返信をTLに含むようにする" newNoteRecived: "新しいノートがあります" sounds: "サウンド" sound: "サウンド" @@ -1969,6 +1970,7 @@ _exportOrImport: userLists: "リスト" excludeMutingUsers: "ミュートしているユーザーを除外" excludeInactiveUsers: "使われていないアカウントを除外" + withReplies: "インポートした人による返信をTLに含むようにする" _charts: federation: "連合" diff --git a/packages/backend/migration/1697441463087-FollowRequestWithReplies.js b/packages/backend/migration/1697441463087-FollowRequestWithReplies.js new file mode 100644 index 0000000000..214c6f6680 --- /dev/null +++ b/packages/backend/migration/1697441463087-FollowRequestWithReplies.js @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + + +export class FollowRequestWithReplies1697441463087 { + name = 'FollowRequestWithReplies1697441463087' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "follow_request" ADD "withReplies" boolean NOT NULL DEFAULT false`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "follow_request" DROP COLUMN "withReplies"`); + } +} diff --git a/packages/backend/src/core/QueueService.ts b/packages/backend/src/core/QueueService.ts index d8c7250034..be378a899b 100644 --- a/packages/backend/src/core/QueueService.ts +++ b/packages/backend/src/core/QueueService.ts @@ -237,10 +237,11 @@ export class QueueService { } @bindThis - public createImportFollowingJob(user: ThinUser, fileId: MiDriveFile['id']) { + public createImportFollowingJob(user: ThinUser, fileId: MiDriveFile['id'], withReplies?: boolean) { return this.dbQueue.add('importFollowing', { user: { id: user.id }, fileId: fileId, + withReplies, }, { removeOnComplete: true, removeOnFail: true, @@ -248,8 +249,8 @@ export class QueueService { } @bindThis - public createImportFollowingToDbJob(user: ThinUser, targets: string[]) { - const jobs = targets.map(rel => this.generateToDbJobData('importFollowingToDb', { user, target: rel })); + public createImportFollowingToDbJob(user: ThinUser, targets: string[], withReplies?: boolean) { + const jobs = targets.map(rel => this.generateToDbJobData('importFollowingToDb', { user, target: rel, withReplies })); return this.dbQueue.addBulk(jobs); } @@ -342,7 +343,7 @@ export class QueueService { } @bindThis - public createFollowJob(followings: { from: ThinUser, to: ThinUser, requestId?: string, silent?: boolean }[]) { + public createFollowJob(followings: { from: ThinUser, to: ThinUser, requestId?: string, silent?: boolean, withReplies?: boolean }[]) { const jobs = followings.map(rel => this.generateRelationshipJobData('follow', rel)); return this.relationshipQueue.addBulk(jobs); } @@ -384,6 +385,7 @@ export class QueueService { to: { id: data.to.id }, silent: data.silent, requestId: data.requestId, + withReplies: data.withReplies, }, opts: { removeOnComplete: true, diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts index 87484f0383..7548e3d28f 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -93,7 +93,15 @@ export class UserFollowingService implements OnModuleInit { } @bindThis - public async follow(_follower: { id: MiUser['id'] }, _followee: { id: MiUser['id'] }, requestId?: string, silent = false): Promise { + public async follow( + _follower: { id: MiUser['id'] }, + _followee: { id: MiUser['id'] }, + { requestId, silent = false, withReplies }: { + requestId?: string, + silent?: boolean, + withReplies?: boolean, + } = {}, + ): Promise { const [follower, followee] = await Promise.all([ this.usersRepository.findOneByOrFail({ id: _follower.id }), this.usersRepository.findOneByOrFail({ id: _followee.id }), @@ -171,12 +179,12 @@ export class UserFollowingService implements OnModuleInit { } if (!autoAccept) { - await this.createFollowRequest(follower, followee, requestId); + await this.createFollowRequest(follower, followee, requestId, withReplies); return; } } - await this.insertFollowingDoc(followee, follower, silent); + await this.insertFollowingDoc(followee, follower, silent, withReplies); if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) { const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee, requestId), followee)); @@ -193,6 +201,7 @@ export class UserFollowingService implements OnModuleInit { id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox']; sharedInbox: MiUser['sharedInbox'] }, silent = false, + withReplies?: boolean, ): Promise { if (follower.id === followee.id) return; @@ -202,6 +211,7 @@ export class UserFollowingService implements OnModuleInit { id: this.idService.gen(), followerId: follower.id, followeeId: followee.id, + withReplies: withReplies, // 非正規化 followerHost: follower.host, @@ -454,6 +464,7 @@ export class UserFollowingService implements OnModuleInit { id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox']; sharedInbox: MiUser['sharedInbox']; }, requestId?: string, + withReplies?: boolean, ): Promise { if (follower.id === followee.id) return; @@ -471,6 +482,7 @@ export class UserFollowingService implements OnModuleInit { followerId: follower.id, followeeId: followee.id, requestId, + withReplies, // 非正規化 followerHost: follower.host, @@ -555,7 +567,7 @@ export class UserFollowingService implements OnModuleInit { throw new IdentifiableError('8884c2dd-5795-4ac9-b27e-6a01d38190f9', 'No follow request.'); } - await this.insertFollowingDoc(followee, follower); + await this.insertFollowingDoc(followee, follower, false, request.withReplies); if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) { const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee as MiPartialLocalUser, request.requestId!), followee)); diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 8d5d34d40b..7aba140689 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -164,7 +164,7 @@ export class ApInboxService { } // don't queue because the sender may attempt again when timeout - await this.userFollowingService.follow(actor, followee, activity.id); + await this.userFollowingService.follow(actor, followee, { requestId: activity.id }); return 'ok'; } diff --git a/packages/backend/src/models/FollowRequest.ts b/packages/backend/src/models/FollowRequest.ts index 1e907f3d68..9899694dd6 100644 --- a/packages/backend/src/models/FollowRequest.ts +++ b/packages/backend/src/models/FollowRequest.ts @@ -45,6 +45,11 @@ export class MiFollowRequest { }) public requestId: string | null; + @Column('boolean', { + default: false, + }) + public withReplies: boolean; + //#region Denormalized fields @Column('varchar', { length: 128, nullable: true, diff --git a/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts b/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts index 2b5e41a12d..e75499a56f 100644 --- a/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts @@ -56,7 +56,7 @@ export class ImportFollowingProcessorService { const csv = await this.downloadService.downloadTextFile(file.url); const targets = csv.trim().split('\n'); - this.queueService.createImportFollowingToDbJob({ id: user.id }, targets); + this.queueService.createImportFollowingToDbJob({ id: user.id }, targets, job.data.withReplies); this.logger.succ('Import jobs created'); } @@ -93,9 +93,9 @@ export class ImportFollowingProcessorService { // skip myself if (target.id === job.data.user.id) return; - this.logger.info(`Follow ${target.id} ...`); + this.logger.info(`Follow ${target.id} ${job.data.withReplies ? 'with replies' : 'without replies'} ...`); - this.queueService.createFollowJob([{ from: user, to: { id: target.id }, silent: true }]); + this.queueService.createFollowJob([{ from: user, to: { id: target.id }, silent: true, withReplies: job.data.withReplies }]); } catch (e) { this.logger.warn(`Error: ${e}`); } diff --git a/packages/backend/src/queue/processors/RelationshipProcessorService.ts b/packages/backend/src/queue/processors/RelationshipProcessorService.ts index 5b2d2ef313..b2d8e3631f 100644 --- a/packages/backend/src/queue/processors/RelationshipProcessorService.ts +++ b/packages/backend/src/queue/processors/RelationshipProcessorService.ts @@ -34,8 +34,12 @@ export class RelationshipProcessorService { @bindThis public async processFollow(job: Bull.Job): Promise { - this.logger.info(`${job.data.from.id} is trying to follow ${job.data.to.id}`); - await this.userFollowingService.follow(job.data.from, job.data.to, job.data.requestId, job.data.silent); + this.logger.info(`${job.data.from.id} is trying to follow ${job.data.to.id} ${job.data.withReplies ? "with replies" : "without replies"}`); + await this.userFollowingService.follow(job.data.from, job.data.to, { + requestId: job.data.requestId, + silent: job.data.silent, + withReplies: job.data.withReplies, + }); return 'ok'; } diff --git a/packages/backend/src/queue/types.ts b/packages/backend/src/queue/types.ts index c9122f5ca2..9330c01528 100644 --- a/packages/backend/src/queue/types.ts +++ b/packages/backend/src/queue/types.ts @@ -32,6 +32,7 @@ export type RelationshipJobData = { to: ThinUser; silent?: boolean; requestId?: string; + withReplies?: boolean; } export type DbJobData = DbJobMap[T]; @@ -79,6 +80,7 @@ export type DbUserDeleteJobData = { export type DbUserImportJobData = { user: ThinUser; fileId: MiDriveFile['id']; + withReplies?: boolean; }; export type DBAntennaImportJobData = { @@ -89,6 +91,7 @@ export type DBAntennaImportJobData = { export type DbUserImportToDbJobData = { user: ThinUser; target: string; + withReplies?: boolean; }; export type ObjectStorageJobData = ObjectStorageFileJobData | Record; diff --git a/packages/backend/src/server/api/endpoints/following/create.ts b/packages/backend/src/server/api/endpoints/following/create.ts index e0e7fed87a..9037944ef9 100644 --- a/packages/backend/src/server/api/endpoints/following/create.ts +++ b/packages/backend/src/server/api/endpoints/following/create.ts @@ -71,6 +71,7 @@ export const paramDef = { type: 'object', properties: { userId: { type: 'string', format: 'misskey:id' }, + withReplies: { type: 'boolean' } }, required: ['userId'], } as const; @@ -112,7 +113,7 @@ export default class extends Endpoint { // eslint- } try { - await this.userFollowingService.follow(follower, followee); + await this.userFollowingService.follow(follower, followee, { withReplies: ps.withReplies }); } catch (e) { if (e instanceof IdentifiableError) { if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking); diff --git a/packages/backend/src/server/api/endpoints/i/import-following.ts b/packages/backend/src/server/api/endpoints/i/import-following.ts index 38c9283043..e5fa2ac96a 100644 --- a/packages/backend/src/server/api/endpoints/i/import-following.ts +++ b/packages/backend/src/server/api/endpoints/i/import-following.ts @@ -52,6 +52,7 @@ export const paramDef = { type: 'object', properties: { fileId: { type: 'string', format: 'misskey:id' }, + withReplies: { type: 'boolean' }, }, required: ['fileId'], } as const; @@ -79,7 +80,7 @@ export default class extends Endpoint { // eslint- ); if (checkMoving ? file.size > 32 * 1024 * 1024 : file.size > 64 * 1024) throw new ApiError(meta.errors.tooBigFile); - this.queueService.createImportFollowingJob(me, file.id); + this.queueService.createImportFollowingJob(me, file.id, ps.withReplies); }); } } diff --git a/packages/frontend/src/components/MkFollowButton.vue b/packages/frontend/src/components/MkFollowButton.vue index 15043fcd0b..b8de71e3b7 100644 --- a/packages/frontend/src/components/MkFollowButton.vue +++ b/packages/frontend/src/components/MkFollowButton.vue @@ -42,6 +42,7 @@ import { useStream } from '@/stream.js'; import { i18n } from '@/i18n.js'; import { claimAchievement } from '@/scripts/achievements.js'; import { $i } from '@/account.js'; +import { defaultStore } from "@/store.js"; const props = withDefaults(defineProps<{ user: Misskey.entities.UserDetailed, @@ -52,6 +53,10 @@ const props = withDefaults(defineProps<{ large: false, }); +const emit = defineEmits<{ + (_: 'update:user', value: Misskey.entities.UserDetailed): void +}>(); + let isFollowing = $ref(props.user.isFollowing); let hasPendingFollowRequestFromYou = $ref(props.user.hasPendingFollowRequestFromYou); let wait = $ref(false); @@ -95,6 +100,11 @@ async function onClick() { } else { await os.api('following/create', { userId: props.user.id, + withReplies: defaultStore.state.defaultWithReplies, + }); + emit('update:user', { + ...props.user, + withReplies: defaultStore.state.defaultWithReplies }); hasPendingFollowRequestFromYou = true; diff --git a/packages/frontend/src/components/MkUserPopup.vue b/packages/frontend/src/components/MkUserPopup.vue index 33ef07d54b..bcba4196b5 100644 --- a/packages/frontend/src/components/MkUserPopup.vue +++ b/packages/frontend/src/components/MkUserPopup.vue @@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +
diff --git a/packages/frontend/src/pages/follow.vue b/packages/frontend/src/pages/follow.vue index e382cabd74..a0a4a480b5 100644 --- a/packages/frontend/src/pages/follow.vue +++ b/packages/frontend/src/pages/follow.vue @@ -14,6 +14,7 @@ import * as Misskey from 'misskey-js'; import * as os from '@/os.js'; import { mainRouter } from '@/router.js'; import { i18n } from '@/i18n.js'; +import { defaultStore } from "@/store.js"; async function follow(user): Promise { const { canceled } = await os.confirm({ @@ -28,7 +29,9 @@ async function follow(user): Promise { os.apiWithDialog('following/create', { userId: user.id, + withReplies: defaultStore.state.defaultWithReplies, }); + user.withReplies = defaultStore.state.defaultWithReplies; } const acct = new URL(location.href).searchParams.get('acct'); diff --git a/packages/frontend/src/pages/gallery/post.vue b/packages/frontend/src/pages/gallery/post.vue index 3f4f657e94..3863348eae 100644 --- a/packages/frontend/src/pages/gallery/post.vue +++ b/packages/frontend/src/pages/gallery/post.vue @@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- + diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index 55de53fb07..30443fded6 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -29,6 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.showFixedPostForm }} {{ i18n.ts.showFixedPostFormInChannel }} + {{ i18n.ts.withRepliesByDefaultForNewlyFollowed }} @@ -249,6 +250,7 @@ const mediaListWithOneImageAppearance = computed(defaultStore.makeGetterSetter(' const notificationPosition = computed(defaultStore.makeGetterSetter('notificationPosition')); const notificationStackAxis = computed(defaultStore.makeGetterSetter('notificationStackAxis')); const keepScreenOn = computed(defaultStore.makeGetterSetter('keepScreenOn')); +const defaultWithReplies = computed(defaultStore.makeGetterSetter('defaultWithReplies')); watch(lang, () => { miLocalStorage.setItem('lang', lang.value as string); diff --git a/packages/frontend/src/pages/settings/import-export.vue b/packages/frontend/src/pages/settings/import-export.vue index 0574a878ae..0f01fda26f 100644 --- a/packages/frontend/src/pages/settings/import-export.vue +++ b/packages/frontend/src/pages/settings/import-export.vue @@ -40,6 +40,9 @@ SPDX-License-Identifier: AGPL-3.0-only + + {{ i18n.ts._exportOrImport.withReplies }} + {{ i18n.ts.import }}
@@ -118,9 +121,11 @@ import { selectFile } from '@/scripts/select-file.js'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { $i } from '@/account.js'; +import { defaultStore } from "@/store.js"; const excludeMutingUsers = ref(false); const excludeInactiveUsers = ref(false); +const withReplies = ref(defaultStore.state.defaultWithReplies); const onExportSuccess = () => { os.alert({ @@ -177,7 +182,10 @@ const exportAntennas = () => { const importFollowing = async (ev) => { const file = await selectFile(ev.currentTarget ?? ev.target); - os.api('i/import-following', { fileId: file.id }).then(onImportSuccess).catch(onError); + os.api('i/import-following', { + fileId: file.id, + withReplies: withReplies.value, + }).then(onImportSuccess).catch(onError); }; const importUserLists = async (ev) => { diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue index 605e9fbb76..4c425898d5 100644 --- a/packages/frontend/src/pages/user/home.vue +++ b/packages/frontend/src/pages/user/home.vue @@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.followsYou }}
- +
@@ -198,6 +198,7 @@ const props = withDefaults(defineProps<{ const router = useRouter(); +let user = $ref(props.user); let parallaxAnimationId = $ref(null); let narrow = $ref(null); let rootEl = $ref(null); @@ -232,7 +233,7 @@ const age = $computed(() => { }); function menu(ev) { - const { menu, cleanup } = getUserMenu(props.user, router); + const { menu, cleanup } = getUserMenu(user, router); os.popupMenu(menu, ev.currentTarget ?? ev.target).finally(cleanup); } diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index 2829411ae5..92d01e4caf 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -361,6 +361,10 @@ export const defaultStore = markRaw(new Storage('base', { where: 'device', default: false, }, + defaultWithReplies: { + where: 'account', + default: false, + }, })); // TODO: 他のタブと永続化されたstateを同期 diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index 6b01321047..895f34689b 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -1185,6 +1185,7 @@ export type Endpoints = { 'following/create': { req: { userId: User['id']; + withReplies?: boolean; }; res: User; }; @@ -2985,7 +2986,7 @@ type UserSorting = '+follower' | '-follower' | '+createdAt' | '-createdAt' | '+u // // src/api.types.ts:16:32 - (ae-forgotten-export) The symbol "TODO" needs to be exported by the entry point index.d.ts // src/api.types.ts:18:25 - (ae-forgotten-export) The symbol "NoParams" needs to be exported by the entry point index.d.ts -// src/api.types.ts:630:18 - (ae-forgotten-export) The symbol "ShowUserReq" needs to be exported by the entry point index.d.ts +// src/api.types.ts:633:18 - (ae-forgotten-export) The symbol "ShowUserReq" needs to be exported by the entry point index.d.ts // src/entities.ts:107:2 - (ae-forgotten-export) The symbol "notificationTypes_2" needs to be exported by the entry point index.d.ts // src/entities.ts:603:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts // src/streaming.types.ts:33:4 - (ae-forgotten-export) The symbol "FIXME" needs to be exported by the entry point index.d.ts diff --git a/packages/misskey-js/src/api.types.ts b/packages/misskey-js/src/api.types.ts index a7a2ea1b36..8c6205bf51 100644 --- a/packages/misskey-js/src/api.types.ts +++ b/packages/misskey-js/src/api.types.ts @@ -321,7 +321,10 @@ export type Endpoints = { 'federation/users': { req: { host: string; limit?: number; sinceId?: User['id']; untilId?: User['id']; }; res: UserDetailed[]; }; // following - 'following/create': { req: { userId: User['id'] }; res: User; }; + 'following/create': { req: { + userId: User['id'], + withReplies?: boolean, + }; res: User; }; 'following/delete': { req: { userId: User['id'] }; res: User; }; 'following/requests/accept': { req: { userId: User['id'] }; res: null; }; 'following/requests/cancel': { req: { userId: User['id'] }; res: User; }; From 145c5c8b2b2c3bbcfe67381389dc8db38be1cb62 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 18 Oct 2023 09:43:59 +0900 Subject: [PATCH 02/12] update deps --- .devcontainer/devcontainer.json | 2 +- package.json | 2 +- packages/backend/package.json | 20 +- packages/frontend/package.json | 34 +- pnpm-lock.yaml | 965 ++++++++++++++++---------------- 5 files changed, 527 insertions(+), 496 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a78d91900b..0583a66960 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,7 +5,7 @@ "workspaceFolder": "/workspace", "features": { "ghcr.io/devcontainers-contrib/features/pnpm:2": { - "version": "8.8.0" + "version": "8.9.2" }, "ghcr.io/devcontainers/features/node:1": { "version": "20.5.1" diff --git a/package.json b/package.json index 01ad0b621f..9fd325c45b 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "type": "git", "url": "https://github.com/misskey-dev/misskey.git" }, - "packageManager": "pnpm@8.8.0", + "packageManager": "pnpm@8.9.2", "workspaces": [ "packages/frontend", "packages/backend", diff --git a/packages/backend/package.json b/packages/backend/package.json index dc8daff1ef..30ca2e1102 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -59,9 +59,9 @@ "@aws-sdk/client-s3": "3.412.0", "@aws-sdk/lib-storage": "3.412.0", "@smithy/node-http-handler": "2.1.5", - "@bull-board/api": "5.8.4", - "@bull-board/fastify": "5.8.4", - "@bull-board/ui": "5.8.4", + "@bull-board/api": "5.9.1", + "@bull-board/fastify": "5.9.1", + "@bull-board/ui": "5.9.1", "@discordapp/twemoji": "14.1.2", "@fastify/accepts": "4.2.0", "@fastify/cookie": "9.1.0", @@ -155,7 +155,7 @@ "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", "summaly": "github:misskey-dev/summaly", - "systeminformation": "5.21.11", + "systeminformation": "5.21.12", "tinycolor2": "1.6.0", "tmp": "0.2.1", "tsc-alias": "1.8.8", @@ -173,13 +173,13 @@ "@jest/globals": "29.7.0", "@simplewebauthn/typescript-types": "8.0.0", "@swc/jest": "0.2.29", - "@types/accepts": "1.3.5", - "@types/archiver": "5.3.3", - "@types/bcryptjs": "2.4.4", - "@types/body-parser": "1.19.3", + "@types/accepts": "1.3.6", + "@types/archiver": "5.3.4", + "@types/bcryptjs": "2.4.5", + "@types/body-parser": "1.19.4", "@types/cbor": "6.0.0", - "@types/color-convert": "2.0.1", - "@types/content-disposition": "0.5.6", + "@types/color-convert": "2.0.2", + "@types/content-disposition": "0.5.7", "@types/fluent-ffmpeg": "2.1.22", "@types/http-link-header": "1.0.3", "@types/jest": "29.5.5", diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 44ecacd992..feadbbb041 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -78,24 +78,24 @@ "vuedraggable": "next" }, "devDependencies": { - "@storybook/addon-actions": "7.4.6", - "@storybook/addon-essentials": "7.4.6", - "@storybook/addon-interactions": "7.4.6", - "@storybook/addon-links": "7.4.6", - "@storybook/addon-storysource": "7.4.6", - "@storybook/addons": "7.4.6", - "@storybook/blocks": "7.4.6", - "@storybook/core-events": "7.4.6", + "@storybook/addon-actions": "7.5.0", + "@storybook/addon-essentials": "7.5.0", + "@storybook/addon-interactions": "7.5.0", + "@storybook/addon-links": "7.5.0", + "@storybook/addon-storysource": "7.5.0", + "@storybook/addons": "7.5.0", + "@storybook/blocks": "7.5.0", + "@storybook/core-events": "7.5.0", "@storybook/jest": "0.2.3", - "@storybook/manager-api": "7.4.6", - "@storybook/preview-api": "7.4.6", - "@storybook/react": "7.4.6", - "@storybook/react-vite": "7.4.6", + "@storybook/manager-api": "7.5.0", + "@storybook/preview-api": "7.5.0", + "@storybook/react": "7.5.0", + "@storybook/react-vite": "7.5.0", "@storybook/testing-library": "0.2.2", - "@storybook/theming": "7.4.6", - "@storybook/types": "7.4.6", - "@storybook/vue3": "7.4.6", - "@storybook/vue3-vite": "7.4.6", + "@storybook/theming": "7.5.0", + "@storybook/types": "7.5.0", + "@storybook/vue3": "7.5.0", + "@storybook/vue3-vite": "7.5.0", "@testing-library/vue": "7.0.0", "@types/escape-regexp": "0.0.1", "@types/estree": "1.0.2", @@ -129,7 +129,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "start-server-and-test": "2.0.1", - "storybook": "7.4.6", + "storybook": "7.5.0", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", "summaly": "github:misskey-dev/summaly", "vite-plugin-turbosnap": "1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 69030bf52c..08f6e9b121 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,14 +63,14 @@ importers: specifier: 3.412.0 version: 3.412.0(@aws-sdk/client-s3@3.412.0) '@bull-board/api': - specifier: 5.8.4 - version: 5.8.4(@bull-board/ui@5.8.4) + specifier: 5.9.1 + version: 5.9.1(@bull-board/ui@5.9.1) '@bull-board/fastify': - specifier: 5.8.4 - version: 5.8.4 + specifier: 5.9.1 + version: 5.9.1 '@bull-board/ui': - specifier: 5.8.4 - version: 5.8.4 + specifier: 5.9.1 + version: 5.9.1 '@discordapp/twemoji': specifier: 14.1.2 version: 14.1.2 @@ -354,8 +354,8 @@ importers: specifier: github:misskey-dev/summaly version: github.com/misskey-dev/summaly/d2d8db49943ccb201c1b1b283e9d0a630519fac7 systeminformation: - specifier: 5.21.11 - version: 5.21.11 + specifier: 5.21.12 + version: 5.21.12 tinycolor2: specifier: 1.6.0 version: 1.6.0 @@ -491,26 +491,26 @@ importers: specifier: 0.2.29 version: 0.2.29(@swc/core@1.3.93) '@types/accepts': - specifier: 1.3.5 - version: 1.3.5 + specifier: 1.3.6 + version: 1.3.6 '@types/archiver': - specifier: 5.3.3 - version: 5.3.3 + specifier: 5.3.4 + version: 5.3.4 '@types/bcryptjs': - specifier: 2.4.4 - version: 2.4.4 + specifier: 2.4.5 + version: 2.4.5 '@types/body-parser': - specifier: 1.19.3 - version: 1.19.3 + specifier: 1.19.4 + version: 1.19.4 '@types/cbor': specifier: 6.0.0 version: 6.0.0 '@types/color-convert': - specifier: 2.0.1 - version: 2.0.1 + specifier: 2.0.2 + version: 2.0.2 '@types/content-disposition': - specifier: 0.5.6 - version: 0.5.6 + specifier: 0.5.7 + version: 0.5.7 '@types/fluent-ffmpeg': specifier: 2.1.22 version: 2.1.22 @@ -822,59 +822,59 @@ importers: version: 4.1.0(vue@3.3.4) devDependencies: '@storybook/addon-actions': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-essentials': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-interactions': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-links': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-storysource': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0) '@storybook/addons': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0) '@storybook/blocks': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0) '@storybook/core-events': - specifier: 7.4.6 - version: 7.4.6 + specifier: 7.5.0 + version: 7.5.0 '@storybook/jest': specifier: 0.2.3 version: 0.2.3(vitest@0.34.6) '@storybook/manager-api': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0) '@storybook/preview-api': - specifier: 7.4.6 - version: 7.4.6 + specifier: 7.5.0 + version: 7.5.0 '@storybook/react': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) '@storybook/react-vite': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.11) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.11) '@storybook/testing-library': specifier: 0.2.2 version: 0.2.2 '@storybook/theming': - specifier: 7.4.6 - version: 7.4.6(react-dom@18.2.0)(react@18.2.0) + specifier: 7.5.0 + version: 7.5.0(react-dom@18.2.0)(react@18.2.0) '@storybook/types': - specifier: 7.4.6 - version: 7.4.6 + specifier: 7.5.0 + version: 7.5.0 '@storybook/vue3': - specifier: 7.4.6 - version: 7.4.6(@vue/compiler-core@3.3.4)(vue@3.3.4) + specifier: 7.5.0 + version: 7.5.0(@vue/compiler-core@3.3.4)(vue@3.3.4) '@storybook/vue3-vite': - specifier: 7.4.6 - version: 7.4.6(@vue/compiler-core@3.3.4)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.4.11)(vue@3.3.4) + specifier: 7.5.0 + version: 7.5.0(@vue/compiler-core@3.3.4)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.4.11)(vue@3.3.4) '@testing-library/vue': specifier: 7.0.0 version: 7.0.0(@vue/compiler-sfc@3.3.4)(vue@3.3.4) @@ -975,11 +975,11 @@ importers: specifier: 2.0.1 version: 2.0.1 storybook: - specifier: 7.4.6 - version: 7.4.6 + specifier: 7.5.0 + version: 7.5.0 storybook-addon-misskey-theme: specifier: github:misskey-dev/storybook-addon-misskey-theme - version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.4.6)(@storybook/components@7.4.6)(@storybook/core-events@7.4.6)(@storybook/manager-api@7.4.6)(@storybook/preview-api@7.4.6)(@storybook/theming@7.4.6)(@storybook/types@7.4.6)(react-dom@18.2.0)(react@18.2.0) + version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.5.0)(@storybook/components@7.4.6)(@storybook/core-events@7.5.0)(@storybook/manager-api@7.5.0)(@storybook/preview-api@7.5.0)(@storybook/theming@7.5.0)(@storybook/types@7.5.0)(react-dom@18.2.0)(react@18.2.0) summaly: specifier: github:misskey-dev/summaly version: github.com/misskey-dev/summaly/d2d8db49943ccb201c1b1b283e9d0a630519fac7 @@ -3009,19 +3009,11 @@ packages: dependencies: regenerator-runtime: 0.13.11 - /@babel/runtime@7.22.10: - resolution: {integrity: sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.0 - dev: true - /@babel/runtime@7.23.1: resolution: {integrity: sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 - dev: false /@babel/template@7.22.5: resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} @@ -3082,29 +3074,29 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true - /@bull-board/api@5.8.4(@bull-board/ui@5.8.4): - resolution: {integrity: sha512-uuB2ziEpMc6FrkqqRAqyqSh+yKx1ukTvxlgDenOimuLAiHlcPfhNLgYuYv3qzqWVaZdvUCLhiNqAvOdURoKT5A==} + /@bull-board/api@5.9.1(@bull-board/ui@5.9.1): + resolution: {integrity: sha512-xZzPYNw9Dp46It4vvZv3tmFScmUu/UT/jWQxYK9cvbkJRXh15rsZrbbR+/phUqou0NxRQGiHoFSZ1y5D107dIA==} peerDependencies: - '@bull-board/ui': 5.8.4 + '@bull-board/ui': 5.9.1 dependencies: - '@bull-board/ui': 5.8.4 + '@bull-board/ui': 5.9.1 redis-info: 3.1.0 dev: false - /@bull-board/fastify@5.8.4: - resolution: {integrity: sha512-so5huv/6WmFqenfm9es5vIOpg46nhwj6F5ZOikfyrUxKcfNdTBgLS0xzB5jnuPp5zp5dVBckH4EnIIgvpdF6cQ==} + /@bull-board/fastify@5.9.1: + resolution: {integrity: sha512-bMktkLGd83K2Wimv+ASBhjgBTOR7ZKQ6OsZsFoaV5xH0CbPlIZ/S0apwTlSSfT/tfBbilWKX9BrE0xta22mkrA==} dependencies: - '@bull-board/api': 5.8.4(@bull-board/ui@5.8.4) - '@bull-board/ui': 5.8.4 + '@bull-board/api': 5.9.1(@bull-board/ui@5.9.1) + '@bull-board/ui': 5.9.1 '@fastify/static': 6.11.2 '@fastify/view': 8.2.0 ejs: 3.1.9 dev: false - /@bull-board/ui@5.8.4: - resolution: {integrity: sha512-OBCwelyO5aptZUanZOSiHCK46Y3dNsCXMj4XXF8rNKx0sg/BMZMZzINjlpsCkgNNM5Lxl51OM1eYLjzZREvaAQ==} + /@bull-board/ui@5.9.1: + resolution: {integrity: sha512-lL93KVRTpLSl73KUFBw7sXOcCrqddGBbpiMKWEbViXxObIq68yFuhRrcfR7JeTSocLF5GsnqSVdSiNCZHmdNpw==} dependencies: - '@bull-board/api': 5.8.4(@bull-board/ui@5.8.4) + '@bull-board/api': 5.9.1(@bull-board/ui@5.9.1) dev: false /@canvas/image-data@1.0.0: @@ -4254,11 +4246,11 @@ packages: chalk: 4.1.2 dev: true - /@joshwooding/vite-plugin-react-docgen-typescript@0.2.1(typescript@5.2.2)(vite@4.4.11): - resolution: {integrity: sha512-ou4ZJSXMMWHqGS4g8uNRbC5TiTWxAgQZiVucoUrOCWuPrTbkpJbmVyIi9jU72SBry7gQtuMEDp4YR8EEXAg7VQ==} + /@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.2.2)(vite@4.4.11): + resolution: {integrity: sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA==} peerDependencies: typescript: '>= 4.3.x' - vite: ^3.0.0 || ^4.0.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: typescript: optional: true @@ -4685,13 +4677,13 @@ packages: /@radix-ui/number@1.0.1: resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 dev: true /@radix-ui/primitive@1.0.1: resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 dev: true /@radix-ui/react-arrow@1.0.3(react-dom@18.2.0)(react@18.2.0): @@ -4707,7 +4699,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-primitive': 1.0.3(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -4726,7 +4718,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-compose-refs': 1.0.1(react@18.2.0) '@radix-ui/react-context': 1.0.1(react@18.2.0) '@radix-ui/react-primitive': 1.0.3(react-dom@18.2.0)(react@18.2.0) @@ -4744,7 +4736,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 react: 18.2.0 dev: true @@ -4757,7 +4749,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 react: 18.2.0 dev: true @@ -4770,7 +4762,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 react: 18.2.0 dev: true @@ -4787,7 +4779,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-compose-refs': 1.0.1(react@18.2.0) '@radix-ui/react-primitive': 1.0.3(react-dom@18.2.0)(react@18.2.0) @@ -4806,7 +4798,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 react: 18.2.0 dev: true @@ -4823,7 +4815,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-compose-refs': 1.0.1(react@18.2.0) '@radix-ui/react-primitive': 1.0.3(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-use-callback-ref': 1.0.1(react@18.2.0) @@ -4840,7 +4832,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-use-layout-effect': 1.0.1(react@18.2.0) react: 18.2.0 dev: true @@ -4858,7 +4850,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@floating-ui/react-dom': 2.0.2(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-arrow': 1.0.3(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-compose-refs': 1.0.1(react@18.2.0) @@ -4886,7 +4878,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-primitive': 1.0.3(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -4905,7 +4897,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-slot': 1.0.2(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -4924,7 +4916,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-collection': 1.0.3(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-compose-refs': 1.0.1(react@18.2.0) @@ -4951,7 +4943,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/number': 1.0.1 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-collection': 1.0.3(react-dom@18.2.0)(react@18.2.0) @@ -4990,7 +4982,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-primitive': 1.0.3(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -5005,7 +4997,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-compose-refs': 1.0.1(react@18.2.0) react: 18.2.0 dev: true @@ -5023,7 +5015,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-context': 1.0.1(react@18.2.0) '@radix-ui/react-direction': 1.0.1(react@18.2.0) @@ -5048,7 +5040,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-primitive': 1.0.3(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-use-controllable-state': 1.0.1(react@18.2.0) @@ -5069,7 +5061,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-context': 1.0.1(react@18.2.0) '@radix-ui/react-direction': 1.0.1(react@18.2.0) @@ -5090,7 +5082,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 react: 18.2.0 dev: true @@ -5103,7 +5095,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-use-callback-ref': 1.0.1(react@18.2.0) react: 18.2.0 dev: true @@ -5117,7 +5109,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-use-callback-ref': 1.0.1(react@18.2.0) react: 18.2.0 dev: true @@ -5131,7 +5123,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 react: 18.2.0 dev: true @@ -5144,7 +5136,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 react: 18.2.0 dev: true @@ -5157,7 +5149,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/rect': 1.0.1 react: 18.2.0 dev: true @@ -5171,7 +5163,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-use-layout-effect': 1.0.1(react@18.2.0) react: 18.2.0 dev: true @@ -5189,7 +5181,7 @@ packages: '@types/react-dom': optional: true dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@radix-ui/react-primitive': 1.0.3(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -5198,7 +5190,7 @@ packages: /@radix-ui/rect@1.0.1: resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==} dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 dev: true /@rollup/plugin-alias@5.0.1(rollup@4.1.4): @@ -5902,8 +5894,8 @@ packages: resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==} dev: false - /@storybook/addon-actions@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-SsqZr3js5NinKPnC8AeNI7Ij+Q6fIl9tRdRmSulEgjksjOg7E5S1/Wsn5Bb2CCgj7MaX6VxGyC7s3XskQtDiIQ==} + /@storybook/addon-actions@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-eeHIFpZXGyhkfmrbHRf3rndL+ppFqlKTgN74y+UfFaAWNUhV3caXxRbHV3BbcPSLkRAsNShBH9hTNTlUAHSVjA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -5913,14 +5905,14 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.4.6 + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 dequal: 2.0.3 lodash: 4.17.21 polished: 4.2.2 @@ -5936,8 +5928,8 @@ packages: - '@types/react-dom' dev: true - /@storybook/addon-backgrounds@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-+LHTZB/ZYMAzkyD5ZxSriBsqmsrvIaW/Nnd/BeuXGbkrVKKqM0qAKiFZAfjc2WchA1piVNy0/1Rsf+kuYCEiJw==} + /@storybook/addon-backgrounds@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Yu/eFHZIfyAhK28GKKcIBwj/9+hRem8pSdI3N0FJuOhErmaE0zg6VDUBzkgLa/Fn9SwC5PNyAeLAtxssg1KSNg==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -5947,14 +5939,14 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.4.6 + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 memoizerific: 1.11.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -5964,8 +5956,8 @@ packages: - '@types/react-dom' dev: true - /@storybook/addon-controls@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-4lq3sycEUIsK8SUWDYc60QgF4vV9FZZ3lDr6M7j2W9bOnvGw49d2fbdlnq+bX1ZprZZ9VgglQpBAorQB3BXZRw==} + /@storybook/addon-controls@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-X56Pd+0GH1A8ddVsziJQaJ8qCaxsWK0aLCKH5li9GLtnyIGHvd5+KvvfYEbjTkeJv3d9J7X0D4uTAH1/dsmI8w==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -5975,16 +5967,16 @@ packages: react-dom: optional: true dependencies: - '@storybook/blocks': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-common': 7.4.6 - '@storybook/core-events': 7.4.6 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/node-logger': 7.4.6 - '@storybook/preview-api': 7.4.6 - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 + '@storybook/blocks': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-common': 7.5.0 + '@storybook/core-events': 7.5.0 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/node-logger': 7.5.0 + '@storybook/preview-api': 7.5.0 + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 lodash: 4.17.21 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -5996,27 +5988,27 @@ packages: - supports-color dev: true - /@storybook/addon-docs@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-dLaub+XWFq4hChw+xfuF9yYg0Txp77FUawKoAigccfjWXx+OOhRV3XTuAcknpXkYq94GWynHgUFXosXT9kbDNA==} + /@storybook/addon-docs@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-lgrum81iJT+i85kO3uOR4wR1t05x4SmJLCB2cyYohCIafiOiV4FuyYFhvT9N6UhHByOfrWgpipKgKg6zsmV2eg==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: '@jest/transform': 29.7.0 '@mdx-js/react': 2.3.0(react@18.2.0) - '@storybook/blocks': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/csf-plugin': 7.4.6 - '@storybook/csf-tools': 7.4.6 + '@storybook/blocks': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/csf-plugin': 7.5.0 + '@storybook/csf-tools': 7.5.0 '@storybook/global': 5.0.0 '@storybook/mdx2-csf': 1.0.0 - '@storybook/node-logger': 7.4.6 - '@storybook/postinstall': 7.4.6 - '@storybook/preview-api': 7.4.6 - '@storybook/react-dom-shim': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 + '@storybook/node-logger': 7.5.0 + '@storybook/postinstall': 7.5.0 + '@storybook/preview-api': 7.5.0 + '@storybook/react-dom-shim': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 fs-extra: 11.1.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -6030,25 +6022,25 @@ packages: - supports-color dev: true - /@storybook/addon-essentials@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-dWodufrt71TK7ELkeIvVae/x4PzECUlbOm57Iqqt4yQCyR291CgvI4PjeB8un2HbpcXCGZ+N/Oj3YkytvzBi4A==} + /@storybook/addon-essentials@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-CKPHdQBP6psTVb3NHsP8cWSUcAA4kwzT8SrJxKddn4ecqmWJWeZo5g5y3WuqVQHlv3edpluJLQYehcVibcljag==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/addon-actions': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-backgrounds': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-controls': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-docs': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-highlight': 7.4.6 - '@storybook/addon-measure': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-outline': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-toolbars': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-viewport': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-common': 7.4.6 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/node-logger': 7.4.6 - '@storybook/preview-api': 7.4.6 + '@storybook/addon-actions': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-backgrounds': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-controls': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-docs': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-highlight': 7.5.0 + '@storybook/addon-measure': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-outline': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-toolbars': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-viewport': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-common': 7.5.0 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/node-logger': 7.5.0 + '@storybook/preview-api': 7.5.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ts-dedent: 2.2.0 @@ -6059,16 +6051,16 @@ packages: - supports-color dev: true - /@storybook/addon-highlight@7.4.6: - resolution: {integrity: sha512-zCufxxD2KS5VwczxfkcBxe1oR/juTTn2H1Qm8kYvWCJQx3UxzX0+G9cwafbpV7eivqaufLweEwROkH+0KjAtkQ==} + /@storybook/addon-highlight@7.5.0: + resolution: {integrity: sha512-6SlEkGCZ/LnEcbN6oE2Au3fgI9VfULErWQ36bx+sV6WWTb1EoooiD7ZJJzobrcOAriSyfWoctO5DF4W+X9I8lg==} dependencies: - '@storybook/core-events': 7.4.6 + '@storybook/core-events': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/preview-api': 7.4.6 + '@storybook/preview-api': 7.5.0 dev: true - /@storybook/addon-interactions@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-zVZYrEPZPhNrXBuPqM7HbQvr6jwsje1sbCYj3wnp83U5wjciuqrngqHIlaSZ30zOWSfRVyzbyqL+JQZKA58BNA==} + /@storybook/addon-interactions@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-OnmFJdzoww8jhiaxY/C/tmppkMRna6f4FKrhqeBytXRai8/PmH+a6tbjrKD8ywtAIt+1MVIxY/oXxXulHtBv8Q==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -6078,16 +6070,16 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-common': 7.4.6 - '@storybook/core-events': 7.4.6 + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-common': 7.5.0 + '@storybook/core-events': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/instrumenter': 7.4.6 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 + '@storybook/instrumenter': 7.5.0 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 jest-mock: 27.5.1 polished: 4.2.2 react: 18.2.0 @@ -6100,8 +6092,8 @@ packages: - supports-color dev: true - /@storybook/addon-links@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-BPygElZKX+CPI9Se6GJNk1dYc5oxuhA+vHigO1tBqhiM6VkHyFP3cvezJNQvpNYhkUnu3cxnZXb3UJnlRbPY3g==} + /@storybook/addon-links@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-1j0I80k8V1sSGN3faduj9uFk0ThgT4qAYyA/5q2YYA4y6V/K8ywJVOR3nv5j7ueTeBD/gUaoncn+NosusrhRNQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -6111,22 +6103,22 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/core-events': 7.4.6 + '@storybook/client-logger': 7.5.0 + '@storybook/core-events': 7.5.0 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/router': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/router': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ts-dedent: 2.2.0 dev: true - /@storybook/addon-measure@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-nCymMLaHnxv8TE3yEM1A9Tulb1NuRXRNmtsdHTkjv7P1aWCxZo8A/GZaottKe/GLT8jSRjZ+dnpYWrbAhw6wTQ==} + /@storybook/addon-measure@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-zzHrQpn+burEr37hV1QV7yA1M33wBa38dUe+RLNYkS9g22BXYYZ/uVUhljpmA9DhZCUNJqYbXWi+ad4XMPE6+Q==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -6136,13 +6128,13 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.4.6 + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/types': 7.4.6 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/types': 7.5.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) tiny-invariant: 1.3.1 @@ -6151,8 +6143,8 @@ packages: - '@types/react-dom' dev: true - /@storybook/addon-outline@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-errNUblRVDLpuEaHQPr/nsrnsUkD2ARmXawkRvizgDWLIDMDJYjTON3MUCaVx3x+hlZ3I6X//G5TVcma8tCc8A==} + /@storybook/addon-outline@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-iVcyFi2N2NEZRytUg8wSiXS9UE9wA8/prs/sIsQ7Y34vHm1UaqAd8KxCE/fhHFNYw4UyHEEDUyTfci/jNrNQYA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -6162,13 +6154,13 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.4.6 + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/types': 7.4.6 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/types': 7.5.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ts-dedent: 2.2.0 @@ -6177,8 +6169,8 @@ packages: - '@types/react-dom' dev: true - /@storybook/addon-storysource@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-qkfwvh/pgVBReuWqO25WyaD7jd6LVqhoIJ6rBWnmx+NBpTds+h3Yt3UJCHgvweIrfSF8J3IqzaTxmmNjnkcrRw==} + /@storybook/addon-storysource@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-D6MfSOjyNNZP1fvnEU6nO5jbgFoMHPvRFXpyYTp9Je2s/mCOjQ/p3elKnVg0tHIcVLoh0aJVutJoW3kkKeNfdw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -6188,13 +6180,13 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/router': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/source-loader': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/router': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/source-loader': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) estraverse: 5.3.0 prop-types: 15.8.1 react: 18.2.0 @@ -6206,8 +6198,8 @@ packages: - '@types/react-dom' dev: true - /@storybook/addon-toolbars@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-L9m2FBcKeteGq7qIYsMJr0LEfiH7Wdrv5IDcldZTn68eZUJTh1p4GdJZcOmzX1P5IFRr76hpu03iWsNlWQjpbQ==} + /@storybook/addon-toolbars@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-RLONWIJE7myVL3DzWZDWnnmb53C1OitCiO3mDt678xyK5ZrFCOV9cznckXASx1wNJVt3P9OOW1N2UY7wul72+Q==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -6217,11 +6209,11 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -6229,8 +6221,8 @@ packages: - '@types/react-dom' dev: true - /@storybook/addon-viewport@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-INDtk54j7bi7NgxMfd2ATmbA0J7nAd6X8itMkLIyPuPJtx8bYHPDORyemDOd0AojgmAdTOAyUtDYdI/PFeo4Cw==} + /@storybook/addon-viewport@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-NXnjHQFKgeFsWOaJE0fl2THgejxDqx8axy4Prtc3ePcoVa/UrMu11G3iEcCaLhDJU7RDNM6CODgifYpH6gyKWg==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -6240,13 +6232,13 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.4.6 + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) memoizerific: 1.11.3 prop-types: 15.8.1 react: 18.2.0 @@ -6256,36 +6248,36 @@ packages: - '@types/react-dom' dev: true - /@storybook/addons@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-c+4awrtwNlJayFdgLkEXa5H2Gj+KNlxuN+Z5oDAdZBLqXI8g0gn7eYO2F/eCSIDWdd/+zcU2uq57XPFKc8veHQ==} + /@storybook/addons@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-ENvleXaJfOUVfWlh+T/318+UpmHfdQz5nB7QxkgK+AX7mQ3tPC41oUivwuEaVE6lP4BsijBtJBrGHEnA29xhUg==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/types': 7.4.6 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/types': 7.5.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/blocks@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-HxBSAeOiTZW2jbHQlo1upRWFgoMsaAyKijUFf5MwwMNIesXCuuTGZDJ3xTABwAVLK2qC9Ektfbo0CZCiPVuDRQ==} + /@storybook/blocks@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-4poS7lQVKhitWKl0TPECMszOMtNamsbNvZdAZ188U/p1EzTrqLg+RT9HtsB8q8Y0owx29Nh5LdfhNOddpx23ig==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/channels': 7.4.6 - '@storybook/client-logger': 7.4.6 - '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.4.6 + '@storybook/channels': 7.5.0 + '@storybook/client-logger': 7.5.0 + '@storybook/components': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.5.0 '@storybook/csf': 0.1.0 - '@storybook/docs-tools': 7.4.6 + '@storybook/docs-tools': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 '@types/lodash': 4.14.191 color-convert: 2.0.1 dequal: 2.0.3 @@ -6307,13 +6299,13 @@ packages: - supports-color dev: true - /@storybook/builder-manager@7.4.6: - resolution: {integrity: sha512-zylZCD2rmyLOOFBFmUgtJg6UNUKmRNgXiig1XApzS2TkIbTZP827DsVEUl0ey/lskCe0uArkrEBR6ICba8p/Rw==} + /@storybook/builder-manager@7.5.0: + resolution: {integrity: sha512-nj+n36i7Mds4RIyGJqvOB+Z47zfgbMes+6Gd6reT1vC22Yda5nAITnd2vxbYfv/sUPhIBBfuFZ/eogomgYCjKg==} dependencies: '@fal-works/esbuild-plugin-global-externals': 2.1.2 - '@storybook/core-common': 7.4.6 - '@storybook/manager': 7.4.6 - '@storybook/node-logger': 7.4.6 + '@storybook/core-common': 7.5.0 + '@storybook/manager': 7.5.0 + '@storybook/node-logger': 7.5.0 '@types/ejs': 3.1.2 '@types/find-cache-dir': 3.2.1 '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.18.17) @@ -6331,12 +6323,12 @@ packages: - supports-color dev: true - /@storybook/builder-vite@7.4.6(typescript@5.2.2)(vite@4.4.11): - resolution: {integrity: sha512-xV9STYK+TkqWWTf2ydm6jx+7P70fjD2UPd1XTUw08uKszIjhuuxk+bG/OF5R1E25mPunAKXm6kBFh351AKejBg==} + /@storybook/builder-vite@7.5.0(typescript@5.2.2)(vite@4.4.11): + resolution: {integrity: sha512-XqiXECAhIDhUryhcPfWfmrvCA2R9p4cebXdyH5Op17yKQ10Bp+OxDWXZlOY/PHdq2KBVhC8CF3Yp7JXCWk8BHw==} peerDependencies: '@preact/preset-vite': '*' typescript: '>= 4.3.x' - vite: ^3.0.0 || ^4.0.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 vite-plugin-glimmerx: '*' peerDependenciesMeta: '@preact/preset-vite': @@ -6346,15 +6338,14 @@ packages: vite-plugin-glimmerx: optional: true dependencies: - '@storybook/channels': 7.4.6 - '@storybook/client-logger': 7.4.6 - '@storybook/core-common': 7.4.6 - '@storybook/csf-plugin': 7.4.6 - '@storybook/mdx2-csf': 1.0.0 - '@storybook/node-logger': 7.4.6 - '@storybook/preview': 7.4.6 - '@storybook/preview-api': 7.4.6 - '@storybook/types': 7.4.6 + '@storybook/channels': 7.5.0 + '@storybook/client-logger': 7.5.0 + '@storybook/core-common': 7.5.0 + '@storybook/csf-plugin': 7.5.0 + '@storybook/node-logger': 7.5.0 + '@storybook/preview': 7.5.0 + '@storybook/preview-api': 7.5.0 + '@storybook/types': 7.5.0 '@types/find-cache-dir': 3.2.1 browser-assert: 1.2.1 es-module-lexer: 0.9.3 @@ -6362,8 +6353,6 @@ packages: find-cache-dir: 3.3.2 fs-extra: 11.1.1 magic-string: 0.30.3 - remark-external-links: 8.0.0 - remark-slug: 6.1.0 rollup: 3.29.4 typescript: 5.2.2 vite: 4.4.11(@types/node@20.8.6)(sass@1.69.3)(terser@5.21.0) @@ -6383,22 +6372,33 @@ packages: tiny-invariant: 1.3.1 dev: true - /@storybook/cli@7.4.6: - resolution: {integrity: sha512-rRwaH8pOL+FHz/pJMEkNpMH2xvZvWsrl7obBYw26NQiHmiVSAkfHJicndSN1mwc+p5w+9iXthrgzbLtSAOSvkA==} + /@storybook/channels@7.5.0: + resolution: {integrity: sha512-/7QJS1UA7TX3uhZqCpjv4Ib8nfMnDOJrBWvjiXiUONaRcSk/he5X+W1Zz/c7dgt+wkYuAh+evjc7glIaBhVNVQ==} + dependencies: + '@storybook/client-logger': 7.5.0 + '@storybook/core-events': 7.5.0 + '@storybook/global': 5.0.0 + qs: 6.11.1 + telejson: 7.2.0 + tiny-invariant: 1.3.1 + dev: true + + /@storybook/cli@7.5.0: + resolution: {integrity: sha512-f14q6sqHhDf7bFS0o/ZTgN2tM00Q0cMGMmGFXTQSCh0HXJUS4ujy/FADL+x62wUylIdr1HkIw+ONWMMqHuenEA==} hasBin: true dependencies: '@babel/core': 7.22.11 '@babel/preset-env': 7.22.9(@babel/core@7.22.11) '@babel/types': 7.22.17 '@ndelangen/get-tarball': 3.0.7 - '@storybook/codemod': 7.4.6 - '@storybook/core-common': 7.4.6 - '@storybook/core-events': 7.4.6 - '@storybook/core-server': 7.4.6 - '@storybook/csf-tools': 7.4.6 - '@storybook/node-logger': 7.4.6 - '@storybook/telemetry': 7.4.6 - '@storybook/types': 7.4.6 + '@storybook/codemod': 7.5.0 + '@storybook/core-common': 7.5.0 + '@storybook/core-events': 7.5.0 + '@storybook/core-server': 7.5.0 + '@storybook/csf-tools': 7.5.0 + '@storybook/node-logger': 7.5.0 + '@storybook/telemetry': 7.5.0 + '@storybook/types': 7.5.0 '@types/semver': 7.5.3 '@yarnpkg/fslib': 2.10.3 '@yarnpkg/libzip': 2.3.0 @@ -6441,16 +6441,22 @@ packages: '@storybook/global': 5.0.0 dev: true - /@storybook/codemod@7.4.6: - resolution: {integrity: sha512-lxmwEpwksCaAq96APN2YlooSDfKjJ1vKzN5Ni2EqQzf2TEXl7XQjLacHd7OOaII1kfsy+D5gNG4N5wBo7Ub30g==} + /@storybook/client-logger@7.5.0: + resolution: {integrity: sha512-JV7J9vc69f9Il4uW62NIeweUU7O38VwFWxtCkhd0bcBA/9RG0go4M2avzxYYEAe9kIOX9IBBk8WGzMacwW4gKQ==} + dependencies: + '@storybook/global': 5.0.0 + dev: true + + /@storybook/codemod@7.5.0: + resolution: {integrity: sha512-QdjFdD1OK+LqhYwNMh60/kgSt9VZIgH2TBUeXrPlCK6gfcZBrCB0ktgtuM8Zk/ROktq09pZoVDxqFi0AbEUPew==} dependencies: '@babel/core': 7.22.11 '@babel/preset-env': 7.22.9(@babel/core@7.22.11) '@babel/types': 7.22.17 '@storybook/csf': 0.1.0 - '@storybook/csf-tools': 7.4.6 - '@storybook/node-logger': 7.4.6 - '@storybook/types': 7.4.6 + '@storybook/csf-tools': 7.5.0 + '@storybook/node-logger': 7.5.0 + '@storybook/types': 7.5.0 '@types/cross-spawn': 6.0.2 cross-spawn: 7.0.3 globby: 11.1.0 @@ -6485,26 +6491,49 @@ packages: - '@types/react-dom' dev: true - /@storybook/core-client@7.4.6: - resolution: {integrity: sha512-tfgxAHeCvMcs6DsVgtb4hQSDaCHeAPJOsoyhb47eDQfk4OmxzriM0qWucJV5DePSMi+KutX/rN2u0JxfOuN68g==} + /@storybook/components@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-6lmZ6PbS27xN32vTJ/NvgaiKkFIQRzZuBeBIg2u+FoAEgCiCwRXjZKe/O8NZC2Xr0uf97+7U2P0kD4Hwr9SNhw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/preview-api': 7.4.6 + '@radix-ui/react-select': 1.2.2(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-toolbar': 1.0.4(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.5.0 + '@storybook/csf': 0.1.0 + '@storybook/global': 5.0.0 + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + use-resize-observer: 9.1.0(react-dom@18.2.0)(react@18.2.0) + util-deprecate: 1.0.2 + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' dev: true - /@storybook/core-common@7.4.6: - resolution: {integrity: sha512-05MJFmOM86qvTLtgDskokIFz9txe0Lbhq4L3by1FtF0GwgH+p+W6I94KI7c6ANER+kVZkXQZhiRzwBFnVTW+Cg==} + /@storybook/core-client@7.5.0: + resolution: {integrity: sha512-lnlPhsHnjK3tQ6jgTL/4TqIsxqznMQ0p7lSnUfhfccc2lGtMO/Ez/xIiTGoJQssJxuJE3d4sj3wRgYvuTDGQYw==} dependencies: - '@storybook/core-events': 7.4.6 - '@storybook/node-logger': 7.4.6 - '@storybook/types': 7.4.6 + '@storybook/client-logger': 7.5.0 + '@storybook/preview-api': 7.5.0 + dev: true + + /@storybook/core-common@7.5.0: + resolution: {integrity: sha512-Gw3/rzRb5+XbwqBcr2ZNaIYGEp+WNTwaBOnMs4yp2SCrNIb0P+i3BxlVQdgABaq43EI3/bksowT6hei0jyhGhw==} + dependencies: + '@storybook/core-events': 7.5.0 + '@storybook/node-logger': 7.5.0 + '@storybook/types': 7.5.0 '@types/find-cache-dir': 3.2.1 - '@types/node': 16.18.46 + '@types/node': 18.17.15 '@types/node-fetch': 2.6.4 '@types/pretty-hrtime': 1.0.1 chalk: 4.1.2 esbuild: 0.18.17 - esbuild-register: 3.4.2(esbuild@0.18.17) + esbuild-register: 3.5.0(esbuild@0.18.17) file-system-cache: 2.3.0 find-cache-dir: 3.3.2 find-up: 5.0.0 @@ -6529,26 +6558,32 @@ packages: ts-dedent: 2.2.0 dev: true - /@storybook/core-server@7.4.6: - resolution: {integrity: sha512-jqmRTGCJ1W0WReImivkisPVaLFT5sjtLnFoAk0feHp6QS5j7EYOPN7CYzliyQmARWTLUEXOVaFf3VD6nJZQhJQ==} + /@storybook/core-events@7.5.0: + resolution: {integrity: sha512-FsD+clTzayqprbVllnL8LLch+uCslJFDgsv7Zh99/zoi7OHtHyauoCZkdLBSiDzgc84qS41dY19HqX1/y7cnOw==} + dependencies: + ts-dedent: 2.2.0 + dev: true + + /@storybook/core-server@7.5.0: + resolution: {integrity: sha512-7QT8uzwSJOsv9PASQ6ywepYkcEYFB7+S7Cj/0nFMh3Vl9vW96LXvEHLAo9CUhSxdEKWeTnD8DS5+j90dLhQFCA==} dependencies: '@aw-web-design/x-default-browser': 1.4.126 '@discoveryjs/json-ext': 0.5.7 - '@storybook/builder-manager': 7.4.6 - '@storybook/channels': 7.4.6 - '@storybook/core-common': 7.4.6 - '@storybook/core-events': 7.4.6 + '@storybook/builder-manager': 7.5.0 + '@storybook/channels': 7.5.0 + '@storybook/core-common': 7.5.0 + '@storybook/core-events': 7.5.0 '@storybook/csf': 0.1.0 - '@storybook/csf-tools': 7.4.6 + '@storybook/csf-tools': 7.5.0 '@storybook/docs-mdx': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/manager': 7.4.6 - '@storybook/node-logger': 7.4.6 - '@storybook/preview-api': 7.4.6 - '@storybook/telemetry': 7.4.6 - '@storybook/types': 7.4.6 + '@storybook/manager': 7.5.0 + '@storybook/node-logger': 7.5.0 + '@storybook/preview-api': 7.5.0 + '@storybook/telemetry': 7.5.0 + '@storybook/types': 7.5.0 '@types/detect-port': 1.3.2 - '@types/node': 16.18.46 + '@types/node': 18.17.15 '@types/pretty-hrtime': 1.0.1 '@types/semver': 7.5.3 better-opn: 3.0.2 @@ -6580,24 +6615,24 @@ packages: - utf-8-validate dev: true - /@storybook/csf-plugin@7.4.6: - resolution: {integrity: sha512-yi7Qa4NSqKOyiJTWCxlB0ih2ijXq6oY5qZKW6MuMMBP14xJNRGLbH5KabpfXgN2T7YECcOWG1uWaGj2veJb1KA==} + /@storybook/csf-plugin@7.5.0: + resolution: {integrity: sha512-kghaEFYvQISdAjQddeicSuvBFMeuuLNtpmMkuoLQzULF7e/Tws6zLCYsjGevqlnqXD0iW2XM/j9q4M5L/mWc5A==} dependencies: - '@storybook/csf-tools': 7.4.6 + '@storybook/csf-tools': 7.5.0 unplugin: 1.4.0 transitivePeerDependencies: - supports-color dev: true - /@storybook/csf-tools@7.4.6: - resolution: {integrity: sha512-ocKpcIUtTBy6hlLY34RUFQyX403cWpB2gGfqvkHbpGe2BQj7EyV0zpWnjsfVxvw+M9OWlCdxHWDOPUgXM33ELw==} + /@storybook/csf-tools@7.5.0: + resolution: {integrity: sha512-KOHbFNSwwc7KTdNz/6yO7S2pxbr7sH6nqfolS6/l+pod45WvRH3VhyqlDIIeX7ESIhfCw87ExC96hNDL3TojCw==} dependencies: '@babel/generator': 7.22.10 '@babel/parser': 7.22.16 '@babel/traverse': 7.22.11 '@babel/types': 7.22.17 '@storybook/csf': 0.1.0 - '@storybook/types': 7.4.6 + '@storybook/types': 7.5.0 fs-extra: 11.1.1 recast: 0.23.1 ts-dedent: 2.2.0 @@ -6615,12 +6650,12 @@ packages: resolution: {integrity: sha512-JDaBR9lwVY4eSH5W8EGHrhODjygPd6QImRbwjAuJNEnY0Vw4ie3bPkeGfnacB3OBW6u/agqPv2aRlR46JcAQLg==} dev: true - /@storybook/docs-tools@7.4.6: - resolution: {integrity: sha512-nZj1L/8WwKWWJ41FW4MaKGajZUtrhnr9UwflRCkQJaWhAKmDfOb5M5TqI93uCOULpFPOm5wpoMBz2IHInQ2Lrg==} + /@storybook/docs-tools@7.5.0: + resolution: {integrity: sha512-NFhqbXj6Wv5YypMwDkt0z9xcfWD7M3wZhr8Z9XcXDlUUPjBrdv0cHt3rfHwEXpTfFyunbK41KQZZ3JkjiAjgTg==} dependencies: - '@storybook/core-common': 7.4.6 - '@storybook/preview-api': 7.4.6 - '@storybook/types': 7.4.6 + '@storybook/core-common': 7.5.0 + '@storybook/preview-api': 7.5.0 + '@storybook/types': 7.5.0 '@types/doctrine': 0.0.3 doctrine: 3.0.0 lodash: 4.17.21 @@ -6639,14 +6674,14 @@ packages: resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} dev: true - /@storybook/instrumenter@7.4.6: - resolution: {integrity: sha512-K5atRoVFCl6HEgkSxIbwygpzgE/iROc7BrtJ3z3a7E70sanFr6Jxt6Egu6fz2QkL3ef4EWpXMnle2vhEfG29pA==} + /@storybook/instrumenter@7.5.0: + resolution: {integrity: sha512-AyutK7uxZbgaF3/Fe+XwKbNxceEThDMi+T/FVIwJ98Ju0VqoIRefg8dbm98K6XyulYyZqmdP+C1/HdNl6Gbltg==} dependencies: - '@storybook/channels': 7.4.6 - '@storybook/client-logger': 7.4.6 - '@storybook/core-events': 7.4.6 + '@storybook/channels': 7.5.0 + '@storybook/client-logger': 7.5.0 + '@storybook/core-events': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/preview-api': 7.4.6 + '@storybook/preview-api': 7.5.0 dev: true /@storybook/jest@0.2.3(vitest@0.34.6): @@ -6662,20 +6697,20 @@ packages: - vitest dev: true - /@storybook/manager-api@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-inrm3DIbCp8wjXSN/wK6e6i2ysQ/IEmtC7IN0OJ7vdrp+USCooPT448SQTUmVctUGCFmOU3fxXByq8g77oIi7w==} + /@storybook/manager-api@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-n9EaJTThsuFiBDs+GcmNBHnvLhH0znJQprhIQqHNVnosCs/7sloYUzWZzZvPwfnfPvRR7ostEEMXvriaYXYdJQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/channels': 7.4.6 - '@storybook/client-logger': 7.4.6 - '@storybook/core-events': 7.4.6 + '@storybook/channels': 7.5.0 + '@storybook/client-logger': 7.5.0 + '@storybook/core-events': 7.5.0 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/router': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 + '@storybook/router': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 dequal: 2.0.3 lodash: 4.17.21 memoizerific: 1.11.3 @@ -6687,31 +6722,31 @@ packages: ts-dedent: 2.2.0 dev: true - /@storybook/manager@7.4.6: - resolution: {integrity: sha512-kA1hUDxpn1i2SO9OinvLvVXDeL4xgJkModp+pbE8IXv4NJWReNq1ecMeQCzPLS3Sil2gnrullQ9uYXsnZ9bxxA==} + /@storybook/manager@7.5.0: + resolution: {integrity: sha512-M4h4b0Y4aZ1sRGaZuJXgvPZHqu7vN/wgWB5yPcSwJqH1+DlPxYXYnPKGERgaEUUVKJV3oWQD2qZ+UpDeTgI5UQ==} dev: true /@storybook/mdx2-csf@1.0.0: resolution: {integrity: sha512-dBAnEL4HfxxJmv7LdEYUoZlQbWj9APZNIbOaq0tgF8XkxiIbzqvgB0jhL/9UOrysSDbQWBiCRTu2wOVxedGfmw==} dev: true - /@storybook/node-logger@7.4.6: - resolution: {integrity: sha512-djZb310Q27GviDug1XBv0jOEDLCiwr4hhDE0aifCEKZpfNCi/EaP31nbWimFzZwxu4hE/YAPWExzScruR1zw9Q==} + /@storybook/node-logger@7.5.0: + resolution: {integrity: sha512-Og3hdB1bjpVCXhmlhvpgVxUfCQGd0DCguXf5qhn2kX4a+D++dxJ8YqzVJ5JQCacI9bCKITV6W9JSGseWcBaXBg==} dev: true - /@storybook/postinstall@7.4.6: - resolution: {integrity: sha512-TqI5BucPAGRWrkh55BYiG2/gHLFtC0In4cuu0GsUzB/1jc4i51npLRorCwhmT7r7YliGl5F7JaP0Bni/qHN3Lg==} + /@storybook/postinstall@7.5.0: + resolution: {integrity: sha512-SHpBItwar7qDZO7BBSqTNQK0yNy+RUROZUhW6wlVvsgVhIGF1bgA4pgpW1iMyfPmmGyNekE1BJjN+v8rjq9s6A==} dev: true - /@storybook/preview-api@7.4.6: - resolution: {integrity: sha512-byUS/Opt3ytWD4cWz3sNEKw5Yks8MkQgRN+GDSyIomaEAQkLAM0rchPC0MYjwCeUSecV7IIQweNX5RbV4a34BA==} + /@storybook/preview-api@7.5.0: + resolution: {integrity: sha512-+DubgKwYFk532FKDB6sEGaG47wr0t137aIQSjbNwVmXXxj0QY0zIAThtERx7w6eHS7ZjOs6xlLEZhzC4FI525g==} dependencies: - '@storybook/channels': 7.4.6 - '@storybook/client-logger': 7.4.6 - '@storybook/core-events': 7.4.6 + '@storybook/channels': 7.5.0 + '@storybook/client-logger': 7.5.0 + '@storybook/core-events': 7.5.0 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/types': 7.4.6 + '@storybook/types': 7.5.0 '@types/qs': 6.9.7 dequal: 2.0.3 lodash: 4.17.21 @@ -6722,12 +6757,12 @@ packages: util-deprecate: 1.0.2 dev: true - /@storybook/preview@7.4.6: - resolution: {integrity: sha512-2RPXusJ4CTDrIipIKKvbotD7fP0+8VzoFjImunflIrzN9rni+2rq5eMjqlXAaB+77w064zIR4uDUzI9fxsMDeQ==} + /@storybook/preview@7.5.0: + resolution: {integrity: sha512-KPhx43pRgIb6UhqjsF0sUG5c3GG2dwzTzjN1/sj0QbPMghZ3b7xKGrCu6VSlsXoWQtcwisMHETFnowk0Ba/AMg==} dev: true - /@storybook/react-dom-shim@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-DSq8l9FDocUF1ooVI+TF83pddj1LynE/Hv0/y8XZhc3IgJ/HkuOQuUmfz29ezgfAi9gFYUR8raTIBi3/xdoRmw==} + /@storybook/react-dom-shim@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-OzJhXg1En/9D9vKvD2t0EcYcuHFzrLTA9kEUWt/eP3Ww41kndfJoZca33JZr17iuKksVAZ8ucETMnkL3yO+ybA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -6736,23 +6771,22 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/react-vite@7.4.6(react-dom@18.2.0)(react@18.2.0)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.11): - resolution: {integrity: sha512-jkjnrf3FxzR5wcmebXRPflrsM4WIDjWyW/NVFJwxi5PeIOk7fE7/QAPrm4NFRUu2Q7DeuH3oLKsw8bigvUI9RA==} + /@storybook/react-vite@7.5.0(react-dom@18.2.0)(react@18.2.0)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.11): + resolution: {integrity: sha512-MnXeO1P+D9l6tZoS9wvC0YwSb8Ur05haUw66I2EJgYVmszbWmAv1XI7lYmfTqBj8bfFXk4DbUdIOVvBMfmIIZg==} engines: {node: '>=16'} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - vite: ^3.0.0 || ^4.0.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.2.1(typescript@5.2.2)(vite@4.4.11) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.2.2)(vite@4.4.11) '@rollup/pluginutils': 5.0.5(rollup@4.1.4) - '@storybook/builder-vite': 7.4.6(typescript@5.2.2)(vite@4.4.11) - '@storybook/react': 7.4.6(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) + '@storybook/builder-vite': 7.5.0(typescript@5.2.2)(vite@4.4.11) + '@storybook/react': 7.5.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) '@vitejs/plugin-react': 3.1.0(vite@4.4.11) - ast-types: 0.14.2 magic-string: 0.30.3 react: 18.2.0 - react-docgen: 6.0.0-alpha.3 + react-docgen: 6.0.4 react-dom: 18.2.0(react@18.2.0) vite: 4.4.11(@types/node@20.8.6)(sass@1.69.3)(terser@5.21.0) transitivePeerDependencies: @@ -6764,8 +6798,8 @@ packages: - vite-plugin-glimmerx dev: true - /@storybook/react@7.4.6(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): - resolution: {integrity: sha512-w0dVo64baFFPTGpUOWFqkKsu6pQincoymegSNgqaBd5DxEyMDRiRoTWSJHMKE9BwgE8SyWhRkP1ak1mkccSOhQ==} + /@storybook/react@7.5.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): + resolution: {integrity: sha512-1oD8sYqBZwtfBKR8zZqfhjRong4wN/4PLYMzs5wl4kYugNOeauD8zWSztnIorxzDrl2yjpwnWlRy9wXN/8FI8g==} engines: {node: '>=16.0.0'} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -6775,16 +6809,16 @@ packages: typescript: optional: true dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/core-client': 7.4.6 - '@storybook/docs-tools': 7.4.6 + '@storybook/client-logger': 7.5.0 + '@storybook/core-client': 7.5.0 + '@storybook/docs-tools': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/preview-api': 7.4.6 - '@storybook/react-dom-shim': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 + '@storybook/preview-api': 7.5.0 + '@storybook/react-dom-shim': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 '@types/escodegen': 0.0.6 '@types/estree': 0.0.51 - '@types/node': 16.18.46 + '@types/node': 18.17.15 acorn: 7.4.1 acorn-jsx: 5.3.2(acorn@7.4.1) acorn-walk: 7.2.0 @@ -6804,27 +6838,27 @@ packages: - supports-color dev: true - /@storybook/router@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-Vl1esrHkcHxDKqc+HY7+6JQpBPW3zYvGk0cQ2rxVMhWdLZTAz1hss9DqzN9tFnPyfn0a1Q77EpMySkUrvWKKNQ==} + /@storybook/router@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-NzPwjndmOEOUL8jK5kUrSvRUIcN5Z+h+l0Z8g4I56RoEhNTcKeOW4jbcT4WKnR9H455dti8HAcTV/4x59GpgxQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/client-logger': 7.4.6 + '@storybook/client-logger': 7.5.0 memoizerific: 1.11.3 qs: 6.11.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/source-loader@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-tBso55luaKIsZmIsgYyT7HJcjbgjxf0pdzbYqdThZhY3oSl3d56xbcFDCWW+yWjFONuFY8RGPCT7iGywwmaBdQ==} + /@storybook/source-loader@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-0u31uiIPV56QxXZoZjAVtcQQ405JnfL+1N495Ob82VUFG3gpDlgkUAwFbsTdJjv7RI0CgmpMLsbJjjW4E/ZR/g==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: '@storybook/csf': 0.1.0 - '@storybook/types': 7.4.6 + '@storybook/types': 7.5.0 estraverse: 5.3.0 lodash: 4.17.21 prettier: 2.8.8 @@ -6832,12 +6866,12 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/telemetry@7.4.6: - resolution: {integrity: sha512-c8p/C1NIH8EMBviZkBCx8MMDk6rrITJ+b29DEp5MaWSRlklIVyhGiC4RPIRv6sxJwlD41PnqWVFtfu2j2eXLdQ==} + /@storybook/telemetry@7.5.0: + resolution: {integrity: sha512-dvc1cjxHYGNfLEvh8eQI/R2KtMft0kUs6TJ2uXZdIX4+WqWG6mfn75sP8eyC1tcjkdslS6AmFWTfgt9EVcIPQA==} dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/core-common': 7.4.6 - '@storybook/csf-tools': 7.4.6 + '@storybook/client-logger': 7.5.0 + '@storybook/core-common': 7.5.0 + '@storybook/csf-tools': 7.5.0 chalk: 4.1.2 detect-package-manager: 2.0.1 fetch-retry: 5.0.4 @@ -6870,6 +6904,20 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true + /@storybook/theming@7.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-uTo97oh+pvmlfsZocFq5qae0zGo0VGk7oiBqNSSw6CiTqE1rIuSxoPrMAY+oCTWCUZV7DjONIGvpnGl2QALsAw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0) + '@storybook/client-logger': 7.5.0 + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + /@storybook/types@7.4.6: resolution: {integrity: sha512-6QLXtMVsFZFpzPkdGWsu/iuc8na9dnS67AMOBKm5qCLPwtUJOYkwhMdFRSSeJthLRpzV7JLAL8Kwvl7MFP3QSw==} dependencies: @@ -6879,17 +6927,26 @@ packages: file-system-cache: 2.3.0 dev: true - /@storybook/vue3-vite@7.4.6(@vue/compiler-core@3.3.4)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.4.11)(vue@3.3.4): - resolution: {integrity: sha512-r/mUDdCifpN99Cqmvm7IvPZGnur7lYiTxbQPhV8NdRBpQGxm3JC0life9yIvvHV9mYRCjn5MEzC65zWx03Nzig==} + /@storybook/types@7.5.0: + resolution: {integrity: sha512-fiOUnHKFi/UZSfvc53F0WEQCiquqcSqslL3f5EffwQRiXfeXlGavJb0kU03BO+CvOXcliRn6qKSF2dL0Rgb7Xw==} + dependencies: + '@storybook/channels': 7.5.0 + '@types/babel__core': 7.20.0 + '@types/express': 4.17.17 + file-system-cache: 2.3.0 + dev: true + + /@storybook/vue3-vite@7.5.0(@vue/compiler-core@3.3.4)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.4.11)(vue@3.3.4): + resolution: {integrity: sha512-Mmyeu2bZGdwA6xXDFKzybOxaEPHhB01ezznlTljaVkVNRAYcxzOna+z6INKfP0LYz3anqSDl4vB5g5b05M7gCA==} engines: {node: ^14.18 || >=16} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - vite: ^3.0.0 || ^4.0.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: - '@storybook/builder-vite': 7.4.6(typescript@5.2.2)(vite@4.4.11) - '@storybook/core-server': 7.4.6 - '@storybook/vue3': 7.4.6(@vue/compiler-core@3.3.4)(vue@3.3.4) + '@storybook/builder-vite': 7.5.0(typescript@5.2.2)(vite@4.4.11) + '@storybook/core-server': 7.5.0 + '@storybook/vue3': 7.5.0(@vue/compiler-core@3.3.4)(vue@3.3.4) '@vitejs/plugin-vue': 4.4.0(vite@4.4.11)(vue@3.3.4) magic-string: 0.30.3 react: 18.2.0 @@ -6908,18 +6965,18 @@ packages: - vue dev: true - /@storybook/vue3@7.4.6(@vue/compiler-core@3.3.4)(vue@3.3.4): - resolution: {integrity: sha512-Azv/GhmPlAUy8UbXZHKubrBlKhGimuJTT2O6zUvIzggR6sJdsRmdWaEv2S90ZpMBkVYyyM9oKS1fZ4eKi/Ds8g==} + /@storybook/vue3@7.5.0(@vue/compiler-core@3.3.4)(vue@3.3.4): + resolution: {integrity: sha512-Z1VhHCUMq2cITyK5Yvkcjgajulz23OdXi/m3sRiyhSOGhaRU2iyfM1yUoymk+3WU0cIBe0CsA4uA9A/PFsW6RA==} engines: {node: '>=16.0.0'} peerDependencies: '@vue/compiler-core': ^3.0.0 vue: ^3.0.0 dependencies: - '@storybook/core-client': 7.4.6 - '@storybook/docs-tools': 7.4.6 + '@storybook/core-client': 7.5.0 + '@storybook/docs-tools': 7.5.0 '@storybook/global': 5.0.0 - '@storybook/preview-api': 7.4.6 - '@storybook/types': 7.4.6 + '@storybook/preview-api': 7.5.0 + '@storybook/types': 7.5.0 '@vue/compiler-core': 3.3.4 lodash: 4.17.21 ts-dedent: 2.2.0 @@ -7374,7 +7431,7 @@ packages: optional: true dependencies: '@adobe/css-tools': 4.3.1 - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 '@types/jest': 28.1.3 aria-query: 5.1.3 chalk: 3.0.0 @@ -7427,14 +7484,14 @@ packages: engines: {node: '>=14.17'} dev: true - /@types/accepts@1.3.5: - resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} + /@types/accepts@1.3.6: + resolution: {integrity: sha512-6+qlUg57yfE9OO63wnsJXLeq9cG3gSHBBIxNMOjNrbDRlDnm/NaR7RctfYcVCPq+j7d+MwOxqVEludH5+FKrlg==} dependencies: '@types/node': 20.8.6 dev: true - /@types/archiver@5.3.3: - resolution: {integrity: sha512-0ABdVcXL6jOwNGY+hjWPqrxUvKelBEwNLcuv/SV2vZ4YCH8w9NttFCt+/QqI5zgMX+iX/XqVy89/r7EmLJmMpQ==} + /@types/archiver@5.3.4: + resolution: {integrity: sha512-Lj7fLBIMwYFgViVVZHEdExZC3lVYsl+QL0VmdNdIzGZH544jHveYWij6qdnBgJQDnR7pMKliN9z2cPZFEbhyPw==} dependencies: '@types/readdir-glob': 1.1.1 dev: true @@ -7476,12 +7533,12 @@ packages: '@babel/types': 7.22.17 dev: true - /@types/bcryptjs@2.4.4: - resolution: {integrity: sha512-9wlJI7k5gRyJEC4yrV7DubzNQFTPiykYxUA6lBtsk5NlOfW9oWLJ1HdIA4YtE+6C3i3mTpDQQEosJ2rVZfBWnw==} + /@types/bcryptjs@2.4.5: + resolution: {integrity: sha512-tOF6TivOIvq+TWQm78335CMdyVJhpBG3NUdWQDAp95ax4E2rSKbws/ELHLk5EBoucwx/tHt3/hhLOHwWJgVrSw==} dev: true - /@types/body-parser@1.19.3: - resolution: {integrity: sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==} + /@types/body-parser@1.19.4: + resolution: {integrity: sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==} dependencies: '@types/connect': 3.4.35 '@types/node': 20.8.6 @@ -7516,8 +7573,8 @@ packages: resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} dev: true - /@types/color-convert@2.0.1: - resolution: {integrity: sha512-GwXanrvq/tBHJtudbl1lSy9Ybt7KS9+rA+YY3bcuIIM+d6jSHUr+5yjO83gtiRpuaPiBccwFjSnAK2qSrIPA7w==} + /@types/color-convert@2.0.2: + resolution: {integrity: sha512-KGRIgCxwcgazts4MXRCikPbIMzBpjfdgEZSy8TRHU/gtg+f9sOfHdtK8unPfxIoBtyd2aTTwINVLSNENlC8U8A==} dependencies: '@types/color-name': 1.1.1 dev: true @@ -7532,8 +7589,8 @@ packages: '@types/node': 20.8.6 dev: true - /@types/content-disposition@0.5.6: - resolution: {integrity: sha512-GmShTb4qA9+HMPPaV2+Up8tJafgi38geFi7vL4qAM7k8BwjoelgHZqEUKJZLvughUw22h6vD/wvwN4IUCaWpDA==} + /@types/content-disposition@0.5.7: + resolution: {integrity: sha512-V9/5u21RHFR1zfdm3rQ6pJUKV+zSSVQt+yq16i1YhdivVzWgPEoKedc3GdT8aFjsqQbakdxuy3FnEdePUQOamQ==} dev: true /@types/cookie@0.4.1: @@ -7564,6 +7621,10 @@ packages: resolution: {integrity: sha512-w5jZ0ee+HaPOaX25X2/2oGR/7rgAQSYII7X7pp0m9KgBfMP7uKfMfTvcpl5Dj+eDBbpxKGiqE+flqDr6XTd2RA==} dev: true + /@types/doctrine@0.0.6: + resolution: {integrity: sha512-KlEqPtaNBHBJ2/fVA4yLdD0Tc8zw34pKU4K5SHBIEwtLJ8xxumIC1xeG+4S+/9qhVj2MqC7O3Ld8WvDG4HqlgA==} + dev: true + /@types/ejs@3.1.2: resolution: {integrity: sha512-ZmiaE3wglXVWBM9fyVC17aGPkLo/UgaOjEiI2FXQfyczrCefORPxIe+2dVmnmk3zkVIbizjrlQzmPGhSYGXG5g==} dev: true @@ -7605,7 +7666,7 @@ packages: /@types/express@4.17.17: resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} dependencies: - '@types/body-parser': 1.19.3 + '@types/body-parser': 1.19.4 '@types/express-serve-static-core': 4.17.33 '@types/qs': 6.9.7 '@types/serve-static': 1.15.1 @@ -7772,10 +7833,6 @@ packages: node-fetch: 3.3.2 dev: true - /@types/node@16.18.46: - resolution: {integrity: sha512-Mnq3O9Xz52exs3mlxMcQuA7/9VFe/dXcrgAyfjLkABIqxXKOgBRjyazTxUbjsxDa4BP7hhPliyjVTP9RDP14xg==} - dev: true - /@types/node@18.17.15: resolution: {integrity: sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA==} dev: true @@ -7888,6 +7945,10 @@ packages: resolution: {integrity: sha512-8/ynozXfy9NZ8JhQRSTb0HMuu5Isl547Mih1fMEpNLi9coPcI16UdvIdSqssMgQEdbWsgQIPkLpkpAcK4DEZ3Q==} dev: true + /@types/resolve@1.20.3: + resolution: {integrity: sha512-NH5oErHOtHZYcjCtg69t26aXEk4BN2zLWqf7wnDZ+dpe0iR7Rds1SPGEItl3fca21oOe0n3OCnZ4W7jBxu7FOw==} + dev: true + /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: @@ -9381,25 +9442,6 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - /c8@7.13.0: - resolution: {integrity: sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==} - engines: {node: '>=10.12.0'} - hasBin: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@istanbuljs/schema': 0.1.3 - find-up: 5.0.0 - foreground-child: 2.0.0 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.1.5 - rimraf: 3.0.2 - test-exclude: 6.0.0 - v8-to-istanbul: 9.1.0 - yargs: 16.2.0 - yargs-parser: 20.2.9 - dev: true - /cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -9791,6 +9833,7 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + dev: false /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} @@ -10940,8 +10983,8 @@ packages: resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} dev: true - /esbuild-register@3.4.2(esbuild@0.18.17): - resolution: {integrity: sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==} + /esbuild-register@3.5.0(esbuild@0.18.17): + resolution: {integrity: sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==} peerDependencies: esbuild: '>=0.12 <1' dependencies: @@ -11254,17 +11297,6 @@ packages: engines: {node: '>=4.0'} dev: true - /estree-to-babel@3.2.1: - resolution: {integrity: sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg==} - engines: {node: '>=8.3.0'} - dependencies: - '@babel/traverse': 7.22.11 - '@babel/types': 7.22.17 - c8: 7.13.0 - transitivePeerDependencies: - - supports-color - dev: true - /estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -11809,14 +11841,6 @@ packages: is-callable: 1.2.7 dev: true - /foreground-child@2.0.0: - resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} - engines: {node: '>=8.0.0'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 3.0.7 - dev: true - /foreground-child@3.1.1: resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} engines: {node: '>=14'} @@ -15781,7 +15805,7 @@ packages: resolution: {integrity: sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ==} engines: {node: '>=10'} dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 dev: true /postcss-calc@9.0.1(postcss@8.4.31): @@ -16622,21 +16646,20 @@ packages: typescript: 5.2.2 dev: true - /react-docgen@6.0.0-alpha.3: - resolution: {integrity: sha512-DDLvB5EV9As1/zoUsct6Iz2Cupw9FObEGD3DMcIs3EDFIoSKyz8FZtoWj3Wj+oodrU4/NfidN0BL5yrapIcTSA==} - engines: {node: '>=12.0.0'} - hasBin: true + /react-docgen@6.0.4: + resolution: {integrity: sha512-gF+p+1ZwC2eO66bt763Tepmh5q9kDiFIrqW3YjUV/a+L96h0m5+/wSFQoOHL2cffyrPMZMxP03IgbggJ11QbOw==} + engines: {node: '>=14.18.0'} dependencies: '@babel/core': 7.22.11 - '@babel/generator': 7.22.10 - ast-types: 0.14.2 - commander: 2.20.3 + '@babel/traverse': 7.22.11 + '@babel/types': 7.22.17 + '@types/babel__core': 7.20.0 + '@types/babel__traverse': 7.20.0 + '@types/doctrine': 0.0.6 + '@types/resolve': 1.20.3 doctrine: 3.0.0 - estree-to-babel: 3.2.1 - neo-async: 2.6.2 - node-dir: 0.1.17 resolve: 1.22.3 - strip-indent: 3.0.0 + strip-indent: 4.0.0 transitivePeerDependencies: - supports-color dev: true @@ -16747,7 +16770,7 @@ packages: peerDependencies: react: '>= 0.14.0' dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 highlight.js: 10.7.3 lowlight: 1.20.0 prismjs: 1.29.0 @@ -16942,7 +16965,7 @@ packages: /regenerator-transform@0.15.1: resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} dependencies: - '@babel/runtime': 7.22.10 + '@babel/runtime': 7.23.1 dev: true /regexp.prototype.flags@1.4.3: @@ -17858,11 +17881,11 @@ packages: resolution: {integrity: sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==} dev: true - /storybook@7.4.6: - resolution: {integrity: sha512-YkFSpnR47j5zz7yElA+2axLjXN7K7TxDGJRHHlqXmG5iQ0PXzmjrj2RxMDKFz4Ybp/QjEUoJ4rx//ESEY0Nb5A==} + /storybook@7.5.0: + resolution: {integrity: sha512-dmvQNSuoHq1KrPcK8siApBi5n5reSf6RFAlLHYD+nhM+EP6SL2fXdVjP6ZynTUMRu1NQ5YR/oJhz/SsBzJNkcA==} hasBin: true dependencies: - '@storybook/cli': 7.4.6 + '@storybook/cli': 7.5.0 transitivePeerDependencies: - bufferutil - encoding @@ -18040,6 +18063,13 @@ packages: min-indent: 1.0.1 dev: true + /strip-indent@4.0.0: + resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + engines: {node: '>=12'} + dependencies: + min-indent: 1.0.1 + dev: true + /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -18134,8 +18164,8 @@ packages: resolution: {integrity: sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==} dev: true - /systeminformation@5.21.11: - resolution: {integrity: sha512-dIJEGoP5W7k4JJGje/b+inJrOL5hV9LPsUi5ndBvJydI80CVEcu2DZYgt6prdRErDi2SA4SqYd/WMR4b+u34mA==} + /systeminformation@5.21.12: + resolution: {integrity: sha512-fxMFr6qNqB8MG6tDsVDSdeQoPIwbFy/fQ3p51LWQYqt6PB1CeWrhcKW0c6U6UtoXuwpNawMDb7wlCkTmLXczCw==} engines: {node: '>=8.0.0'} os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true @@ -19656,6 +19686,7 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 20.2.9 + dev: false /yargs@17.6.2: resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==} @@ -19722,7 +19753,7 @@ packages: sharp: 0.31.3 dev: false - github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.4.6)(@storybook/components@7.4.6)(@storybook/core-events@7.4.6)(@storybook/manager-api@7.4.6)(@storybook/preview-api@7.4.6)(@storybook/theming@7.4.6)(@storybook/types@7.4.6)(react-dom@18.2.0)(react@18.2.0): + github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.5.0)(@storybook/components@7.4.6)(@storybook/core-events@7.5.0)(@storybook/manager-api@7.5.0)(@storybook/preview-api@7.5.0)(@storybook/theming@7.5.0)(@storybook/types@7.5.0)(react-dom@18.2.0)(react@18.2.0): resolution: {tarball: https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640} id: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640 name: storybook-addon-misskey-theme @@ -19743,13 +19774,13 @@ packages: react-dom: optional: true dependencies: - '@storybook/blocks': 7.4.6(react-dom@18.2.0)(react@18.2.0) + '@storybook/blocks': 7.5.0(react-dom@18.2.0)(react@18.2.0) '@storybook/components': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.4.6 - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 + '@storybook/core-events': 7.5.0 + '@storybook/manager-api': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.0 + '@storybook/theming': 7.5.0(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.5.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true From 53099cad5a6d933756cb86c3c3d7cdaaccaadb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Wed, 18 Oct 2023 09:48:49 +0900 Subject: [PATCH 03/12] =?UTF-8?q?fix:=20`admin/update-meta`=20=E3=81=8C?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E3=81=A7=E3=81=8D=E3=81=AA=E3=81=84=20(#1205?= =?UTF-8?q?7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix: invalid param impressumUrl * Update CHANGELOG.md --- CHANGELOG.md | 1 + .../backend/src/server/api/endpoints/admin/update-meta.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c9967c46..08e9b09a28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ ### Server - Enhance: ストリーミングAPIのパフォーマンスを向上 +- Fix: コントロールパネルの設定項目が正しく保存できない問題を修正 ## 2023.10.1 ### General diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index 72c4936c13..f05819b186 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -96,8 +96,8 @@ export const paramDef = { tosUrl: { type: 'string', nullable: true }, repositoryUrl: { type: 'string' }, feedbackUrl: { type: 'string' }, - impressumUrl: { type: 'string' }, - privacyPolicyUrl: { type: 'string' }, + impressumUrl: { type: 'string', nullable: true }, + privacyPolicyUrl: { type: 'string', nullable: true }, useObjectStorage: { type: 'boolean' }, objectStorageBaseUrl: { type: 'string', nullable: true }, objectStorageBucket: { type: 'string', nullable: true }, From 0bddd0ceae8a94fa5835150bc127032af37e652d Mon Sep 17 00:00:00 2001 From: woxtu Date: Wed, 18 Oct 2023 09:54:18 +0900 Subject: [PATCH 04/12] Remove unnecessary nullish coalescing (#12058) --- packages/backend/src/core/CustomEmojiService.ts | 2 +- packages/backend/src/core/HashtagService.ts | 2 +- packages/backend/src/core/NoteCreateService.ts | 4 ++-- packages/backend/src/core/ReactionService.ts | 2 +- .../src/core/entities/DriveFileEntityService.ts | 10 +++++----- .../backend/src/core/entities/NoteEntityService.ts | 2 +- .../backend/src/core/entities/UserEntityService.ts | 6 +++--- packages/backend/src/daemons/ServerStatsService.ts | 3 +-- .../src/queue/processors/InboxProcessorService.ts | 2 +- .../src/server/api/stream/channels/home-timeline.ts | 2 +- .../src/server/api/stream/channels/hybrid-timeline.ts | 2 +- packages/backend/src/server/web/FeedService.ts | 2 +- 12 files changed, 19 insertions(+), 20 deletions(-) diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index 505c8e4269..9a8267b466 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -331,7 +331,7 @@ export class CustomEmojiService implements OnApplicationShutdown { const queryOrNull = async () => (await this.emojisRepository.findOneBy({ name, - host: host ?? IsNull(), + host, })) ?? null; const emoji = await this.cache.fetch(`${name} ${host}`, queryOrNull); diff --git a/packages/backend/src/core/HashtagService.ts b/packages/backend/src/core/HashtagService.ts index 1a2f37be39..d378999907 100644 --- a/packages/backend/src/core/HashtagService.ts +++ b/packages/backend/src/core/HashtagService.ts @@ -45,7 +45,7 @@ export class HashtagService { await this.updateHashtag(user, tag, true, true); } - for (const tag of (user.tags ?? []).filter(x => !tags.includes(x))) { + for (const tag of user.tags.filter(x => !tags.includes(x))) { await this.updateHashtag(user, tag, true, false); } } diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 3aefde50e0..7a47cba0e9 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -317,7 +317,7 @@ export class NoteCreateService implements OnApplicationShutdown { data.text = data.text.trim(); if (user.isCat) { - patsedText = patsedText ?? mfm.parse(data.text); + patsedText = mfm.parse(data.text); function nyaizeNode(node: mfm.MfmNode) { if (node.type === 'quote') return; if (node.type === 'text') { @@ -359,7 +359,7 @@ export class NoteCreateService implements OnApplicationShutdown { mentionedUsers = data.apMentions ?? await this.extractMentionedUsers(user, combinedTokens); } - tags = tags.filter(tag => Array.from(tag ?? '').length <= 128).splice(0, 32); + tags = tags.filter(tag => Array.from(tag).length <= 128).splice(0, 32); if (data.reply && (user.id !== data.reply.userId) && !mentionedUsers.some(u => u.id === data.reply!.userId)) { mentionedUsers.push(await this.usersRepository.findOneByOrFail({ id: data.reply!.userId })); diff --git a/packages/backend/src/core/ReactionService.ts b/packages/backend/src/core/ReactionService.ts index 49b465a0f8..1458e2b173 100644 --- a/packages/backend/src/core/ReactionService.ts +++ b/packages/backend/src/core/ReactionService.ts @@ -148,7 +148,7 @@ export class ReactionService { reaction = FALLBACK; } } else { - reaction = this.normalize(reaction ?? null); + reaction = this.normalize(reaction); } } diff --git a/packages/backend/src/core/entities/DriveFileEntityService.ts b/packages/backend/src/core/entities/DriveFileEntityService.ts index 5148b2ca9e..14be000367 100644 --- a/packages/backend/src/core/entities/DriveFileEntityService.ts +++ b/packages/backend/src/core/entities/DriveFileEntityService.ts @@ -90,7 +90,7 @@ export class DriveFileEntityService { if (file.type.startsWith('video')) { if (file.thumbnailUrl) return file.thumbnailUrl; - return this.videoProcessingService.getExternalVideoThumbnailUrl(file.webpublicUrl ?? file.url ?? file.uri); + return this.videoProcessingService.getExternalVideoThumbnailUrl(file.webpublicUrl ?? file.url); } else if (file.uri != null && file.userHost != null && this.config.externalMediaProxyEnabled) { // 動画ではなくリモートかつメディアプロキシ return this.getProxiedUrl(file.uri, 'static'); @@ -145,7 +145,7 @@ export class DriveFileEntityService { .select('SUM(file.size)', 'sum') .getRawOne(); - return parseInt(sum, 10) ?? 0; + return parseInt(sum, 10) || 0; } @bindThis @@ -157,7 +157,7 @@ export class DriveFileEntityService { .select('SUM(file.size)', 'sum') .getRawOne(); - return parseInt(sum, 10) ?? 0; + return parseInt(sum, 10) || 0; } @bindThis @@ -169,7 +169,7 @@ export class DriveFileEntityService { .select('SUM(file.size)', 'sum') .getRawOne(); - return parseInt(sum, 10) ?? 0; + return parseInt(sum, 10) || 0; } @bindThis @@ -181,7 +181,7 @@ export class DriveFileEntityService { .select('SUM(file.size)', 'sum') .getRawOne(); - return parseInt(sum, 10) ?? 0; + return parseInt(sum, 10) || 0; } @bindThis diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts index 674594296c..7cb7e4b913 100644 --- a/packages/backend/src/core/entities/NoteEntityService.ts +++ b/packages/backend/src/core/entities/NoteEntityService.ts @@ -318,7 +318,7 @@ export class NoteEntityService implements OnModuleInit { text: text, cw: note.cw, visibility: note.visibility, - localOnly: note.localOnly ?? undefined, + localOnly: note.localOnly, reactionAcceptance: note.reactionAcceptance, visibleUserIds: note.visibility === 'specified' ? note.visibleUserIds : undefined, renoteCount: note.renoteCount, diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 212994feef..4a3ca00849 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -333,8 +333,8 @@ export class UserEntityService implements OnModuleInit { host: user.host, avatarUrl: user.avatarUrl ?? this.getIdenticonUrl(user), avatarBlurhash: user.avatarBlurhash, - isBot: user.isBot ?? falsy, - isCat: user.isCat ?? falsy, + isBot: user.isBot, + isCat: user.isCat, instance: user.host ? this.federatedInstanceService.federatedInstanceCache.fetch(user.host).then(instance => instance ? { name: instance.name, softwareName: instance.softwareName, @@ -367,7 +367,7 @@ export class UserEntityService implements OnModuleInit { bannerBlurhash: user.bannerBlurhash, isLocked: user.isLocked, isSilenced: this.roleService.getUserPolicies(user.id).then(r => !r.canPublicNote), - isSuspended: user.isSuspended ?? falsy, + isSuspended: user.isSuspended, description: profile!.description, location: profile!.location, birthday: profile!.birthday, diff --git a/packages/backend/src/daemons/ServerStatsService.ts b/packages/backend/src/daemons/ServerStatsService.ts index d294628740..c5ef9b2fa3 100644 --- a/packages/backend/src/daemons/ServerStatsService.ts +++ b/packages/backend/src/daemons/ServerStatsService.ts @@ -108,6 +108,5 @@ async function net() { // FS STAT async function fs() { - const data = await si.disksIO().catch(() => ({ rIO_sec: 0, wIO_sec: 0 })); - return data ?? { rIO_sec: 0, wIO_sec: 0 }; + return await si.disksIO().catch(() => ({ rIO_sec: 0, wIO_sec: 0 })); } diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index 99e823f9fa..89d4ea503e 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -88,7 +88,7 @@ export class InboxProcessorService { if (err.isClientError) { throw new Bull.UnrecoverableError(`skip: Ignored deleted actors on both ends ${activity.actor} - ${err.statusCode}`); } - throw new Error(`Error in actor ${activity.actor} - ${err.statusCode ?? err}`); + throw new Error(`Error in actor ${activity.actor} - ${err.statusCode}`); } } } diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts index de755cccb9..3ccf4af66d 100644 --- a/packages/backend/src/server/api/stream/channels/home-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts @@ -49,7 +49,7 @@ class HomeTimelineChannel extends Channel { } // Ignore notes from instances the user has muted - if (isInstanceMuted(note, new Set(this.userProfile!.mutedInstances ?? []))) return; + if (isInstanceMuted(note, new Set(this.userProfile!.mutedInstances))) return; if (note.visibility === 'followers') { if (!Object.hasOwn(this.following, note.userId)) return; diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts index 83f0bccd90..760fab60a4 100644 --- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts @@ -69,7 +69,7 @@ class HybridTimelineChannel extends Channel { } // Ignore notes from instances the user has muted - if (isInstanceMuted(note, new Set(this.userProfile!.mutedInstances ?? []))) return; + if (isInstanceMuted(note, new Set(this.userProfile!.mutedInstances))) return; // 関係ない返信は除外 if (note.reply && !this.following[note.userId]?.withReplies && !this.withReplies) { diff --git a/packages/backend/src/server/web/FeedService.ts b/packages/backend/src/server/web/FeedService.ts index b547630298..3ba26ad34a 100644 --- a/packages/backend/src/server/web/FeedService.ts +++ b/packages/backend/src/server/web/FeedService.ts @@ -83,7 +83,7 @@ export class FeedService { date: this.idService.parse(note.id).date, description: note.cw ?? undefined, content: note.text ?? undefined, - image: file ? this.driveFileEntityService.getPublicUrl(file) ?? undefined : undefined, + image: file ? this.driveFileEntityService.getPublicUrl(file) : undefined, }); } From f6e1ee1d408bfad1d8e944fe886c9f59577423c1 Mon Sep 17 00:00:00 2001 From: taichan <40626578+taichanNE30@users.noreply.github.com> Date: Wed, 18 Oct 2023 09:55:15 +0900 Subject: [PATCH 05/12] =?UTF-8?q?users/notes=E3=81=A7DB=E3=81=8B=E3=82=89?= =?UTF-8?q?=E5=8F=82=E7=85=A7=E3=81=97=E3=81=9F=E9=9A=9B=E3=81=AB=E3=83=81?= =?UTF-8?q?=E3=83=A3=E3=83=B3=E3=83=8D=E3=83=AB=E6=8A=95=E7=A8=BF=E3=81=AE?= =?UTF-8?q?=E3=81=BF=E5=8F=96=E5=BE=97=E3=81=95=E3=82=8C=E3=82=8B=E5=95=8F?= =?UTF-8?q?=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3=20(#12056)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backend): ユーザーのノート取得でDBにfallbackした際にチャンネルノートのみになる * Update CHANGELOG --------- Co-authored-by: syuilo --- CHANGELOG.md | 1 + packages/backend/src/server/api/endpoints/users/notes.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08e9b09a28..b33f0e3df1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ ### Server - Enhance: ストリーミングAPIのパフォーマンスを向上 +- Fix: users/notesでDBから参照した際にチャンネル投稿のみ取得される問題を修正 - Fix: コントロールパネルの設定項目が正しく保存できない問題を修正 ## 2023.10.1 diff --git a/packages/backend/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts index 4f3d61ce07..2e9eb0dd86 100644 --- a/packages/backend/src/server/api/endpoints/users/notes.ts +++ b/packages/backend/src/server/api/endpoints/users/notes.ts @@ -151,7 +151,10 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); if (ps.withChannelNotes) { - if (!isSelf) query.andWhere('channel.isSensitive = false'); + if (!isSelf) query.andWhere(new Brackets(qb => { + qb.orWhere('note.channelId IS NULL'); + qb.orWhere('channel.isSensitive = false'); + })); } else { query.andWhere('note.channelId IS NULL'); } From d82b3a08e21c731d765558821c634f86e175f15b Mon Sep 17 00:00:00 2001 From: nryeouo <43399370+nryeouo@users.noreply.github.com> Date: Wed, 18 Oct 2023 10:01:50 +0900 Subject: [PATCH 06/12] Update ja-JP.yml (#12053) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ポスト --- locales/ja-JP.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index bc539d17dd..f1b57f8bde 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -593,7 +593,7 @@ poll: "アンケート" useCw: "内容を隠す" enablePlayer: "プレイヤーを開く" disablePlayer: "プレイヤーを閉じる" -expandTweet: "ツイートを展開する" +expandTweet: "ポストを展開する" themeEditor: "テーマエディター" description: "説明" describeFile: "キャプションを付ける" From 52a82ac193e540c6e6d5175eef04d1e259768706 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 18 Oct 2023 10:07:21 +0900 Subject: [PATCH 07/12] Update about-misskey.vue --- packages/frontend/src/pages/about-misskey.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue index f67697db55..6314f9f5d2 100644 --- a/packages/frontend/src/pages/about-misskey.vue +++ b/packages/frontend/src/pages/about-misskey.vue @@ -190,6 +190,9 @@ const patronsWithIcon = [{ }, { name: '百日紅', icon: 'https://misskey-hub.net/patrons/302dce2898dd457ba03c3f7dc037900b.jpg', +}, { + name: 'taichan', + icon: 'https://misskey-hub.net/patrons/f981ab0159fb4e2c998e05f7263e1cd9.png', }]; const patrons = [ From 2a88d8ee2d153bc7dbfcd027154c2c658fc06142 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 18 Oct 2023 12:07:18 +0900 Subject: [PATCH 08/12] refactor(backend): rename service --- packages/backend/src/core/AntennaService.ts | 6 ++-- packages/backend/src/core/CoreModule.ts | 12 +++---- ...ineService.ts => FunoutTimelineService.ts} | 2 +- .../backend/src/core/NoteCreateService.ts | 36 +++++++++---------- packages/backend/src/core/RoleService.ts | 6 ++-- .../server/api/endpoints/antennas/notes.ts | 6 ++-- .../server/api/endpoints/channels/timeline.ts | 6 ++-- .../api/endpoints/notes/hybrid-timeline.ts | 10 +++--- .../api/endpoints/notes/local-timeline.ts | 8 ++--- .../server/api/endpoints/notes/timeline.ts | 6 ++-- .../api/endpoints/notes/user-list-timeline.ts | 6 ++-- .../src/server/api/endpoints/roles/notes.ts | 6 ++-- .../src/server/api/endpoints/users/notes.ts | 10 +++--- 13 files changed, 60 insertions(+), 60 deletions(-) rename packages/backend/src/core/{RedisTimelineService.ts => FunoutTimelineService.ts} (98%) diff --git a/packages/backend/src/core/AntennaService.ts b/packages/backend/src/core/AntennaService.ts index 94c8ad0cf1..65be275548 100644 --- a/packages/backend/src/core/AntennaService.ts +++ b/packages/backend/src/core/AntennaService.ts @@ -16,7 +16,7 @@ import type { AntennasRepository, UserListMembershipsRepository } from '@/models import { UtilityService } from '@/core/UtilityService.js'; import { bindThis } from '@/decorators.js'; import type { GlobalEvents } from '@/core/GlobalEventService.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import type { OnApplicationShutdown } from '@nestjs/common'; @Injectable() @@ -39,7 +39,7 @@ export class AntennaService implements OnApplicationShutdown { private utilityService: UtilityService, private globalEventService: GlobalEventService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, ) { this.antennasFetched = false; this.antennas = []; @@ -84,7 +84,7 @@ export class AntennaService implements OnApplicationShutdown { const redisPipeline = this.redisForTimelines.pipeline(); for (const antenna of matchedAntennas) { - this.redisTimelineService.push(`antennaTimeline:${antenna.id}`, note.id, 200, redisPipeline); + this.funoutTimelineService.push(`antennaTimeline:${antenna.id}`, note.id, 200, redisPipeline); this.globalEventService.publishAntennaStream(antenna.id, 'note', note); } diff --git a/packages/backend/src/core/CoreModule.ts b/packages/backend/src/core/CoreModule.ts index 0dc025d998..e7e66646fc 100644 --- a/packages/backend/src/core/CoreModule.ts +++ b/packages/backend/src/core/CoreModule.ts @@ -61,7 +61,7 @@ import { FileInfoService } from './FileInfoService.js'; import { SearchService } from './SearchService.js'; import { ClipService } from './ClipService.js'; import { FeaturedService } from './FeaturedService.js'; -import { RedisTimelineService } from './RedisTimelineService.js'; +import { FunoutTimelineService } from './FunoutTimelineService.js'; import { ChartLoggerService } from './chart/ChartLoggerService.js'; import FederationChart from './chart/charts/federation.js'; import NotesChart from './chart/charts/notes.js'; @@ -190,7 +190,7 @@ const $FileInfoService: Provider = { provide: 'FileInfoService', useExisting: Fi const $SearchService: Provider = { provide: 'SearchService', useExisting: SearchService }; const $ClipService: Provider = { provide: 'ClipService', useExisting: ClipService }; const $FeaturedService: Provider = { provide: 'FeaturedService', useExisting: FeaturedService }; -const $RedisTimelineService: Provider = { provide: 'RedisTimelineService', useExisting: RedisTimelineService }; +const $FunoutTimelineService: Provider = { provide: 'FunoutTimelineService', useExisting: FunoutTimelineService }; const $ChartLoggerService: Provider = { provide: 'ChartLoggerService', useExisting: ChartLoggerService }; const $FederationChart: Provider = { provide: 'FederationChart', useExisting: FederationChart }; @@ -323,7 +323,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting SearchService, ClipService, FeaturedService, - RedisTimelineService, + FunoutTimelineService, ChartLoggerService, FederationChart, NotesChart, @@ -449,7 +449,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $SearchService, $ClipService, $FeaturedService, - $RedisTimelineService, + $FunoutTimelineService, $ChartLoggerService, $FederationChart, $NotesChart, @@ -576,7 +576,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting SearchService, ClipService, FeaturedService, - RedisTimelineService, + FunoutTimelineService, FederationChart, NotesChart, UsersChart, @@ -701,7 +701,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $SearchService, $ClipService, $FeaturedService, - $RedisTimelineService, + $FunoutTimelineService, $FederationChart, $NotesChart, $UsersChart, diff --git a/packages/backend/src/core/RedisTimelineService.ts b/packages/backend/src/core/FunoutTimelineService.ts similarity index 98% rename from packages/backend/src/core/RedisTimelineService.ts rename to packages/backend/src/core/FunoutTimelineService.ts index 94541759cc..512b2d9833 100644 --- a/packages/backend/src/core/RedisTimelineService.ts +++ b/packages/backend/src/core/FunoutTimelineService.ts @@ -10,7 +10,7 @@ import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; @Injectable() -export class RedisTimelineService { +export class FunoutTimelineService { constructor( @Inject(DI.redisForTimelines) private redisForTimelines: Redis.Redis, diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 7a47cba0e9..30d7f3e76a 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -54,7 +54,7 @@ import { RoleService } from '@/core/RoleService.js'; import { MetaService } from '@/core/MetaService.js'; import { SearchService } from '@/core/SearchService.js'; import { FeaturedService } from '@/core/FeaturedService.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import { nyaize } from '@/misc/nyaize.js'; import { UtilityService } from '@/core/UtilityService.js'; @@ -197,7 +197,7 @@ export class NoteCreateService implements OnApplicationShutdown { private idService: IdService, private globalEventService: GlobalEventService, private queueService: QueueService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, private noteReadService: NoteReadService, private notificationService: NotificationService, private relayService: RelayService, @@ -851,9 +851,9 @@ export class NoteCreateService implements OnApplicationShutdown { const r = this.redisForTimelines.pipeline(); if (note.channelId) { - this.redisTimelineService.push(`channelTimeline:${note.channelId}`, note.id, this.config.perChannelMaxNoteCacheCount, r); + this.funoutTimelineService.push(`channelTimeline:${note.channelId}`, note.id, this.config.perChannelMaxNoteCacheCount, r); - this.redisTimelineService.push(`userTimelineWithChannel:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r); + this.funoutTimelineService.push(`userTimelineWithChannel:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r); const channelFollowings = await this.channelFollowingsRepository.find({ where: { @@ -863,9 +863,9 @@ export class NoteCreateService implements OnApplicationShutdown { }); for (const channelFollowing of channelFollowings) { - this.redisTimelineService.push(`homeTimeline:${channelFollowing.followerId}`, note.id, meta.perUserHomeTimelineCacheMax, r); + this.funoutTimelineService.push(`homeTimeline:${channelFollowing.followerId}`, note.id, meta.perUserHomeTimelineCacheMax, r); if (note.fileIds.length > 0) { - this.redisTimelineService.push(`homeTimelineWithFiles:${channelFollowing.followerId}`, note.id, meta.perUserHomeTimelineCacheMax / 2, r); + this.funoutTimelineService.push(`homeTimelineWithFiles:${channelFollowing.followerId}`, note.id, meta.perUserHomeTimelineCacheMax / 2, r); } } } else { @@ -903,9 +903,9 @@ export class NoteCreateService implements OnApplicationShutdown { if (!following.withReplies) continue; } - this.redisTimelineService.push(`homeTimeline:${following.followerId}`, note.id, meta.perUserHomeTimelineCacheMax, r); + this.funoutTimelineService.push(`homeTimeline:${following.followerId}`, note.id, meta.perUserHomeTimelineCacheMax, r); if (note.fileIds.length > 0) { - this.redisTimelineService.push(`homeTimelineWithFiles:${following.followerId}`, note.id, meta.perUserHomeTimelineCacheMax / 2, r); + this.funoutTimelineService.push(`homeTimelineWithFiles:${following.followerId}`, note.id, meta.perUserHomeTimelineCacheMax / 2, r); } } @@ -921,36 +921,36 @@ export class NoteCreateService implements OnApplicationShutdown { if (!userListMembership.withReplies) continue; } - this.redisTimelineService.push(`userListTimeline:${userListMembership.userListId}`, note.id, meta.perUserListTimelineCacheMax, r); + this.funoutTimelineService.push(`userListTimeline:${userListMembership.userListId}`, note.id, meta.perUserListTimelineCacheMax, r); if (note.fileIds.length > 0) { - this.redisTimelineService.push(`userListTimelineWithFiles:${userListMembership.userListId}`, note.id, meta.perUserListTimelineCacheMax / 2, r); + this.funoutTimelineService.push(`userListTimelineWithFiles:${userListMembership.userListId}`, note.id, meta.perUserListTimelineCacheMax / 2, r); } } if (note.visibility !== 'specified' || !note.visibleUserIds.some(v => v === user.id)) { // 自分自身のHTL - this.redisTimelineService.push(`homeTimeline:${user.id}`, note.id, meta.perUserHomeTimelineCacheMax, r); + this.funoutTimelineService.push(`homeTimeline:${user.id}`, note.id, meta.perUserHomeTimelineCacheMax, r); if (note.fileIds.length > 0) { - this.redisTimelineService.push(`homeTimelineWithFiles:${user.id}`, note.id, meta.perUserHomeTimelineCacheMax / 2, r); + this.funoutTimelineService.push(`homeTimelineWithFiles:${user.id}`, note.id, meta.perUserHomeTimelineCacheMax / 2, r); } } // 自分自身以外への返信 if (note.replyId && note.replyUserId !== note.userId) { - this.redisTimelineService.push(`userTimelineWithReplies:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r); + this.funoutTimelineService.push(`userTimelineWithReplies:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r); if (note.visibility === 'public' && note.userHost == null) { - this.redisTimelineService.push('localTimelineWithReplies', note.id, 300, r); + this.funoutTimelineService.push('localTimelineWithReplies', note.id, 300, r); } } else { - this.redisTimelineService.push(`userTimeline:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r); + this.funoutTimelineService.push(`userTimeline:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r); if (note.fileIds.length > 0) { - this.redisTimelineService.push(`userTimelineWithFiles:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax / 2 : meta.perRemoteUserUserTimelineCacheMax / 2, r); + this.funoutTimelineService.push(`userTimelineWithFiles:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax / 2 : meta.perRemoteUserUserTimelineCacheMax / 2, r); } if (note.visibility === 'public' && note.userHost == null) { - this.redisTimelineService.push('localTimeline', note.id, 1000, r); + this.funoutTimelineService.push('localTimeline', note.id, 1000, r); if (note.fileIds.length > 0) { - this.redisTimelineService.push('localTimelineWithFiles', note.id, 500, r); + this.funoutTimelineService.push('localTimelineWithFiles', note.id, 500, r); } } } diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index d18fb240f7..2c2ff7af1d 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -20,7 +20,7 @@ import { IdService } from '@/core/IdService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; import type { Packed } from '@/misc/json-schema.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import type { OnApplicationShutdown } from '@nestjs/common'; export type RolePolicies = { @@ -103,7 +103,7 @@ export class RoleService implements OnApplicationShutdown { private globalEventService: GlobalEventService, private idService: IdService, private moderationLogService: ModerationLogService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, ) { //this.onMessage = this.onMessage.bind(this); @@ -470,7 +470,7 @@ export class RoleService implements OnApplicationShutdown { const redisPipeline = this.redisClient.pipeline(); for (const role of roles) { - this.redisTimelineService.push(`roleTimeline:${role.id}`, note.id, 1000, redisPipeline); + this.funoutTimelineService.push(`roleTimeline:${role.id}`, note.id, 1000, redisPipeline); this.globalEventService.publishRoleTimelineStream(role.id, 'note', note); } diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts index ff96411f3b..9b5911800c 100644 --- a/packages/backend/src/server/api/endpoints/antennas/notes.ts +++ b/packages/backend/src/server/api/endpoints/antennas/notes.ts @@ -12,7 +12,7 @@ import { NoteReadService } from '@/core/NoteReadService.js'; import { DI } from '@/di-symbols.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { IdService } from '@/core/IdService.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -70,7 +70,7 @@ export default class extends Endpoint { // eslint- private noteEntityService: NoteEntityService, private queryService: QueryService, private noteReadService: NoteReadService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, ) { super(meta, paramDef, async (ps, me) => { const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); @@ -90,7 +90,7 @@ export default class extends Endpoint { // eslint- lastUsedAt: new Date(), }); - let noteIds = await this.redisTimelineService.get(`antennaTimeline:${antenna.id}`, untilId, sinceId); + let noteIds = await this.funoutTimelineService.get(`antennaTimeline:${antenna.id}`, untilId, sinceId); noteIds = noteIds.slice(0, ps.limit); if (noteIds.length === 0) { return []; diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts index 9c39d0ed86..fae4249c8a 100644 --- a/packages/backend/src/server/api/endpoints/channels/timeline.ts +++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts @@ -12,7 +12,7 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js'; import { DI } from '@/di-symbols.js'; import { IdService } from '@/core/IdService.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; import { CacheService } from '@/core/CacheService.js'; import { ApiError } from '../../error.js'; @@ -69,7 +69,7 @@ export default class extends Endpoint { // eslint- private idService: IdService, private noteEntityService: NoteEntityService, private queryService: QueryService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, private cacheService: CacheService, private activeUsersChart: ActiveUsersChart, ) { @@ -95,7 +95,7 @@ export default class extends Endpoint { // eslint- this.cacheService.userMutingsCache.fetch(me.id), ]) : [new Set()]; - let noteIds = await this.redisTimelineService.get(`channelTimeline:${channel.id}`, untilId, sinceId); + let noteIds = await this.funoutTimelineService.get(`channelTimeline:${channel.id}`, untilId, sinceId); noteIds = noteIds.slice(0, ps.limit); if (noteIds.length > 0) { diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts index 378529e30d..adb0f87bba 100644 --- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -15,7 +15,7 @@ import { RoleService } from '@/core/RoleService.js'; import { IdService } from '@/core/IdService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; import { CacheService } from '@/core/CacheService.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -74,7 +74,7 @@ export default class extends Endpoint { // eslint- private activeUsersChart: ActiveUsersChart, private idService: IdService, private cacheService: CacheService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, ) { super(meta, paramDef, async (ps, me) => { const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); @@ -98,20 +98,20 @@ export default class extends Endpoint { // eslint- let noteIds: string[]; if (ps.withFiles) { - const [htlNoteIds, ltlNoteIds] = await this.redisTimelineService.getMulti([ + const [htlNoteIds, ltlNoteIds] = await this.funoutTimelineService.getMulti([ `homeTimelineWithFiles:${me.id}`, 'localTimelineWithFiles', ], untilId, sinceId); noteIds = Array.from(new Set([...htlNoteIds, ...ltlNoteIds])); } else if (ps.withReplies) { - const [htlNoteIds, ltlNoteIds, ltlReplyNoteIds] = await this.redisTimelineService.getMulti([ + const [htlNoteIds, ltlNoteIds, ltlReplyNoteIds] = await this.funoutTimelineService.getMulti([ `homeTimeline:${me.id}`, 'localTimeline', 'localTimelineWithReplies', ], untilId, sinceId); noteIds = Array.from(new Set([...htlNoteIds, ...ltlNoteIds, ...ltlReplyNoteIds])); } else { - const [htlNoteIds, ltlNoteIds] = await this.redisTimelineService.getMulti([ + const [htlNoteIds, ltlNoteIds] = await this.funoutTimelineService.getMulti([ `homeTimeline:${me.id}`, 'localTimeline', ], untilId, sinceId); diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts index f69e60ab54..d39b0358f5 100644 --- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts @@ -15,7 +15,7 @@ import { RoleService } from '@/core/RoleService.js'; import { IdService } from '@/core/IdService.js'; import { CacheService } from '@/core/CacheService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -70,7 +70,7 @@ export default class extends Endpoint { // eslint- private activeUsersChart: ActiveUsersChart, private idService: IdService, private cacheService: CacheService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, ) { super(meta, paramDef, async (ps, me) => { const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); @@ -94,9 +94,9 @@ export default class extends Endpoint { // eslint- let noteIds: string[]; if (ps.withFiles) { - noteIds = await this.redisTimelineService.get('localTimelineWithFiles', untilId, sinceId); + noteIds = await this.funoutTimelineService.get('localTimelineWithFiles', untilId, sinceId); } else { - const [nonReplyNoteIds, replyNoteIds] = await this.redisTimelineService.getMulti([ + const [nonReplyNoteIds, replyNoteIds] = await this.funoutTimelineService.getMulti([ 'localTimeline', 'localTimelineWithReplies', ], untilId, sinceId); diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index 8f13b3a4ba..c0b78b8ee9 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -15,7 +15,7 @@ import { DI } from '@/di-symbols.js'; import { IdService } from '@/core/IdService.js'; import { CacheService } from '@/core/CacheService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; export const meta = { tags: ['notes'], @@ -63,7 +63,7 @@ export default class extends Endpoint { // eslint- private activeUsersChart: ActiveUsersChart, private idService: IdService, private cacheService: CacheService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, ) { super(meta, paramDef, async (ps, me) => { const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); @@ -81,7 +81,7 @@ export default class extends Endpoint { // eslint- this.cacheService.userBlockedCache.fetch(me.id), ]); - let noteIds = await this.redisTimelineService.get(ps.withFiles ? `homeTimelineWithFiles:${me.id}` : `homeTimeline:${me.id}`, untilId, sinceId); + let noteIds = await this.funoutTimelineService.get(ps.withFiles ? `homeTimelineWithFiles:${me.id}` : `homeTimeline:${me.id}`, untilId, sinceId); noteIds = noteIds.slice(0, ps.limit); if (noteIds.length === 0) { diff --git a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts index b8007e78fd..2b31e6169c 100644 --- a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts @@ -15,7 +15,7 @@ import { DI } from '@/di-symbols.js'; import { CacheService } from '@/core/CacheService.js'; import { IdService } from '@/core/IdService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -80,7 +80,7 @@ export default class extends Endpoint { // eslint- private activeUsersChart: ActiveUsersChart, private cacheService: CacheService, private idService: IdService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, ) { super(meta, paramDef, async (ps, me) => { const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); @@ -105,7 +105,7 @@ export default class extends Endpoint { // eslint- this.cacheService.userBlockedCache.fetch(me.id), ]); - let noteIds = await this.redisTimelineService.get(ps.withFiles ? `userListTimelineWithFiles:${list.id}` : `userListTimeline:${list.id}`, untilId, sinceId); + let noteIds = await this.funoutTimelineService.get(ps.withFiles ? `userListTimelineWithFiles:${list.id}` : `userListTimeline:${list.id}`, untilId, sinceId); noteIds = noteIds.slice(0, ps.limit); if (noteIds.length === 0) { diff --git a/packages/backend/src/server/api/endpoints/roles/notes.ts b/packages/backend/src/server/api/endpoints/roles/notes.ts index e6e1daaa51..daa9affc20 100644 --- a/packages/backend/src/server/api/endpoints/roles/notes.ts +++ b/packages/backend/src/server/api/endpoints/roles/notes.ts @@ -11,7 +11,7 @@ import { QueryService } from '@/core/QueryService.js'; import { DI } from '@/di-symbols.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { IdService } from '@/core/IdService.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -66,7 +66,7 @@ export default class extends Endpoint { // eslint- private idService: IdService, private noteEntityService: NoteEntityService, private queryService: QueryService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, ) { super(meta, paramDef, async (ps, me) => { const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); @@ -84,7 +84,7 @@ export default class extends Endpoint { // eslint- return []; } - let noteIds = await this.redisTimelineService.get(`roleTimeline:${role.id}`, untilId, sinceId); + let noteIds = await this.funoutTimelineService.get(`roleTimeline:${role.id}`, untilId, sinceId); noteIds = noteIds.slice(0, ps.limit); if (noteIds.length === 0) { diff --git a/packages/backend/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts index 2e9eb0dd86..343d320f6e 100644 --- a/packages/backend/src/server/api/endpoints/users/notes.ts +++ b/packages/backend/src/server/api/endpoints/users/notes.ts @@ -14,7 +14,7 @@ import { CacheService } from '@/core/CacheService.js'; import { IdService } from '@/core/IdService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; import { QueryService } from '@/core/QueryService.js'; -import { RedisTimelineService } from '@/core/RedisTimelineService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -71,7 +71,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, private cacheService: CacheService, private idService: IdService, - private redisTimelineService: RedisTimelineService, + private funoutTimelineService: FunoutTimelineService, ) { super(meta, paramDef, async (ps, me) => { const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); @@ -87,9 +87,9 @@ export default class extends Endpoint { // eslint- ]) : [new Set()]; const [noteIdsRes, repliesNoteIdsRes, channelNoteIdsRes] = await Promise.all([ - this.redisTimelineService.get(ps.withFiles ? `userTimelineWithFiles:${ps.userId}` : `userTimeline:${ps.userId}`, untilId, sinceId), - ps.withReplies ? this.redisTimelineService.get(`userTimelineWithReplies:${ps.userId}`, untilId, sinceId) : Promise.resolve([]), - ps.withChannelNotes ? this.redisTimelineService.get(`userTimelineWithChannel:${ps.userId}`, untilId, sinceId) : Promise.resolve([]), + this.funoutTimelineService.get(ps.withFiles ? `userTimelineWithFiles:${ps.userId}` : `userTimeline:${ps.userId}`, untilId, sinceId), + ps.withReplies ? this.funoutTimelineService.get(`userTimelineWithReplies:${ps.userId}`, untilId, sinceId) : Promise.resolve([]), + ps.withChannelNotes ? this.funoutTimelineService.get(`userTimelineWithChannel:${ps.userId}`, untilId, sinceId) : Promise.resolve([]), ]); let noteIds = Array.from(new Set([ From 6cc02fee99d11d3866c6f5df8879d857d31f7f4c Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 18 Oct 2023 12:26:16 +0900 Subject: [PATCH 09/12] enhance(backend): improve fanout tl Resolve #11958 Resolve #12061 --- CHANGELOG.md | 2 + .../backend/src/core/FunoutTimelineService.ts | 5 + .../backend/src/core/UserFollowingService.ts | 18 ++- .../api/endpoints/notes/local-timeline.ts | 102 ++++++++----- .../server/api/endpoints/notes/timeline.ts | 138 +++++++++++++----- 5 files changed, 187 insertions(+), 78 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b33f0e3df1..faaac57de7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ - Feat: サーバーサイレンス機能が追加されました - Enhance: 依存関係の更新 - Enhance: 新規にフォローした人のをデフォルトでTLに追加できるように +- Enhance: HTLとLTLを2023.10.0アップデート以前まで遡れるように +- Enhance: フォロー/フォロー解除したときに過去分のHTLにも含まれる投稿が反映されるように ### Client - Enhance: TLの返信表示オプションを記憶するように diff --git a/packages/backend/src/core/FunoutTimelineService.ts b/packages/backend/src/core/FunoutTimelineService.ts index 512b2d9833..c633c329e5 100644 --- a/packages/backend/src/core/FunoutTimelineService.ts +++ b/packages/backend/src/core/FunoutTimelineService.ts @@ -77,4 +77,9 @@ export class FunoutTimelineService { ); }); } + + @bindThis + public purge(name: string) { + return this.redisForTimelines.del('list:' + name); + } } diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts index 7548e3d28f..4d7e14f683 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -29,6 +29,7 @@ import { CacheService } from '@/core/CacheService.js'; import type { Config } from '@/config.js'; import { AccountMoveService } from '@/core/AccountMoveService.js'; import { UtilityService } from '@/core/UtilityService.js'; +import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; import Logger from '../logger.js'; const logger = new Logger('following/create'); @@ -83,6 +84,7 @@ export class UserFollowingService implements OnModuleInit { private webhookService: WebhookService, private apRendererService: ApRendererService, private accountMoveService: AccountMoveService, + private funoutTimelineService: FunoutTimelineService, private perUserFollowingChart: PerUserFollowingChart, private instanceChart: InstanceChart, ) { @@ -288,8 +290,8 @@ export class UserFollowingService implements OnModuleInit { this.perUserFollowingChart.update(follower, followee, true); } - // Publish follow event if (this.userEntityService.isLocalUser(follower) && !silent) { + // Publish follow event this.userEntityService.pack(followee.id, follower, { detail: true, }).then(async packed => { @@ -302,6 +304,8 @@ export class UserFollowingService implements OnModuleInit { }); } }); + + this.funoutTimelineService.purge(`homeTimeline:${follower.id}`); } // Publish followed event @@ -355,8 +359,8 @@ export class UserFollowingService implements OnModuleInit { this.decrementFollowing(following.follower, following.followee); - // Publish unfollow event if (!silent && this.userEntityService.isLocalUser(follower)) { + // Publish unfollow event this.userEntityService.pack(followee.id, follower, { detail: true, }).then(async packed => { @@ -369,6 +373,8 @@ export class UserFollowingService implements OnModuleInit { }); } }); + + this.funoutTimelineService.purge(`homeTimeline:${follower.id}`); } if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) { @@ -707,4 +713,12 @@ export class UserFollowingService implements OnModuleInit { }); } } + + @bindThis + public getFollowees(userId: MiUser['id']) { + return this.followingsRepository.createQueryBuilder('following') + .select('following.followeeId') + .where('following.followerId = :followerId', { followerId: userId }) + .getMany(); + } } diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts index d39b0358f5..9d5688f96f 100644 --- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts @@ -5,7 +5,6 @@ import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; -import * as Redis from 'ioredis'; import type { MiNote, NotesRepository } from '@/models/_.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; @@ -16,6 +15,7 @@ import { IdService } from '@/core/IdService.js'; import { CacheService } from '@/core/CacheService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; +import { QueryService } from '@/core/QueryService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -59,9 +59,6 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.redisForTimelines) - private redisForTimelines: Redis.Redis, - @Inject(DI.notesRepository) private notesRepository: NotesRepository, @@ -71,6 +68,7 @@ export default class extends Endpoint { // eslint- private idService: IdService, private cacheService: CacheService, private funoutTimelineService: FunoutTimelineService, + private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); @@ -106,49 +104,75 @@ export default class extends Endpoint { // eslint- noteIds = noteIds.slice(0, ps.limit); - if (noteIds.length === 0) { - return []; - } + if (noteIds.length > 0) { + const query = this.notesRepository.createQueryBuilder('note') + .where('note.id IN (:...noteIds)', { noteIds: noteIds }) + .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('note.reply', 'reply') + .leftJoinAndSelect('note.renote', 'renote') + .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('note.channel', 'channel'); + + let timeline = await query.getMany(); + + timeline = timeline.filter(note => { + if (me && (note.userId === me.id)) { + return true; + } + if (!ps.withReplies && note.replyId && (me == null || note.replyUserId !== me.id)) return false; + if (me && isUserRelated(note, userIdsWhoBlockingMe)) return false; + if (me && isUserRelated(note, userIdsWhoMeMuting)) return false; + if (note.renoteId) { + if (note.text == null && note.fileIds.length === 0 && !note.hasPoll) { + if (me && isUserRelated(note, userIdsWhoMeMutingRenotes)) return false; + if (ps.withRenotes === false) return false; + } + } - const query = this.notesRepository.createQueryBuilder('note') - .where('note.id IN (:...noteIds)', { noteIds: noteIds }) - .innerJoinAndSelect('note.user', 'user') - .leftJoinAndSelect('note.reply', 'reply') - .leftJoinAndSelect('note.renote', 'renote') - .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser') - .leftJoinAndSelect('note.channel', 'channel'); + return true; + }); - let timeline = await query.getMany(); + // TODO: フィルタした結果件数が足りなかった場合の対応 - timeline = timeline.filter(note => { - if (me && (note.userId === me.id)) { - return true; - } - if (!ps.withReplies && note.replyId && (me == null || note.replyUserId !== me.id)) return false; - if (me && isUserRelated(note, userIdsWhoBlockingMe)) return false; - if (me && isUserRelated(note, userIdsWhoMeMuting)) return false; - if (note.renoteId) { - if (note.text == null && note.fileIds.length === 0 && !note.hasPoll) { - if (me && isUserRelated(note, userIdsWhoMeMutingRenotes)) return false; - if (ps.withRenotes === false) return false; + timeline.sort((a, b) => a.id > b.id ? -1 : 1); + + process.nextTick(() => { + if (me) { + this.activeUsersChart.read(me); } + }); + + return await this.noteEntityService.packMany(timeline, me); + } else { // fallback to db + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), + ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) + .andWhere('(note.visibility = \'public\') AND (note.userHost IS NULL)') + .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('note.reply', 'reply') + .leftJoinAndSelect('note.renote', 'renote') + .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('renote.user', 'renoteUser'); + + this.queryService.generateVisibilityQuery(query, me); + if (me) this.queryService.generateMutedUserQuery(query, me); + if (me) this.queryService.generateBlockedUserQuery(query, me); + if (me) this.queryService.generateMutedUserRenotesQueryForNotes(query, me); + + if (ps.withFiles) { + query.andWhere('note.fileIds != \'{}\''); } - return true; - }); - - // TODO: フィルタした結果件数が足りなかった場合の対応 - - timeline.sort((a, b) => a.id > b.id ? -1 : 1); + const timeline = await query.limit(ps.limit).getMany(); - process.nextTick(() => { - if (me) { - this.activeUsersChart.read(me); - } - }); + process.nextTick(() => { + if (me) { + this.activeUsersChart.read(me); + } + }); - return await this.noteEntityService.packMany(timeline, me); + return await this.noteEntityService.packMany(timeline, me); + } }); } } diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index c0b78b8ee9..8660e1602b 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -5,8 +5,7 @@ import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; -import * as Redis from 'ioredis'; -import type { NotesRepository, FollowingsRepository, MiNote } from '@/models/_.js'; +import type { NotesRepository } from '@/models/_.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js'; @@ -16,6 +15,7 @@ import { IdService } from '@/core/IdService.js'; import { CacheService } from '@/core/CacheService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; +import { UserFollowingService } from '@/core/UserFollowingService.js'; export const meta = { tags: ['notes'], @@ -53,9 +53,6 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.redisForTimelines) - private redisForTimelines: Redis.Redis, - @Inject(DI.notesRepository) private notesRepository: NotesRepository, @@ -64,6 +61,8 @@ export default class extends Endpoint { // eslint- private idService: IdService, private cacheService: CacheService, private funoutTimelineService: FunoutTimelineService, + private userFollowingService: UserFollowingService, + private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); @@ -84,49 +83,114 @@ export default class extends Endpoint { // eslint- let noteIds = await this.funoutTimelineService.get(ps.withFiles ? `homeTimelineWithFiles:${me.id}` : `homeTimeline:${me.id}`, untilId, sinceId); noteIds = noteIds.slice(0, ps.limit); - if (noteIds.length === 0) { - return []; - } + if (noteIds.length > 0) { + const query = this.notesRepository.createQueryBuilder('note') + .where('note.id IN (:...noteIds)', { noteIds: noteIds }) + .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('note.reply', 'reply') + .leftJoinAndSelect('note.renote', 'renote') + .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('note.channel', 'channel'); + + let timeline = await query.getMany(); + + timeline = timeline.filter(note => { + if (note.userId === me.id) { + return true; + } + if (isUserRelated(note, userIdsWhoBlockingMe)) return false; + if (isUserRelated(note, userIdsWhoMeMuting)) return false; + if (note.renoteId) { + if (note.text == null && note.fileIds.length === 0 && !note.hasPoll) { + if (isUserRelated(note, userIdsWhoMeMutingRenotes)) return false; + if (ps.withRenotes === false) return false; + } + } + if (note.reply && note.reply.visibility === 'followers') { + if (!Object.hasOwn(followings, note.reply.userId)) return false; + } - const query = this.notesRepository.createQueryBuilder('note') - .where('note.id IN (:...noteIds)', { noteIds: noteIds }) - .innerJoinAndSelect('note.user', 'user') - .leftJoinAndSelect('note.reply', 'reply') - .leftJoinAndSelect('note.renote', 'renote') - .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser') - .leftJoinAndSelect('note.channel', 'channel'); + return true; + }); - let timeline = await query.getMany(); + // TODO: フィルタした結果件数が足りなかった場合の対応 - timeline = timeline.filter(note => { - if (note.userId === me.id) { - return true; + timeline.sort((a, b) => a.id > b.id ? -1 : 1); + + process.nextTick(() => { + this.activeUsersChart.read(me); + }); + + return await this.noteEntityService.packMany(timeline, me); + } else { // fallback to db + const followees = await this.userFollowingService.getFollowees(me.id); + + //#region Construct query + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), + ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) + .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('note.reply', 'reply') + .leftJoinAndSelect('note.renote', 'renote') + .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('renote.user', 'renoteUser'); + + if (followees.length > 0) { + const meOrFolloweeIds = [me.id, ...followees.map(f => f.followeeId)]; + + query.andWhere('note.userId IN (:...meOrFolloweeIds)', { meOrFolloweeIds: meOrFolloweeIds }); + } else { + query.andWhere('note.userId = :meId', { meId: me.id }); } - if (isUserRelated(note, userIdsWhoBlockingMe)) return false; - if (isUserRelated(note, userIdsWhoMeMuting)) return false; - if (note.renoteId) { - if (note.text == null && note.fileIds.length === 0 && !note.hasPoll) { - if (isUserRelated(note, userIdsWhoMeMutingRenotes)) return false; - if (ps.withRenotes === false) return false; - } + + this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateMutedUserQuery(query, me); + this.queryService.generateBlockedUserQuery(query, me); + this.queryService.generateMutedUserRenotesQueryForNotes(query, me); + + if (ps.includeMyRenotes === false) { + query.andWhere(new Brackets(qb => { + qb.orWhere('note.userId != :meId', { meId: me.id }); + qb.orWhere('note.renoteId IS NULL'); + qb.orWhere('note.text IS NOT NULL'); + qb.orWhere('note.fileIds != \'{}\''); + qb.orWhere('0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)'); + })); } - if (note.reply && note.reply.visibility === 'followers') { - if (!Object.hasOwn(followings, note.reply.userId)) return false; + + if (ps.includeRenotedMyNotes === false) { + query.andWhere(new Brackets(qb => { + qb.orWhere('note.renoteUserId != :meId', { meId: me.id }); + qb.orWhere('note.renoteId IS NULL'); + qb.orWhere('note.text IS NOT NULL'); + qb.orWhere('note.fileIds != \'{}\''); + qb.orWhere('0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)'); + })); } - return true; - }); + if (ps.includeLocalRenotes === false) { + query.andWhere(new Brackets(qb => { + qb.orWhere('note.renoteUserHost IS NOT NULL'); + qb.orWhere('note.renoteId IS NULL'); + qb.orWhere('note.text IS NOT NULL'); + qb.orWhere('note.fileIds != \'{}\''); + qb.orWhere('0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)'); + })); + } - // TODO: フィルタした結果件数が足りなかった場合の対応 + if (ps.withFiles) { + query.andWhere('note.fileIds != \'{}\''); + } + //#endregion - timeline.sort((a, b) => a.id > b.id ? -1 : 1); + const timeline = await query.limit(ps.limit).getMany(); - process.nextTick(() => { - this.activeUsersChart.read(me); - }); + process.nextTick(() => { + this.activeUsersChart.read(me); + }); - return await this.noteEntityService.packMany(timeline, me); + return await this.noteEntityService.packMany(timeline, me); + } }); } } From 3c5bcdd7b35666437bc25ac53524a16c7db3adf1 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 18 Oct 2023 12:27:15 +0900 Subject: [PATCH 10/12] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index faaac57de7..a3bd7feb74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Enhance: 新規にフォローした人のをデフォルトでTLに追加できるように - Enhance: HTLとLTLを2023.10.0アップデート以前まで遡れるように - Enhance: フォロー/フォロー解除したときに過去分のHTLにも含まれる投稿が反映されるように +- Change: nyaizeはAPIレスポンス時ではなく投稿時に一度だけ非可逆的に行われるようになりました ### Client - Enhance: TLの返信表示オプションを記憶するように From 6b7efb6f1dbf865be6fd406b50cfcfa998bc84ed Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 18 Oct 2023 15:32:35 +0900 Subject: [PATCH 11/12] fix(backend): fix admin/get-user-ips error --- packages/backend/src/server/api/endpoints/admin/get-user-ips.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts b/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts index 7b807e848b..6afa824703 100644 --- a/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts +++ b/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts @@ -41,7 +41,7 @@ export default class extends Endpoint { // eslint- return ips.map(x => ({ ip: x.ip, - createdAt: this.idService.parse(x.id).date.toISOString(), + createdAt: x.createdAt.toISOString(), })); }); } From 6b5ee43800a8e4679f15c2ae7f1f79fbe177b950 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 18 Oct 2023 15:51:50 +0900 Subject: [PATCH 12/12] enhance(backend): improve fanout tl for stl --- .../api/endpoints/notes/hybrid-timeline.ts | 138 +++++++++++++----- 1 file changed, 103 insertions(+), 35 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts index adb0f87bba..faaeb32c79 100644 --- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -5,7 +5,6 @@ import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; -import * as Redis from 'ioredis'; import type { NotesRepository, FollowingsRepository, MiNote } from '@/models/_.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js'; @@ -16,6 +15,8 @@ import { IdService } from '@/core/IdService.js'; import { isUserRelated } from '@/misc/is-user-related.js'; import { CacheService } from '@/core/CacheService.js'; import { FunoutTimelineService } from '@/core/FunoutTimelineService.js'; +import { QueryService } from '@/core/QueryService.js'; +import { UserFollowingService } from '@/core/UserFollowingService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -63,9 +64,6 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.redisForTimelines) - private redisForTimelines: Redis.Redis, - @Inject(DI.notesRepository) private notesRepository: NotesRepository, @@ -75,6 +73,8 @@ export default class extends Endpoint { // eslint- private idService: IdService, private cacheService: CacheService, private funoutTimelineService: FunoutTimelineService, + private queryService: QueryService, + private userFollowingService: UserFollowingService, ) { super(meta, paramDef, async (ps, me) => { const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); @@ -96,6 +96,7 @@ export default class extends Endpoint { // eslint- ]); let noteIds: string[]; + let shouldFallbackToDb = false; if (ps.withFiles) { const [htlNoteIds, ltlNoteIds] = await this.funoutTimelineService.getMulti([ @@ -116,51 +117,118 @@ export default class extends Endpoint { // eslint- 'localTimeline', ], untilId, sinceId); noteIds = Array.from(new Set([...htlNoteIds, ...ltlNoteIds])); + shouldFallbackToDb = htlNoteIds.length === 0; } noteIds.sort((a, b) => a > b ? -1 : 1); noteIds = noteIds.slice(0, ps.limit); - if (noteIds.length === 0) { - return []; - } - - const query = this.notesRepository.createQueryBuilder('note') - .where('note.id IN (:...noteIds)', { noteIds: noteIds }) - .innerJoinAndSelect('note.user', 'user') - .leftJoinAndSelect('note.reply', 'reply') - .leftJoinAndSelect('note.renote', 'renote') - .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser') - .leftJoinAndSelect('note.channel', 'channel'); - - let timeline = await query.getMany(); + if (!shouldFallbackToDb) { + const query = this.notesRepository.createQueryBuilder('note') + .where('note.id IN (:...noteIds)', { noteIds: noteIds }) + .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('note.reply', 'reply') + .leftJoinAndSelect('note.renote', 'renote') + .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('note.channel', 'channel'); + + let timeline = await query.getMany(); + + timeline = timeline.filter(note => { + if (note.userId === me.id) { + return true; + } + if (isUserRelated(note, userIdsWhoBlockingMe)) return false; + if (isUserRelated(note, userIdsWhoMeMuting)) return false; + if (note.renoteId) { + if (note.text == null && note.fileIds.length === 0 && !note.hasPoll) { + if (isUserRelated(note, userIdsWhoMeMutingRenotes)) return false; + if (ps.withRenotes === false) return false; + } + } - timeline = timeline.filter(note => { - if (note.userId === me.id) { return true; + }); + + // TODO: フィルタした結果件数が足りなかった場合の対応 + + timeline.sort((a, b) => a.id > b.id ? -1 : 1); + + process.nextTick(() => { + this.activeUsersChart.read(me); + }); + + return await this.noteEntityService.packMany(timeline, me); + } else { // fallback to db + const followees = await this.userFollowingService.getFollowees(me.id); + + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), + ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) + .andWhere(new Brackets(qb => { + if (followees.length > 0) { + const meOrFolloweeIds = [me.id, ...followees.map(f => f.followeeId)]; + qb.where('note.userId IN (:...meOrFolloweeIds)', { meOrFolloweeIds: meOrFolloweeIds }); + qb.orWhere('(note.visibility = \'public\') AND (note.userHost IS NULL)'); + } else { + qb.where('note.userId = :meId', { meId: me.id }); + qb.orWhere('(note.visibility = \'public\') AND (note.userHost IS NULL)'); + } + })) + .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('note.reply', 'reply') + .leftJoinAndSelect('note.renote', 'renote') + .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('renote.user', 'renoteUser'); + + this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateMutedUserQuery(query, me); + this.queryService.generateBlockedUserQuery(query, me); + this.queryService.generateMutedUserRenotesQueryForNotes(query, me); + + if (ps.includeMyRenotes === false) { + query.andWhere(new Brackets(qb => { + qb.orWhere('note.userId != :meId', { meId: me.id }); + qb.orWhere('note.renoteId IS NULL'); + qb.orWhere('note.text IS NOT NULL'); + qb.orWhere('note.fileIds != \'{}\''); + qb.orWhere('0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)'); + })); } - if (isUserRelated(note, userIdsWhoBlockingMe)) return false; - if (isUserRelated(note, userIdsWhoMeMuting)) return false; - if (note.renoteId) { - if (note.text == null && note.fileIds.length === 0 && !note.hasPoll) { - if (isUserRelated(note, userIdsWhoMeMutingRenotes)) return false; - if (ps.withRenotes === false) return false; - } + + if (ps.includeRenotedMyNotes === false) { + query.andWhere(new Brackets(qb => { + qb.orWhere('note.renoteUserId != :meId', { meId: me.id }); + qb.orWhere('note.renoteId IS NULL'); + qb.orWhere('note.text IS NOT NULL'); + qb.orWhere('note.fileIds != \'{}\''); + qb.orWhere('0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)'); + })); } - return true; - }); + if (ps.includeLocalRenotes === false) { + query.andWhere(new Brackets(qb => { + qb.orWhere('note.renoteUserHost IS NOT NULL'); + qb.orWhere('note.renoteId IS NULL'); + qb.orWhere('note.text IS NOT NULL'); + qb.orWhere('note.fileIds != \'{}\''); + qb.orWhere('0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)'); + })); + } - // TODO: フィルタした結果件数が足りなかった場合の対応 + if (ps.withFiles) { + query.andWhere('note.fileIds != \'{}\''); + } + //#endregion - timeline.sort((a, b) => a.id > b.id ? -1 : 1); + const timeline = await query.limit(ps.limit).getMany(); - process.nextTick(() => { - this.activeUsersChart.read(me); - }); + process.nextTick(() => { + this.activeUsersChart.read(me); + }); - return await this.noteEntityService.packMany(timeline, me); + return await this.noteEntityService.packMany(timeline, me); + } }); } }