From 2eaa3e256ff7310bd63197aafe7e72fa207e347b Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 31 May 2024 20:42:02 +0900 Subject: [PATCH 001/268] Update README.md for Sentry --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 24013a7bd817..92e8fef6396e 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ ## Thanks +Sentry + +Thanks to [Sentry](https://sentry.io/) for providing the error tracking platform that helps us catch unexpected errors. + Chromatic Thanks to [Chromatic](https://www.chromatic.com/) for providing the visual testing platform that helps us review UI changes and catch visual regressions. From ecf7945fe8e4554c0db248512fbc51a41cfaf2c9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 31 May 2024 12:25:00 +0000 Subject: [PATCH 002/268] [skip ci] Update CHANGELOG.md (prepend template) --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f78ba677d6b..9d4ef23d272d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## Unreleased + +### General +- + +### Client +- + +### Server +- + + ## 2024.5.0 ### Note From 2b8056a8525e1b38536aa0406ba9446a88b365b9 Mon Sep 17 00:00:00 2001 From: Acid Chicken Date: Sat, 1 Jun 2024 11:16:44 +0900 Subject: [PATCH 003/268] fix(backend): use insertOne insteadof insert/findOneOrFail combination (#13908) * fix(backend): use insertOne insteadof insert/findOneOrFail combination * fix: typo * fix(backend): inherit mainAlias? * refactor(backend): use extend * fix(backend): invalid entityTarget * fix(backend): fake where * chore: debug * chore: debug * test: log * fix(backend): column names * fix(backend): remove dummy from * revert: log * fix(backend): position * fix(backend): automatic aliasing * chore(backend): alias * chore(backend): remove from * fix(backend): type * fix(backend): avoid pure name * test(backend): fix type * chore(backend): use cte * fix(backend): avoid useless alias * fix(backend): fix typo * fix(backend): __disambiguation__ * fix(backend): quote * chore(backend): t * chore(backend): accessible * chore(backend): concrete returning * fix(backend): quote * chore: log more * chore: log metadata * chore(backend): use raw * fix(backend): returning column name * fix(backend): transform * build(backend): wanna logging * build(backend): transform empty * build(backend): build alias * build(backend): restore name * chore: return entity * fix: test case * test(backend): 204 * chore(backend): log sql * chore(backend): assert user joined * fix(backend): typo * chore(backend): log long sql * chore(backend): log join * chore(backend): log join depth null * chore(backend): joinAttributes * chore(backend): override createJoinExpression * chore: join log * fix(backend): escape * test(backend): log log * chore(backend): join gonna success? * chore(backend): relations * chore(backend): undefined * chore(backend): target * chore(backend): remove log * chore(backend): log chart update * chore(backend): log columns * chore(backend): check hasMetadata * chore(backend): unshift id when not included * chore(backend): missing select * chore(backend): remove debug code --- .../backend/src/core/AnnouncementService.ts | 4 +- .../src/core/AvatarDecorationService.ts | 4 +- packages/backend/src/core/ClipService.ts | 4 +- .../backend/src/core/CustomEmojiService.ts | 4 +- packages/backend/src/core/DriveService.ts | 6 +- .../src/core/FederatedInstanceService.ts | 4 +- packages/backend/src/core/RelayService.ts | 4 +- packages/backend/src/core/ReversiService.ts | 7 +- packages/backend/src/core/RoleService.ts | 8 +- .../backend/src/core/UserFollowingService.ts | 4 +- .../core/activitypub/models/ApNoteService.ts | 4 +- packages/backend/src/core/chart/core.ts | 23 +- .../backend/src/models/RepositoryModule.ts | 136 ++++++------ packages/backend/src/models/_.ts | 205 ++++++++++++------ .../ImportAntennasProcessorService.ts | 4 +- .../ImportUserListsProcessorService.ts | 4 +- .../backend/src/server/api/SigninService.ts | 4 +- .../src/server/api/SignupApiService.ts | 4 +- .../server/api/endpoints/admin/ad/create.ts | 4 +- .../api/endpoints/admin/invite/create.ts | 4 +- .../server/api/endpoints/antennas/create.ts | 4 +- .../src/server/api/endpoints/app/create.ts | 4 +- .../api/endpoints/auth/session/generate.ts | 4 +- .../server/api/endpoints/channels/create.ts | 4 +- .../api/endpoints/drive/folders/create.ts | 4 +- .../src/server/api/endpoints/flash/create.ts | 4 +- .../api/endpoints/gallery/posts/create.ts | 4 +- .../server/api/endpoints/i/webhooks/create.ts | 4 +- .../src/server/api/endpoints/invite/create.ts | 4 +- .../server/api/endpoints/notes/polls/vote.ts | 4 +- .../src/server/api/endpoints/pages/create.ts | 4 +- .../users/lists/create-from-public.ts | 4 +- .../api/endpoints/users/lists/create.ts | 4 +- .../api/endpoints/users/report-abuse.ts | 4 +- packages/backend/test/e2e/move.ts | 4 +- packages/backend/test/e2e/reversi-game.ts | 33 +++ 36 files changed, 319 insertions(+), 215 deletions(-) create mode 100644 packages/backend/test/e2e/reversi-game.ts diff --git a/packages/backend/src/core/AnnouncementService.ts b/packages/backend/src/core/AnnouncementService.ts index 9b60df2cae99..40a9db01c057 100644 --- a/packages/backend/src/core/AnnouncementService.ts +++ b/packages/backend/src/core/AnnouncementService.ts @@ -67,7 +67,7 @@ export class AnnouncementService { @bindThis public async create(values: Partial, moderator?: MiUser): Promise<{ raw: MiAnnouncement; packed: Packed<'Announcement'> }> { - const announcement = await this.announcementsRepository.insert({ + const announcement = await this.announcementsRepository.insertOne({ id: this.idService.gen(), updatedAt: null, title: values.title, @@ -79,7 +79,7 @@ export class AnnouncementService { silence: values.silence, needConfirmationToRead: values.needConfirmationToRead, userId: values.userId, - }).then(x => this.announcementsRepository.findOneByOrFail(x.identifiers[0])); + }); const packed = await this.announcementEntityService.pack(announcement); diff --git a/packages/backend/src/core/AvatarDecorationService.ts b/packages/backend/src/core/AvatarDecorationService.ts index 21e31d79a429..8b54bbe01241 100644 --- a/packages/backend/src/core/AvatarDecorationService.ts +++ b/packages/backend/src/core/AvatarDecorationService.ts @@ -55,10 +55,10 @@ export class AvatarDecorationService implements OnApplicationShutdown { @bindThis public async create(options: Partial, moderator?: MiUser): Promise { - const created = await this.avatarDecorationsRepository.insert({ + const created = await this.avatarDecorationsRepository.insertOne({ id: this.idService.gen(), ...options, - }).then(x => this.avatarDecorationsRepository.findOneByOrFail(x.identifiers[0])); + }); this.globalEventService.publishInternalEvent('avatarDecorationCreated', created); diff --git a/packages/backend/src/core/ClipService.ts b/packages/backend/src/core/ClipService.ts index bb8be26ce6c5..9fd1ebad8724 100644 --- a/packages/backend/src/core/ClipService.ts +++ b/packages/backend/src/core/ClipService.ts @@ -45,13 +45,13 @@ export class ClipService { throw new ClipService.TooManyClipsError(); } - const clip = await this.clipsRepository.insert({ + const clip = await this.clipsRepository.insertOne({ id: this.idService.gen(), userId: me.id, name: name, isPublic: isPublic, description: description, - }).then(x => this.clipsRepository.findOneByOrFail(x.identifiers[0])); + }); return clip; } diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index b1feca7fb4d3..7e11b9cdca15 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -68,7 +68,7 @@ export class CustomEmojiService implements OnApplicationShutdown { localOnly: boolean; roleIdsThatCanBeUsedThisEmojiAsReaction: MiRole['id'][]; }, moderator?: MiUser): Promise { - const emoji = await this.emojisRepository.insert({ + const emoji = await this.emojisRepository.insertOne({ id: this.idService.gen(), updatedAt: new Date(), name: data.name, @@ -82,7 +82,7 @@ export class CustomEmojiService implements OnApplicationShutdown { isSensitive: data.isSensitive, localOnly: data.localOnly, roleIdsThatCanBeUsedThisEmojiAsReaction: data.roleIdsThatCanBeUsedThisEmojiAsReaction, - }).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0])); + }); if (data.host == null) { this.localEmojisCache.refresh(); diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 26cf532c7016..37c5d1adf7b7 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -220,7 +220,7 @@ export class DriveService { file.size = size; file.storedInternal = false; - return await this.driveFilesRepository.insert(file).then(x => this.driveFilesRepository.findOneByOrFail(x.identifiers[0])); + return await this.driveFilesRepository.insertOne(file); } else { // use internal storage const accessKey = randomUUID(); const thumbnailAccessKey = 'thumbnail-' + randomUUID(); @@ -254,7 +254,7 @@ export class DriveService { file.md5 = hash; file.size = size; - return await this.driveFilesRepository.insert(file).then(x => this.driveFilesRepository.findOneByOrFail(x.identifiers[0])); + return await this.driveFilesRepository.insertOne(file); } } @@ -615,7 +615,7 @@ export class DriveService { file.type = info.type.mime; file.storedInternal = false; - file = await this.driveFilesRepository.insert(file).then(x => this.driveFilesRepository.findOneByOrFail(x.identifiers[0])); + file = await this.driveFilesRepository.insertOne(file); } catch (err) { // duplicate key error (when already registered) if (isDuplicateKeyValueError(err)) { diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts index 66db2067d9f8..6799f2c5bbdc 100644 --- a/packages/backend/src/core/FederatedInstanceService.ts +++ b/packages/backend/src/core/FederatedInstanceService.ts @@ -55,11 +55,11 @@ export class FederatedInstanceService implements OnApplicationShutdown { const index = await this.instancesRepository.findOneBy({ host }); if (index == null) { - const i = await this.instancesRepository.insert({ + const i = await this.instancesRepository.insertOne({ id: this.idService.gen(), host, firstRetrievedAt: new Date(), - }).then(x => this.instancesRepository.findOneByOrFail(x.identifiers[0])); + }); this.federatedInstanceCache.set(host, i); return i; diff --git a/packages/backend/src/core/RelayService.ts b/packages/backend/src/core/RelayService.ts index e9dc9b57afef..8dd3d64f5b29 100644 --- a/packages/backend/src/core/RelayService.ts +++ b/packages/backend/src/core/RelayService.ts @@ -53,11 +53,11 @@ export class RelayService { @bindThis public async addRelay(inbox: string): Promise { - const relay = await this.relaysRepository.insert({ + const relay = await this.relaysRepository.insertOne({ id: this.idService.gen(), inbox, status: 'requesting', - }).then(x => this.relaysRepository.findOneByOrFail(x.identifiers[0])); + }); const relayActor = await this.getRelayActor(); const follow = await this.apRendererService.renderFollowRelay(relay, relayActor); diff --git a/packages/backend/src/core/ReversiService.ts b/packages/backend/src/core/ReversiService.ts index 439bc0884585..7f939b99c7a6 100644 --- a/packages/backend/src/core/ReversiService.ts +++ b/packages/backend/src/core/ReversiService.ts @@ -281,7 +281,7 @@ export class ReversiService implements OnApplicationShutdown, OnModuleInit { @bindThis private async matched(parentId: MiUser['id'], childId: MiUser['id'], options: { noIrregularRules: boolean; }): Promise { - const game = await this.reversiGamesRepository.insert({ + const game = await this.reversiGamesRepository.insertOne({ id: this.idService.gen(), user1Id: parentId, user2Id: childId, @@ -294,10 +294,7 @@ export class ReversiService implements OnApplicationShutdown, OnModuleInit { bw: 'random', isLlotheo: false, noIrregularRules: options.noIrregularRules, - }).then(x => this.reversiGamesRepository.findOneOrFail({ - where: { id: x.identifiers[0].id }, - relations: ['user1', 'user2'], - })); + }, { relations: ['user1', 'user2'] }); this.cacheGame(game); const packed = await this.reversiGameEntityService.packDetail(game); diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 70c537f9abdc..d6eea702970b 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -471,12 +471,12 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { } } - const created = await this.roleAssignmentsRepository.insert({ + const created = await this.roleAssignmentsRepository.insertOne({ id: this.idService.gen(now), expiresAt: expiresAt, roleId: roleId, userId: userId, - }).then(x => this.roleAssignmentsRepository.findOneByOrFail(x.identifiers[0])); + }); this.rolesRepository.update(roleId, { lastUsedAt: new Date(), @@ -558,7 +558,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { @bindThis public async create(values: Partial, moderator?: MiUser): Promise { const date = new Date(); - const created = await this.rolesRepository.insert({ + const created = await this.rolesRepository.insertOne({ id: this.idService.gen(date.getTime()), updatedAt: date, lastUsedAt: date, @@ -576,7 +576,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { canEditMembersByModerator: values.canEditMembersByModerator, displayOrder: values.displayOrder, policies: values.policies, - }).then(x => this.rolesRepository.findOneByOrFail(x.identifiers[0])); + }); this.globalEventService.publishInternalEvent('roleCreated', created); diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts index deeecdeb1f12..406ea040316a 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -517,7 +517,7 @@ export class UserFollowingService implements OnModuleInit { followerId: follower.id, }); - const followRequest = await this.followRequestsRepository.insert({ + const followRequest = await this.followRequestsRepository.insertOne({ id: this.idService.gen(), followerId: follower.id, followeeId: followee.id, @@ -531,7 +531,7 @@ export class UserFollowingService implements OnModuleInit { followeeHost: followee.host, followeeInbox: this.userEntityService.isRemoteUser(followee) ? followee.inbox : undefined, followeeSharedInbox: this.userEntityService.isRemoteUser(followee) ? followee.sharedInbox : undefined, - }).then(x => this.followRequestsRepository.findOneByOrFail(x.identifiers[0])); + }); // Publish receiveRequest event if (this.userEntityService.isLocalUser(followee)) { diff --git a/packages/backend/src/core/activitypub/models/ApNoteService.ts b/packages/backend/src/core/activitypub/models/ApNoteService.ts index e6dff067f31f..c6e6b3a1e8db 100644 --- a/packages/backend/src/core/activitypub/models/ApNoteService.ts +++ b/packages/backend/src/core/activitypub/models/ApNoteService.ts @@ -407,7 +407,7 @@ export class ApNoteService { this.logger.info(`register emoji host=${host}, name=${name}`); - return await this.emojisRepository.insert({ + return await this.emojisRepository.insertOne({ id: this.idService.gen(), host, name, @@ -416,7 +416,7 @@ export class ApNoteService { publicUrl: tag.icon.url, updatedAt: new Date(), aliases: [], - }).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0])); + }); })); } } diff --git a/packages/backend/src/core/chart/core.ts b/packages/backend/src/core/chart/core.ts index f10e30ef1048..af5485a46ee9 100644 --- a/packages/backend/src/core/chart/core.ts +++ b/packages/backend/src/core/chart/core.ts @@ -14,7 +14,8 @@ import { EntitySchema, LessThan, Between } from 'typeorm'; import { dateUTC, isTimeSame, isTimeBefore, subtractTime, addTime } from '@/misc/prelude/time.js'; import type Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; -import type { Repository, DataSource } from 'typeorm'; +import { MiRepository, miRepository } from '@/models/_.js'; +import type { DataSource, Repository } from 'typeorm'; const COLUMN_PREFIX = '___' as const; const UNIQUE_TEMP_COLUMN_PREFIX = 'unique_temp___' as const; @@ -145,10 +146,10 @@ export default abstract class Chart { group: string | null; }[] = []; // ↓にしたいけどfindOneとかで型エラーになる - //private repositoryForHour: Repository>; - //private repositoryForDay: Repository>; - private repositoryForHour: Repository<{ id: number; group?: string | null; date: number; }>; - private repositoryForDay: Repository<{ id: number; group?: string | null; date: number; }>; + //private repositoryForHour: Repository> & MiRepository>; + //private repositoryForDay: Repository> & MiRepository>; + private repositoryForHour: Repository<{ id: number; group?: string | null; date: number; }> & MiRepository<{ id: number; group?: string | null; date: number; }>; + private repositoryForDay: Repository<{ id: number; group?: string | null; date: number; }> & MiRepository<{ id: number; group?: string | null; date: number; }>; /** * 1日に一回程度実行されれば良いような計算処理を入れる(主にCASCADE削除などアプリケーション側で感知できない変動によるズレの修正用) @@ -211,6 +212,10 @@ export default abstract class Chart { } { const createEntity = (span: 'hour' | 'day'): EntitySchema => new EntitySchema({ name: + span === 'hour' ? `ChartX${name}` : + span === 'day' ? `ChartDayX${name}` : + new Error('not happen') as never, + tableName: span === 'hour' ? `__chart__${camelToSnake(name)}` : span === 'day' ? `__chart_day__${camelToSnake(name)}` : new Error('not happen') as never, @@ -271,8 +276,8 @@ export default abstract class Chart { this.logger = logger; const { hour, day } = Chart.schemaToEntity(name, schema, grouped); - this.repositoryForHour = db.getRepository<{ id: number; group?: string | null; date: number; }>(hour); - this.repositoryForDay = db.getRepository<{ id: number; group?: string | null; date: number; }>(day); + this.repositoryForHour = db.getRepository<{ id: number; group?: string | null; date: number; }>(hour).extend(miRepository as MiRepository<{ id: number; group?: string | null; date: number; }>); + this.repositoryForDay = db.getRepository<{ id: number; group?: string | null; date: number; }>(day).extend(miRepository as MiRepository<{ id: number; group?: string | null; date: number; }>); } @bindThis @@ -387,11 +392,11 @@ export default abstract class Chart { } // 新規ログ挿入 - log = await repository.insert({ + log = await repository.insertOne({ date: date, ...(group ? { group: group } : {}), ...columns, - }).then(x => repository.findOneByOrFail(x.identifiers[0])) as RawRecord; + }) as RawRecord; this.logger.info(`${this.name + (group ? `:${group}` : '')}(${span}): New commit created`); diff --git a/packages/backend/src/models/RepositoryModule.ts b/packages/backend/src/models/RepositoryModule.ts index bd447570ddf0..d3062d6b36f8 100644 --- a/packages/backend/src/models/RepositoryModule.ts +++ b/packages/backend/src/models/RepositoryModule.ts @@ -5,409 +5,409 @@ import { Module } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; -import { MiAbuseUserReport, MiAccessToken, MiAd, MiAnnouncement, MiAnnouncementRead, MiAntenna, MiApp, MiAuthSession, MiAvatarDecoration, MiBlocking, MiChannel, MiChannelFavorite, MiChannelFollowing, MiClip, MiClipFavorite, MiClipNote, MiDriveFile, MiDriveFolder, MiEmoji, MiFlash, MiFlashLike, MiFollowRequest, MiFollowing, MiGalleryLike, MiGalleryPost, MiHashtag, MiInstance, MiMeta, MiModerationLog, MiMuting, MiNote, MiNoteFavorite, MiNoteReaction, MiNoteThreadMuting, MiNoteUnread, MiPage, MiPageLike, MiPasswordResetRequest, MiPoll, MiPollVote, MiPromoNote, MiPromoRead, MiRegistrationTicket, MiRegistryItem, MiRelay, MiRenoteMuting, MiRetentionAggregation, MiRole, MiRoleAssignment, MiSignin, MiSwSubscription, MiUsedUsername, MiUser, MiUserIp, MiUserKeypair, MiUserList, MiUserListFavorite, MiUserListMembership, MiUserMemo, MiUserNotePining, MiUserPending, MiUserProfile, MiUserPublickey, MiUserSecurityKey, MiWebhook, MiBubbleGameRecord, MiReversiGame } from './_.js'; +import { MiRepository, MiAbuseUserReport, MiAccessToken, MiAd, MiAnnouncement, MiAnnouncementRead, MiAntenna, MiApp, MiAuthSession, MiAvatarDecoration, MiBlocking, MiChannel, MiChannelFavorite, MiChannelFollowing, MiClip, MiClipFavorite, MiClipNote, MiDriveFile, MiDriveFolder, MiEmoji, MiFlash, MiFlashLike, MiFollowRequest, MiFollowing, MiGalleryLike, MiGalleryPost, MiHashtag, MiInstance, MiMeta, MiModerationLog, MiMuting, MiNote, MiNoteFavorite, MiNoteReaction, MiNoteThreadMuting, MiNoteUnread, MiPage, MiPageLike, MiPasswordResetRequest, MiPoll, MiPollVote, MiPromoNote, MiPromoRead, MiRegistrationTicket, MiRegistryItem, MiRelay, MiRenoteMuting, MiRetentionAggregation, MiRole, MiRoleAssignment, MiSignin, MiSwSubscription, MiUsedUsername, MiUser, MiUserIp, MiUserKeypair, MiUserList, MiUserListFavorite, MiUserListMembership, MiUserMemo, MiUserNotePining, MiUserPending, MiUserProfile, MiUserPublickey, MiUserSecurityKey, MiWebhook, MiBubbleGameRecord, MiReversiGame, miRepository } from './_.js'; import type { DataSource } from 'typeorm'; import type { Provider } from '@nestjs/common'; const $usersRepository: Provider = { provide: DI.usersRepository, - useFactory: (db: DataSource) => db.getRepository(MiUser), + useFactory: (db: DataSource) => db.getRepository(MiUser).extend(miRepository as MiRepository), inject: [DI.db], }; const $notesRepository: Provider = { provide: DI.notesRepository, - useFactory: (db: DataSource) => db.getRepository(MiNote), + useFactory: (db: DataSource) => db.getRepository(MiNote).extend(miRepository as MiRepository), inject: [DI.db], }; const $announcementsRepository: Provider = { provide: DI.announcementsRepository, - useFactory: (db: DataSource) => db.getRepository(MiAnnouncement), + useFactory: (db: DataSource) => db.getRepository(MiAnnouncement).extend(miRepository as MiRepository), inject: [DI.db], }; const $announcementReadsRepository: Provider = { provide: DI.announcementReadsRepository, - useFactory: (db: DataSource) => db.getRepository(MiAnnouncementRead), + useFactory: (db: DataSource) => db.getRepository(MiAnnouncementRead).extend(miRepository as MiRepository), inject: [DI.db], }; const $appsRepository: Provider = { provide: DI.appsRepository, - useFactory: (db: DataSource) => db.getRepository(MiApp), + useFactory: (db: DataSource) => db.getRepository(MiApp).extend(miRepository as MiRepository), inject: [DI.db], }; const $avatarDecorationsRepository: Provider = { provide: DI.avatarDecorationsRepository, - useFactory: (db: DataSource) => db.getRepository(MiAvatarDecoration), + useFactory: (db: DataSource) => db.getRepository(MiAvatarDecoration).extend(miRepository as MiRepository), inject: [DI.db], }; const $noteFavoritesRepository: Provider = { provide: DI.noteFavoritesRepository, - useFactory: (db: DataSource) => db.getRepository(MiNoteFavorite), + useFactory: (db: DataSource) => db.getRepository(MiNoteFavorite).extend(miRepository as MiRepository), inject: [DI.db], }; const $noteThreadMutingsRepository: Provider = { provide: DI.noteThreadMutingsRepository, - useFactory: (db: DataSource) => db.getRepository(MiNoteThreadMuting), + useFactory: (db: DataSource) => db.getRepository(MiNoteThreadMuting).extend(miRepository as MiRepository), inject: [DI.db], }; const $noteReactionsRepository: Provider = { provide: DI.noteReactionsRepository, - useFactory: (db: DataSource) => db.getRepository(MiNoteReaction), + useFactory: (db: DataSource) => db.getRepository(MiNoteReaction).extend(miRepository as MiRepository), inject: [DI.db], }; const $noteUnreadsRepository: Provider = { provide: DI.noteUnreadsRepository, - useFactory: (db: DataSource) => db.getRepository(MiNoteUnread), + useFactory: (db: DataSource) => db.getRepository(MiNoteUnread).extend(miRepository as MiRepository), inject: [DI.db], }; const $pollsRepository: Provider = { provide: DI.pollsRepository, - useFactory: (db: DataSource) => db.getRepository(MiPoll), + useFactory: (db: DataSource) => db.getRepository(MiPoll).extend(miRepository as MiRepository), inject: [DI.db], }; const $pollVotesRepository: Provider = { provide: DI.pollVotesRepository, - useFactory: (db: DataSource) => db.getRepository(MiPollVote), + useFactory: (db: DataSource) => db.getRepository(MiPollVote).extend(miRepository as MiRepository), inject: [DI.db], }; const $userProfilesRepository: Provider = { provide: DI.userProfilesRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserProfile), + useFactory: (db: DataSource) => db.getRepository(MiUserProfile).extend(miRepository as MiRepository), inject: [DI.db], }; const $userKeypairsRepository: Provider = { provide: DI.userKeypairsRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserKeypair), + useFactory: (db: DataSource) => db.getRepository(MiUserKeypair).extend(miRepository as MiRepository), inject: [DI.db], }; const $userPendingsRepository: Provider = { provide: DI.userPendingsRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserPending), + useFactory: (db: DataSource) => db.getRepository(MiUserPending).extend(miRepository as MiRepository), inject: [DI.db], }; const $userSecurityKeysRepository: Provider = { provide: DI.userSecurityKeysRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserSecurityKey), + useFactory: (db: DataSource) => db.getRepository(MiUserSecurityKey).extend(miRepository as MiRepository), inject: [DI.db], }; const $userPublickeysRepository: Provider = { provide: DI.userPublickeysRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserPublickey), + useFactory: (db: DataSource) => db.getRepository(MiUserPublickey).extend(miRepository as MiRepository), inject: [DI.db], }; const $userListsRepository: Provider = { provide: DI.userListsRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserList), + useFactory: (db: DataSource) => db.getRepository(MiUserList).extend(miRepository as MiRepository), inject: [DI.db], }; const $userListFavoritesRepository: Provider = { provide: DI.userListFavoritesRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserListFavorite), + useFactory: (db: DataSource) => db.getRepository(MiUserListFavorite).extend(miRepository as MiRepository), inject: [DI.db], }; const $userListMembershipsRepository: Provider = { provide: DI.userListMembershipsRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserListMembership), + useFactory: (db: DataSource) => db.getRepository(MiUserListMembership).extend(miRepository as MiRepository), inject: [DI.db], }; const $userNotePiningsRepository: Provider = { provide: DI.userNotePiningsRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserNotePining), + useFactory: (db: DataSource) => db.getRepository(MiUserNotePining).extend(miRepository as MiRepository), inject: [DI.db], }; const $userIpsRepository: Provider = { provide: DI.userIpsRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserIp), + useFactory: (db: DataSource) => db.getRepository(MiUserIp).extend(miRepository as MiRepository), inject: [DI.db], }; const $usedUsernamesRepository: Provider = { provide: DI.usedUsernamesRepository, - useFactory: (db: DataSource) => db.getRepository(MiUsedUsername), + useFactory: (db: DataSource) => db.getRepository(MiUsedUsername).extend(miRepository as MiRepository), inject: [DI.db], }; const $followingsRepository: Provider = { provide: DI.followingsRepository, - useFactory: (db: DataSource) => db.getRepository(MiFollowing), + useFactory: (db: DataSource) => db.getRepository(MiFollowing).extend(miRepository as MiRepository), inject: [DI.db], }; const $followRequestsRepository: Provider = { provide: DI.followRequestsRepository, - useFactory: (db: DataSource) => db.getRepository(MiFollowRequest), + useFactory: (db: DataSource) => db.getRepository(MiFollowRequest).extend(miRepository as MiRepository), inject: [DI.db], }; const $instancesRepository: Provider = { provide: DI.instancesRepository, - useFactory: (db: DataSource) => db.getRepository(MiInstance), + useFactory: (db: DataSource) => db.getRepository(MiInstance).extend(miRepository as MiRepository), inject: [DI.db], }; const $emojisRepository: Provider = { provide: DI.emojisRepository, - useFactory: (db: DataSource) => db.getRepository(MiEmoji), + useFactory: (db: DataSource) => db.getRepository(MiEmoji).extend(miRepository as MiRepository), inject: [DI.db], }; const $driveFilesRepository: Provider = { provide: DI.driveFilesRepository, - useFactory: (db: DataSource) => db.getRepository(MiDriveFile), + useFactory: (db: DataSource) => db.getRepository(MiDriveFile).extend(miRepository as MiRepository), inject: [DI.db], }; const $driveFoldersRepository: Provider = { provide: DI.driveFoldersRepository, - useFactory: (db: DataSource) => db.getRepository(MiDriveFolder), + useFactory: (db: DataSource) => db.getRepository(MiDriveFolder).extend(miRepository as MiRepository), inject: [DI.db], }; const $metasRepository: Provider = { provide: DI.metasRepository, - useFactory: (db: DataSource) => db.getRepository(MiMeta), + useFactory: (db: DataSource) => db.getRepository(MiMeta).extend(miRepository as MiRepository), inject: [DI.db], }; const $mutingsRepository: Provider = { provide: DI.mutingsRepository, - useFactory: (db: DataSource) => db.getRepository(MiMuting), + useFactory: (db: DataSource) => db.getRepository(MiMuting).extend(miRepository as MiRepository), inject: [DI.db], }; const $renoteMutingsRepository: Provider = { provide: DI.renoteMutingsRepository, - useFactory: (db: DataSource) => db.getRepository(MiRenoteMuting), + useFactory: (db: DataSource) => db.getRepository(MiRenoteMuting).extend(miRepository as MiRepository), inject: [DI.db], }; const $blockingsRepository: Provider = { provide: DI.blockingsRepository, - useFactory: (db: DataSource) => db.getRepository(MiBlocking), + useFactory: (db: DataSource) => db.getRepository(MiBlocking).extend(miRepository as MiRepository), inject: [DI.db], }; const $swSubscriptionsRepository: Provider = { provide: DI.swSubscriptionsRepository, - useFactory: (db: DataSource) => db.getRepository(MiSwSubscription), + useFactory: (db: DataSource) => db.getRepository(MiSwSubscription).extend(miRepository as MiRepository), inject: [DI.db], }; const $hashtagsRepository: Provider = { provide: DI.hashtagsRepository, - useFactory: (db: DataSource) => db.getRepository(MiHashtag), + useFactory: (db: DataSource) => db.getRepository(MiHashtag).extend(miRepository as MiRepository), inject: [DI.db], }; const $abuseUserReportsRepository: Provider = { provide: DI.abuseUserReportsRepository, - useFactory: (db: DataSource) => db.getRepository(MiAbuseUserReport), + useFactory: (db: DataSource) => db.getRepository(MiAbuseUserReport).extend(miRepository as MiRepository), inject: [DI.db], }; const $registrationTicketsRepository: Provider = { provide: DI.registrationTicketsRepository, - useFactory: (db: DataSource) => db.getRepository(MiRegistrationTicket), + useFactory: (db: DataSource) => db.getRepository(MiRegistrationTicket).extend(miRepository as MiRepository), inject: [DI.db], }; const $authSessionsRepository: Provider = { provide: DI.authSessionsRepository, - useFactory: (db: DataSource) => db.getRepository(MiAuthSession), + useFactory: (db: DataSource) => db.getRepository(MiAuthSession).extend(miRepository as MiRepository), inject: [DI.db], }; const $accessTokensRepository: Provider = { provide: DI.accessTokensRepository, - useFactory: (db: DataSource) => db.getRepository(MiAccessToken), + useFactory: (db: DataSource) => db.getRepository(MiAccessToken).extend(miRepository as MiRepository), inject: [DI.db], }; const $signinsRepository: Provider = { provide: DI.signinsRepository, - useFactory: (db: DataSource) => db.getRepository(MiSignin), + useFactory: (db: DataSource) => db.getRepository(MiSignin).extend(miRepository as MiRepository), inject: [DI.db], }; const $pagesRepository: Provider = { provide: DI.pagesRepository, - useFactory: (db: DataSource) => db.getRepository(MiPage), + useFactory: (db: DataSource) => db.getRepository(MiPage).extend(miRepository as MiRepository), inject: [DI.db], }; const $pageLikesRepository: Provider = { provide: DI.pageLikesRepository, - useFactory: (db: DataSource) => db.getRepository(MiPageLike), + useFactory: (db: DataSource) => db.getRepository(MiPageLike).extend(miRepository as MiRepository), inject: [DI.db], }; const $galleryPostsRepository: Provider = { provide: DI.galleryPostsRepository, - useFactory: (db: DataSource) => db.getRepository(MiGalleryPost), + useFactory: (db: DataSource) => db.getRepository(MiGalleryPost).extend(miRepository as MiRepository), inject: [DI.db], }; const $galleryLikesRepository: Provider = { provide: DI.galleryLikesRepository, - useFactory: (db: DataSource) => db.getRepository(MiGalleryLike), + useFactory: (db: DataSource) => db.getRepository(MiGalleryLike).extend(miRepository as MiRepository), inject: [DI.db], }; const $moderationLogsRepository: Provider = { provide: DI.moderationLogsRepository, - useFactory: (db: DataSource) => db.getRepository(MiModerationLog), + useFactory: (db: DataSource) => db.getRepository(MiModerationLog).extend(miRepository as MiRepository), inject: [DI.db], }; const $clipsRepository: Provider = { provide: DI.clipsRepository, - useFactory: (db: DataSource) => db.getRepository(MiClip), + useFactory: (db: DataSource) => db.getRepository(MiClip).extend(miRepository as MiRepository), inject: [DI.db], }; const $clipNotesRepository: Provider = { provide: DI.clipNotesRepository, - useFactory: (db: DataSource) => db.getRepository(MiClipNote), + useFactory: (db: DataSource) => db.getRepository(MiClipNote).extend(miRepository as MiRepository), inject: [DI.db], }; const $clipFavoritesRepository: Provider = { provide: DI.clipFavoritesRepository, - useFactory: (db: DataSource) => db.getRepository(MiClipFavorite), + useFactory: (db: DataSource) => db.getRepository(MiClipFavorite).extend(miRepository as MiRepository), inject: [DI.db], }; const $antennasRepository: Provider = { provide: DI.antennasRepository, - useFactory: (db: DataSource) => db.getRepository(MiAntenna), + useFactory: (db: DataSource) => db.getRepository(MiAntenna).extend(miRepository as MiRepository), inject: [DI.db], }; const $promoNotesRepository: Provider = { provide: DI.promoNotesRepository, - useFactory: (db: DataSource) => db.getRepository(MiPromoNote), + useFactory: (db: DataSource) => db.getRepository(MiPromoNote).extend(miRepository as MiRepository), inject: [DI.db], }; const $promoReadsRepository: Provider = { provide: DI.promoReadsRepository, - useFactory: (db: DataSource) => db.getRepository(MiPromoRead), + useFactory: (db: DataSource) => db.getRepository(MiPromoRead).extend(miRepository as MiRepository), inject: [DI.db], }; const $relaysRepository: Provider = { provide: DI.relaysRepository, - useFactory: (db: DataSource) => db.getRepository(MiRelay), + useFactory: (db: DataSource) => db.getRepository(MiRelay).extend(miRepository as MiRepository), inject: [DI.db], }; const $channelsRepository: Provider = { provide: DI.channelsRepository, - useFactory: (db: DataSource) => db.getRepository(MiChannel), + useFactory: (db: DataSource) => db.getRepository(MiChannel).extend(miRepository as MiRepository), inject: [DI.db], }; const $channelFollowingsRepository: Provider = { provide: DI.channelFollowingsRepository, - useFactory: (db: DataSource) => db.getRepository(MiChannelFollowing), + useFactory: (db: DataSource) => db.getRepository(MiChannelFollowing).extend(miRepository as MiRepository), inject: [DI.db], }; const $channelFavoritesRepository: Provider = { provide: DI.channelFavoritesRepository, - useFactory: (db: DataSource) => db.getRepository(MiChannelFavorite), + useFactory: (db: DataSource) => db.getRepository(MiChannelFavorite).extend(miRepository as MiRepository), inject: [DI.db], }; const $registryItemsRepository: Provider = { provide: DI.registryItemsRepository, - useFactory: (db: DataSource) => db.getRepository(MiRegistryItem), + useFactory: (db: DataSource) => db.getRepository(MiRegistryItem).extend(miRepository as MiRepository), inject: [DI.db], }; const $webhooksRepository: Provider = { provide: DI.webhooksRepository, - useFactory: (db: DataSource) => db.getRepository(MiWebhook), + useFactory: (db: DataSource) => db.getRepository(MiWebhook).extend(miRepository as MiRepository), inject: [DI.db], }; const $adsRepository: Provider = { provide: DI.adsRepository, - useFactory: (db: DataSource) => db.getRepository(MiAd), + useFactory: (db: DataSource) => db.getRepository(MiAd).extend(miRepository as MiRepository), inject: [DI.db], }; const $passwordResetRequestsRepository: Provider = { provide: DI.passwordResetRequestsRepository, - useFactory: (db: DataSource) => db.getRepository(MiPasswordResetRequest), + useFactory: (db: DataSource) => db.getRepository(MiPasswordResetRequest).extend(miRepository as MiRepository), inject: [DI.db], }; const $retentionAggregationsRepository: Provider = { provide: DI.retentionAggregationsRepository, - useFactory: (db: DataSource) => db.getRepository(MiRetentionAggregation), + useFactory: (db: DataSource) => db.getRepository(MiRetentionAggregation).extend(miRepository as MiRepository), inject: [DI.db], }; const $flashsRepository: Provider = { provide: DI.flashsRepository, - useFactory: (db: DataSource) => db.getRepository(MiFlash), + useFactory: (db: DataSource) => db.getRepository(MiFlash).extend(miRepository as MiRepository), inject: [DI.db], }; const $flashLikesRepository: Provider = { provide: DI.flashLikesRepository, - useFactory: (db: DataSource) => db.getRepository(MiFlashLike), + useFactory: (db: DataSource) => db.getRepository(MiFlashLike).extend(miRepository as MiRepository), inject: [DI.db], }; const $rolesRepository: Provider = { provide: DI.rolesRepository, - useFactory: (db: DataSource) => db.getRepository(MiRole), + useFactory: (db: DataSource) => db.getRepository(MiRole).extend(miRepository as MiRepository), inject: [DI.db], }; const $roleAssignmentsRepository: Provider = { provide: DI.roleAssignmentsRepository, - useFactory: (db: DataSource) => db.getRepository(MiRoleAssignment), + useFactory: (db: DataSource) => db.getRepository(MiRoleAssignment).extend(miRepository as MiRepository), inject: [DI.db], }; const $userMemosRepository: Provider = { provide: DI.userMemosRepository, - useFactory: (db: DataSource) => db.getRepository(MiUserMemo), + useFactory: (db: DataSource) => db.getRepository(MiUserMemo).extend(miRepository as MiRepository), inject: [DI.db], }; const $bubbleGameRecordsRepository: Provider = { provide: DI.bubbleGameRecordsRepository, - useFactory: (db: DataSource) => db.getRepository(MiBubbleGameRecord), + useFactory: (db: DataSource) => db.getRepository(MiBubbleGameRecord).extend(miRepository as MiRepository), inject: [DI.db], }; const $reversiGamesRepository: Provider = { provide: DI.reversiGamesRepository, - useFactory: (db: DataSource) => db.getRepository(MiReversiGame), + useFactory: (db: DataSource) => db.getRepository(MiReversiGame).extend(miRepository as MiRepository), inject: [DI.db], }; diff --git a/packages/backend/src/models/_.ts b/packages/backend/src/models/_.ts index 43d42d80dd32..2e6a41586e45 100644 --- a/packages/backend/src/models/_.ts +++ b/packages/backend/src/models/_.ts @@ -3,6 +3,13 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { FindOneOptions, InsertQueryBuilder, ObjectLiteral, Repository, SelectQueryBuilder, TypeORMError } from 'typeorm'; +import { DriverUtils } from 'typeorm/driver/DriverUtils.js'; +import { RelationCountLoader } from 'typeorm/query-builder/relation-count/RelationCountLoader.js'; +import { RelationIdLoader } from 'typeorm/query-builder/relation-id/RelationIdLoader.js'; +import { RawSqlResultsToEntityTransformer } from 'typeorm/query-builder/transformer/RawSqlResultsToEntityTransformer.js'; +import { ObjectUtils } from 'typeorm/util/ObjectUtils.js'; +import { OrmUtils } from 'typeorm/util/OrmUtils.js'; import { MiAbuseUserReport } from '@/models/AbuseUserReport.js'; import { MiAccessToken } from '@/models/AccessToken.js'; import { MiAd } from '@/models/Ad.js'; @@ -70,8 +77,70 @@ import { MiFlashLike } from '@/models/FlashLike.js'; import { MiUserListFavorite } from '@/models/UserListFavorite.js'; import { MiBubbleGameRecord } from '@/models/BubbleGameRecord.js'; import { MiReversiGame } from '@/models/ReversiGame.js'; +import type { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity.js'; -import type { Repository } from 'typeorm'; +export interface MiRepository { + createTableColumnNames(this: Repository & MiRepository, queryBuilder: InsertQueryBuilder): string[]; + createTableColumnNamesWithPrimaryKey(this: Repository & MiRepository, queryBuilder: InsertQueryBuilder): string[]; + insertOne(this: Repository & MiRepository, entity: QueryDeepPartialEntity, findOptions?: Pick, 'relations'>): Promise; + selectAliasColumnNames(this: Repository & MiRepository, queryBuilder: InsertQueryBuilder, builder: SelectQueryBuilder): void; +} + +export const miRepository = { + createTableColumnNames(queryBuilder) { + // @ts-expect-error -- protected + const insertedColumns = queryBuilder.getInsertedColumns(); + if (insertedColumns.length) { + return insertedColumns.map(column => column.databaseName); + } + if (!queryBuilder.expressionMap.mainAlias?.hasMetadata && !queryBuilder.expressionMap.insertColumns.length) { + // @ts-expect-error -- protected + const valueSets = queryBuilder.getValueSets(); + if (valueSets.length === 1) { + return Object.keys(valueSets[0]); + } + } + return queryBuilder.expressionMap.insertColumns; + }, + createTableColumnNamesWithPrimaryKey(queryBuilder) { + const columnNames = this.createTableColumnNames(queryBuilder); + if (!columnNames.includes('id')) { + columnNames.unshift('id'); + } + return columnNames; + }, + async insertOne(entity, findOptions?) { + const queryBuilder = this.createQueryBuilder().insert().values(entity); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const mainAlias = queryBuilder.expressionMap.mainAlias!; + const name = mainAlias.name; + mainAlias.name = 't'; + const columnNames = this.createTableColumnNamesWithPrimaryKey(queryBuilder); + queryBuilder.returning(columnNames.reduce((a, c) => `${a}, ${queryBuilder.escape(c)}`, '').slice(2)); + const builder = this.createQueryBuilder().addCommonTableExpression(queryBuilder, 'cte', { columnNames }); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + builder.expressionMap.mainAlias!.tablePath = 'cte'; + this.selectAliasColumnNames(queryBuilder, builder); + if (findOptions) { + builder.setFindOptions(findOptions); + } + const raw = await builder.execute(); + mainAlias.name = name; + const relationId = await new RelationIdLoader(builder.connection, this.queryRunner, builder.expressionMap.relationIdAttributes).load(raw); + const relationCount = await new RelationCountLoader(builder.connection, this.queryRunner, builder.expressionMap.relationCountAttributes).load(raw); + const result = new RawSqlResultsToEntityTransformer(builder.expressionMap, builder.connection.driver, relationId, relationCount, this.queryRunner).transform(raw, mainAlias); + return result[0]; + }, + selectAliasColumnNames(queryBuilder, builder) { + let selectOrAddSelect = (selection: string, selectionAliasName?: string) => { + selectOrAddSelect = (selection, selectionAliasName) => builder.addSelect(selection, selectionAliasName); + return builder.select(selection, selectionAliasName); + }; + for (const columnName of this.createTableColumnNamesWithPrimaryKey(queryBuilder)) { + selectOrAddSelect(`${builder.alias}.${columnName}`, `${builder.alias}_${columnName}`); + } + }, +} satisfies MiRepository; export { MiAbuseUserReport, @@ -143,70 +212,70 @@ export { MiReversiGame, }; -export type AbuseUserReportsRepository = Repository; -export type AccessTokensRepository = Repository; -export type AdsRepository = Repository; -export type AnnouncementsRepository = Repository; -export type AnnouncementReadsRepository = Repository; -export type AntennasRepository = Repository; -export type AppsRepository = Repository; -export type AvatarDecorationsRepository = Repository; -export type AuthSessionsRepository = Repository; -export type BlockingsRepository = Repository; -export type ChannelFollowingsRepository = Repository; -export type ChannelFavoritesRepository = Repository; -export type ClipsRepository = Repository; -export type ClipNotesRepository = Repository; -export type ClipFavoritesRepository = Repository; -export type DriveFilesRepository = Repository; -export type DriveFoldersRepository = Repository; -export type EmojisRepository = Repository; -export type FollowingsRepository = Repository; -export type FollowRequestsRepository = Repository; -export type GalleryLikesRepository = Repository; -export type GalleryPostsRepository = Repository; -export type HashtagsRepository = Repository; -export type InstancesRepository = Repository; -export type MetasRepository = Repository; -export type ModerationLogsRepository = Repository; -export type MutingsRepository = Repository; -export type RenoteMutingsRepository = Repository; -export type NotesRepository = Repository; -export type NoteFavoritesRepository = Repository; -export type NoteReactionsRepository = Repository; -export type NoteThreadMutingsRepository = Repository; -export type NoteUnreadsRepository = Repository; -export type PagesRepository = Repository; -export type PageLikesRepository = Repository; -export type PasswordResetRequestsRepository = Repository; -export type PollsRepository = Repository; -export type PollVotesRepository = Repository; -export type PromoNotesRepository = Repository; -export type PromoReadsRepository = Repository; -export type RegistrationTicketsRepository = Repository; -export type RegistryItemsRepository = Repository; -export type RelaysRepository = Repository; -export type SigninsRepository = Repository; -export type SwSubscriptionsRepository = Repository; -export type UsedUsernamesRepository = Repository; -export type UsersRepository = Repository; -export type UserIpsRepository = Repository; -export type UserKeypairsRepository = Repository; -export type UserListsRepository = Repository; -export type UserListFavoritesRepository = Repository; -export type UserListMembershipsRepository = Repository; -export type UserNotePiningsRepository = Repository; -export type UserPendingsRepository = Repository; -export type UserProfilesRepository = Repository; -export type UserPublickeysRepository = Repository; -export type UserSecurityKeysRepository = Repository; -export type WebhooksRepository = Repository; -export type ChannelsRepository = Repository; -export type RetentionAggregationsRepository = Repository; -export type RolesRepository = Repository; -export type RoleAssignmentsRepository = Repository; -export type FlashsRepository = Repository; -export type FlashLikesRepository = Repository; -export type UserMemoRepository = Repository; -export type BubbleGameRecordsRepository = Repository; -export type ReversiGamesRepository = Repository; +export type AbuseUserReportsRepository = Repository & MiRepository; +export type AccessTokensRepository = Repository & MiRepository; +export type AdsRepository = Repository & MiRepository; +export type AnnouncementsRepository = Repository & MiRepository; +export type AnnouncementReadsRepository = Repository & MiRepository; +export type AntennasRepository = Repository & MiRepository; +export type AppsRepository = Repository & MiRepository; +export type AvatarDecorationsRepository = Repository & MiRepository; +export type AuthSessionsRepository = Repository & MiRepository; +export type BlockingsRepository = Repository & MiRepository; +export type ChannelFollowingsRepository = Repository & MiRepository; +export type ChannelFavoritesRepository = Repository & MiRepository; +export type ClipsRepository = Repository & MiRepository; +export type ClipNotesRepository = Repository & MiRepository; +export type ClipFavoritesRepository = Repository & MiRepository; +export type DriveFilesRepository = Repository & MiRepository; +export type DriveFoldersRepository = Repository & MiRepository; +export type EmojisRepository = Repository & MiRepository; +export type FollowingsRepository = Repository & MiRepository; +export type FollowRequestsRepository = Repository & MiRepository; +export type GalleryLikesRepository = Repository & MiRepository; +export type GalleryPostsRepository = Repository & MiRepository; +export type HashtagsRepository = Repository & MiRepository; +export type InstancesRepository = Repository & MiRepository; +export type MetasRepository = Repository & MiRepository; +export type ModerationLogsRepository = Repository & MiRepository; +export type MutingsRepository = Repository & MiRepository; +export type RenoteMutingsRepository = Repository & MiRepository; +export type NotesRepository = Repository & MiRepository; +export type NoteFavoritesRepository = Repository & MiRepository; +export type NoteReactionsRepository = Repository & MiRepository; +export type NoteThreadMutingsRepository = Repository & MiRepository; +export type NoteUnreadsRepository = Repository & MiRepository; +export type PagesRepository = Repository & MiRepository; +export type PageLikesRepository = Repository & MiRepository; +export type PasswordResetRequestsRepository = Repository & MiRepository; +export type PollsRepository = Repository & MiRepository; +export type PollVotesRepository = Repository & MiRepository; +export type PromoNotesRepository = Repository & MiRepository; +export type PromoReadsRepository = Repository & MiRepository; +export type RegistrationTicketsRepository = Repository & MiRepository; +export type RegistryItemsRepository = Repository & MiRepository; +export type RelaysRepository = Repository & MiRepository; +export type SigninsRepository = Repository & MiRepository; +export type SwSubscriptionsRepository = Repository & MiRepository; +export type UsedUsernamesRepository = Repository & MiRepository; +export type UsersRepository = Repository & MiRepository; +export type UserIpsRepository = Repository & MiRepository; +export type UserKeypairsRepository = Repository & MiRepository; +export type UserListsRepository = Repository & MiRepository; +export type UserListFavoritesRepository = Repository & MiRepository; +export type UserListMembershipsRepository = Repository & MiRepository; +export type UserNotePiningsRepository = Repository & MiRepository; +export type UserPendingsRepository = Repository & MiRepository; +export type UserProfilesRepository = Repository & MiRepository; +export type UserPublickeysRepository = Repository & MiRepository; +export type UserSecurityKeysRepository = Repository & MiRepository; +export type WebhooksRepository = Repository & MiRepository; +export type ChannelsRepository = Repository & MiRepository; +export type RetentionAggregationsRepository = Repository & MiRepository; +export type RolesRepository = Repository & MiRepository; +export type RoleAssignmentsRepository = Repository & MiRepository; +export type FlashsRepository = Repository & MiRepository; +export type FlashLikesRepository = Repository & MiRepository; +export type UserMemoRepository = Repository & MiRepository; +export type BubbleGameRecordsRepository = Repository & MiRepository; +export type ReversiGamesRepository = Repository & MiRepository; diff --git a/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts b/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts index e5b7c5ac5213..9c033b73e2b7 100644 --- a/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts @@ -76,7 +76,7 @@ export class ImportAntennasProcessorService { this.logger.warn('Validation Failed'); continue; } - const result = await this.antennasRepository.insert({ + const result = await this.antennasRepository.insertOne({ id: this.idService.gen(now.getTime()), lastUsedAt: now, userId: job.data.user.id, @@ -91,7 +91,7 @@ export class ImportAntennasProcessorService { excludeBots: antenna.excludeBots, withReplies: antenna.withReplies, withFile: antenna.withFile, - }).then(x => this.antennasRepository.findOneByOrFail(x.identifiers[0])); + }); this.logger.succ('Antenna created: ' + result.id); this.globalEventService.publishInternalEvent('antennaCreated', result); } diff --git a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts index a5992c28c846..db9255b35d5c 100644 --- a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts @@ -79,11 +79,11 @@ export class ImportUserListsProcessorService { }); if (list == null) { - list = await this.userListsRepository.insert({ + list = await this.userListsRepository.insertOne({ id: this.idService.gen(), userId: user.id, name: listName, - }).then(x => this.userListsRepository.findOneByOrFail(x.identifiers[0])); + }); } let target = this.utilityService.isSelfHost(host!) ? await this.usersRepository.findOneBy({ diff --git a/packages/backend/src/server/api/SigninService.ts b/packages/backend/src/server/api/SigninService.ts index 714e56e8c3fa..70306c31135b 100644 --- a/packages/backend/src/server/api/SigninService.ts +++ b/packages/backend/src/server/api/SigninService.ts @@ -29,13 +29,13 @@ export class SigninService { public signin(request: FastifyRequest, reply: FastifyReply, user: MiLocalUser) { setImmediate(async () => { // Append signin history - const record = await this.signinsRepository.insert({ + const record = await this.signinsRepository.insertOne({ id: this.idService.gen(), userId: user.id, ip: request.ip, headers: request.headers as any, success: true, - }).then(x => this.signinsRepository.findOneByOrFail(x.identifiers[0])); + }); // Publish signin event this.globalEventService.publishMainStream(user.id, 'signin', await this.signinEntityService.pack(record)); diff --git a/packages/backend/src/server/api/SignupApiService.ts b/packages/backend/src/server/api/SignupApiService.ts index 546de48e6bdb..632b0c62bc5d 100644 --- a/packages/backend/src/server/api/SignupApiService.ts +++ b/packages/backend/src/server/api/SignupApiService.ts @@ -183,13 +183,13 @@ export class SignupApiService { const salt = await bcrypt.genSalt(8); const hash = await bcrypt.hash(password, salt); - const pendingUser = await this.userPendingsRepository.insert({ + const pendingUser = await this.userPendingsRepository.insertOne({ id: this.idService.gen(), code, email: emailAddress!, username: username, password: hash, - }).then(x => this.userPendingsRepository.findOneByOrFail(x.identifiers[0])); + }); const link = `${this.config.url}/signup-complete/${code}`; diff --git a/packages/backend/src/server/api/endpoints/admin/ad/create.ts b/packages/backend/src/server/api/endpoints/admin/ad/create.ts index 1e7a9fb3ecf3..955154f4fb08 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/create.ts @@ -50,7 +50,7 @@ export default class extends Endpoint { // eslint- private moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { - const ad = await this.adsRepository.insert({ + const ad = await this.adsRepository.insertOne({ id: this.idService.gen(), expiresAt: new Date(ps.expiresAt), startsAt: new Date(ps.startsAt), @@ -61,7 +61,7 @@ export default class extends Endpoint { // eslint- ratio: ps.ratio, place: ps.place, memo: ps.memo, - }).then(r => this.adsRepository.findOneByOrFail({ id: r.identifiers[0].id })); + }); this.moderationLogService.log(me, 'createAd', { adId: ad.id, diff --git a/packages/backend/src/server/api/endpoints/admin/invite/create.ts b/packages/backend/src/server/api/endpoints/admin/invite/create.ts index 0f551e1ba2c4..5ecae3161a39 100644 --- a/packages/backend/src/server/api/endpoints/admin/invite/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/invite/create.ts @@ -66,11 +66,11 @@ export default class extends Endpoint { // eslint- const ticketsPromises = []; for (let i = 0; i < ps.count; i++) { - ticketsPromises.push(this.registrationTicketsRepository.insert({ + ticketsPromises.push(this.registrationTicketsRepository.insertOne({ id: this.idService.gen(), expiresAt: ps.expiresAt ? new Date(ps.expiresAt) : null, code: generateInviteCode(), - }).then(x => this.registrationTicketsRepository.findOneByOrFail(x.identifiers[0]))); + })); } const tickets = await Promise.all(ticketsPromises); diff --git a/packages/backend/src/server/api/endpoints/antennas/create.ts b/packages/backend/src/server/api/endpoints/antennas/create.ts index 6b7bacb05499..ec081985142c 100644 --- a/packages/backend/src/server/api/endpoints/antennas/create.ts +++ b/packages/backend/src/server/api/endpoints/antennas/create.ts @@ -112,7 +112,7 @@ export default class extends Endpoint { // eslint- const now = new Date(); - const antenna = await this.antennasRepository.insert({ + const antenna = await this.antennasRepository.insertOne({ id: this.idService.gen(now.getTime()), lastUsedAt: now, userId: me.id, @@ -127,7 +127,7 @@ export default class extends Endpoint { // eslint- excludeBots: ps.excludeBots, withReplies: ps.withReplies, withFile: ps.withFile, - }).then(x => this.antennasRepository.findOneByOrFail(x.identifiers[0])); + }); this.globalEventService.publishInternalEvent('antennaCreated', antenna); diff --git a/packages/backend/src/server/api/endpoints/app/create.ts b/packages/backend/src/server/api/endpoints/app/create.ts index 492705d6f921..ba847fc4f0ee 100644 --- a/packages/backend/src/server/api/endpoints/app/create.ts +++ b/packages/backend/src/server/api/endpoints/app/create.ts @@ -54,7 +54,7 @@ export default class extends Endpoint { // eslint- const permission = unique(ps.permission.map(v => v.replace(/^(.+)(\/|-)(read|write)$/, '$3:$1'))); // Create account - const app = await this.appsRepository.insert({ + const app = await this.appsRepository.insertOne({ id: this.idService.gen(), userId: me ? me.id : null, name: ps.name, @@ -62,7 +62,7 @@ export default class extends Endpoint { // eslint- permission, callbackUrl: ps.callbackUrl, secret: secret, - }).then(x => this.appsRepository.findOneByOrFail(x.identifiers[0])); + }); return await this.appEntityService.pack(app, null, { detail: true, diff --git a/packages/backend/src/server/api/endpoints/auth/session/generate.ts b/packages/backend/src/server/api/endpoints/auth/session/generate.ts index 26dd8931385e..f8ddfdb75cbd 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/generate.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/generate.ts @@ -78,11 +78,11 @@ export default class extends Endpoint { // eslint- const token = randomUUID(); // Create session token document - const doc = await this.authSessionsRepository.insert({ + const doc = await this.authSessionsRepository.insertOne({ id: this.idService.gen(), appId: app.id, token: token, - }).then(x => this.authSessionsRepository.findOneByOrFail(x.identifiers[0])); + }); return { token: doc.token, diff --git a/packages/backend/src/server/api/endpoints/channels/create.ts b/packages/backend/src/server/api/endpoints/channels/create.ts index 2866db54240c..e3a6d2d670e6 100644 --- a/packages/backend/src/server/api/endpoints/channels/create.ts +++ b/packages/backend/src/server/api/endpoints/channels/create.ts @@ -80,7 +80,7 @@ export default class extends Endpoint { // eslint- } } - const channel = await this.channelsRepository.insert({ + const channel = await this.channelsRepository.insertOne({ id: this.idService.gen(), userId: me.id, name: ps.name, @@ -89,7 +89,7 @@ export default class extends Endpoint { // eslint- isSensitive: ps.isSensitive ?? false, ...(ps.color !== undefined ? { color: ps.color } : {}), allowRenoteToExternal: ps.allowRenoteToExternal ?? true, - } as MiChannel).then(x => this.channelsRepository.findOneByOrFail(x.identifiers[0])); + } as MiChannel); return await this.channelEntityService.pack(channel, me); }); diff --git a/packages/backend/src/server/api/endpoints/drive/folders/create.ts b/packages/backend/src/server/api/endpoints/drive/folders/create.ts index c94070d9ff09..08d9d9cdc340 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders/create.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders/create.ts @@ -75,12 +75,12 @@ export default class extends Endpoint { // eslint- } // Create folder - const folder = await this.driveFoldersRepository.insert({ + const folder = await this.driveFoldersRepository.insertOne({ id: this.idService.gen(), name: ps.name, parentId: parent !== null ? parent.id : null, userId: me.id, - }).then(x => this.driveFoldersRepository.findOneByOrFail(x.identifiers[0])); + }); const folderObj = await this.driveFolderEntityService.pack(folder); diff --git a/packages/backend/src/server/api/endpoints/flash/create.ts b/packages/backend/src/server/api/endpoints/flash/create.ts index 361496e17e12..64f13a577e35 100644 --- a/packages/backend/src/server/api/endpoints/flash/create.ts +++ b/packages/backend/src/server/api/endpoints/flash/create.ts @@ -59,7 +59,7 @@ export default class extends Endpoint { // eslint- private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { - const flash = await this.flashsRepository.insert({ + const flash = await this.flashsRepository.insertOne({ id: this.idService.gen(), userId: me.id, updatedAt: new Date(), @@ -68,7 +68,7 @@ export default class extends Endpoint { // eslint- script: ps.script, permissions: ps.permissions, visibility: ps.visibility, - }).then(x => this.flashsRepository.findOneByOrFail(x.identifiers[0])); + }); return await this.flashEntityService.pack(flash); }); diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts index b07cdf1ed979..46f8998810d4 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts @@ -76,7 +76,7 @@ export default class extends Endpoint { // eslint- throw new Error(); } - const post = await this.galleryPostsRepository.insert(new MiGalleryPost({ + const post = await this.galleryPostsRepository.insertOne(new MiGalleryPost({ id: this.idService.gen(), updatedAt: new Date(), title: ps.title, @@ -84,7 +84,7 @@ export default class extends Endpoint { // eslint- userId: me.id, isSensitive: ps.isSensitive, fileIds: files.map(file => file.id), - })).then(x => this.galleryPostsRepository.findOneByOrFail(x.identifiers[0])); + })); return await this.galleryPostEntityService.pack(post, me); }); diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/create.ts b/packages/backend/src/server/api/endpoints/i/webhooks/create.ts index 535a3ea30850..c69238028804 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/create.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/create.ts @@ -89,14 +89,14 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.tooManyWebhooks); } - const webhook = await this.webhooksRepository.insert({ + const webhook = await this.webhooksRepository.insertOne({ id: this.idService.gen(), userId: me.id, name: ps.name, url: ps.url, secret: ps.secret, on: ps.on, - }).then(x => this.webhooksRepository.findOneByOrFail(x.identifiers[0])); + }); this.globalEventService.publishInternalEvent('webhookCreated', webhook); diff --git a/packages/backend/src/server/api/endpoints/invite/create.ts b/packages/backend/src/server/api/endpoints/invite/create.ts index 0ff125ad9cbe..a70b587da7e5 100644 --- a/packages/backend/src/server/api/endpoints/invite/create.ts +++ b/packages/backend/src/server/api/endpoints/invite/create.ts @@ -66,13 +66,13 @@ export default class extends Endpoint { // eslint- } } - const ticket = await this.registrationTicketsRepository.insert({ + const ticket = await this.registrationTicketsRepository.insertOne({ id: this.idService.gen(), createdBy: me, createdById: me.id, expiresAt: policies.inviteExpirationTime ? new Date(Date.now() + (policies.inviteExpirationTime * 1000 * 60)) : null, code: generateInviteCode(), - }).then(x => this.registrationTicketsRepository.findOneByOrFail(x.identifiers[0])); + }); return await this.inviteCodeEntityService.pack(ticket, me); }); diff --git a/packages/backend/src/server/api/endpoints/notes/polls/vote.ts b/packages/backend/src/server/api/endpoints/notes/polls/vote.ts index a91c506afd27..f33f49075bc0 100644 --- a/packages/backend/src/server/api/endpoints/notes/polls/vote.ts +++ b/packages/backend/src/server/api/endpoints/notes/polls/vote.ts @@ -144,12 +144,12 @@ export default class extends Endpoint { // eslint- } // Create vote - const vote = await this.pollVotesRepository.insert({ + const vote = await this.pollVotesRepository.insertOne({ id: this.idService.gen(createdAt.getTime()), noteId: note.id, userId: me.id, choice: ps.choice, - }).then(x => this.pollVotesRepository.findOneByOrFail(x.identifiers[0])); + }); // Increment votes count const index = ps.choice + 1; // In SQL, array index is 1 based diff --git a/packages/backend/src/server/api/endpoints/pages/create.ts b/packages/backend/src/server/api/endpoints/pages/create.ts index 3a02d359f80b..fa03b0b4575f 100644 --- a/packages/backend/src/server/api/endpoints/pages/create.ts +++ b/packages/backend/src/server/api/endpoints/pages/create.ts @@ -102,7 +102,7 @@ export default class extends Endpoint { // eslint- } }); - const page = await this.pagesRepository.insert(new MiPage({ + const page = await this.pagesRepository.insertOne(new MiPage({ id: this.idService.gen(), updatedAt: new Date(), title: ps.title, @@ -117,7 +117,7 @@ export default class extends Endpoint { // eslint- alignCenter: ps.alignCenter, hideTitleWhenPinned: ps.hideTitleWhenPinned, font: ps.font, - })).then(x => this.pagesRepository.findOneByOrFail(x.identifiers[0])); + })); return await this.pageEntityService.pack(page); }); diff --git a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts index e2db71c5c7f4..8504da0209d2 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts @@ -104,11 +104,11 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.tooManyUserLists); } - const userList = await this.userListsRepository.insert({ + const userList = await this.userListsRepository.insertOne({ id: this.idService.gen(), userId: me.id, name: ps.name, - } as MiUserList).then(x => this.userListsRepository.findOneByOrFail(x.identifiers[0])); + } as MiUserList); const users = (await this.userListMembershipsRepository.findBy({ userListId: ps.listId, diff --git a/packages/backend/src/server/api/endpoints/users/lists/create.ts b/packages/backend/src/server/api/endpoints/users/lists/create.ts index 952580e639fd..9378bde5cb55 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/create.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/create.ts @@ -65,11 +65,11 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.tooManyUserLists); } - const userList = await this.userListsRepository.insert({ + const userList = await this.userListsRepository.insertOne({ id: this.idService.gen(), userId: me.id, name: ps.name, - } as MiUserList).then(x => this.userListsRepository.findOneByOrFail(x.identifiers[0])); + } as MiUserList); return await this.userListEntityService.pack(userList); }); diff --git a/packages/backend/src/server/api/endpoints/users/report-abuse.ts b/packages/backend/src/server/api/endpoints/users/report-abuse.ts index 1750dd6206f1..48e14b68cca5 100644 --- a/packages/backend/src/server/api/endpoints/users/report-abuse.ts +++ b/packages/backend/src/server/api/endpoints/users/report-abuse.ts @@ -82,14 +82,14 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.cannotReportAdmin); } - const report = await this.abuseUserReportsRepository.insert({ + const report = await this.abuseUserReportsRepository.insertOne({ id: this.idService.gen(), targetUserId: user.id, targetUserHost: user.host, reporterId: me.id, reporterHost: null, comment: ps.comment, - }).then(x => this.abuseUserReportsRepository.findOneByOrFail(x.identifiers[0])); + }); // Publish event to moderators setImmediate(async () => { diff --git a/packages/backend/test/e2e/move.ts b/packages/backend/test/e2e/move.ts index 35050130dc1b..74cf61a7857a 100644 --- a/packages/backend/test/e2e/move.ts +++ b/packages/backend/test/e2e/move.ts @@ -9,7 +9,7 @@ process.env.NODE_ENV = 'test'; import * as assert from 'assert'; import { loadConfig } from '@/config.js'; -import { MiUser, UsersRepository } from '@/models/_.js'; +import { MiRepository, MiUser, UsersRepository, miRepository } from '@/models/_.js'; import { secureRndstr } from '@/misc/secure-rndstr.js'; import { jobQueue } from '@/boot/common.js'; import { api, initTestDb, signup, sleep, successfulApiCall, uploadFile } from '../utils.js'; @@ -42,7 +42,7 @@ describe('Account Move', () => { dave = await signup({ username: 'dave' }); eve = await signup({ username: 'eve' }); frank = await signup({ username: 'frank' }); - Users = connection.getRepository(MiUser); + Users = connection.getRepository(MiUser).extend(miRepository as MiRepository); }, 1000 * 60 * 2); afterAll(async () => { diff --git a/packages/backend/test/e2e/reversi-game.ts b/packages/backend/test/e2e/reversi-game.ts new file mode 100644 index 000000000000..788255beac12 --- /dev/null +++ b/packages/backend/test/e2e/reversi-game.ts @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +process.env.NODE_ENV = 'test'; + +import * as assert from 'assert'; +import { ReversiMatchResponse } from 'misskey-js/entities.js'; +import { api, signup } from '../utils.js'; +import type * as misskey from 'misskey-js'; + +describe('ReversiGame', () => { + let alice: misskey.entities.SignupResponse; + let bob: misskey.entities.SignupResponse; + + beforeAll(async () => { + alice = await signup({ username: 'alice' }); + bob = await signup({ username: 'bob' }); + }, 1000 * 60 * 2); + + test('matches when alice invites bob and bob accepts', async () => { + const response1 = await api('reversi/match', { userId: bob.id }, alice); + assert.strictEqual(response1.status, 204); + assert.strictEqual(response1.body, null); + const response2 = await api('reversi/match', { userId: alice.id }, bob); + assert.strictEqual(response2.status, 200); + assert.notStrictEqual(response2.body, null); + const body = response2.body as ReversiMatchResponse; + assert.strictEqual(body.user1.id, alice.id); + assert.strictEqual(body.user2.id, bob.id); + }); +}); From 27ac3d795e7098124a7eea0dd59f6f1ef8f32394 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: Tue, 4 Jun 2024 13:14:37 +0900 Subject: [PATCH 004/268] Update about-misskey.vue --- packages/frontend/src/pages/about-misskey.vue | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue index b55ae220d8ef..629f00689d16 100644 --- a/packages/frontend/src/pages/about-misskey.vue +++ b/packages/frontend/src/pages/about-misskey.vue @@ -102,13 +102,16 @@ SPDX-License-Identifier: AGPL-3.0-only
- Mask Network + Mask Network
- XServer + XServer
- Skeb + Skeb +
+
+ Skeb
From 43cccaaee9be42fab38eaa9ca04bb5e55b5d8db7 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: Tue, 4 Jun 2024 13:15:35 +0900 Subject: [PATCH 005/268] fix --- packages/frontend/src/pages/about-misskey.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue index 629f00689d16..cc0394f4018b 100644 --- a/packages/frontend/src/pages/about-misskey.vue +++ b/packages/frontend/src/pages/about-misskey.vue @@ -111,7 +111,7 @@ SPDX-License-Identifier: AGPL-3.0-only Skeb
- Skeb + GMO Pepabo
From d4a8c63264939c4ec36af628f7e1516d2ae60254 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 6 Jun 2024 09:32:04 +0900 Subject: [PATCH 006/268] enhance(backend): sentry integration for job queues --- .../src/queue/QueueProcessorService.ts | 417 ++++++++++-------- 1 file changed, 245 insertions(+), 172 deletions(-) diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts index ce999d9cef6b..eb1901d069fe 100644 --- a/packages/backend/src/queue/QueueProcessorService.ts +++ b/packages/backend/src/queue/QueueProcessorService.ts @@ -5,6 +5,7 @@ import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import * as Bull from 'bullmq'; +import * as Sentry from '@sentry/node'; import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; import type Logger from '@/logger.js'; @@ -135,199 +136,271 @@ export class QueueProcessorService implements OnApplicationShutdown { } //#region system - this.systemQueueWorker = new Bull.Worker(QUEUE.SYSTEM, (job) => { - switch (job.name) { - case 'tickCharts': return this.tickChartsProcessorService.process(); - case 'resyncCharts': return this.resyncChartsProcessorService.process(); - case 'cleanCharts': return this.cleanChartsProcessorService.process(); - case 'aggregateRetention': return this.aggregateRetentionProcessorService.process(); - case 'checkExpiredMutings': return this.checkExpiredMutingsProcessorService.process(); - case 'clean': return this.cleanProcessorService.process(); - default: throw new Error(`unrecognized job type ${job.name} for system`); - } - }, { - ...baseQueueOptions(this.config, QUEUE.SYSTEM), - autorun: false, - }); - - const systemLogger = this.logger.createSubLogger('system'); - - this.systemQueueWorker - .on('active', (job) => systemLogger.debug(`active id=${job.id}`)) - .on('completed', (job, result) => systemLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => systemLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) - .on('error', (err: Error) => systemLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => systemLogger.warn(`stalled id=${jobId}`)); + { + const processer = (job: Bull.Job) => { + switch (job.name) { + case 'tickCharts': return this.tickChartsProcessorService.process(); + case 'resyncCharts': return this.resyncChartsProcessorService.process(); + case 'cleanCharts': return this.cleanChartsProcessorService.process(); + case 'aggregateRetention': return this.aggregateRetentionProcessorService.process(); + case 'checkExpiredMutings': return this.checkExpiredMutingsProcessorService.process(); + case 'clean': return this.cleanProcessorService.process(); + default: throw new Error(`unrecognized job type ${job.name} for system`); + } + }; + + this.systemQueueWorker = new Bull.Worker(QUEUE.SYSTEM, (job) => { + if (this.config.sentryForBackend) { + return Sentry.startSpan({ name: 'Queue: System: ' + job.name }, () => processer(job)); + } else { + return processer(job); + } + }, { + ...baseQueueOptions(this.config, QUEUE.SYSTEM), + autorun: false, + }); + + const systemLogger = this.logger.createSubLogger('system'); + + this.systemQueueWorker + .on('active', (job) => systemLogger.debug(`active id=${job.id}`)) + .on('completed', (job, result) => systemLogger.debug(`completed(${result}) id=${job.id}`)) + .on('failed', (job, err) => systemLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) + .on('error', (err: Error) => systemLogger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => systemLogger.warn(`stalled id=${jobId}`)); + } //#endregion //#region db - this.dbQueueWorker = new Bull.Worker(QUEUE.DB, (job) => { - switch (job.name) { - case 'deleteDriveFiles': return this.deleteDriveFilesProcessorService.process(job); - case 'exportCustomEmojis': return this.exportCustomEmojisProcessorService.process(job); - case 'exportNotes': return this.exportNotesProcessorService.process(job); - case 'exportClips': return this.exportClipsProcessorService.process(job); - case 'exportFavorites': return this.exportFavoritesProcessorService.process(job); - case 'exportFollowing': return this.exportFollowingProcessorService.process(job); - case 'exportMuting': return this.exportMutingProcessorService.process(job); - case 'exportBlocking': return this.exportBlockingProcessorService.process(job); - case 'exportUserLists': return this.exportUserListsProcessorService.process(job); - case 'exportAntennas': return this.exportAntennasProcessorService.process(job); - case 'importFollowing': return this.importFollowingProcessorService.process(job); - case 'importFollowingToDb': return this.importFollowingProcessorService.processDb(job); - case 'importMuting': return this.importMutingProcessorService.process(job); - case 'importBlocking': return this.importBlockingProcessorService.process(job); - case 'importBlockingToDb': return this.importBlockingProcessorService.processDb(job); - case 'importUserLists': return this.importUserListsProcessorService.process(job); - case 'importCustomEmojis': return this.importCustomEmojisProcessorService.process(job); - case 'importAntennas': return this.importAntennasProcessorService.process(job); - case 'deleteAccount': return this.deleteAccountProcessorService.process(job); - default: throw new Error(`unrecognized job type ${job.name} for db`); - } - }, { - ...baseQueueOptions(this.config, QUEUE.DB), - autorun: false, - }); - - const dbLogger = this.logger.createSubLogger('db'); - - this.dbQueueWorker - .on('active', (job) => dbLogger.debug(`active id=${job.id}`)) - .on('completed', (job, result) => dbLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => dbLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) - .on('error', (err: Error) => dbLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => dbLogger.warn(`stalled id=${jobId}`)); + { + const processer = (job: Bull.Job) => { + switch (job.name) { + case 'deleteDriveFiles': return this.deleteDriveFilesProcessorService.process(job); + case 'exportCustomEmojis': return this.exportCustomEmojisProcessorService.process(job); + case 'exportNotes': return this.exportNotesProcessorService.process(job); + case 'exportClips': return this.exportClipsProcessorService.process(job); + case 'exportFavorites': return this.exportFavoritesProcessorService.process(job); + case 'exportFollowing': return this.exportFollowingProcessorService.process(job); + case 'exportMuting': return this.exportMutingProcessorService.process(job); + case 'exportBlocking': return this.exportBlockingProcessorService.process(job); + case 'exportUserLists': return this.exportUserListsProcessorService.process(job); + case 'exportAntennas': return this.exportAntennasProcessorService.process(job); + case 'importFollowing': return this.importFollowingProcessorService.process(job); + case 'importFollowingToDb': return this.importFollowingProcessorService.processDb(job); + case 'importMuting': return this.importMutingProcessorService.process(job); + case 'importBlocking': return this.importBlockingProcessorService.process(job); + case 'importBlockingToDb': return this.importBlockingProcessorService.processDb(job); + case 'importUserLists': return this.importUserListsProcessorService.process(job); + case 'importCustomEmojis': return this.importCustomEmojisProcessorService.process(job); + case 'importAntennas': return this.importAntennasProcessorService.process(job); + case 'deleteAccount': return this.deleteAccountProcessorService.process(job); + default: throw new Error(`unrecognized job type ${job.name} for db`); + } + }; + + this.dbQueueWorker = new Bull.Worker(QUEUE.DB, (job) => { + if (this.config.sentryForBackend) { + return Sentry.startSpan({ name: 'Queue: DB: ' + job.name }, () => processer(job)); + } else { + return processer(job); + } + }, { + ...baseQueueOptions(this.config, QUEUE.DB), + autorun: false, + }); + + const dbLogger = this.logger.createSubLogger('db'); + + this.dbQueueWorker + .on('active', (job) => dbLogger.debug(`active id=${job.id}`)) + .on('completed', (job, result) => dbLogger.debug(`completed(${result}) id=${job.id}`)) + .on('failed', (job, err) => dbLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) + .on('error', (err: Error) => dbLogger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => dbLogger.warn(`stalled id=${jobId}`)); + } //#endregion //#region deliver - this.deliverQueueWorker = new Bull.Worker(QUEUE.DELIVER, (job) => this.deliverProcessorService.process(job), { - ...baseQueueOptions(this.config, QUEUE.DELIVER), - autorun: false, - concurrency: this.config.deliverJobConcurrency ?? 128, - limiter: { - max: this.config.deliverJobPerSec ?? 128, - duration: 1000, - }, - settings: { - backoffStrategy: httpRelatedBackoff, - }, - }); - - const deliverLogger = this.logger.createSubLogger('deliver'); - - this.deliverQueueWorker - .on('active', (job) => deliverLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) - .on('completed', (job, result) => deliverLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) - .on('failed', (job, err) => deliverLogger.warn(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`)) - .on('error', (err: Error) => deliverLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => deliverLogger.warn(`stalled id=${jobId}`)); + { + this.deliverQueueWorker = new Bull.Worker(QUEUE.DELIVER, (job) => { + if (this.config.sentryForBackend) { + return Sentry.startSpan({ name: 'Queue: Deliver' }, () => this.deliverProcessorService.process(job)); + } else { + return this.deliverProcessorService.process(job); + } + }, { + ...baseQueueOptions(this.config, QUEUE.DELIVER), + autorun: false, + concurrency: this.config.deliverJobConcurrency ?? 128, + limiter: { + max: this.config.deliverJobPerSec ?? 128, + duration: 1000, + }, + settings: { + backoffStrategy: httpRelatedBackoff, + }, + }); + + const deliverLogger = this.logger.createSubLogger('deliver'); + + this.deliverQueueWorker + .on('active', (job) => deliverLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) + .on('completed', (job, result) => deliverLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) + .on('failed', (job, err) => deliverLogger.warn(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`)) + .on('error', (err: Error) => deliverLogger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => deliverLogger.warn(`stalled id=${jobId}`)); + } //#endregion //#region inbox - this.inboxQueueWorker = new Bull.Worker(QUEUE.INBOX, (job) => this.inboxProcessorService.process(job), { - ...baseQueueOptions(this.config, QUEUE.INBOX), - autorun: false, - concurrency: this.config.inboxJobConcurrency ?? 16, - limiter: { - max: this.config.inboxJobPerSec ?? 32, - duration: 1000, - }, - settings: { - backoffStrategy: httpRelatedBackoff, - }, - }); - - const inboxLogger = this.logger.createSubLogger('inbox'); - - this.inboxQueueWorker - .on('active', (job) => inboxLogger.debug(`active ${getJobInfo(job, true)}`)) - .on('completed', (job, result) => inboxLogger.debug(`completed(${result}) ${getJobInfo(job, true)}`)) - .on('failed', (job, err) => inboxLogger.warn(`failed(${err.stack}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job, e: renderError(err) })) - .on('error', (err: Error) => inboxLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => inboxLogger.warn(`stalled id=${jobId}`)); + { + this.inboxQueueWorker = new Bull.Worker(QUEUE.INBOX, (job) => { + if (this.config.sentryForBackend) { + return Sentry.startSpan({ name: 'Queue: Inbox' }, () => this.inboxProcessorService.process(job)); + } else { + return this.inboxProcessorService.process(job); + } + }, { + ...baseQueueOptions(this.config, QUEUE.INBOX), + autorun: false, + concurrency: this.config.inboxJobConcurrency ?? 16, + limiter: { + max: this.config.inboxJobPerSec ?? 32, + duration: 1000, + }, + settings: { + backoffStrategy: httpRelatedBackoff, + }, + }); + + const inboxLogger = this.logger.createSubLogger('inbox'); + + this.inboxQueueWorker + .on('active', (job) => inboxLogger.debug(`active ${getJobInfo(job, true)}`)) + .on('completed', (job, result) => inboxLogger.debug(`completed(${result}) ${getJobInfo(job, true)}`)) + .on('failed', (job, err) => inboxLogger.warn(`failed(${err.stack}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job, e: renderError(err) })) + .on('error', (err: Error) => inboxLogger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => inboxLogger.warn(`stalled id=${jobId}`)); + } //#endregion //#region webhook deliver - this.webhookDeliverQueueWorker = new Bull.Worker(QUEUE.WEBHOOK_DELIVER, (job) => this.webhookDeliverProcessorService.process(job), { - ...baseQueueOptions(this.config, QUEUE.WEBHOOK_DELIVER), - autorun: false, - concurrency: 64, - limiter: { - max: 64, - duration: 1000, - }, - settings: { - backoffStrategy: httpRelatedBackoff, - }, - }); - - const webhookLogger = this.logger.createSubLogger('webhook'); - - this.webhookDeliverQueueWorker - .on('active', (job) => webhookLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) - .on('completed', (job, result) => webhookLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) - .on('failed', (job, err) => webhookLogger.warn(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`)) - .on('error', (err: Error) => webhookLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => webhookLogger.warn(`stalled id=${jobId}`)); + { + this.webhookDeliverQueueWorker = new Bull.Worker(QUEUE.WEBHOOK_DELIVER, (job) => { + if (this.config.sentryForBackend) { + return Sentry.startSpan({ name: 'Queue: WebhookDeliver' }, () => this.webhookDeliverProcessorService.process(job)); + } else { + return this.webhookDeliverProcessorService.process(job); + } + }, { + ...baseQueueOptions(this.config, QUEUE.WEBHOOK_DELIVER), + autorun: false, + concurrency: 64, + limiter: { + max: 64, + duration: 1000, + }, + settings: { + backoffStrategy: httpRelatedBackoff, + }, + }); + + const webhookLogger = this.logger.createSubLogger('webhook'); + + this.webhookDeliverQueueWorker + .on('active', (job) => webhookLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) + .on('completed', (job, result) => webhookLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) + .on('failed', (job, err) => webhookLogger.warn(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`)) + .on('error', (err: Error) => webhookLogger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => webhookLogger.warn(`stalled id=${jobId}`)); + } //#endregion //#region relationship - this.relationshipQueueWorker = new Bull.Worker(QUEUE.RELATIONSHIP, (job) => { - switch (job.name) { - case 'follow': return this.relationshipProcessorService.processFollow(job); - case 'unfollow': return this.relationshipProcessorService.processUnfollow(job); - case 'block': return this.relationshipProcessorService.processBlock(job); - case 'unblock': return this.relationshipProcessorService.processUnblock(job); - default: throw new Error(`unrecognized job type ${job.name} for relationship`); - } - }, { - ...baseQueueOptions(this.config, QUEUE.RELATIONSHIP), - autorun: false, - concurrency: this.config.relationshipJobConcurrency ?? 16, - limiter: { - max: this.config.relationshipJobPerSec ?? 64, - duration: 1000, - }, - }); - - const relationshipLogger = this.logger.createSubLogger('relationship'); - - this.relationshipQueueWorker - .on('active', (job) => relationshipLogger.debug(`active id=${job.id}`)) - .on('completed', (job, result) => relationshipLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => relationshipLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) - .on('error', (err: Error) => relationshipLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => relationshipLogger.warn(`stalled id=${jobId}`)); + { + const processer = (job: Bull.Job) => { + switch (job.name) { + case 'follow': return this.relationshipProcessorService.processFollow(job); + case 'unfollow': return this.relationshipProcessorService.processUnfollow(job); + case 'block': return this.relationshipProcessorService.processBlock(job); + case 'unblock': return this.relationshipProcessorService.processUnblock(job); + default: throw new Error(`unrecognized job type ${job.name} for relationship`); + } + }; + + this.relationshipQueueWorker = new Bull.Worker(QUEUE.RELATIONSHIP, (job) => { + if (this.config.sentryForBackend) { + return Sentry.startSpan({ name: 'Queue: Relationship: ' + job.name }, () => processer(job)); + } else { + return processer(job); + } + }, { + ...baseQueueOptions(this.config, QUEUE.RELATIONSHIP), + autorun: false, + concurrency: this.config.relationshipJobConcurrency ?? 16, + limiter: { + max: this.config.relationshipJobPerSec ?? 64, + duration: 1000, + }, + }); + + const relationshipLogger = this.logger.createSubLogger('relationship'); + + this.relationshipQueueWorker + .on('active', (job) => relationshipLogger.debug(`active id=${job.id}`)) + .on('completed', (job, result) => relationshipLogger.debug(`completed(${result}) id=${job.id}`)) + .on('failed', (job, err) => relationshipLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) + .on('error', (err: Error) => relationshipLogger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => relationshipLogger.warn(`stalled id=${jobId}`)); + } //#endregion //#region object storage - this.objectStorageQueueWorker = new Bull.Worker(QUEUE.OBJECT_STORAGE, (job) => { - switch (job.name) { - case 'deleteFile': return this.deleteFileProcessorService.process(job); - case 'cleanRemoteFiles': return this.cleanRemoteFilesProcessorService.process(job); - default: throw new Error(`unrecognized job type ${job.name} for objectStorage`); - } - }, { - ...baseQueueOptions(this.config, QUEUE.OBJECT_STORAGE), - autorun: false, - concurrency: 16, - }); - - const objectStorageLogger = this.logger.createSubLogger('objectStorage'); - - this.objectStorageQueueWorker - .on('active', (job) => objectStorageLogger.debug(`active id=${job.id}`)) - .on('completed', (job, result) => objectStorageLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => objectStorageLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) - .on('error', (err: Error) => objectStorageLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => objectStorageLogger.warn(`stalled id=${jobId}`)); + { + const processer = (job: Bull.Job) => { + switch (job.name) { + case 'deleteFile': return this.deleteFileProcessorService.process(job); + case 'cleanRemoteFiles': return this.cleanRemoteFilesProcessorService.process(job); + default: throw new Error(`unrecognized job type ${job.name} for objectStorage`); + } + }; + + this.objectStorageQueueWorker = new Bull.Worker(QUEUE.OBJECT_STORAGE, (job) => { + if (this.config.sentryForBackend) { + return Sentry.startSpan({ name: 'Queue: ObjectStorage: ' + job.name }, () => processer(job)); + } else { + return processer(job); + } + }, { + ...baseQueueOptions(this.config, QUEUE.OBJECT_STORAGE), + autorun: false, + concurrency: 16, + }); + + const objectStorageLogger = this.logger.createSubLogger('objectStorage'); + + this.objectStorageQueueWorker + .on('active', (job) => objectStorageLogger.debug(`active id=${job.id}`)) + .on('completed', (job, result) => objectStorageLogger.debug(`completed(${result}) id=${job.id}`)) + .on('failed', (job, err) => objectStorageLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) + .on('error', (err: Error) => objectStorageLogger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => objectStorageLogger.warn(`stalled id=${jobId}`)); + } //#endregion //#region ended poll notification - this.endedPollNotificationQueueWorker = new Bull.Worker(QUEUE.ENDED_POLL_NOTIFICATION, (job) => this.endedPollNotificationProcessorService.process(job), { - ...baseQueueOptions(this.config, QUEUE.ENDED_POLL_NOTIFICATION), - autorun: false, - }); + { + this.endedPollNotificationQueueWorker = new Bull.Worker(QUEUE.ENDED_POLL_NOTIFICATION, (job) => { + if (this.config.sentryForBackend) { + return Sentry.startSpan({ name: 'Queue: EndedPollNotification' }, () => this.endedPollNotificationProcessorService.process(job)); + } else { + return this.endedPollNotificationProcessorService.process(job); + } + }, { + ...baseQueueOptions(this.config, QUEUE.ENDED_POLL_NOTIFICATION), + autorun: false, + }); + } //#endregion } From dbf9e1194bf5b84ec711c14f27c11d2bfeb37f20 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 6 Jun 2024 10:01:50 +0900 Subject: [PATCH 007/268] refactor(backend): remove unused logger option --- packages/backend/src/core/LoggerService.ts | 4 ++-- .../backend/src/core/chart/ChartLoggerService.ts | 2 +- packages/backend/src/logger.ts | 14 +++++--------- packages/backend/src/server/FileServerService.ts | 2 +- packages/backend/src/server/ServerService.ts | 2 +- 5 files changed, 10 insertions(+), 14 deletions(-) diff --git a/packages/backend/src/core/LoggerService.ts b/packages/backend/src/core/LoggerService.ts index 96d9b099927b..f102461a5065 100644 --- a/packages/backend/src/core/LoggerService.ts +++ b/packages/backend/src/core/LoggerService.ts @@ -15,7 +15,7 @@ export class LoggerService { } @bindThis - public getLogger(domain: string, color?: KEYWORD | undefined, store?: boolean) { - return new Logger(domain, color, store); + public getLogger(domain: string, color?: KEYWORD | undefined) { + return new Logger(domain, color); } } diff --git a/packages/backend/src/core/chart/ChartLoggerService.ts b/packages/backend/src/core/chart/ChartLoggerService.ts index afc728d56478..20815ea96869 100644 --- a/packages/backend/src/core/chart/ChartLoggerService.ts +++ b/packages/backend/src/core/chart/ChartLoggerService.ts @@ -14,6 +14,6 @@ export class ChartLoggerService { constructor( private loggerService: LoggerService, ) { - this.logger = this.loggerService.getLogger('chart', 'white', process.env.NODE_ENV !== 'test'); + this.logger = this.loggerService.getLogger('chart', 'white'); } } diff --git a/packages/backend/src/logger.ts b/packages/backend/src/logger.ts index d4705af60114..ff5363a425d7 100644 --- a/packages/backend/src/logger.ts +++ b/packages/backend/src/logger.ts @@ -22,31 +22,27 @@ type Level = 'error' | 'success' | 'warning' | 'debug' | 'info'; export default class Logger { private context: Context; private parentLogger: Logger | null = null; - private store: boolean; - constructor(context: string, color?: KEYWORD, store = true) { + constructor(context: string, color?: KEYWORD) { this.context = { name: context, color: color, }; - this.store = store; } @bindThis - public createSubLogger(context: string, color?: KEYWORD, store = true): Logger { - const logger = new Logger(context, color, store); + public createSubLogger(context: string, color?: KEYWORD): Logger { + const logger = new Logger(context, color); logger.parentLogger = this; return logger; } @bindThis - private log(level: Level, message: string, data?: Record | null, important = false, subContexts: Context[] = [], store = true): void { + private log(level: Level, message: string, data?: Record | null, important = false, subContexts: Context[] = []): void { if (envOption.quiet) return; - if (!this.store) store = false; - if (level === 'debug') store = false; if (this.parentLogger) { - this.parentLogger.log(level, message, data, important, [this.context].concat(subContexts), store); + this.parentLogger.log(level, message, data, important, [this.context].concat(subContexts)); return; } diff --git a/packages/backend/src/server/FileServerService.ts b/packages/backend/src/server/FileServerService.ts index 9db3aa1bfb37..77a637d89516 100644 --- a/packages/backend/src/server/FileServerService.ts +++ b/packages/backend/src/server/FileServerService.ts @@ -53,7 +53,7 @@ export class FileServerService { private internalStorageService: InternalStorageService, private loggerService: LoggerService, ) { - this.logger = this.loggerService.getLogger('server', 'gray', false); + this.logger = this.loggerService.getLogger('server', 'gray'); //this.createServer = this.createServer.bind(this); } diff --git a/packages/backend/src/server/ServerService.ts b/packages/backend/src/server/ServerService.ts index 3572f16627cc..9c849480f21f 100644 --- a/packages/backend/src/server/ServerService.ts +++ b/packages/backend/src/server/ServerService.ts @@ -68,7 +68,7 @@ export class ServerService implements OnApplicationShutdown { private loggerService: LoggerService, private oauth2ProviderService: OAuth2ProviderService, ) { - this.logger = this.loggerService.getLogger('server', 'gray', false); + this.logger = this.loggerService.getLogger('server', 'gray'); } @bindThis From 65d19279a2c19c3e6be1c4c50cc9b01c94420d6c Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 6 Jun 2024 10:11:43 +0900 Subject: [PATCH 008/268] fix --- packages/backend/src/boot/master.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts index 75e1a80cd1df..4bc5c799cfb9 100644 --- a/packages/backend/src/boot/master.ts +++ b/packages/backend/src/boot/master.ts @@ -25,7 +25,7 @@ const _dirname = dirname(_filename); const meta = JSON.parse(fs.readFileSync(`${_dirname}/../../../../built/meta.json`, 'utf-8')); const logger = new Logger('core', 'cyan'); -const bootLogger = logger.createSubLogger('boot', 'magenta', false); +const bootLogger = logger.createSubLogger('boot', 'magenta'); const themeColor = chalk.hex('#86b300'); From ab69e113f4921462b72f1f352dfefe52b37862f5 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:20:54 +0900 Subject: [PATCH 009/268] enhance(backend): improve sentry integration --- packages/backend/src/boot/worker.ts | 23 +++++++++++++++++++ .../src/queue/QueueProcessorService.ts | 4 ++-- .../backend/src/server/api/ApiCallService.ts | 14 +++++++---- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/packages/backend/src/boot/worker.ts b/packages/backend/src/boot/worker.ts index d4a7cd56e5ce..5d4a15b29f02 100644 --- a/packages/backend/src/boot/worker.ts +++ b/packages/backend/src/boot/worker.ts @@ -4,13 +4,36 @@ */ import cluster from 'node:cluster'; +import * as Sentry from '@sentry/node'; +import { nodeProfilingIntegration } from '@sentry/profiling-node'; import { envOption } from '@/env.js'; +import { loadConfig } from '@/config.js'; import { jobQueue, server } from './common.js'; /** * Init worker process */ export async function workerMain() { + const config = loadConfig(); + + if (config.sentryForBackend) { + Sentry.init({ + integrations: [ + ...(config.sentryForBackend.enableNodeProfiling ? [nodeProfilingIntegration()] : []), + ], + + // Performance Monitoring + tracesSampleRate: 1.0, // Capture 100% of the transactions + + // Set sampling rate for profiling - this is relative to tracesSampleRate + profilesSampleRate: 1.0, + + maxBreadcrumbs: 0, + + ...config.sentryForBackend.options, + }); + } + if (envOption.onlyServer) { await server(); } else if (envOption.onlyQueue) { diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts index eb1901d069fe..4f333df791e3 100644 --- a/packages/backend/src/queue/QueueProcessorService.ts +++ b/packages/backend/src/queue/QueueProcessorService.ts @@ -165,7 +165,7 @@ export class QueueProcessorService implements OnApplicationShutdown { this.systemQueueWorker .on('active', (job) => systemLogger.debug(`active id=${job.id}`)) .on('completed', (job, result) => systemLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => systemLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) + .on('failed', (job, err) => systemLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) .on('error', (err: Error) => systemLogger.error(`error ${err.stack}`, { e: renderError(err) })) .on('stalled', (jobId) => systemLogger.warn(`stalled id=${jobId}`)); } @@ -214,7 +214,7 @@ export class QueueProcessorService implements OnApplicationShutdown { this.dbQueueWorker .on('active', (job) => dbLogger.debug(`active id=${job.id}`)) .on('completed', (job, result) => dbLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => dbLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) + .on('failed', (job, err) => dbLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) .on('error', (err: Error) => dbLogger.error(`error ${err.stack}`, { e: renderError(err) })) .on('stalled', (jobId) => dbLogger.warn(`stalled id=${jobId}`)); } diff --git a/packages/backend/src/server/api/ApiCallService.ts b/packages/backend/src/server/api/ApiCallService.ts index 271ef80554a8..e21a5e90abbd 100644 --- a/packages/backend/src/server/api/ApiCallService.ts +++ b/packages/backend/src/server/api/ApiCallService.ts @@ -93,7 +93,7 @@ export class ApiCallService implements OnApplicationShutdown { } } - #onExecError(ep: IEndpoint, data: any, err: Error): void { + #onExecError(ep: IEndpoint, data: any, err: Error, userId?: MiUser['id']): void { if (err instanceof ApiError || err instanceof AuthenticationError) { throw err; } else { @@ -108,10 +108,12 @@ export class ApiCallService implements OnApplicationShutdown { id: errId, }, }); - console.error(err, errId); if (this.config.sentryForBackend) { Sentry.captureMessage(`Internal error occurred in ${ep.name}: ${err.message}`, { + user: { + id: userId, + }, extra: { ep: ep.name, ps: data, @@ -410,9 +412,13 @@ export class ApiCallService implements OnApplicationShutdown { // API invoking if (this.config.sentryForBackend) { - return await Sentry.startSpan({ name: 'API: ' + ep.name }, () => ep.exec(data, user, token, file, request.ip, request.headers).catch((err: Error) => this.#onExecError(ep, data, err))); + return await Sentry.startSpan({ + name: 'API: ' + ep.name, + }, () => ep.exec(data, user, token, file, request.ip, request.headers) + .catch((err: Error) => this.#onExecError(ep, data, err, user?.id))); } else { - return await ep.exec(data, user, token, file, request.ip, request.headers).catch((err: Error) => this.#onExecError(ep, data, err)); + return await ep.exec(data, user, token, file, request.ip, request.headers) + .catch((err: Error) => this.#onExecError(ep, data, err, user?.id)); } } From a697a7f97b401d1545a7f61694b2704b4d3ac9fc Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:38:34 +0900 Subject: [PATCH 010/268] enhance(backend): improve sentry integration --- .../src/queue/QueueProcessorService.ts | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts index 4f333df791e3..fdeb6a9518a7 100644 --- a/packages/backend/src/queue/QueueProcessorService.ts +++ b/packages/backend/src/queue/QueueProcessorService.ts @@ -165,7 +165,14 @@ export class QueueProcessorService implements OnApplicationShutdown { this.systemQueueWorker .on('active', (job) => systemLogger.debug(`active id=${job.id}`)) .on('completed', (job, result) => systemLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => systemLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) + .on('failed', (job, err) => { + systemLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + if (config.sentryForBackend) { + Sentry.captureMessage(`Queue: System: ${job?.name ?? '?'}`, { + extra: { job, err }, + }); + } + }) .on('error', (err: Error) => systemLogger.error(`error ${err.stack}`, { e: renderError(err) })) .on('stalled', (jobId) => systemLogger.warn(`stalled id=${jobId}`)); } @@ -214,7 +221,14 @@ export class QueueProcessorService implements OnApplicationShutdown { this.dbQueueWorker .on('active', (job) => dbLogger.debug(`active id=${job.id}`)) .on('completed', (job, result) => dbLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => dbLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) + .on('failed', (job, err) => { + dbLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + if (config.sentryForBackend) { + Sentry.captureMessage(`Queue: DB: ${job?.name ?? '?'}`, { + extra: { job, err }, + }); + } + }) .on('error', (err: Error) => dbLogger.error(`error ${err.stack}`, { e: renderError(err) })) .on('stalled', (jobId) => dbLogger.warn(`stalled id=${jobId}`)); } @@ -246,7 +260,14 @@ export class QueueProcessorService implements OnApplicationShutdown { this.deliverQueueWorker .on('active', (job) => deliverLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) .on('completed', (job, result) => deliverLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) - .on('failed', (job, err) => deliverLogger.warn(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`)) + .on('failed', (job, err) => { + deliverLogger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); + if (config.sentryForBackend) { + Sentry.captureMessage('Queue: Deliver', { + extra: { job, err }, + }); + } + }) .on('error', (err: Error) => deliverLogger.error(`error ${err.stack}`, { e: renderError(err) })) .on('stalled', (jobId) => deliverLogger.warn(`stalled id=${jobId}`)); } @@ -278,7 +299,14 @@ export class QueueProcessorService implements OnApplicationShutdown { this.inboxQueueWorker .on('active', (job) => inboxLogger.debug(`active ${getJobInfo(job, true)}`)) .on('completed', (job, result) => inboxLogger.debug(`completed(${result}) ${getJobInfo(job, true)}`)) - .on('failed', (job, err) => inboxLogger.warn(`failed(${err.stack}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job, e: renderError(err) })) + .on('failed', (job, err) => { + inboxLogger.error(`failed(${err.stack}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job, e: renderError(err) }); + if (config.sentryForBackend) { + Sentry.captureMessage('Queue: Inbox', { + extra: { job, err }, + }); + } + }) .on('error', (err: Error) => inboxLogger.error(`error ${err.stack}`, { e: renderError(err) })) .on('stalled', (jobId) => inboxLogger.warn(`stalled id=${jobId}`)); } @@ -310,7 +338,14 @@ export class QueueProcessorService implements OnApplicationShutdown { this.webhookDeliverQueueWorker .on('active', (job) => webhookLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) .on('completed', (job, result) => webhookLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) - .on('failed', (job, err) => webhookLogger.warn(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`)) + .on('failed', (job, err) => { + webhookLogger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); + if (config.sentryForBackend) { + Sentry.captureMessage('Queue: WebhookDeliver', { + extra: { job, err }, + }); + } + }) .on('error', (err: Error) => webhookLogger.error(`error ${err.stack}`, { e: renderError(err) })) .on('stalled', (jobId) => webhookLogger.warn(`stalled id=${jobId}`)); } @@ -349,7 +384,14 @@ export class QueueProcessorService implements OnApplicationShutdown { this.relationshipQueueWorker .on('active', (job) => relationshipLogger.debug(`active id=${job.id}`)) .on('completed', (job, result) => relationshipLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => relationshipLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) + .on('failed', (job, err) => { + relationshipLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + if (config.sentryForBackend) { + Sentry.captureMessage(`Queue: Relationship: ${job?.name ?? '?'}`, { + extra: { job, err }, + }); + } + }) .on('error', (err: Error) => relationshipLogger.error(`error ${err.stack}`, { e: renderError(err) })) .on('stalled', (jobId) => relationshipLogger.warn(`stalled id=${jobId}`)); } @@ -382,7 +424,14 @@ export class QueueProcessorService implements OnApplicationShutdown { this.objectStorageQueueWorker .on('active', (job) => objectStorageLogger.debug(`active id=${job.id}`)) .on('completed', (job, result) => objectStorageLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => objectStorageLogger.warn(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) })) + .on('failed', (job, err) => { + objectStorageLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + if (config.sentryForBackend) { + Sentry.captureMessage(`Queue: ObjectStorage: ${job?.name ?? '?'}`, { + extra: { job, err }, + }); + } + }) .on('error', (err: Error) => objectStorageLogger.error(`error ${err.stack}`, { e: renderError(err) })) .on('stalled', (jobId) => objectStorageLogger.warn(`stalled id=${jobId}`)); } From d55e638a231b380e733dc0ada3c3de410f918a93 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:40:11 +0900 Subject: [PATCH 011/268] lint fixes --- packages/backend/src/NestLogger.ts | 2 +- packages/backend/src/boot/entry.ts | 2 +- packages/backend/src/postgres.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/NestLogger.ts b/packages/backend/src/NestLogger.ts index 80f1f7a024d6..d0be19664f31 100644 --- a/packages/backend/src/NestLogger.ts +++ b/packages/backend/src/NestLogger.ts @@ -7,7 +7,7 @@ import { LoggerService } from '@nestjs/common'; import Logger from '@/logger.js'; const logger = new Logger('core', 'cyan'); -const nestLogger = logger.createSubLogger('nest', 'green', false); +const nestLogger = logger.createSubLogger('nest', 'green'); export class NestLogger implements LoggerService { /** diff --git a/packages/backend/src/boot/entry.ts b/packages/backend/src/boot/entry.ts index 04c6ca9723cb..25375c3015f7 100644 --- a/packages/backend/src/boot/entry.ts +++ b/packages/backend/src/boot/entry.ts @@ -25,7 +25,7 @@ Error.stackTraceLimit = Infinity; EventEmitter.defaultMaxListeners = 128; const logger = new Logger('core', 'cyan'); -const clusterLogger = logger.createSubLogger('cluster', 'orange', false); +const clusterLogger = logger.createSubLogger('cluster', 'orange'); const ev = new Xev(); //#region Events diff --git a/packages/backend/src/postgres.ts b/packages/backend/src/postgres.ts index 2d14537bbb07..aa2aa5e373da 100644 --- a/packages/backend/src/postgres.ts +++ b/packages/backend/src/postgres.ts @@ -85,7 +85,7 @@ import { bindThis } from '@/decorators.js'; export const dbLogger = new MisskeyLogger('db'); -const sqlLogger = dbLogger.createSubLogger('sql', 'gray', false); +const sqlLogger = dbLogger.createSubLogger('sql', 'gray'); class MyCustomLogger implements Logger { @bindThis From 8f833d742fdb10f088479c78ad489461773a8b81 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:51:31 +0900 Subject: [PATCH 012/268] enhance(backend): improve sentry integration --- .../backend/src/queue/QueueProcessorService.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts index fdeb6a9518a7..6a87be021ee6 100644 --- a/packages/backend/src/queue/QueueProcessorService.ts +++ b/packages/backend/src/queue/QueueProcessorService.ts @@ -165,10 +165,10 @@ export class QueueProcessorService implements OnApplicationShutdown { this.systemQueueWorker .on('active', (job) => systemLogger.debug(`active id=${job.id}`)) .on('completed', (job, result) => systemLogger.debug(`completed(${result}) id=${job.id}`)) - .on('failed', (job, err) => { + .on('failed', (job, err: Error) => { systemLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: System: ${job?.name ?? '?'}`, { + Sentry.captureMessage(`Queue: System: ${job?.name ?? '?'}: ${err.message}`, { extra: { job, err }, }); } @@ -224,7 +224,7 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('failed', (job, err) => { dbLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: DB: ${job?.name ?? '?'}`, { + Sentry.captureMessage(`Queue: DB: ${job?.name ?? '?'}: ${err.message}`, { extra: { job, err }, }); } @@ -263,7 +263,7 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('failed', (job, err) => { deliverLogger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); if (config.sentryForBackend) { - Sentry.captureMessage('Queue: Deliver', { + Sentry.captureMessage(`Queue: Deliver: ${err.message}`, { extra: { job, err }, }); } @@ -302,7 +302,7 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('failed', (job, err) => { inboxLogger.error(`failed(${err.stack}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { - Sentry.captureMessage('Queue: Inbox', { + Sentry.captureMessage(`Queue: Inbox: ${err.message}`, { extra: { job, err }, }); } @@ -341,7 +341,7 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('failed', (job, err) => { webhookLogger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); if (config.sentryForBackend) { - Sentry.captureMessage('Queue: WebhookDeliver', { + Sentry.captureMessage(`Queue: WebhookDeliver: ${err.message}`, { extra: { job, err }, }); } @@ -387,7 +387,7 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('failed', (job, err) => { relationshipLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: Relationship: ${job?.name ?? '?'}`, { + Sentry.captureMessage(`Queue: Relationship: ${job?.name ?? '?'}: ${err.message}`, { extra: { job, err }, }); } @@ -427,7 +427,7 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('failed', (job, err) => { objectStorageLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: ObjectStorage: ${job?.name ?? '?'}`, { + Sentry.captureMessage(`Queue: ObjectStorage: ${job?.name ?? '?'}: ${err.message}`, { extra: { job, err }, }); } From 00157864e95f4fae0c8aacff16ddac7f322ad68c Mon Sep 17 00:00:00 2001 From: taichan <40626578+tai-cha@users.noreply.github.com> Date: Fri, 7 Jun 2024 09:00:01 +0900 Subject: [PATCH 013/268] =?UTF-8?q?fix(backend):=20=E3=83=81=E3=83=A3?= =?UTF-8?q?=E3=83=BC=E3=83=88=E7=94=9F=E6=88=90=E6=99=82=E3=81=ABinstance.?= =?UTF-8?q?isSuspended=E3=81=8C=E8=AA=AD=E3=81=BE=E3=82=8C=E3=81=A6?= =?UTF-8?q?=E3=81=97=E3=81=BE=E3=81=86=E5=95=8F=E9=A1=8C=E3=81=AE=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=20(#13951)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backend): use sustensionState instead of isSuspended * Update CHANGELOG.md --- CHANGELOG.md | 2 +- packages/backend/src/core/chart/charts/federation.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d4ef23d272d..3cccb451d578 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ - ### Server -- +- チャート生成時にinstance.suspentionStateに置き換えられたinstance.isSuspendedが参照されてしまう問題を修正 ## 2024.5.0 diff --git a/packages/backend/src/core/chart/charts/federation.ts b/packages/backend/src/core/chart/charts/federation.ts index 5e4555ee96f5..c2329a2f7357 100644 --- a/packages/backend/src/core/chart/charts/federation.ts +++ b/packages/backend/src/core/chart/charts/federation.ts @@ -47,7 +47,7 @@ export default class FederationChart extends Chart { // eslint-di const suspendedInstancesQuery = this.instancesRepository.createQueryBuilder('instance') .select('instance.host') - .where('instance.isSuspended = true'); + .where('instance.suspensionState != \'none\''); const pubsubSubQuery = this.followingsRepository.createQueryBuilder('f') .select('f.followerHost') @@ -89,7 +89,7 @@ export default class FederationChart extends Chart { // eslint-di .select('COUNT(instance.id)') .where(`instance.host IN (${ subInstancesQuery.getQuery() })`) .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT ILIKE ANY(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) }) - .andWhere('instance.isSuspended = false') + .andWhere('instance.suspensionState = \'none\'') .andWhere('instance.isNotResponding = false') .getRawOne() .then(x => parseInt(x.count, 10)), @@ -97,7 +97,7 @@ export default class FederationChart extends Chart { // eslint-di .select('COUNT(instance.id)') .where(`instance.host IN (${ pubInstancesQuery.getQuery() })`) .andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT ILIKE ANY(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) }) - .andWhere('instance.isSuspended = false') + .andWhere('instance.suspensionState = \'none\'') .andWhere('instance.isNotResponding = false') .getRawOne() .then(x => parseInt(x.count, 10)), From 859271613958cc4a9bc8fcd9616c3146c07a50a4 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:15:37 +0900 Subject: [PATCH 014/268] enhance(backend): improve sentry integration --- packages/backend/src/queue/QueueProcessorService.ts | 7 +++++++ packages/backend/src/server/api/ApiCallService.ts | 1 + 2 files changed, 8 insertions(+) diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts index 6a87be021ee6..7bfe1f4caa47 100644 --- a/packages/backend/src/queue/QueueProcessorService.ts +++ b/packages/backend/src/queue/QueueProcessorService.ts @@ -169,6 +169,7 @@ export class QueueProcessorService implements OnApplicationShutdown { systemLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: System: ${job?.name ?? '?'}: ${err.message}`, { + level: 'error', extra: { job, err }, }); } @@ -225,6 +226,7 @@ export class QueueProcessorService implements OnApplicationShutdown { dbLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: DB: ${job?.name ?? '?'}: ${err.message}`, { + level: 'error', extra: { job, err }, }); } @@ -264,6 +266,7 @@ export class QueueProcessorService implements OnApplicationShutdown { deliverLogger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: Deliver: ${err.message}`, { + level: 'error', extra: { job, err }, }); } @@ -303,6 +306,7 @@ export class QueueProcessorService implements OnApplicationShutdown { inboxLogger.error(`failed(${err.stack}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: Inbox: ${err.message}`, { + level: 'error', extra: { job, err }, }); } @@ -342,6 +346,7 @@ export class QueueProcessorService implements OnApplicationShutdown { webhookLogger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: WebhookDeliver: ${err.message}`, { + level: 'error', extra: { job, err }, }); } @@ -388,6 +393,7 @@ export class QueueProcessorService implements OnApplicationShutdown { relationshipLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: Relationship: ${job?.name ?? '?'}: ${err.message}`, { + level: 'error', extra: { job, err }, }); } @@ -428,6 +434,7 @@ export class QueueProcessorService implements OnApplicationShutdown { objectStorageLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: ObjectStorage: ${job?.name ?? '?'}: ${err.message}`, { + level: 'error', extra: { job, err }, }); } diff --git a/packages/backend/src/server/api/ApiCallService.ts b/packages/backend/src/server/api/ApiCallService.ts index e21a5e90abbd..166f9c8675fd 100644 --- a/packages/backend/src/server/api/ApiCallService.ts +++ b/packages/backend/src/server/api/ApiCallService.ts @@ -111,6 +111,7 @@ export class ApiCallService implements OnApplicationShutdown { if (this.config.sentryForBackend) { Sentry.captureMessage(`Internal error occurred in ${ep.name}: ${err.message}`, { + level: 'error', user: { id: userId, }, From e0cf5b24022e22179355cf9439d3cfea6036daba Mon Sep 17 00:00:00 2001 From: Porlam Nicla <84321396+GrapeApple0@users.noreply.github.com> Date: Fri, 7 Jun 2024 14:46:46 +0900 Subject: [PATCH 015/268] =?UTF-8?q?=E9=85=8D=E4=BF=A1=E5=81=9C=E6=AD=A2?= =?UTF-8?q?=E3=81=97=E3=81=9F=E3=82=A4=E3=83=B3=E3=82=B9=E3=82=BF=E3=83=B3?= =?UTF-8?q?=E3=82=B9=E4=B8=80=E8=A6=A7=E3=81=8C=E8=A6=8B=E3=82=8C=E3=81=AA?= =?UTF-8?q?=E3=81=8F=E3=81=AA=E3=82=8B=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=20(#13945)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 配信停止したインスタンス一覧が見れなくなる問題を修正 * Update CHANGELOG.md --- CHANGELOG.md | 2 +- .../backend/src/server/api/endpoints/federation/instances.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cccb451d578..f93811c60672 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## Unreleased ### General -- +- Fix: 配信停止したインスタンス一覧が見れなくなる問題を修正 ### Client - diff --git a/packages/backend/src/server/api/endpoints/federation/instances.ts b/packages/backend/src/server/api/endpoints/federation/instances.ts index 4ef4315fb308..36f4bf5aa682 100644 --- a/packages/backend/src/server/api/endpoints/federation/instances.ts +++ b/packages/backend/src/server/api/endpoints/federation/instances.ts @@ -117,9 +117,9 @@ export default class extends Endpoint { // eslint- if (typeof ps.suspended === 'boolean') { if (ps.suspended) { - query.andWhere('instance.isSuspended = TRUE'); + query.andWhere('instance.suspensionState != \'none\''); } else { - query.andWhere('instance.isSuspended = FALSE'); + query.andWhere('instance.suspensionState = \'none\''); } } From 61fae45390283aee7ac582aa5303aae863de0f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?= <46447427+samunohito@users.noreply.github.com> Date: Sat, 8 Jun 2024 15:34:19 +0900 Subject: [PATCH 016/268] =?UTF-8?q?feat:=20=E9=80=9A=E5=A0=B1=E3=82=92?= =?UTF-8?q?=E5=8F=97=E3=81=91=E3=81=9F=E9=9A=9B=E3=81=AB=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=83=AB=E3=81=BE=E3=81=9F=E3=81=AFWebhook=E3=81=A7=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E3=82=92=E9=80=81=E5=87=BA=E5=87=BA=E6=9D=A5=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B=20(#13758)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 通報を受けた際にメールまたはWebhookで通知を送出出来るようにする * モデログに対応&エンドポイントを単一オブジェクトでのサポートに変更(API経由で大量に作るシチュエーションもないと思うので) * fix spdx * fix migration * fix migration * fix models * add e2e webhook * tweak * fix modlog * fix bugs * add tests and fix bugs * add tests and fix bugs * add tests * fix path * regenerate locale * 混入除去 * 混入除去 * add abuseReportResolved * fix pnpm-lock.yaml * add abuseReportResolved test * fix bugs * fix ui * add tests * fix CHANGELOG.md * add tests * add RoleService.getModeratorIds tests * WebhookServiceをUserとSystemに分割 * fix CHANGELOG.md * fix test * insertOneを使う用に * fix * regenerate locales * revert version * separate webhook job queue * fix * :art: * Update QueueProcessorService.ts --------- Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com> Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> --- CHANGELOG.md | 1 + locales/index.d.ts | 94 ++ locales/ja-JP.yml | 27 + ...1713656541000-abuse-report-notification.js | 62 ++ .../core/AbuseReportNotificationService.ts | 406 ++++++++ .../backend/src/core/AbuseReportService.ts | 128 +++ packages/backend/src/core/CoreModule.ts | 44 +- packages/backend/src/core/EmailService.ts | 2 + .../backend/src/core/GlobalEventService.ts | 4 + .../backend/src/core/NoteCreateService.ts | 12 +- packages/backend/src/core/QueueModule.ts | 38 +- packages/backend/src/core/QueueService.ts | 63 +- packages/backend/src/core/RoleService.ts | 30 +- .../backend/src/core/SystemWebhookService.ts | 233 +++++ .../backend/src/core/UserBlockingService.ts | 6 +- .../backend/src/core/UserFollowingService.ts | 12 +- .../backend/src/core/UserWebhookService.ts | 99 ++ packages/backend/src/core/WebhookService.ts | 97 -- .../src/core/activitypub/ApInboxService.ts | 10 +- ...eportNotificationRecipientEntityService.ts | 88 ++ .../entities/SystemWebhookEntityService.ts | 74 ++ packages/backend/src/di-symbols.ts | 2 + packages/backend/src/misc/json-schema.ts | 28 +- .../AbuseReportNotificationRecipient.ts | 100 ++ .../backend/src/models/RepositoryModule.ts | 98 +- packages/backend/src/models/SystemWebhook.ts | 98 ++ packages/backend/src/models/_.ts | 6 + .../abuse-report-notification-recipient.ts | 50 + .../src/models/json-schema/system-webhook.ts | 54 + packages/backend/src/postgres.ts | 8 +- .../backend/src/queue/QueueProcessorModule.ts | 6 +- .../src/queue/QueueProcessorService.ts | 153 ++- packages/backend/src/queue/const.ts | 3 +- .../SystemWebhookDeliverProcessorService.ts | 87 ++ ... => UserWebhookDeliverProcessorService.ts} | 6 +- packages/backend/src/queue/types.ts | 12 +- .../backend/src/server/api/EndpointsModule.ts | 42 +- packages/backend/src/server/api/endpoints.ts | 38 +- .../notification-recipient/create.ts | 122 +++ .../notification-recipient/delete.ts | 44 + .../notification-recipient/list.ts | 55 + .../notification-recipient/show.ts | 64 ++ .../notification-recipient/update.ts | 128 +++ .../server/api/endpoints/admin/queue/stats.ts | 5 +- .../admin/resolve-abuse-user-report.ts | 53 +- .../endpoints/admin/system-webhook/create.ts | 85 ++ .../endpoints/admin/system-webhook/delete.ts | 44 + .../endpoints/admin/system-webhook/list.ts | 60 ++ .../endpoints/admin/system-webhook/show.ts | 62 ++ .../endpoints/admin/system-webhook/update.ts | 91 ++ .../api/endpoints/users/report-abuse.ts | 54 +- .../src/server/web/ClientServerService.ts | 17 +- packages/backend/src/types.ts | 32 + .../backend/test/e2e/synalio/abuse-report.ts | 401 ++++++++ .../unit/AbuseReportNotificationService.ts | 343 +++++++ packages/backend/test/unit/RoleService.ts | 132 ++- .../backend/test/unit/SystemWebhookService.ts | 515 ++++++++++ packages/frontend/src/components/MkButton.vue | 2 + .../frontend/src/components/MkDivider.vue | 32 + packages/frontend/src/components/MkSwitch.vue | 5 +- .../components/MkSystemWebhookEditor.impl.ts | 45 + .../src/components/MkSystemWebhookEditor.vue | 217 ++++ .../notification-recipient.editor.vue | 307 ++++++ .../notification-recipient.item.vue | 114 +++ .../abuse-report/notification-recipient.vue | 176 ++++ packages/frontend/src/pages/admin/abuses.vue | 85 +- packages/frontend/src/pages/admin/index.vue | 5 + .../src/pages/admin/modlog.ModLog.vue | 48 +- .../src/pages/admin/system-webhook.item.vue | 117 +++ .../src/pages/admin/system-webhook.vue | 96 ++ packages/frontend/src/router/definition.ts | 8 + packages/misskey-js/etc/misskey-js.api.md | 105 +- .../misskey-js/src/autogen/apiClientJSDoc.ts | 120 +++ packages/misskey-js/src/autogen/endpoint.ts | 28 + packages/misskey-js/src/autogen/entities.ts | 18 + packages/misskey-js/src/autogen/models.ts | 2 + packages/misskey-js/src/autogen/types.ts | 939 +++++++++++++++--- packages/misskey-js/src/consts.ts | 26 + packages/misskey-js/src/entities.ts | 19 +- 79 files changed, 6650 insertions(+), 492 deletions(-) create mode 100644 packages/backend/migration/1713656541000-abuse-report-notification.js create mode 100644 packages/backend/src/core/AbuseReportNotificationService.ts create mode 100644 packages/backend/src/core/AbuseReportService.ts create mode 100644 packages/backend/src/core/SystemWebhookService.ts create mode 100644 packages/backend/src/core/UserWebhookService.ts delete mode 100644 packages/backend/src/core/WebhookService.ts create mode 100644 packages/backend/src/core/entities/AbuseReportNotificationRecipientEntityService.ts create mode 100644 packages/backend/src/core/entities/SystemWebhookEntityService.ts create mode 100644 packages/backend/src/models/AbuseReportNotificationRecipient.ts create mode 100644 packages/backend/src/models/SystemWebhook.ts create mode 100644 packages/backend/src/models/json-schema/abuse-report-notification-recipient.ts create mode 100644 packages/backend/src/models/json-schema/system-webhook.ts create mode 100644 packages/backend/src/queue/processors/SystemWebhookDeliverProcessorService.ts rename packages/backend/src/queue/processors/{WebhookDeliverProcessorService.ts => UserWebhookDeliverProcessorService.ts} (92%) create mode 100644 packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/create.ts create mode 100644 packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/delete.ts create mode 100644 packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/list.ts create mode 100644 packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/show.ts create mode 100644 packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/update.ts create mode 100644 packages/backend/src/server/api/endpoints/admin/system-webhook/create.ts create mode 100644 packages/backend/src/server/api/endpoints/admin/system-webhook/delete.ts create mode 100644 packages/backend/src/server/api/endpoints/admin/system-webhook/list.ts create mode 100644 packages/backend/src/server/api/endpoints/admin/system-webhook/show.ts create mode 100644 packages/backend/src/server/api/endpoints/admin/system-webhook/update.ts create mode 100644 packages/backend/test/e2e/synalio/abuse-report.ts create mode 100644 packages/backend/test/unit/AbuseReportNotificationService.ts create mode 100644 packages/backend/test/unit/SystemWebhookService.ts create mode 100644 packages/frontend/src/components/MkDivider.vue create mode 100644 packages/frontend/src/components/MkSystemWebhookEditor.impl.ts create mode 100644 packages/frontend/src/components/MkSystemWebhookEditor.vue create mode 100644 packages/frontend/src/pages/admin/abuse-report/notification-recipient.editor.vue create mode 100644 packages/frontend/src/pages/admin/abuse-report/notification-recipient.item.vue create mode 100644 packages/frontend/src/pages/admin/abuse-report/notification-recipient.vue create mode 100644 packages/frontend/src/pages/admin/system-webhook.item.vue create mode 100644 packages/frontend/src/pages/admin/system-webhook.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index f93811c60672..8b70636d8265 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Unreleased ### General +- Feat: 通報を受けた際、または解決した際に、予め登録した宛先に通知を飛ばせるように(mail or webhook) #13705 - Fix: 配信停止したインスタンス一覧が見れなくなる問題を修正 ### Client diff --git a/locales/index.d.ts b/locales/index.d.ts index 0b1b86d37378..acdc1fc421c3 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -9305,6 +9305,10 @@ export interface Locale extends ILocale { * Webhookを作成 */ "createWebhook": string; + /** + * Webhookを編集 + */ + "modifyWebhook": string; /** * 名前 */ @@ -9351,6 +9355,72 @@ export interface Locale extends ILocale { */ "mention": string; }; + "_systemEvents": { + /** + * ユーザーから通報があったとき + */ + "abuseReport": string; + /** + * ユーザーからの通報を処理したとき + */ + "abuseReportResolved": string; + }; + /** + * Webhookを削除しますか? + */ + "deleteConfirm": string; + }; + "_abuseReport": { + "_notificationRecipient": { + /** + * 通報の通知先を追加 + */ + "createRecipient": string; + /** + * 通報の通知先を編集 + */ + "modifyRecipient": string; + /** + * 通知先の種類 + */ + "recipientType": string; + "_recipientType": { + /** + * メール + */ + "mail": string; + /** + * Webhook + */ + "webhook": string; + "_captions": { + /** + * モデレーター権限を持つユーザーのメールアドレスに通知を送ります(通報を受けた時のみ) + */ + "mail": string; + /** + * 指定したSystemWebhookに通知を送ります(通報を受けた時と通報を解決した時にそれぞれ発信) + */ + "webhook": string; + }; + }; + /** + * キーワード + */ + "keywords": string; + /** + * 通知先ユーザー + */ + "notifiedUser": string; + /** + * 使用するWebhook + */ + "notifiedWebhook": string; + /** + * 通知先を削除しますか? + */ + "deleteConfirm": string; + }; }; "_moderationLogTypes": { /** @@ -9497,6 +9567,30 @@ export interface Locale extends ILocale { * ユーザーのバナーを解除 */ "unsetUserBanner": string; + /** + * SystemWebhookを作成 + */ + "createSystemWebhook": string; + /** + * SystemWebhookを更新 + */ + "updateSystemWebhook": string; + /** + * SystemWebhookを削除 + */ + "deleteSystemWebhook": string; + /** + * 通報の通知先を作成 + */ + "createAbuseReportNotificationRecipient": string; + /** + * 通報の通知先を更新 + */ + "updateAbuseReportNotificationRecipient": string; + /** + * 通報の通知先を削除 + */ + "deleteAbuseReportNotificationRecipient": string; }; "_fileViewer": { /** diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index a89cfbd843a3..3ac1ce82a3b7 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2468,6 +2468,7 @@ _drivecleaner: _webhookSettings: createWebhook: "Webhookを作成" + modifyWebhook: "Webhookを編集" name: "名前" secret: "シークレット" events: "Webhookを実行するタイミング" @@ -2480,6 +2481,26 @@ _webhookSettings: renote: "Renoteされたとき" reaction: "リアクションがあったとき" mention: "メンションされたとき" + _systemEvents: + abuseReport: "ユーザーから通報があったとき" + abuseReportResolved: "ユーザーからの通報を処理したとき" + deleteConfirm: "Webhookを削除しますか?" + +_abuseReport: + _notificationRecipient: + createRecipient: "通報の通知先を追加" + modifyRecipient: "通報の通知先を編集" + recipientType: "通知先の種類" + _recipientType: + mail: "メール" + webhook: "Webhook" + _captions: + mail: "モデレーター権限を持つユーザーのメールアドレスに通知を送ります(通報を受けた時のみ)" + webhook: "指定したSystemWebhookに通知を送ります(通報を受けた時と通報を解決した時にそれぞれ発信)" + keywords: "キーワード" + notifiedUser: "通知先ユーザー" + notifiedWebhook: "使用するWebhook" + deleteConfirm: "通知先を削除しますか?" _moderationLogTypes: createRole: "ロールを作成" @@ -2518,6 +2539,12 @@ _moderationLogTypes: deleteAvatarDecoration: "アイコンデコレーションを削除" unsetUserAvatar: "ユーザーのアイコンを解除" unsetUserBanner: "ユーザーのバナーを解除" + createSystemWebhook: "SystemWebhookを作成" + updateSystemWebhook: "SystemWebhookを更新" + deleteSystemWebhook: "SystemWebhookを削除" + createAbuseReportNotificationRecipient: "通報の通知先を作成" + updateAbuseReportNotificationRecipient: "通報の通知先を更新" + deleteAbuseReportNotificationRecipient: "通報の通知先を削除" _fileViewer: title: "ファイルの詳細" diff --git a/packages/backend/migration/1713656541000-abuse-report-notification.js b/packages/backend/migration/1713656541000-abuse-report-notification.js new file mode 100644 index 000000000000..4a754f81e2f5 --- /dev/null +++ b/packages/backend/migration/1713656541000-abuse-report-notification.js @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class AbuseReportNotification1713656541000 { + name = 'AbuseReportNotification1713656541000' + + async up(queryRunner) { + await queryRunner.query(` + CREATE TABLE "system_webhook" ( + "id" varchar(32) NOT NULL, + "isActive" boolean NOT NULL DEFAULT true, + "updatedAt" timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP, + "latestSentAt" timestamp with time zone NULL DEFAULT NULL, + "latestStatus" integer NULL DEFAULT NULL, + "name" varchar(255) NOT NULL, + "on" varchar(128) [] NOT NULL DEFAULT '{}'::character varying[], + "url" varchar(1024) NOT NULL, + "secret" varchar(1024) NOT NULL, + CONSTRAINT "PK_system_webhook_id" PRIMARY KEY ("id") + ); + CREATE INDEX "IDX_system_webhook_isActive" ON "system_webhook" ("isActive"); + CREATE INDEX "IDX_system_webhook_on" ON "system_webhook" USING gin ("on"); + + CREATE TABLE "abuse_report_notification_recipient" ( + "id" varchar(32) NOT NULL, + "isActive" boolean NOT NULL DEFAULT true, + "updatedAt" timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP, + "name" varchar(255) NOT NULL, + "method" varchar(64) NOT NULL, + "userId" varchar(32) NULL DEFAULT NULL, + "systemWebhookId" varchar(32) NULL DEFAULT NULL, + CONSTRAINT "PK_abuse_report_notification_recipient_id" PRIMARY KEY ("id"), + CONSTRAINT "FK_abuse_report_notification_recipient_userId1" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_abuse_report_notification_recipient_userId2" FOREIGN KEY ("userId") REFERENCES "user_profile"("userId") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_abuse_report_notification_recipient_systemWebhookId" FOREIGN KEY ("systemWebhookId") REFERENCES "system_webhook"("id") ON DELETE CASCADE ON UPDATE NO ACTION + ); + CREATE INDEX "IDX_abuse_report_notification_recipient_isActive" ON "abuse_report_notification_recipient" ("isActive"); + CREATE INDEX "IDX_abuse_report_notification_recipient_method" ON "abuse_report_notification_recipient" ("method"); + CREATE INDEX "IDX_abuse_report_notification_recipient_userId" ON "abuse_report_notification_recipient" ("userId"); + CREATE INDEX "IDX_abuse_report_notification_recipient_systemWebhookId" ON "abuse_report_notification_recipient" ("systemWebhookId"); + `); + } + + async down(queryRunner) { + await queryRunner.query(` + ALTER TABLE "abuse_report_notification_recipient" DROP CONSTRAINT "FK_abuse_report_notification_recipient_userId1"; + ALTER TABLE "abuse_report_notification_recipient" DROP CONSTRAINT "FK_abuse_report_notification_recipient_userId2"; + ALTER TABLE "abuse_report_notification_recipient" DROP CONSTRAINT "FK_abuse_report_notification_recipient_systemWebhookId"; + DROP INDEX "IDX_abuse_report_notification_recipient_isActive"; + DROP INDEX "IDX_abuse_report_notification_recipient_method"; + DROP INDEX "IDX_abuse_report_notification_recipient_userId"; + DROP INDEX "IDX_abuse_report_notification_recipient_systemWebhookId"; + DROP TABLE "abuse_report_notification_recipient"; + + DROP INDEX "IDX_system_webhook_isActive"; + DROP INDEX "IDX_system_webhook_on"; + DROP TABLE "system_webhook"; + `); + } +} diff --git a/packages/backend/src/core/AbuseReportNotificationService.ts b/packages/backend/src/core/AbuseReportNotificationService.ts new file mode 100644 index 000000000000..df752afcd876 --- /dev/null +++ b/packages/backend/src/core/AbuseReportNotificationService.ts @@ -0,0 +1,406 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable, type OnApplicationShutdown } from '@nestjs/common'; +import { Brackets, In, IsNull, Not } from 'typeorm'; +import * as Redis from 'ioredis'; +import sanitizeHtml from 'sanitize-html'; +import { DI } from '@/di-symbols.js'; +import { bindThis } from '@/decorators.js'; +import { GlobalEvents, GlobalEventService } from '@/core/GlobalEventService.js'; +import { isNotNull } from '@/misc/is-not-null.js'; +import type { + AbuseReportNotificationRecipientRepository, + MiAbuseReportNotificationRecipient, + MiAbuseUserReport, + MiUser, +} from '@/models/_.js'; +import { EmailService } from '@/core/EmailService.js'; +import { MetaService } from '@/core/MetaService.js'; +import { RoleService } from '@/core/RoleService.js'; +import { RecipientMethod } from '@/models/AbuseReportNotificationRecipient.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { SystemWebhookService } from '@/core/SystemWebhookService.js'; +import { IdService } from './IdService.js'; + +@Injectable() +export class AbuseReportNotificationService implements OnApplicationShutdown { + constructor( + @Inject(DI.abuseReportNotificationRecipientRepository) + private abuseReportNotificationRecipientRepository: AbuseReportNotificationRecipientRepository, + @Inject(DI.redisForSub) + private redisForSub: Redis.Redis, + private idService: IdService, + private roleService: RoleService, + private systemWebhookService: SystemWebhookService, + private emailService: EmailService, + private metaService: MetaService, + private moderationLogService: ModerationLogService, + private globalEventService: GlobalEventService, + ) { + this.redisForSub.on('message', this.onMessage); + } + + /** + * 管理者用Redisイベントを用いて{@link abuseReports}の内容を管理者各位に通知する. + * 通知先ユーザは{@link RoleService.getModeratorIds}の取得結果に依る. + * + * @see RoleService.getModeratorIds + * @see GlobalEventService.publishAdminStream + */ + @bindThis + public async notifyAdminStream(abuseReports: MiAbuseUserReport[]) { + if (abuseReports.length <= 0) { + return; + } + + const moderatorIds = await this.roleService.getModeratorIds(true, true); + + for (const moderatorId of moderatorIds) { + for (const abuseReport of abuseReports) { + this.globalEventService.publishAdminStream( + moderatorId, + 'newAbuseUserReport', + { + id: abuseReport.id, + targetUserId: abuseReport.targetUserId, + reporterId: abuseReport.reporterId, + comment: abuseReport.comment, + }, + ); + } + } + } + + /** + * Mailを用いて{@link abuseReports}の内容を管理者各位に通知する. + * メールアドレスの送信先は以下の通り. + * - モデレータ権限所有者ユーザ(設定画面からメールアドレスの設定を行っているユーザに限る) + * - metaテーブルに設定されているメールアドレス + * + * @see EmailService.sendEmail + */ + @bindThis + public async notifyMail(abuseReports: MiAbuseUserReport[]) { + if (abuseReports.length <= 0) { + return; + } + + const recipientEMailAddresses = await this.fetchEMailRecipients().then(it => it + .filter(it => it.isActive && it.userProfile?.emailVerified) + .map(it => it.userProfile?.email) + .filter(isNotNull), + ); + + // 送信先の鮮度を保つため、毎回取得する + const meta = await this.metaService.fetch(true); + recipientEMailAddresses.push( + ...(meta.email ? [meta.email] : []), + ); + + if (recipientEMailAddresses.length <= 0) { + return; + } + + for (const mailAddress of recipientEMailAddresses) { + await Promise.all( + abuseReports.map(it => { + // TODO: 送信処理はJobQueue化したい + return this.emailService.sendEmail( + mailAddress, + 'New Abuse Report', + sanitizeHtml(it.comment), + sanitizeHtml(it.comment), + ); + }), + ); + } + } + + /** + * SystemWebhookを用いて{@link abuseReports}の内容を管理者各位に通知する. + * ここではJobQueueへのエンキューのみを行うため、即時実行されない. + * + * @see SystemWebhookService.enqueueSystemWebhook + */ + @bindThis + public async notifySystemWebhook( + abuseReports: MiAbuseUserReport[], + type: 'abuseReport' | 'abuseReportResolved', + ) { + if (abuseReports.length <= 0) { + return; + } + + const recipientWebhookIds = await this.fetchWebhookRecipients() + .then(it => it + .filter(it => it.isActive && it.systemWebhookId && it.method === 'webhook') + .map(it => it.systemWebhookId) + .filter(isNotNull)); + for (const webhookId of recipientWebhookIds) { + await Promise.all( + abuseReports.map(it => { + return this.systemWebhookService.enqueueSystemWebhook( + webhookId, + type, + it, + ); + }), + ); + } + } + + /** + * 通報の通知先一覧を取得する. + * + * @param {Object} [params] クエリの取得条件 + * @param {Object} [params.method] 取得する通知先の通知方法 + * @param {Object} [opts] 動作時の詳細なオプション + * @param {boolean} [opts.removeUnauthorized] 副作用としてモデレータ権限を持たない送信先ユーザをDBから削除するかどうか(default: true) + * @param {boolean} [opts.joinUser] 通知先のユーザ情報をJOINするかどうか(default: false) + * @param {boolean} [opts.joinSystemWebhook] 通知先のSystemWebhook情報をJOINするかどうか(default: false) + * @see removeUnauthorizedRecipientUsers + */ + @bindThis + public async fetchRecipients( + params?: { + ids?: MiAbuseReportNotificationRecipient['id'][], + method?: RecipientMethod[], + }, + opts?: { + removeUnauthorized?: boolean, + joinUser?: boolean, + joinSystemWebhook?: boolean, + }, + ): Promise { + const query = this.abuseReportNotificationRecipientRepository.createQueryBuilder('recipient'); + + if (opts?.joinUser) { + query.innerJoinAndSelect('user', 'user', 'recipient.userId = user.id'); + query.innerJoinAndSelect('recipient.userProfile', 'userProfile'); + } + + if (opts?.joinSystemWebhook) { + query.innerJoinAndSelect('recipient.systemWebhook', 'systemWebhook'); + } + + if (params?.ids) { + query.andWhere({ id: In(params.ids) }); + } + + if (params?.method) { + query.andWhere(new Brackets(qb => { + if (params.method?.includes('email')) { + qb.orWhere({ method: 'email', userId: Not(IsNull()) }); + } + if (params.method?.includes('webhook')) { + qb.orWhere({ method: 'webhook', userId: IsNull() }); + } + })); + } + + const recipients = await query.getMany(); + if (recipients.length <= 0) { + return []; + } + + // アサイン有効期限切れはイベントで拾えないので、このタイミングでチェック及び削除(オプション) + return (opts?.removeUnauthorized ?? true) + ? await this.removeUnauthorizedRecipientUsers(recipients) + : recipients; + } + + /** + * EMailの通知先一覧を取得する. + * リレーション先の{@link MiUser}および{@link MiUserProfile}も同時に取得する. + * + * @param {Object} [opts] + * @param {boolean} [opts.removeUnauthorized] 副作用としてモデレータ権限を持たない送信先ユーザをDBから削除するかどうか(default: true) + * @see removeUnauthorizedRecipientUsers + */ + @bindThis + public async fetchEMailRecipients(opts?: { + removeUnauthorized?: boolean + }): Promise { + return this.fetchRecipients({ method: ['email'] }, { joinUser: true, ...opts }); + } + + /** + * Webhookの通知先一覧を取得する. + * リレーション先の{@link MiSystemWebhook}も同時に取得する. + */ + @bindThis + public fetchWebhookRecipients(): Promise { + return this.fetchRecipients({ method: ['webhook'] }, { joinSystemWebhook: true }); + } + + /** + * 通知先を作成する. + */ + @bindThis + public async createRecipient( + params: { + isActive: MiAbuseReportNotificationRecipient['isActive']; + name: MiAbuseReportNotificationRecipient['name']; + method: MiAbuseReportNotificationRecipient['method']; + userId: MiAbuseReportNotificationRecipient['userId']; + systemWebhookId: MiAbuseReportNotificationRecipient['systemWebhookId']; + }, + updater: MiUser, + ): Promise { + const id = this.idService.gen(); + await this.abuseReportNotificationRecipientRepository.insert({ + ...params, + id, + }); + + const created = await this.abuseReportNotificationRecipientRepository.findOneByOrFail({ id: id }); + + this.moderationLogService + .log(updater, 'createAbuseReportNotificationRecipient', { + recipientId: id, + recipient: created, + }) + .then(); + + return created; + } + + /** + * 通知先を更新する. + */ + @bindThis + public async updateRecipient( + params: { + id: MiAbuseReportNotificationRecipient['id']; + isActive: MiAbuseReportNotificationRecipient['isActive']; + name: MiAbuseReportNotificationRecipient['name']; + method: MiAbuseReportNotificationRecipient['method']; + userId: MiAbuseReportNotificationRecipient['userId']; + systemWebhookId: MiAbuseReportNotificationRecipient['systemWebhookId']; + }, + updater: MiUser, + ): Promise { + const beforeEntity = await this.abuseReportNotificationRecipientRepository.findOneByOrFail({ id: params.id }); + + await this.abuseReportNotificationRecipientRepository.update(params.id, { + isActive: params.isActive, + updatedAt: new Date(), + name: params.name, + method: params.method, + userId: params.userId, + systemWebhookId: params.systemWebhookId, + }); + + const afterEntity = await this.abuseReportNotificationRecipientRepository.findOneByOrFail({ id: params.id }); + + this.moderationLogService + .log(updater, 'updateAbuseReportNotificationRecipient', { + recipientId: params.id, + before: beforeEntity, + after: afterEntity, + }) + .then(); + + return afterEntity; + } + + /** + * 通知先を削除する. + */ + @bindThis + public async deleteRecipient( + id: MiAbuseReportNotificationRecipient['id'], + updater: MiUser, + ) { + const entity = await this.abuseReportNotificationRecipientRepository.findBy({ id }); + + await this.abuseReportNotificationRecipientRepository.delete(id); + + this.moderationLogService + .log(updater, 'deleteAbuseReportNotificationRecipient', { + recipientId: id, + recipient: entity, + }) + .then(); + } + + /** + * モデレータ権限を持たない(*1)通知先ユーザを削除する. + * + * *1: 以下の両方を満たすものの事を言う + * - 通知先にユーザIDが設定されている + * - 付与ロールにモデレータ権限がない or アサインの有効期限が切れている + * + * @param recipients 通知先一覧の配列 + * @returns {@lisk recipients}からモデレータ権限を持たない通知先を削除した配列 + */ + @bindThis + private async removeUnauthorizedRecipientUsers(recipients: MiAbuseReportNotificationRecipient[]): Promise { + const userRecipients = recipients.filter(it => it.userId !== null); + const recipientUserIds = new Set(userRecipients.map(it => it.userId).filter(isNotNull)); + if (recipientUserIds.size <= 0) { + // ユーザが通知先として設定されていない場合、この関数での処理を行うべきレコードが無い + return recipients; + } + + // モデレータ権限の有無で通知先設定を振り分ける + const authorizedUserIds = await this.roleService.getModeratorIds(true, true); + const authorizedUserRecipients = Array.of(); + const unauthorizedUserRecipients = Array.of(); + for (const recipient of userRecipients) { + // eslint-disable-next-line + if (authorizedUserIds.includes(recipient.userId!)) { + authorizedUserRecipients.push(recipient); + } else { + unauthorizedUserRecipients.push(recipient); + } + } + + // モデレータ権限を持たない通知先をDBから削除する + if (unauthorizedUserRecipients.length > 0) { + await this.abuseReportNotificationRecipientRepository.delete(unauthorizedUserRecipients.map(it => it.id)); + } + const nonUserRecipients = recipients.filter(it => it.userId === null); + return [...nonUserRecipients, ...authorizedUserRecipients].sort((a, b) => a.id.localeCompare(b.id)); + } + + @bindThis + private async onMessage(_: string, data: string): Promise { + const obj = JSON.parse(data); + if (obj.channel !== 'internal') { + return; + } + + const { type } = obj.message as GlobalEvents['internal']['payload']; + switch (type) { + case 'roleUpdated': + case 'roleDeleted': + case 'userRoleUnassigned': { + // 場合によってはキャッシュ更新よりも先にここが呼ばれてしまう可能性があるのでnextTickで遅延実行 + process.nextTick(async () => { + const recipients = await this.abuseReportNotificationRecipientRepository.findBy({ + userId: Not(IsNull()), + }); + await this.removeUnauthorizedRecipientUsers(recipients); + }); + break; + } + default: { + break; + } + } + } + + @bindThis + public dispose(): void { + this.redisForSub.off('message', this.onMessage); + } + + @bindThis + public onApplicationShutdown(signal?: string | undefined): void { + this.dispose(); + } +} diff --git a/packages/backend/src/core/AbuseReportService.ts b/packages/backend/src/core/AbuseReportService.ts new file mode 100644 index 000000000000..69c51509ba40 --- /dev/null +++ b/packages/backend/src/core/AbuseReportService.ts @@ -0,0 +1,128 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { In } from 'typeorm'; +import { DI } from '@/di-symbols.js'; +import { bindThis } from '@/decorators.js'; +import type { AbuseUserReportsRepository, MiAbuseUserReport, MiUser, UsersRepository } from '@/models/_.js'; +import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js'; +import { QueueService } from '@/core/QueueService.js'; +import { InstanceActorService } from '@/core/InstanceActorService.js'; +import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { IdService } from './IdService.js'; + +@Injectable() +export class AbuseReportService { + constructor( + @Inject(DI.abuseUserReportsRepository) + private abuseUserReportsRepository: AbuseUserReportsRepository, + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + private idService: IdService, + private abuseReportNotificationService: AbuseReportNotificationService, + private queueService: QueueService, + private instanceActorService: InstanceActorService, + private apRendererService: ApRendererService, + private moderationLogService: ModerationLogService, + ) { + } + + /** + * ユーザからの通報をDBに記録し、その内容を下記の手段で管理者各位に通知する. + * - 管理者用Redisイベント + * - EMail(モデレータ権限所有者ユーザ+metaテーブルに設定されているメールアドレス) + * - SystemWebhook + * + * @param params 通報内容. もし複数件の通報に対応した時のために、あらかじめ複数件を処理できる前提で考える + * @see AbuseReportNotificationService.notify + */ + @bindThis + public async report(params: { + targetUserId: MiAbuseUserReport['targetUserId'], + targetUserHost: MiAbuseUserReport['targetUserHost'], + reporterId: MiAbuseUserReport['reporterId'], + reporterHost: MiAbuseUserReport['reporterHost'], + comment: string, + }[]) { + const entities = params.map(param => { + return { + id: this.idService.gen(), + targetUserId: param.targetUserId, + targetUserHost: param.targetUserHost, + reporterId: param.reporterId, + reporterHost: param.reporterHost, + comment: param.comment, + }; + }); + + const reports = Array.of(); + for (const entity of entities) { + const report = await this.abuseUserReportsRepository.insertOne(entity); + reports.push(report); + } + + return Promise.all([ + this.abuseReportNotificationService.notifyAdminStream(reports), + this.abuseReportNotificationService.notifySystemWebhook(reports, 'abuseReport'), + this.abuseReportNotificationService.notifyMail(reports), + ]); + } + + /** + * 通報を解決し、その内容を下記の手段で管理者各位に通知する. + * - SystemWebhook + * + * @param params 通報内容. もし複数件の通報に対応した時のために、あらかじめ複数件を処理できる前提で考える + * @param operator 通報を処理したユーザ + * @see AbuseReportNotificationService.notify + */ + @bindThis + public async resolve( + params: { + reportId: string; + forward: boolean; + }[], + operator: MiUser, + ) { + const paramsMap = new Map(params.map(it => [it.reportId, it])); + const reports = await this.abuseUserReportsRepository.findBy({ + id: In(params.map(it => it.reportId)), + }); + + for (const report of reports) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const ps = paramsMap.get(report.id)!; + + await this.abuseUserReportsRepository.update(report.id, { + resolved: true, + assigneeId: operator.id, + forwarded: ps.forward && report.targetUserHost !== null, + }); + + if (ps.forward && report.targetUserHost != null) { + const actor = await this.instanceActorService.getInstanceActor(); + const targetUser = await this.usersRepository.findOneByOrFail({ id: report.targetUserId }); + + // eslint-disable-next-line + const flag = this.apRendererService.renderFlag(actor, targetUser.uri!, report.comment); + const contextAssignedFlag = this.apRendererService.addContext(flag); + this.queueService.deliver(actor, contextAssignedFlag, targetUser.inbox, false); + } + + this.moderationLogService + .log(operator, 'resolveAbuseReport', { + reportId: report.id, + report: report, + forwarded: ps.forward && report.targetUserHost !== null, + }) + .then(); + } + + return this.abuseUserReportsRepository.findBy({ id: In(reports.map(it => it.id)) }) + .then(reports => this.abuseReportNotificationService.notifySystemWebhook(reports, 'abuseReportResolved')); + } +} diff --git a/packages/backend/src/core/CoreModule.ts b/packages/backend/src/core/CoreModule.ts index be80df6f1cf1..b5b34487ec81 100644 --- a/packages/backend/src/core/CoreModule.ts +++ b/packages/backend/src/core/CoreModule.ts @@ -5,6 +5,13 @@ import { Module } from '@nestjs/common'; import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js'; +import { AbuseReportService } from '@/core/AbuseReportService.js'; +import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js'; +import { + AbuseReportNotificationRecipientEntityService, +} from '@/core/entities/AbuseReportNotificationRecipientEntityService.js'; +import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js'; +import { SystemWebhookService } from '@/core/SystemWebhookService.js'; import { AccountMoveService } from './AccountMoveService.js'; import { AccountUpdateService } from './AccountUpdateService.js'; import { AiService } from './AiService.js'; @@ -56,7 +63,7 @@ import { UserMutingService } from './UserMutingService.js'; import { UserSuspendService } from './UserSuspendService.js'; import { UserAuthService } from './UserAuthService.js'; import { VideoProcessingService } from './VideoProcessingService.js'; -import { WebhookService } from './WebhookService.js'; +import { UserWebhookService } from './UserWebhookService.js'; import { ProxyAccountService } from './ProxyAccountService.js'; import { UtilityService } from './UtilityService.js'; import { FileInfoService } from './FileInfoService.js'; @@ -144,6 +151,8 @@ import type { Provider } from '@nestjs/common'; //#region 文字列ベースでのinjection用(循環参照対応のため) const $LoggerService: Provider = { provide: 'LoggerService', useExisting: LoggerService }; +const $AbuseReportService: Provider = { provide: 'AbuseReportService', useExisting: AbuseReportService }; +const $AbuseReportNotificationService: Provider = { provide: 'AbuseReportNotificationService', useExisting: AbuseReportNotificationService }; const $AccountMoveService: Provider = { provide: 'AccountMoveService', useExisting: AccountMoveService }; const $AccountUpdateService: Provider = { provide: 'AccountUpdateService', useExisting: AccountUpdateService }; const $AiService: Provider = { provide: 'AiService', useExisting: AiService }; @@ -196,7 +205,8 @@ const $UserMutingService: Provider = { provide: 'UserMutingService', useExisting const $UserSuspendService: Provider = { provide: 'UserSuspendService', useExisting: UserSuspendService }; const $UserAuthService: Provider = { provide: 'UserAuthService', useExisting: UserAuthService }; const $VideoProcessingService: Provider = { provide: 'VideoProcessingService', useExisting: VideoProcessingService }; -const $WebhookService: Provider = { provide: 'WebhookService', useExisting: WebhookService }; +const $UserWebhookService: Provider = { provide: 'UserWebhookService', useExisting: UserWebhookService }; +const $SystemWebhookService: Provider = { provide: 'SystemWebhookService', useExisting: SystemWebhookService }; const $UtilityService: Provider = { provide: 'UtilityService', useExisting: UtilityService }; const $FileInfoService: Provider = { provide: 'FileInfoService', useExisting: FileInfoService }; const $SearchService: Provider = { provide: 'SearchService', useExisting: SearchService }; @@ -225,6 +235,7 @@ const $ChartManagementService: Provider = { provide: 'ChartManagementService', u const $AbuseUserReportEntityService: Provider = { provide: 'AbuseUserReportEntityService', useExisting: AbuseUserReportEntityService }; const $AnnouncementEntityService: Provider = { provide: 'AnnouncementEntityService', useExisting: AnnouncementEntityService }; +const $AbuseReportNotificationRecipientEntityService: Provider = { provide: 'AbuseReportNotificationRecipientEntityService', useExisting: AbuseReportNotificationRecipientEntityService }; const $AntennaEntityService: Provider = { provide: 'AntennaEntityService', useExisting: AntennaEntityService }; const $AppEntityService: Provider = { provide: 'AppEntityService', useExisting: AppEntityService }; const $AuthSessionEntityService: Provider = { provide: 'AuthSessionEntityService', useExisting: AuthSessionEntityService }; @@ -258,6 +269,7 @@ const $FlashLikeEntityService: Provider = { provide: 'FlashLikeEntityService', u const $RoleEntityService: Provider = { provide: 'RoleEntityService', useExisting: RoleEntityService }; const $ReversiGameEntityService: Provider = { provide: 'ReversiGameEntityService', useExisting: ReversiGameEntityService }; const $MetaEntityService: Provider = { provide: 'MetaEntityService', useExisting: MetaEntityService }; +const $SystemWebhookEntityService: Provider = { provide: 'SystemWebhookEntityService', useExisting: SystemWebhookEntityService }; const $ApAudienceService: Provider = { provide: 'ApAudienceService', useExisting: ApAudienceService }; const $ApDbResolverService: Provider = { provide: 'ApDbResolverService', useExisting: ApDbResolverService }; @@ -285,6 +297,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting ], providers: [ LoggerService, + AbuseReportService, + AbuseReportNotificationService, AccountMoveService, AccountUpdateService, AiService, @@ -337,7 +351,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting UserSuspendService, UserAuthService, VideoProcessingService, - WebhookService, + UserWebhookService, + SystemWebhookService, UtilityService, FileInfoService, SearchService, @@ -366,6 +381,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting AbuseUserReportEntityService, AnnouncementEntityService, + AbuseReportNotificationRecipientEntityService, AntennaEntityService, AppEntityService, AuthSessionEntityService, @@ -399,6 +415,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting RoleEntityService, ReversiGameEntityService, MetaEntityService, + SystemWebhookEntityService, ApAudienceService, ApDbResolverService, @@ -422,6 +439,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting //#region 文字列ベースでのinjection用(循環参照対応のため) $LoggerService, + $AbuseReportService, + $AbuseReportNotificationService, $AccountMoveService, $AccountUpdateService, $AiService, @@ -474,7 +493,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $UserSuspendService, $UserAuthService, $VideoProcessingService, - $WebhookService, + $UserWebhookService, + $SystemWebhookService, $UtilityService, $FileInfoService, $SearchService, @@ -503,6 +523,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $AbuseUserReportEntityService, $AnnouncementEntityService, + $AbuseReportNotificationRecipientEntityService, $AntennaEntityService, $AppEntityService, $AuthSessionEntityService, @@ -536,6 +557,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $RoleEntityService, $ReversiGameEntityService, $MetaEntityService, + $SystemWebhookEntityService, $ApAudienceService, $ApDbResolverService, @@ -560,6 +582,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting exports: [ QueueModule, LoggerService, + AbuseReportService, + AbuseReportNotificationService, AccountMoveService, AccountUpdateService, AiService, @@ -612,7 +636,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting UserSuspendService, UserAuthService, VideoProcessingService, - WebhookService, + UserWebhookService, + SystemWebhookService, UtilityService, FileInfoService, SearchService, @@ -640,6 +665,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting AbuseUserReportEntityService, AnnouncementEntityService, + AbuseReportNotificationRecipientEntityService, AntennaEntityService, AppEntityService, AuthSessionEntityService, @@ -673,6 +699,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting RoleEntityService, ReversiGameEntityService, MetaEntityService, + SystemWebhookEntityService, ApAudienceService, ApDbResolverService, @@ -696,6 +723,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting //#region 文字列ベースでのinjection用(循環参照対応のため) $LoggerService, + $AbuseReportService, + $AbuseReportNotificationService, $AccountMoveService, $AccountUpdateService, $AiService, @@ -748,7 +777,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $UserSuspendService, $UserAuthService, $VideoProcessingService, - $WebhookService, + $UserWebhookService, + $SystemWebhookService, $UtilityService, $FileInfoService, $SearchService, @@ -776,6 +806,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $AbuseUserReportEntityService, $AnnouncementEntityService, + $AbuseReportNotificationRecipientEntityService, $AntennaEntityService, $AppEntityService, $AuthSessionEntityService, @@ -809,6 +840,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $RoleEntityService, $ReversiGameEntityService, $MetaEntityService, + $SystemWebhookEntityService, $ApAudienceService, $ApDbResolverService, diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts index 08f8f80a6ed9..435dbbae28a9 100644 --- a/packages/backend/src/core/EmailService.ts +++ b/packages/backend/src/core/EmailService.ts @@ -16,6 +16,7 @@ import type { UserProfilesRepository } from '@/models/_.js'; import { LoggerService } from '@/core/LoggerService.js'; import { bindThis } from '@/decorators.js'; import { HttpRequestService } from '@/core/HttpRequestService.js'; +import { QueueService } from '@/core/QueueService.js'; @Injectable() export class EmailService { @@ -32,6 +33,7 @@ export class EmailService { private loggerService: LoggerService, private utilityService: UtilityService, private httpRequestService: HttpRequestService, + private queueService: QueueService, ) { this.logger = this.loggerService.getLogger('email'); } diff --git a/packages/backend/src/core/GlobalEventService.ts b/packages/backend/src/core/GlobalEventService.ts index 90efd63f3a05..a70743bed203 100644 --- a/packages/backend/src/core/GlobalEventService.ts +++ b/packages/backend/src/core/GlobalEventService.ts @@ -18,6 +18,7 @@ import type { MiAbuseUserReport } from '@/models/AbuseUserReport.js'; import type { MiSignin } from '@/models/Signin.js'; import type { MiPage } from '@/models/Page.js'; import type { MiWebhook } from '@/models/Webhook.js'; +import type { MiSystemWebhook } from '@/models/SystemWebhook.js'; import type { MiMeta } from '@/models/Meta.js'; import { MiAvatarDecoration, MiReversiGame, MiRole, MiRoleAssignment } from '@/models/_.js'; import type { Packed } from '@/misc/json-schema.js'; @@ -227,6 +228,9 @@ export interface InternalEventTypes { webhookCreated: MiWebhook; webhookDeleted: MiWebhook; webhookUpdated: MiWebhook; + systemWebhookCreated: MiSystemWebhook; + systemWebhookDeleted: MiSystemWebhook; + systemWebhookUpdated: MiSystemWebhook; antennaCreated: MiAntenna; antennaDeleted: MiAntenna; antennaUpdated: MiAntenna; diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index e5580f36d111..0c9de117d2c3 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -38,7 +38,7 @@ import InstanceChart from '@/core/chart/charts/instance.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { NotificationService } from '@/core/NotificationService.js'; -import { WebhookService } from '@/core/WebhookService.js'; +import { UserWebhookService } from '@/core/UserWebhookService.js'; import { HashtagService } from '@/core/HashtagService.js'; import { AntennaService } from '@/core/AntennaService.js'; import { QueueService } from '@/core/QueueService.js'; @@ -205,7 +205,7 @@ export class NoteCreateService implements OnApplicationShutdown { private federatedInstanceService: FederatedInstanceService, private hashtagService: HashtagService, private antennaService: AntennaService, - private webhookService: WebhookService, + private webhookService: UserWebhookService, private featuredService: FeaturedService, private remoteUserResolveService: RemoteUserResolveService, private apDeliverManagerService: ApDeliverManagerService, @@ -606,7 +606,7 @@ export class NoteCreateService implements OnApplicationShutdown { this.webhookService.getActiveWebhooks().then(webhooks => { webhooks = webhooks.filter(x => x.userId === user.id && x.on.includes('note')); for (const webhook of webhooks) { - this.queueService.webhookDeliver(webhook, 'note', { + this.queueService.userWebhookDeliver(webhook, 'note', { note: noteObj, }); } @@ -633,7 +633,7 @@ export class NoteCreateService implements OnApplicationShutdown { const webhooks = (await this.webhookService.getActiveWebhooks()).filter(x => x.userId === data.reply!.userId && x.on.includes('reply')); for (const webhook of webhooks) { - this.queueService.webhookDeliver(webhook, 'reply', { + this.queueService.userWebhookDeliver(webhook, 'reply', { note: noteObj, }); } @@ -656,7 +656,7 @@ export class NoteCreateService implements OnApplicationShutdown { const webhooks = (await this.webhookService.getActiveWebhooks()).filter(x => x.userId === data.renote!.userId && x.on.includes('renote')); for (const webhook of webhooks) { - this.queueService.webhookDeliver(webhook, 'renote', { + this.queueService.userWebhookDeliver(webhook, 'renote', { note: noteObj, }); } @@ -788,7 +788,7 @@ export class NoteCreateService implements OnApplicationShutdown { const webhooks = (await this.webhookService.getActiveWebhooks()).filter(x => x.userId === u.id && x.on.includes('mention')); for (const webhook of webhooks) { - this.queueService.webhookDeliver(webhook, 'mention', { + this.queueService.userWebhookDeliver(webhook, 'mention', { note: detailPackedNote, }); } diff --git a/packages/backend/src/core/QueueModule.ts b/packages/backend/src/core/QueueModule.ts index 216734e9e5e4..b10b8e589955 100644 --- a/packages/backend/src/core/QueueModule.ts +++ b/packages/backend/src/core/QueueModule.ts @@ -7,10 +7,17 @@ import { Inject, Module, OnApplicationShutdown } from '@nestjs/common'; import * as Bull from 'bullmq'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; -import { QUEUE, baseQueueOptions } from '@/queue/const.js'; +import { baseQueueOptions, QUEUE } from '@/queue/const.js'; import { allSettled } from '@/misc/promise-tracker.js'; +import { + DeliverJobData, + EndedPollNotificationJobData, + InboxJobData, + RelationshipJobData, + UserWebhookDeliverJobData, + SystemWebhookDeliverJobData, +} from '../queue/types.js'; import type { Provider } from '@nestjs/common'; -import type { DeliverJobData, InboxJobData, EndedPollNotificationJobData, WebhookDeliverJobData, RelationshipJobData } from '../queue/types.js'; export type SystemQueue = Bull.Queue>; export type EndedPollNotificationQueue = Bull.Queue; @@ -19,7 +26,8 @@ export type InboxQueue = Bull.Queue; export type DbQueue = Bull.Queue; export type RelationshipQueue = Bull.Queue; export type ObjectStorageQueue = Bull.Queue; -export type WebhookDeliverQueue = Bull.Queue; +export type UserWebhookDeliverQueue = Bull.Queue; +export type SystemWebhookDeliverQueue = Bull.Queue; const $system: Provider = { provide: 'queue:system', @@ -63,9 +71,15 @@ const $objectStorage: Provider = { inject: [DI.config], }; -const $webhookDeliver: Provider = { - provide: 'queue:webhookDeliver', - useFactory: (config: Config) => new Bull.Queue(QUEUE.WEBHOOK_DELIVER, baseQueueOptions(config, QUEUE.WEBHOOK_DELIVER)), +const $userWebhookDeliver: Provider = { + provide: 'queue:userWebhookDeliver', + useFactory: (config: Config) => new Bull.Queue(QUEUE.USER_WEBHOOK_DELIVER, baseQueueOptions(config, QUEUE.USER_WEBHOOK_DELIVER)), + inject: [DI.config], +}; + +const $systemWebhookDeliver: Provider = { + provide: 'queue:systemWebhookDeliver', + useFactory: (config: Config) => new Bull.Queue(QUEUE.SYSTEM_WEBHOOK_DELIVER, baseQueueOptions(config, QUEUE.SYSTEM_WEBHOOK_DELIVER)), inject: [DI.config], }; @@ -80,7 +94,8 @@ const $webhookDeliver: Provider = { $db, $relationship, $objectStorage, - $webhookDeliver, + $userWebhookDeliver, + $systemWebhookDeliver, ], exports: [ $system, @@ -90,7 +105,8 @@ const $webhookDeliver: Provider = { $db, $relationship, $objectStorage, - $webhookDeliver, + $userWebhookDeliver, + $systemWebhookDeliver, ], }) export class QueueModule implements OnApplicationShutdown { @@ -102,7 +118,8 @@ export class QueueModule implements OnApplicationShutdown { @Inject('queue:db') public dbQueue: DbQueue, @Inject('queue:relationship') public relationshipQueue: RelationshipQueue, @Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue, - @Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue, + @Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue, + @Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue, ) {} public async dispose(): Promise { @@ -117,7 +134,8 @@ export class QueueModule implements OnApplicationShutdown { this.dbQueue.close(), this.relationshipQueue.close(), this.objectStorageQueue.close(), - this.webhookDeliverQueue.close(), + this.userWebhookDeliverQueue.close(), + this.systemWebhookDeliverQueue.close(), ]); } diff --git a/packages/backend/src/core/QueueService.ts b/packages/backend/src/core/QueueService.ts index c258a22927d4..80827a500b56 100644 --- a/packages/backend/src/core/QueueService.ts +++ b/packages/backend/src/core/QueueService.ts @@ -8,15 +8,33 @@ import { Inject, Injectable } from '@nestjs/common'; import type { IActivity } from '@/core/activitypub/type.js'; import type { MiDriveFile } from '@/models/DriveFile.js'; import type { MiWebhook, webhookEventTypes } from '@/models/Webhook.js'; +import type { MiSystemWebhook, SystemWebhookEventType } from '@/models/SystemWebhook.js'; import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js'; -import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, RelationshipQueue, SystemQueue, WebhookDeliverQueue } from './QueueModule.js'; -import type { DbJobData, DeliverJobData, RelationshipJobData, ThinUser } from '../queue/types.js'; +import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js'; +import type { + DbJobData, + DeliverJobData, + RelationshipJobData, + SystemWebhookDeliverJobData, + ThinUser, + UserWebhookDeliverJobData, +} from '../queue/types.js'; +import type { + DbQueue, + DeliverQueue, + EndedPollNotificationQueue, + InboxQueue, + ObjectStorageQueue, + RelationshipQueue, + SystemQueue, + UserWebhookDeliverQueue, + SystemWebhookDeliverQueue, +} from './QueueModule.js'; import type httpSignature from '@peertube/http-signature'; import type * as Bull from 'bullmq'; -import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js'; @Injectable() export class QueueService { @@ -31,7 +49,8 @@ export class QueueService { @Inject('queue:db') public dbQueue: DbQueue, @Inject('queue:relationship') public relationshipQueue: RelationshipQueue, @Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue, - @Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue, + @Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue, + @Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue, ) { this.systemQueue.add('tickCharts', { }, { @@ -431,9 +450,13 @@ export class QueueService { }); } + /** + * @see UserWebhookDeliverJobData + * @see WebhookDeliverProcessorService + */ @bindThis - public webhookDeliver(webhook: MiWebhook, type: typeof webhookEventTypes[number], content: unknown) { - const data = { + public userWebhookDeliver(webhook: MiWebhook, type: typeof webhookEventTypes[number], content: unknown) { + const data: UserWebhookDeliverJobData = { type, content, webhookId: webhook.id, @@ -444,7 +467,33 @@ export class QueueService { eventId: randomUUID(), }; - return this.webhookDeliverQueue.add(webhook.id, data, { + return this.userWebhookDeliverQueue.add(webhook.id, data, { + attempts: 4, + backoff: { + type: 'custom', + }, + removeOnComplete: true, + removeOnFail: true, + }); + } + + /** + * @see SystemWebhookDeliverJobData + * @see WebhookDeliverProcessorService + */ + @bindThis + public systemWebhookDeliver(webhook: MiSystemWebhook, type: SystemWebhookEventType, content: unknown) { + const data: SystemWebhookDeliverJobData = { + type, + content, + webhookId: webhook.id, + to: webhook.url, + secret: webhook.secret, + createdAt: Date.now(), + eventId: randomUUID(), + }; + + return this.systemWebhookDeliverQueue.add(webhook.id, data, { attempts: 4, backoff: { type: 'custom', diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index d6eea702970b..e2ebecb99f4f 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -410,14 +410,32 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { } @bindThis - public async getModeratorIds(includeAdmins = true): Promise { + public async getModeratorIds(includeAdmins = true, excludeExpire = false): Promise { const roles = await this.rolesCache.fetch(() => this.rolesRepository.findBy({})); - const moderatorRoles = includeAdmins ? roles.filter(r => r.isModerator || r.isAdministrator) : roles.filter(r => r.isModerator); - const assigns = moderatorRoles.length > 0 ? await this.roleAssignmentsRepository.findBy({ - roleId: In(moderatorRoles.map(r => r.id)), - }) : []; + const moderatorRoles = includeAdmins + ? roles.filter(r => r.isModerator || r.isAdministrator) + : roles.filter(r => r.isModerator); + // TODO: isRootなアカウントも含める - return assigns.map(a => a.userId); + const assigns = moderatorRoles.length > 0 + ? await this.roleAssignmentsRepository.findBy({ roleId: In(moderatorRoles.map(r => r.id)) }) + : []; + + const now = Date.now(); + const result = [ + // Setを経由して重複を除去(ユーザIDは重複する可能性があるので) + ...new Set( + assigns + .filter(it => + (excludeExpire) + ? (it.expiresAt == null || it.expiresAt.getTime() > now) + : true, + ) + .map(a => a.userId), + ), + ]; + + return result.sort((x, y) => x.localeCompare(y)); } @bindThis diff --git a/packages/backend/src/core/SystemWebhookService.ts b/packages/backend/src/core/SystemWebhookService.ts new file mode 100644 index 000000000000..bc6851f788da --- /dev/null +++ b/packages/backend/src/core/SystemWebhookService.ts @@ -0,0 +1,233 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import * as Redis from 'ioredis'; +import type { MiUser, SystemWebhooksRepository } from '@/models/_.js'; +import { DI } from '@/di-symbols.js'; +import { bindThis } from '@/decorators.js'; +import { GlobalEvents, GlobalEventService } from '@/core/GlobalEventService.js'; +import { MiSystemWebhook, type SystemWebhookEventType } from '@/models/SystemWebhook.js'; +import { IdService } from '@/core/IdService.js'; +import { QueueService } from '@/core/QueueService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { LoggerService } from '@/core/LoggerService.js'; +import Logger from '@/logger.js'; +import type { OnApplicationShutdown } from '@nestjs/common'; + +@Injectable() +export class SystemWebhookService implements OnApplicationShutdown { + private logger: Logger; + private activeSystemWebhooksFetched = false; + private activeSystemWebhooks: MiSystemWebhook[] = []; + + constructor( + @Inject(DI.redisForSub) + private redisForSub: Redis.Redis, + @Inject(DI.systemWebhooksRepository) + private systemWebhooksRepository: SystemWebhooksRepository, + private idService: IdService, + private queueService: QueueService, + private moderationLogService: ModerationLogService, + private loggerService: LoggerService, + private globalEventService: GlobalEventService, + ) { + this.redisForSub.on('message', this.onMessage); + this.logger = this.loggerService.getLogger('webhook'); + } + + @bindThis + public async fetchActiveSystemWebhooks() { + if (!this.activeSystemWebhooksFetched) { + this.activeSystemWebhooks = await this.systemWebhooksRepository.findBy({ + isActive: true, + }); + this.activeSystemWebhooksFetched = true; + } + + return this.activeSystemWebhooks; + } + + /** + * SystemWebhook の一覧を取得する. + */ + @bindThis + public async fetchSystemWebhooks(params?: { + ids?: MiSystemWebhook['id'][]; + isActive?: MiSystemWebhook['isActive']; + on?: MiSystemWebhook['on']; + }): Promise { + const query = this.systemWebhooksRepository.createQueryBuilder('systemWebhook'); + if (params) { + if (params.ids && params.ids.length > 0) { + query.andWhere('systemWebhook.id IN (:...ids)', { ids: params.ids }); + } + if (params.isActive !== undefined) { + query.andWhere('systemWebhook.isActive = :isActive', { isActive: params.isActive }); + } + if (params.on && params.on.length > 0) { + query.andWhere(':on <@ systemWebhook.on', { on: params.on }); + } + } + + return query.getMany(); + } + + /** + * SystemWebhook を作成する. + */ + @bindThis + public async createSystemWebhook( + params: { + isActive: MiSystemWebhook['isActive']; + name: MiSystemWebhook['name']; + on: MiSystemWebhook['on']; + url: MiSystemWebhook['url']; + secret: MiSystemWebhook['secret']; + }, + updater: MiUser, + ): Promise { + const id = this.idService.gen(); + await this.systemWebhooksRepository.insert({ + ...params, + id, + }); + + const webhook = await this.systemWebhooksRepository.findOneByOrFail({ id }); + this.globalEventService.publishInternalEvent('systemWebhookCreated', webhook); + this.moderationLogService + .log(updater, 'createSystemWebhook', { + systemWebhookId: webhook.id, + webhook: webhook, + }) + .then(); + + return webhook; + } + + /** + * SystemWebhook を更新する. + */ + @bindThis + public async updateSystemWebhook( + params: { + id: MiSystemWebhook['id']; + isActive: MiSystemWebhook['isActive']; + name: MiSystemWebhook['name']; + on: MiSystemWebhook['on']; + url: MiSystemWebhook['url']; + secret: MiSystemWebhook['secret']; + }, + updater: MiUser, + ): Promise { + const beforeEntity = await this.systemWebhooksRepository.findOneByOrFail({ id: params.id }); + await this.systemWebhooksRepository.update(beforeEntity.id, { + updatedAt: new Date(), + isActive: params.isActive, + name: params.name, + on: params.on, + url: params.url, + secret: params.secret, + }); + + const afterEntity = await this.systemWebhooksRepository.findOneByOrFail({ id: beforeEntity.id }); + this.globalEventService.publishInternalEvent('systemWebhookUpdated', afterEntity); + this.moderationLogService + .log(updater, 'updateSystemWebhook', { + systemWebhookId: beforeEntity.id, + before: beforeEntity, + after: afterEntity, + }) + .then(); + + return afterEntity; + } + + /** + * SystemWebhook を削除する. + */ + @bindThis + public async deleteSystemWebhook(id: MiSystemWebhook['id'], updater: MiUser) { + const webhook = await this.systemWebhooksRepository.findOneByOrFail({ id }); + await this.systemWebhooksRepository.delete(id); + + this.globalEventService.publishInternalEvent('systemWebhookDeleted', webhook); + this.moderationLogService + .log(updater, 'deleteSystemWebhook', { + systemWebhookId: webhook.id, + webhook, + }) + .then(); + } + + /** + * SystemWebhook をWebhook配送キューに追加する + * @see QueueService.systemWebhookDeliver + */ + @bindThis + public async enqueueSystemWebhook(webhook: MiSystemWebhook | MiSystemWebhook['id'], type: SystemWebhookEventType, content: unknown) { + const webhookEntity = typeof webhook === 'string' + ? (await this.fetchActiveSystemWebhooks()).find(a => a.id === webhook) + : webhook; + if (!webhookEntity || !webhookEntity.isActive) { + this.logger.info(`Webhook is not active or not found : ${webhook}`); + return; + } + + if (!webhookEntity.on.includes(type)) { + this.logger.info(`Webhook ${webhookEntity.id} is not listening to ${type}`); + return; + } + + return this.queueService.systemWebhookDeliver(webhookEntity, type, content); + } + + @bindThis + private async onMessage(_: string, data: string): Promise { + const obj = JSON.parse(data); + if (obj.channel !== 'internal') { + return; + } + + const { type, body } = obj.message as GlobalEvents['internal']['payload']; + switch (type) { + case 'systemWebhookCreated': { + if (body.isActive) { + this.activeSystemWebhooks.push(MiSystemWebhook.deserialize(body)); + } + break; + } + case 'systemWebhookUpdated': { + if (body.isActive) { + const i = this.activeSystemWebhooks.findIndex(a => a.id === body.id); + if (i > -1) { + this.activeSystemWebhooks[i] = MiSystemWebhook.deserialize(body); + } else { + this.activeSystemWebhooks.push(MiSystemWebhook.deserialize(body)); + } + } else { + this.activeSystemWebhooks = this.activeSystemWebhooks.filter(a => a.id !== body.id); + } + break; + } + case 'systemWebhookDeleted': { + this.activeSystemWebhooks = this.activeSystemWebhooks.filter(a => a.id !== body.id); + break; + } + default: + break; + } + } + + @bindThis + public dispose(): void { + this.redisForSub.off('message', this.onMessage); + } + + @bindThis + public onApplicationShutdown(signal?: string | undefined): void { + this.dispose(); + } +} diff --git a/packages/backend/src/core/UserBlockingService.ts b/packages/backend/src/core/UserBlockingService.ts index 96f389b54c55..2f1310b8efe7 100644 --- a/packages/backend/src/core/UserBlockingService.ts +++ b/packages/backend/src/core/UserBlockingService.ts @@ -16,7 +16,7 @@ import Logger from '@/logger.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; import { LoggerService } from '@/core/LoggerService.js'; -import { WebhookService } from '@/core/WebhookService.js'; +import { UserWebhookService } from '@/core/UserWebhookService.js'; import { bindThis } from '@/decorators.js'; import { CacheService } from '@/core/CacheService.js'; import { UserFollowingService } from '@/core/UserFollowingService.js'; @@ -46,7 +46,7 @@ export class UserBlockingService implements OnModuleInit { private idService: IdService, private queueService: QueueService, private globalEventService: GlobalEventService, - private webhookService: WebhookService, + private webhookService: UserWebhookService, private apRendererService: ApRendererService, private loggerService: LoggerService, ) { @@ -121,7 +121,7 @@ export class UserBlockingService implements OnModuleInit { const webhooks = (await this.webhookService.getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('unfollow')); for (const webhook of webhooks) { - this.queueService.webhookDeliver(webhook, 'unfollow', { + this.queueService.userWebhookDeliver(webhook, 'unfollow', { user: packed, }); } diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts index 406ea040316a..267a6a3f1b78 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -16,7 +16,7 @@ import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js import type { Packed } from '@/misc/json-schema.js'; import InstanceChart from '@/core/chart/charts/instance.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; -import { WebhookService } from '@/core/WebhookService.js'; +import { UserWebhookService } from '@/core/UserWebhookService.js'; import { NotificationService } from '@/core/NotificationService.js'; import { DI } from '@/di-symbols.js'; import type { FollowingsRepository, FollowRequestsRepository, InstancesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js'; @@ -82,7 +82,7 @@ export class UserFollowingService implements OnModuleInit { private metaService: MetaService, private notificationService: NotificationService, private federatedInstanceService: FederatedInstanceService, - private webhookService: WebhookService, + private webhookService: UserWebhookService, private apRendererService: ApRendererService, private accountMoveService: AccountMoveService, private fanoutTimelineService: FanoutTimelineService, @@ -331,7 +331,7 @@ export class UserFollowingService implements OnModuleInit { const webhooks = (await this.webhookService.getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('follow')); for (const webhook of webhooks) { - this.queueService.webhookDeliver(webhook, 'follow', { + this.queueService.userWebhookDeliver(webhook, 'follow', { user: packed, }); } @@ -345,7 +345,7 @@ export class UserFollowingService implements OnModuleInit { const webhooks = (await this.webhookService.getActiveWebhooks()).filter(x => x.userId === followee.id && x.on.includes('followed')); for (const webhook of webhooks) { - this.queueService.webhookDeliver(webhook, 'followed', { + this.queueService.userWebhookDeliver(webhook, 'followed', { user: packed, }); } @@ -398,7 +398,7 @@ export class UserFollowingService implements OnModuleInit { const webhooks = (await this.webhookService.getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('unfollow')); for (const webhook of webhooks) { - this.queueService.webhookDeliver(webhook, 'unfollow', { + this.queueService.userWebhookDeliver(webhook, 'unfollow', { user: packed, }); } @@ -740,7 +740,7 @@ export class UserFollowingService implements OnModuleInit { const webhooks = (await this.webhookService.getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('unfollow')); for (const webhook of webhooks) { - this.queueService.webhookDeliver(webhook, 'unfollow', { + this.queueService.userWebhookDeliver(webhook, 'unfollow', { user: packedFollowee, }); } diff --git a/packages/backend/src/core/UserWebhookService.ts b/packages/backend/src/core/UserWebhookService.ts new file mode 100644 index 000000000000..e96bfeea9581 --- /dev/null +++ b/packages/backend/src/core/UserWebhookService.ts @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import * as Redis from 'ioredis'; +import type { WebhooksRepository } from '@/models/_.js'; +import type { MiWebhook } from '@/models/Webhook.js'; +import { DI } from '@/di-symbols.js'; +import { bindThis } from '@/decorators.js'; +import { GlobalEvents } from '@/core/GlobalEventService.js'; +import type { OnApplicationShutdown } from '@nestjs/common'; + +@Injectable() +export class UserWebhookService implements OnApplicationShutdown { + private activeWebhooksFetched = false; + private activeWebhooks: MiWebhook[] = []; + + constructor( + @Inject(DI.redisForSub) + private redisForSub: Redis.Redis, + @Inject(DI.webhooksRepository) + private webhooksRepository: WebhooksRepository, + ) { + this.redisForSub.on('message', this.onMessage); + } + + @bindThis + public async getActiveWebhooks() { + if (!this.activeWebhooksFetched) { + this.activeWebhooks = await this.webhooksRepository.findBy({ + active: true, + }); + this.activeWebhooksFetched = true; + } + + return this.activeWebhooks; + } + + @bindThis + private async onMessage(_: string, data: string): Promise { + const obj = JSON.parse(data); + if (obj.channel !== 'internal') { + return; + } + + const { type, body } = obj.message as GlobalEvents['internal']['payload']; + switch (type) { + case 'webhookCreated': { + if (body.active) { + this.activeWebhooks.push({ // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい + ...body, + latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null, + user: null, // joinなカラムは通常取ってこないので + }); + } + break; + } + case 'webhookUpdated': { + if (body.active) { + const i = this.activeWebhooks.findIndex(a => a.id === body.id); + if (i > -1) { + this.activeWebhooks[i] = { // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい + ...body, + latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null, + user: null, // joinなカラムは通常取ってこないので + }; + } else { + this.activeWebhooks.push({ // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい + ...body, + latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null, + user: null, // joinなカラムは通常取ってこないので + }); + } + } else { + this.activeWebhooks = this.activeWebhooks.filter(a => a.id !== body.id); + } + break; + } + case 'webhookDeleted': { + this.activeWebhooks = this.activeWebhooks.filter(a => a.id !== body.id); + break; + } + default: + break; + } + } + + @bindThis + public dispose(): void { + this.redisForSub.off('message', this.onMessage); + } + + @bindThis + public onApplicationShutdown(signal?: string | undefined): void { + this.dispose(); + } +} diff --git a/packages/backend/src/core/WebhookService.ts b/packages/backend/src/core/WebhookService.ts deleted file mode 100644 index 6be34977b064..000000000000 --- a/packages/backend/src/core/WebhookService.ts +++ /dev/null @@ -1,97 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Inject, Injectable } from '@nestjs/common'; -import * as Redis from 'ioredis'; -import type { WebhooksRepository } from '@/models/_.js'; -import type { MiWebhook } from '@/models/Webhook.js'; -import { DI } from '@/di-symbols.js'; -import { bindThis } from '@/decorators.js'; -import type { GlobalEvents } from '@/core/GlobalEventService.js'; -import type { OnApplicationShutdown } from '@nestjs/common'; - -@Injectable() -export class WebhookService implements OnApplicationShutdown { - private webhooksFetched = false; - private webhooks: MiWebhook[] = []; - - constructor( - @Inject(DI.redisForSub) - private redisForSub: Redis.Redis, - - @Inject(DI.webhooksRepository) - private webhooksRepository: WebhooksRepository, - ) { - //this.onMessage = this.onMessage.bind(this); - this.redisForSub.on('message', this.onMessage); - } - - @bindThis - public async getActiveWebhooks() { - if (!this.webhooksFetched) { - this.webhooks = await this.webhooksRepository.findBy({ - active: true, - }); - this.webhooksFetched = true; - } - - return this.webhooks; - } - - @bindThis - private async onMessage(_: string, data: string): Promise { - const obj = JSON.parse(data); - - if (obj.channel === 'internal') { - const { type, body } = obj.message as GlobalEvents['internal']['payload']; - switch (type) { - case 'webhookCreated': - if (body.active) { - this.webhooks.push({ // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい - ...body, - latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null, - user: null, // joinなカラムは通常取ってこないので - }); - } - break; - case 'webhookUpdated': - if (body.active) { - const i = this.webhooks.findIndex(a => a.id === body.id); - if (i > -1) { - this.webhooks[i] = { // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい - ...body, - latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null, - user: null, // joinなカラムは通常取ってこないので - }; - } else { - this.webhooks.push({ // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい - ...body, - latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null, - user: null, // joinなカラムは通常取ってこないので - }); - } - } else { - this.webhooks = this.webhooks.filter(a => a.id !== body.id); - } - break; - case 'webhookDeleted': - this.webhooks = this.webhooks.filter(a => a.id !== body.id); - break; - default: - break; - } - } - } - - @bindThis - public dispose(): void { - this.redisForSub.off('message', this.onMessage); - } - - @bindThis - public onApplicationShutdown(signal?: string | undefined): void { - this.dispose(); - } -} diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index d0d206760cb9..de3178b4827f 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -29,6 +29,7 @@ import { bindThis } from '@/decorators.js'; import type { MiRemoteUser } from '@/models/User.js'; import { isNotNull } from '@/misc/is-not-null.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; +import { AbuseReportService } from '@/core/AbuseReportService.js'; import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js'; import { ApNoteService } from './models/ApNoteService.js'; import { ApLoggerService } from './ApLoggerService.js'; @@ -57,9 +58,6 @@ export class ApInboxService { @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, - @Inject(DI.abuseUserReportsRepository) - private abuseUserReportsRepository: AbuseUserReportsRepository, - @Inject(DI.followRequestsRepository) private followRequestsRepository: FollowRequestsRepository, @@ -68,6 +66,7 @@ export class ApInboxService { private utilityService: UtilityService, private idService: IdService, private metaService: MetaService, + private abuseReportService: AbuseReportService, private userFollowingService: UserFollowingService, private apAudienceService: ApAudienceService, private reactionService: ReactionService, @@ -545,14 +544,13 @@ export class ApInboxService { }); if (users.length < 1) return 'skip'; - await this.abuseUserReportsRepository.insert({ - id: this.idService.gen(), + await this.abuseReportService.report([{ targetUserId: users[0].id, targetUserHost: users[0].host, reporterId: actor.id, reporterHost: actor.host, comment: `${activity.content}\n${JSON.stringify(uris, null, 2)}`, - }); + }]); return 'ok'; } diff --git a/packages/backend/src/core/entities/AbuseReportNotificationRecipientEntityService.ts b/packages/backend/src/core/entities/AbuseReportNotificationRecipientEntityService.ts new file mode 100644 index 000000000000..6819afafd9f5 --- /dev/null +++ b/packages/backend/src/core/entities/AbuseReportNotificationRecipientEntityService.ts @@ -0,0 +1,88 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { In } from 'typeorm'; +import { DI } from '@/di-symbols.js'; +import type { AbuseReportNotificationRecipientRepository, MiAbuseReportNotificationRecipient } from '@/models/_.js'; +import { bindThis } from '@/decorators.js'; +import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { Packed } from '@/misc/json-schema.js'; +import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js'; +import { isNotNull } from '@/misc/is-not-null.js'; + +@Injectable() +export class AbuseReportNotificationRecipientEntityService { + constructor( + @Inject(DI.abuseReportNotificationRecipientRepository) + private abuseReportNotificationRecipientRepository: AbuseReportNotificationRecipientRepository, + private userEntityService: UserEntityService, + private systemWebhookEntityService: SystemWebhookEntityService, + ) { + } + + @bindThis + public async pack( + src: MiAbuseReportNotificationRecipient['id'] | MiAbuseReportNotificationRecipient, + opts?: { + users: Map>, + webhooks: Map>, + }, + ): Promise> { + const recipient = typeof src === 'object' + ? src + : await this.abuseReportNotificationRecipientRepository.findOneByOrFail({ id: src }); + const user = recipient.userId + ? (opts?.users.get(recipient.userId) ?? await this.userEntityService.pack<'UserLite'>(recipient.userId)) + : undefined; + const webhook = recipient.systemWebhookId + ? (opts?.webhooks.get(recipient.systemWebhookId) ?? await this.systemWebhookEntityService.pack(recipient.systemWebhookId)) + : undefined; + + return { + id: recipient.id, + isActive: recipient.isActive, + updatedAt: recipient.updatedAt.toISOString(), + name: recipient.name, + method: recipient.method, + userId: recipient.userId ?? undefined, + user: user, + systemWebhookId: recipient.systemWebhookId ?? undefined, + systemWebhook: webhook, + }; + } + + @bindThis + public async packMany( + src: MiAbuseReportNotificationRecipient['id'][] | MiAbuseReportNotificationRecipient[], + ): Promise[]> { + const objs = src.filter((it): it is MiAbuseReportNotificationRecipient => typeof it === 'object'); + const ids = src.filter((it): it is MiAbuseReportNotificationRecipient['id'] => typeof it === 'string'); + if (ids.length > 0) { + objs.push( + ...await this.abuseReportNotificationRecipientRepository.findBy({ id: In(ids) }), + ); + } + + const userIds = objs.map(it => it.userId).filter(isNotNull); + const users: Map> = (userIds.length > 0) + ? await this.userEntityService.packMany(userIds) + .then(it => new Map(it.map(it => [it.id, it]))) + : new Map(); + + const systemWebhookIds = objs.map(it => it.systemWebhookId).filter(isNotNull); + const systemWebhooks: Map> = (systemWebhookIds.length > 0) + ? await this.systemWebhookEntityService.packMany(systemWebhookIds) + .then(it => new Map(it.map(it => [it.id, it]))) + : new Map(); + + return Promise + .all( + objs.map(it => this.pack(it, { users: users, webhooks: systemWebhooks })), + ) + .then(it => it.sort((a, b) => a.id.localeCompare(b.id))); + } +} + diff --git a/packages/backend/src/core/entities/SystemWebhookEntityService.ts b/packages/backend/src/core/entities/SystemWebhookEntityService.ts new file mode 100644 index 000000000000..e18734091c62 --- /dev/null +++ b/packages/backend/src/core/entities/SystemWebhookEntityService.ts @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { In } from 'typeorm'; +import { DI } from '@/di-symbols.js'; +import type { MiSystemWebhook, SystemWebhooksRepository } from '@/models/_.js'; +import { bindThis } from '@/decorators.js'; +import { Packed } from '@/misc/json-schema.js'; + +@Injectable() +export class SystemWebhookEntityService { + constructor( + @Inject(DI.systemWebhooksRepository) + private systemWebhooksRepository: SystemWebhooksRepository, + ) { + } + + @bindThis + public async pack( + src: MiSystemWebhook['id'] | MiSystemWebhook, + opts?: { + webhooks: Map + }, + ): Promise> { + const webhook = typeof src === 'object' + ? src + : opts?.webhooks.get(src) ?? await this.systemWebhooksRepository.findOneByOrFail({ id: src }); + + return { + id: webhook.id, + isActive: webhook.isActive, + updatedAt: webhook.updatedAt.toISOString(), + latestSentAt: webhook.latestSentAt?.toISOString() ?? null, + latestStatus: webhook.latestStatus, + name: webhook.name, + on: webhook.on, + url: webhook.url, + secret: webhook.secret, + }; + } + + @bindThis + public async packMany(src: MiSystemWebhook['id'][] | MiSystemWebhook[]): Promise[]> { + if (src.length === 0) { + return []; + } + + const webhooks = Array.of(); + webhooks.push( + ...src.filter((it): it is MiSystemWebhook => typeof it === 'object'), + ); + + const ids = src.filter((it): it is MiSystemWebhook['id'] => typeof it === 'string'); + if (ids.length > 0) { + webhooks.push( + ...await this.systemWebhooksRepository.findBy({ id: In(ids) }), + ); + } + + return Promise + .all( + webhooks.map(x => + this.pack(x, { + webhooks: new Map(webhooks.map(x => [x.id, x])), + }), + ), + ) + .then(it => it.sort((a, b) => a.id.localeCompare(b.id))); + } +} + diff --git a/packages/backend/src/di-symbols.ts b/packages/backend/src/di-symbols.ts index 919f4794a325..271082b4ff35 100644 --- a/packages/backend/src/di-symbols.ts +++ b/packages/backend/src/di-symbols.ts @@ -49,6 +49,7 @@ export const DI = { swSubscriptionsRepository: Symbol('swSubscriptionsRepository'), hashtagsRepository: Symbol('hashtagsRepository'), abuseUserReportsRepository: Symbol('abuseUserReportsRepository'), + abuseReportNotificationRecipientRepository: Symbol('abuseReportNotificationRecipientRepository'), registrationTicketsRepository: Symbol('registrationTicketsRepository'), authSessionsRepository: Symbol('authSessionsRepository'), accessTokensRepository: Symbol('accessTokensRepository'), @@ -70,6 +71,7 @@ export const DI = { channelFavoritesRepository: Symbol('channelFavoritesRepository'), registryItemsRepository: Symbol('registryItemsRepository'), webhooksRepository: Symbol('webhooksRepository'), + systemWebhooksRepository: Symbol('systemWebhooksRepository'), adsRepository: Symbol('adsRepository'), passwordResetRequestsRepository: Symbol('passwordResetRequestsRepository'), retentionAggregationsRepository: Symbol('retentionAggregationsRepository'), diff --git a/packages/backend/src/misc/json-schema.ts b/packages/backend/src/misc/json-schema.ts index 41e5bfe9e4ad..a721b8663c3c 100644 --- a/packages/backend/src/misc/json-schema.ts +++ b/packages/backend/src/misc/json-schema.ts @@ -4,12 +4,12 @@ */ import { - packedUserLiteSchema, - packedUserDetailedNotMeOnlySchema, packedMeDetailedOnlySchema, - packedUserDetailedNotMeSchema, packedMeDetailedSchema, + packedUserDetailedNotMeOnlySchema, + packedUserDetailedNotMeSchema, packedUserDetailedSchema, + packedUserLiteSchema, packedUserSchema, } from '@/models/json-schema/user.js'; import { packedNoteSchema } from '@/models/json-schema/note.js'; @@ -25,7 +25,7 @@ import { packedBlockingSchema } from '@/models/json-schema/blocking.js'; import { packedNoteReactionSchema } from '@/models/json-schema/note-reaction.js'; import { packedHashtagSchema } from '@/models/json-schema/hashtag.js'; import { packedInviteCodeSchema } from '@/models/json-schema/invite-code.js'; -import { packedPageSchema, packedPageBlockSchema } from '@/models/json-schema/page.js'; +import { packedPageBlockSchema, packedPageSchema } from '@/models/json-schema/page.js'; import { packedNoteFavoriteSchema } from '@/models/json-schema/note-favorite.js'; import { packedChannelSchema } from '@/models/json-schema/channel.js'; import { packedAntennaSchema } from '@/models/json-schema/antenna.js'; @@ -38,25 +38,27 @@ import { packedFlashSchema } from '@/models/json-schema/flash.js'; import { packedAnnouncementSchema } from '@/models/json-schema/announcement.js'; import { packedSigninSchema } from '@/models/json-schema/signin.js'; import { - packedRoleLiteSchema, - packedRoleSchema, - packedRolePoliciesSchema, + packedRoleCondFormulaFollowersOrFollowingOrNotesSchema, packedRoleCondFormulaLogicsSchema, - packedRoleCondFormulaValueNot, - packedRoleCondFormulaValueIsLocalOrRemoteSchema, packedRoleCondFormulaValueAssignedRoleSchema, packedRoleCondFormulaValueCreatedSchema, - packedRoleCondFormulaFollowersOrFollowingOrNotesSchema, + packedRoleCondFormulaValueIsLocalOrRemoteSchema, + packedRoleCondFormulaValueNot, packedRoleCondFormulaValueSchema, packedRoleCondFormulaValueUserSettingBooleanSchema, + packedRoleLiteSchema, + packedRolePoliciesSchema, + packedRoleSchema, } from '@/models/json-schema/role.js'; import { packedAdSchema } from '@/models/json-schema/ad.js'; -import { packedReversiGameLiteSchema, packedReversiGameDetailedSchema } from '@/models/json-schema/reversi-game.js'; +import { packedReversiGameDetailedSchema, packedReversiGameLiteSchema } from '@/models/json-schema/reversi-game.js'; import { - packedMetaLiteSchema, packedMetaDetailedOnlySchema, packedMetaDetailedSchema, + packedMetaLiteSchema, } from '@/models/json-schema/meta.js'; +import { packedSystemWebhookSchema } from '@/models/json-schema/system-webhook.js'; +import { packedAbuseReportNotificationRecipientSchema } from '@/models/json-schema/abuse-report-notification-recipient.js'; export const refs = { UserLite: packedUserLiteSchema, @@ -111,6 +113,8 @@ export const refs = { MetaLite: packedMetaLiteSchema, MetaDetailedOnly: packedMetaDetailedOnlySchema, MetaDetailed: packedMetaDetailedSchema, + SystemWebhook: packedSystemWebhookSchema, + AbuseReportNotificationRecipient: packedAbuseReportNotificationRecipientSchema, }; export type Packed = SchemaType; diff --git a/packages/backend/src/models/AbuseReportNotificationRecipient.ts b/packages/backend/src/models/AbuseReportNotificationRecipient.ts new file mode 100644 index 000000000000..fbff880afca4 --- /dev/null +++ b/packages/backend/src/models/AbuseReportNotificationRecipient.ts @@ -0,0 +1,100 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Column, Entity, Index, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm'; +import { MiSystemWebhook } from '@/models/SystemWebhook.js'; +import { MiUserProfile } from '@/models/UserProfile.js'; +import { id } from './util/id.js'; +import { MiUser } from './User.js'; + +/** + * 通報受信時に通知を送信する方法. + */ +export type RecipientMethod = 'email' | 'webhook'; + +@Entity('abuse_report_notification_recipient') +export class MiAbuseReportNotificationRecipient { + @PrimaryColumn(id()) + public id: string; + + /** + * 有効かどうか. + */ + @Index() + @Column('boolean', { + default: true, + }) + public isActive: boolean; + + /** + * 更新日時. + */ + @Column('timestamp with time zone', { + default: () => 'CURRENT_TIMESTAMP', + }) + public updatedAt: Date; + + /** + * 通知設定名. + */ + @Column('varchar', { + length: 255, + }) + public name: string; + + /** + * 通知方法. + */ + @Index() + @Column('varchar', { + length: 64, + }) + public method: RecipientMethod; + + /** + * 通知先のユーザID. + */ + @Index() + @Column({ + ...id(), + nullable: true, + }) + public userId: MiUser['id'] | null; + + /** + * 通知先のユーザ. + */ + @ManyToOne(type => MiUser, { + onDelete: 'CASCADE', + }) + @JoinColumn({ name: 'userId', referencedColumnName: 'id', foreignKeyConstraintName: 'FK_abuse_report_notification_recipient_userId1' }) + public user: MiUser | null; + + /** + * 通知先のユーザプロフィール. + */ + @ManyToOne(type => MiUserProfile, {}) + @JoinColumn({ name: 'userId', referencedColumnName: 'userId', foreignKeyConstraintName: 'FK_abuse_report_notification_recipient_userId2' }) + public userProfile: MiUserProfile | null; + + /** + * 通知先のシステムWebhookId. + */ + @Index() + @Column({ + ...id(), + nullable: true, + }) + public systemWebhookId: string | null; + + /** + * 通知先のシステムWebhook. + */ + @ManyToOne(type => MiSystemWebhook, { + onDelete: 'CASCADE', + }) + @JoinColumn() + public systemWebhook: MiSystemWebhook | null; +} diff --git a/packages/backend/src/models/RepositoryModule.ts b/packages/backend/src/models/RepositoryModule.ts index d3062d6b36f8..ea0f88babaa7 100644 --- a/packages/backend/src/models/RepositoryModule.ts +++ b/packages/backend/src/models/RepositoryModule.ts @@ -3,11 +3,83 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import type { Provider } from '@nestjs/common'; import { Module } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; -import { MiRepository, MiAbuseUserReport, MiAccessToken, MiAd, MiAnnouncement, MiAnnouncementRead, MiAntenna, MiApp, MiAuthSession, MiAvatarDecoration, MiBlocking, MiChannel, MiChannelFavorite, MiChannelFollowing, MiClip, MiClipFavorite, MiClipNote, MiDriveFile, MiDriveFolder, MiEmoji, MiFlash, MiFlashLike, MiFollowRequest, MiFollowing, MiGalleryLike, MiGalleryPost, MiHashtag, MiInstance, MiMeta, MiModerationLog, MiMuting, MiNote, MiNoteFavorite, MiNoteReaction, MiNoteThreadMuting, MiNoteUnread, MiPage, MiPageLike, MiPasswordResetRequest, MiPoll, MiPollVote, MiPromoNote, MiPromoRead, MiRegistrationTicket, MiRegistryItem, MiRelay, MiRenoteMuting, MiRetentionAggregation, MiRole, MiRoleAssignment, MiSignin, MiSwSubscription, MiUsedUsername, MiUser, MiUserIp, MiUserKeypair, MiUserList, MiUserListFavorite, MiUserListMembership, MiUserMemo, MiUserNotePining, MiUserPending, MiUserProfile, MiUserPublickey, MiUserSecurityKey, MiWebhook, MiBubbleGameRecord, MiReversiGame, miRepository } from './_.js'; +import { + MiAbuseReportNotificationRecipient, + MiAbuseUserReport, + MiAccessToken, + MiAd, + MiAnnouncement, + MiAnnouncementRead, + MiAntenna, + MiApp, + MiAuthSession, + MiAvatarDecoration, + MiBlocking, + MiBubbleGameRecord, + MiChannel, + MiChannelFavorite, + MiChannelFollowing, + MiClip, + MiClipFavorite, + MiClipNote, + MiDriveFile, + MiDriveFolder, + MiEmoji, + MiFlash, + MiFlashLike, + MiFollowing, + MiFollowRequest, + MiGalleryLike, + MiGalleryPost, + MiHashtag, + MiInstance, + MiMeta, + MiModerationLog, + MiMuting, + MiNote, + MiNoteFavorite, + MiNoteReaction, + MiNoteThreadMuting, + MiNoteUnread, + MiPage, + MiPageLike, + MiPasswordResetRequest, + MiPoll, + MiPollVote, + MiPromoNote, + MiPromoRead, + MiRegistrationTicket, + MiRegistryItem, + MiRelay, + MiRenoteMuting, + MiRepository, + miRepository, + MiRetentionAggregation, + MiReversiGame, + MiRole, + MiRoleAssignment, + MiSignin, + MiSwSubscription, + MiSystemWebhook, + MiUsedUsername, + MiUser, + MiUserIp, + MiUserKeypair, + MiUserList, + MiUserListFavorite, + MiUserListMembership, + MiUserMemo, + MiUserNotePining, + MiUserPending, + MiUserProfile, + MiUserPublickey, + MiUserSecurityKey, + MiWebhook +} from './_.js'; import type { DataSource } from 'typeorm'; -import type { Provider } from '@nestjs/common'; const $usersRepository: Provider = { provide: DI.usersRepository, @@ -225,6 +297,12 @@ const $abuseUserReportsRepository: Provider = { inject: [DI.db], }; +const $abuseReportNotificationRecipientRepository: Provider = { + provide: DI.abuseReportNotificationRecipientRepository, + useFactory: (db: DataSource) => db.getRepository(MiAbuseReportNotificationRecipient), + inject: [DI.db], +}; + const $registrationTicketsRepository: Provider = { provide: DI.registrationTicketsRepository, useFactory: (db: DataSource) => db.getRepository(MiRegistrationTicket).extend(miRepository as MiRepository), @@ -351,6 +429,12 @@ const $webhooksRepository: Provider = { inject: [DI.db], }; +const $systemWebhooksRepository: Provider = { + provide: DI.systemWebhooksRepository, + useFactory: (db: DataSource) => db.getRepository(MiSystemWebhook), + inject: [DI.db], +}; + const $adsRepository: Provider = { provide: DI.adsRepository, useFactory: (db: DataSource) => db.getRepository(MiAd).extend(miRepository as MiRepository), @@ -412,8 +496,7 @@ const $reversiGamesRepository: Provider = { }; @Module({ - imports: [ - ], + imports: [], providers: [ $usersRepository, $notesRepository, @@ -451,6 +534,7 @@ const $reversiGamesRepository: Provider = { $swSubscriptionsRepository, $hashtagsRepository, $abuseUserReportsRepository, + $abuseReportNotificationRecipientRepository, $registrationTicketsRepository, $authSessionsRepository, $accessTokensRepository, @@ -472,6 +556,7 @@ const $reversiGamesRepository: Provider = { $channelFavoritesRepository, $registryItemsRepository, $webhooksRepository, + $systemWebhooksRepository, $adsRepository, $passwordResetRequestsRepository, $retentionAggregationsRepository, @@ -520,6 +605,7 @@ const $reversiGamesRepository: Provider = { $swSubscriptionsRepository, $hashtagsRepository, $abuseUserReportsRepository, + $abuseReportNotificationRecipientRepository, $registrationTicketsRepository, $authSessionsRepository, $accessTokensRepository, @@ -541,6 +627,7 @@ const $reversiGamesRepository: Provider = { $channelFavoritesRepository, $registryItemsRepository, $webhooksRepository, + $systemWebhooksRepository, $adsRepository, $passwordResetRequestsRepository, $retentionAggregationsRepository, @@ -553,4 +640,5 @@ const $reversiGamesRepository: Provider = { $reversiGamesRepository, ], }) -export class RepositoryModule {} +export class RepositoryModule { +} diff --git a/packages/backend/src/models/SystemWebhook.ts b/packages/backend/src/models/SystemWebhook.ts new file mode 100644 index 000000000000..86fb323d1daf --- /dev/null +++ b/packages/backend/src/models/SystemWebhook.ts @@ -0,0 +1,98 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Column, Entity, Index, PrimaryColumn } from 'typeorm'; +import { Serialized } from '@/types.js'; +import { id } from './util/id.js'; + +export const systemWebhookEventTypes = [ + // ユーザからの通報を受けたとき + 'abuseReport', + // 通報を処理したとき + 'abuseReportResolved', +] as const; +export type SystemWebhookEventType = typeof systemWebhookEventTypes[number]; + +@Entity('system_webhook') +export class MiSystemWebhook { + @PrimaryColumn(id()) + public id: string; + + /** + * 有効かどうか. + */ + @Index('IDX_system_webhook_isActive', { synchronize: false }) + @Column('boolean', { + default: true, + }) + public isActive: boolean; + + /** + * 更新日時. + */ + @Column('timestamp with time zone', { + default: () => 'CURRENT_TIMESTAMP', + }) + public updatedAt: Date; + + /** + * 最後に送信された日時. + */ + @Column('timestamp with time zone', { + nullable: true, + }) + public latestSentAt: Date | null; + + /** + * 最後に送信されたステータスコード + */ + @Column('integer', { + nullable: true, + }) + public latestStatus: number | null; + + /** + * 通知設定名. + */ + @Column('varchar', { + length: 255, + }) + public name: string; + + /** + * イベント種別. + */ + @Index('IDX_system_webhook_on', { synchronize: false }) + @Column('varchar', { + length: 128, + array: true, + default: '{}', + }) + public on: SystemWebhookEventType[]; + + /** + * Webhook送信先のURL. + */ + @Column('varchar', { + length: 1024, + }) + public url: string; + + /** + * Webhook検証用の値. + */ + @Column('varchar', { + length: 1024, + }) + public secret: string; + + static deserialize(obj: Serialized): MiSystemWebhook { + return { + ...obj, + updatedAt: new Date(obj.updatedAt), + latestSentAt: obj.latestSentAt ? new Date(obj.latestSentAt) : null, + }; + } +} diff --git a/packages/backend/src/models/_.ts b/packages/backend/src/models/_.ts index 2e6a41586e45..d366ce48d035 100644 --- a/packages/backend/src/models/_.ts +++ b/packages/backend/src/models/_.ts @@ -11,6 +11,7 @@ import { RawSqlResultsToEntityTransformer } from 'typeorm/query-builder/transfor import { ObjectUtils } from 'typeorm/util/ObjectUtils.js'; import { OrmUtils } from 'typeorm/util/OrmUtils.js'; import { MiAbuseUserReport } from '@/models/AbuseUserReport.js'; +import { MiAbuseReportNotificationRecipient } from '@/models/AbuseReportNotificationRecipient.js'; import { MiAccessToken } from '@/models/AccessToken.js'; import { MiAd } from '@/models/Ad.js'; import { MiAnnouncement } from '@/models/Announcement.js'; @@ -68,6 +69,7 @@ import { MiUserPublickey } from '@/models/UserPublickey.js'; import { MiUserSecurityKey } from '@/models/UserSecurityKey.js'; import { MiUserMemo } from '@/models/UserMemo.js'; import { MiWebhook } from '@/models/Webhook.js'; +import { MiSystemWebhook } from '@/models/SystemWebhook.js'; import { MiChannel } from '@/models/Channel.js'; import { MiRetentionAggregation } from '@/models/RetentionAggregation.js'; import { MiRole } from '@/models/Role.js'; @@ -144,6 +146,7 @@ export const miRepository = { export { MiAbuseUserReport, + MiAbuseReportNotificationRecipient, MiAccessToken, MiAd, MiAnnouncement, @@ -201,6 +204,7 @@ export { MiUserPublickey, MiUserSecurityKey, MiWebhook, + MiSystemWebhook, MiChannel, MiRetentionAggregation, MiRole, @@ -213,6 +217,7 @@ export { }; export type AbuseUserReportsRepository = Repository & MiRepository; +export type AbuseReportNotificationRecipientRepository = Repository & MiRepository; export type AccessTokensRepository = Repository & MiRepository; export type AdsRepository = Repository & MiRepository; export type AnnouncementsRepository = Repository & MiRepository; @@ -270,6 +275,7 @@ export type UserProfilesRepository = Repository & MiRepository & MiRepository; export type UserSecurityKeysRepository = Repository & MiRepository; export type WebhooksRepository = Repository & MiRepository; +export type SystemWebhooksRepository = Repository & MiRepository; export type ChannelsRepository = Repository & MiRepository; export type RetentionAggregationsRepository = Repository & MiRepository; export type RolesRepository = Repository & MiRepository; diff --git a/packages/backend/src/models/json-schema/abuse-report-notification-recipient.ts b/packages/backend/src/models/json-schema/abuse-report-notification-recipient.ts new file mode 100644 index 000000000000..6215f0f5a202 --- /dev/null +++ b/packages/backend/src/models/json-schema/abuse-report-notification-recipient.ts @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export const packedAbuseReportNotificationRecipientSchema = { + type: 'object', + properties: { + id: { + type: 'string', + optional: false, nullable: false, + }, + isActive: { + type: 'boolean', + optional: false, nullable: false, + }, + updatedAt: { + type: 'string', + format: 'date-time', + optional: false, nullable: false, + }, + name: { + type: 'string', + optional: false, nullable: false, + }, + method: { + type: 'string', + optional: false, nullable: false, + enum: ['email', 'webhook'], + }, + userId: { + type: 'string', + optional: true, nullable: false, + }, + user: { + type: 'object', + optional: true, nullable: false, + ref: 'UserLite', + }, + systemWebhookId: { + type: 'string', + optional: true, nullable: false, + }, + systemWebhook: { + type: 'object', + optional: true, nullable: false, + ref: 'SystemWebhook', + }, + }, +} as const; diff --git a/packages/backend/src/models/json-schema/system-webhook.ts b/packages/backend/src/models/json-schema/system-webhook.ts new file mode 100644 index 000000000000..d83065a74329 --- /dev/null +++ b/packages/backend/src/models/json-schema/system-webhook.ts @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { systemWebhookEventTypes } from '@/models/SystemWebhook.js'; + +export const packedSystemWebhookSchema = { + type: 'object', + properties: { + id: { + type: 'string', + optional: false, nullable: false, + }, + isActive: { + type: 'boolean', + optional: false, nullable: false, + }, + updatedAt: { + type: 'string', + format: 'date-time', + optional: false, nullable: false, + }, + latestSentAt: { + type: 'string', + format: 'date-time', + optional: false, nullable: true, + }, + latestStatus: { + type: 'number', + optional: false, nullable: true, + }, + name: { + type: 'string', + optional: false, nullable: false, + }, + on: { + type: 'array', + items: { + type: 'string', + optional: false, nullable: false, + enum: systemWebhookEventTypes, + }, + }, + url: { + type: 'string', + optional: false, nullable: false, + }, + secret: { + type: 'string', + optional: false, nullable: false, + }, + }, +} as const; diff --git a/packages/backend/src/postgres.ts b/packages/backend/src/postgres.ts index aa2aa5e373da..251a03c303a7 100644 --- a/packages/backend/src/postgres.ts +++ b/packages/backend/src/postgres.ts @@ -5,13 +5,12 @@ // https://github.com/typeorm/typeorm/issues/2400 import pg from 'pg'; -pg.types.setTypeParser(20, Number); - import { DataSource, Logger } from 'typeorm'; import * as highlight from 'cli-highlight'; import { entities as charts } from '@/core/chart/entities.js'; import { MiAbuseUserReport } from '@/models/AbuseUserReport.js'; +import { MiAbuseReportNotificationRecipient } from '@/models/AbuseReportNotificationRecipient.js'; import { MiAccessToken } from '@/models/AccessToken.js'; import { MiAd } from '@/models/Ad.js'; import { MiAnnouncement } from '@/models/Announcement.js'; @@ -69,6 +68,7 @@ import { MiUserProfile } from '@/models/UserProfile.js'; import { MiUserPublickey } from '@/models/UserPublickey.js'; import { MiUserSecurityKey } from '@/models/UserSecurityKey.js'; import { MiWebhook } from '@/models/Webhook.js'; +import { MiSystemWebhook } from '@/models/SystemWebhook.js'; import { MiChannel } from '@/models/Channel.js'; import { MiRetentionAggregation } from '@/models/RetentionAggregation.js'; import { MiRole } from '@/models/Role.js'; @@ -83,6 +83,8 @@ import { Config } from '@/config.js'; import MisskeyLogger from '@/logger.js'; import { bindThis } from '@/decorators.js'; +pg.types.setTypeParser(20, Number); + export const dbLogger = new MisskeyLogger('db'); const sqlLogger = dbLogger.createSubLogger('sql', 'gray'); @@ -167,6 +169,7 @@ export const entities = [ MiHashtag, MiSwSubscription, MiAbuseUserReport, + MiAbuseReportNotificationRecipient, MiRegistrationTicket, MiSignin, MiModerationLog, @@ -185,6 +188,7 @@ export const entities = [ MiPasswordResetRequest, MiUserPending, MiWebhook, + MiSystemWebhook, MiUserIp, MiRetentionAggregation, MiRole, diff --git a/packages/backend/src/queue/QueueProcessorModule.ts b/packages/backend/src/queue/QueueProcessorModule.ts index 808615899769..a1fd38fcc58c 100644 --- a/packages/backend/src/queue/QueueProcessorModule.ts +++ b/packages/backend/src/queue/QueueProcessorModule.ts @@ -11,7 +11,8 @@ import { QueueProcessorService } from './QueueProcessorService.js'; import { DeliverProcessorService } from './processors/DeliverProcessorService.js'; import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js'; import { InboxProcessorService } from './processors/InboxProcessorService.js'; -import { WebhookDeliverProcessorService } from './processors/WebhookDeliverProcessorService.js'; +import { UserWebhookDeliverProcessorService } from './processors/UserWebhookDeliverProcessorService.js'; +import { SystemWebhookDeliverProcessorService } from './processors/SystemWebhookDeliverProcessorService.js'; import { CheckExpiredMutingsProcessorService } from './processors/CheckExpiredMutingsProcessorService.js'; import { CleanChartsProcessorService } from './processors/CleanChartsProcessorService.js'; import { CleanProcessorService } from './processors/CleanProcessorService.js'; @@ -71,7 +72,8 @@ import { RelationshipProcessorService } from './processors/RelationshipProcessor DeleteFileProcessorService, CleanRemoteFilesProcessorService, RelationshipProcessorService, - WebhookDeliverProcessorService, + UserWebhookDeliverProcessorService, + SystemWebhookDeliverProcessorService, EndedPollNotificationProcessorService, DeliverProcessorService, InboxProcessorService, diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts index 7bfe1f4caa47..7bd74f3210f8 100644 --- a/packages/backend/src/queue/QueueProcessorService.ts +++ b/packages/backend/src/queue/QueueProcessorService.ts @@ -10,7 +10,8 @@ import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; import type Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; -import { WebhookDeliverProcessorService } from './processors/WebhookDeliverProcessorService.js'; +import { UserWebhookDeliverProcessorService } from './processors/UserWebhookDeliverProcessorService.js'; +import { SystemWebhookDeliverProcessorService } from './processors/SystemWebhookDeliverProcessorService.js'; import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js'; import { DeliverProcessorService } from './processors/DeliverProcessorService.js'; import { InboxProcessorService } from './processors/InboxProcessorService.js'; @@ -76,7 +77,8 @@ export class QueueProcessorService implements OnApplicationShutdown { private dbQueueWorker: Bull.Worker; private deliverQueueWorker: Bull.Worker; private inboxQueueWorker: Bull.Worker; - private webhookDeliverQueueWorker: Bull.Worker; + private userWebhookDeliverQueueWorker: Bull.Worker; + private systemWebhookDeliverQueueWorker: Bull.Worker; private relationshipQueueWorker: Bull.Worker; private objectStorageQueueWorker: Bull.Worker; private endedPollNotificationQueueWorker: Bull.Worker; @@ -86,7 +88,8 @@ export class QueueProcessorService implements OnApplicationShutdown { private config: Config, private queueLoggerService: QueueLoggerService, - private webhookDeliverProcessorService: WebhookDeliverProcessorService, + private userWebhookDeliverProcessorService: UserWebhookDeliverProcessorService, + private systemWebhookDeliverProcessorService: SystemWebhookDeliverProcessorService, private endedPollNotificationProcessorService: EndedPollNotificationProcessorService, private deliverProcessorService: DeliverProcessorService, private inboxProcessorService: InboxProcessorService, @@ -160,13 +163,13 @@ export class QueueProcessorService implements OnApplicationShutdown { autorun: false, }); - const systemLogger = this.logger.createSubLogger('system'); + const logger = this.logger.createSubLogger('system'); this.systemQueueWorker - .on('active', (job) => systemLogger.debug(`active id=${job.id}`)) - .on('completed', (job, result) => systemLogger.debug(`completed(${result}) id=${job.id}`)) + .on('active', (job) => logger.debug(`active id=${job.id}`)) + .on('completed', (job, result) => logger.debug(`completed(${result}) id=${job.id}`)) .on('failed', (job, err: Error) => { - systemLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + logger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: System: ${job?.name ?? '?'}: ${err.message}`, { level: 'error', @@ -174,8 +177,8 @@ export class QueueProcessorService implements OnApplicationShutdown { }); } }) - .on('error', (err: Error) => systemLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => systemLogger.warn(`stalled id=${jobId}`)); + .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -217,13 +220,13 @@ export class QueueProcessorService implements OnApplicationShutdown { autorun: false, }); - const dbLogger = this.logger.createSubLogger('db'); + const logger = this.logger.createSubLogger('db'); this.dbQueueWorker - .on('active', (job) => dbLogger.debug(`active id=${job.id}`)) - .on('completed', (job, result) => dbLogger.debug(`completed(${result}) id=${job.id}`)) + .on('active', (job) => logger.debug(`active id=${job.id}`)) + .on('completed', (job, result) => logger.debug(`completed(${result}) id=${job.id}`)) .on('failed', (job, err) => { - dbLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + logger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: DB: ${job?.name ?? '?'}: ${err.message}`, { level: 'error', @@ -231,8 +234,8 @@ export class QueueProcessorService implements OnApplicationShutdown { }); } }) - .on('error', (err: Error) => dbLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => dbLogger.warn(`stalled id=${jobId}`)); + .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -257,13 +260,13 @@ export class QueueProcessorService implements OnApplicationShutdown { }, }); - const deliverLogger = this.logger.createSubLogger('deliver'); + const logger = this.logger.createSubLogger('deliver'); this.deliverQueueWorker - .on('active', (job) => deliverLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) - .on('completed', (job, result) => deliverLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) + .on('active', (job) => logger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) + .on('completed', (job, result) => logger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) .on('failed', (job, err) => { - deliverLogger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); + logger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: Deliver: ${err.message}`, { level: 'error', @@ -271,8 +274,8 @@ export class QueueProcessorService implements OnApplicationShutdown { }); } }) - .on('error', (err: Error) => deliverLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => deliverLogger.warn(`stalled id=${jobId}`)); + .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -297,13 +300,13 @@ export class QueueProcessorService implements OnApplicationShutdown { }, }); - const inboxLogger = this.logger.createSubLogger('inbox'); + const logger = this.logger.createSubLogger('inbox'); this.inboxQueueWorker - .on('active', (job) => inboxLogger.debug(`active ${getJobInfo(job, true)}`)) - .on('completed', (job, result) => inboxLogger.debug(`completed(${result}) ${getJobInfo(job, true)}`)) + .on('active', (job) => logger.debug(`active ${getJobInfo(job, true)}`)) + .on('completed', (job, result) => logger.debug(`completed(${result}) ${getJobInfo(job, true)}`)) .on('failed', (job, err) => { - inboxLogger.error(`failed(${err.stack}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job, e: renderError(err) }); + logger.error(`failed(${err.stack}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: Inbox: ${err.message}`, { level: 'error', @@ -311,21 +314,21 @@ export class QueueProcessorService implements OnApplicationShutdown { }); } }) - .on('error', (err: Error) => inboxLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => inboxLogger.warn(`stalled id=${jobId}`)); + .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion - //#region webhook deliver + //#region user-webhook deliver { - this.webhookDeliverQueueWorker = new Bull.Worker(QUEUE.WEBHOOK_DELIVER, (job) => { + this.userWebhookDeliverQueueWorker = new Bull.Worker(QUEUE.USER_WEBHOOK_DELIVER, (job) => { if (this.config.sentryForBackend) { - return Sentry.startSpan({ name: 'Queue: WebhookDeliver' }, () => this.webhookDeliverProcessorService.process(job)); + return Sentry.startSpan({ name: 'Queue: UserWebhookDeliver' }, () => this.userWebhookDeliverProcessorService.process(job)); } else { - return this.webhookDeliverProcessorService.process(job); + return this.userWebhookDeliverProcessorService.process(job); } }, { - ...baseQueueOptions(this.config, QUEUE.WEBHOOK_DELIVER), + ...baseQueueOptions(this.config, QUEUE.USER_WEBHOOK_DELIVER), autorun: false, concurrency: 64, limiter: { @@ -337,22 +340,62 @@ export class QueueProcessorService implements OnApplicationShutdown { }, }); - const webhookLogger = this.logger.createSubLogger('webhook'); + const logger = this.logger.createSubLogger('user-webhook'); - this.webhookDeliverQueueWorker - .on('active', (job) => webhookLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) - .on('completed', (job, result) => webhookLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) + this.userWebhookDeliverQueueWorker + .on('active', (job) => logger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) + .on('completed', (job, result) => logger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) .on('failed', (job, err) => { - webhookLogger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); + logger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: WebhookDeliver: ${err.message}`, { + Sentry.captureMessage(`Queue: UserWebhookDeliver: ${err.message}`, { level: 'error', extra: { job, err }, }); } }) - .on('error', (err: Error) => webhookLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => webhookLogger.warn(`stalled id=${jobId}`)); + .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); + } + //#endregion + + //#region system-webhook deliver + { + this.systemWebhookDeliverQueueWorker = new Bull.Worker(QUEUE.SYSTEM_WEBHOOK_DELIVER, (job) => { + if (this.config.sentryForBackend) { + return Sentry.startSpan({ name: 'Queue: SystemWebhookDeliver' }, () => this.systemWebhookDeliverProcessorService.process(job)); + } else { + return this.systemWebhookDeliverProcessorService.process(job); + } + }, { + ...baseQueueOptions(this.config, QUEUE.SYSTEM_WEBHOOK_DELIVER), + autorun: false, + concurrency: 16, + limiter: { + max: 16, + duration: 1000, + }, + settings: { + backoffStrategy: httpRelatedBackoff, + }, + }); + + const logger = this.logger.createSubLogger('system-webhook'); + + this.systemWebhookDeliverQueueWorker + .on('active', (job) => logger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) + .on('completed', (job, result) => logger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) + .on('failed', (job, err) => { + logger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); + if (config.sentryForBackend) { + Sentry.captureMessage(`Queue: SystemWebhookDeliver: ${err.message}`, { + level: 'error', + extra: { job, err }, + }); + } + }) + .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -384,13 +427,13 @@ export class QueueProcessorService implements OnApplicationShutdown { }, }); - const relationshipLogger = this.logger.createSubLogger('relationship'); + const logger = this.logger.createSubLogger('relationship'); this.relationshipQueueWorker - .on('active', (job) => relationshipLogger.debug(`active id=${job.id}`)) - .on('completed', (job, result) => relationshipLogger.debug(`completed(${result}) id=${job.id}`)) + .on('active', (job) => logger.debug(`active id=${job.id}`)) + .on('completed', (job, result) => logger.debug(`completed(${result}) id=${job.id}`)) .on('failed', (job, err) => { - relationshipLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + logger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: Relationship: ${job?.name ?? '?'}: ${err.message}`, { level: 'error', @@ -398,8 +441,8 @@ export class QueueProcessorService implements OnApplicationShutdown { }); } }) - .on('error', (err: Error) => relationshipLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => relationshipLogger.warn(`stalled id=${jobId}`)); + .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -425,13 +468,13 @@ export class QueueProcessorService implements OnApplicationShutdown { concurrency: 16, }); - const objectStorageLogger = this.logger.createSubLogger('objectStorage'); + const logger = this.logger.createSubLogger('objectStorage'); this.objectStorageQueueWorker - .on('active', (job) => objectStorageLogger.debug(`active id=${job.id}`)) - .on('completed', (job, result) => objectStorageLogger.debug(`completed(${result}) id=${job.id}`)) + .on('active', (job) => logger.debug(`active id=${job.id}`)) + .on('completed', (job, result) => logger.debug(`completed(${result}) id=${job.id}`)) .on('failed', (job, err) => { - objectStorageLogger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + logger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); if (config.sentryForBackend) { Sentry.captureMessage(`Queue: ObjectStorage: ${job?.name ?? '?'}: ${err.message}`, { level: 'error', @@ -439,8 +482,8 @@ export class QueueProcessorService implements OnApplicationShutdown { }); } }) - .on('error', (err: Error) => objectStorageLogger.error(`error ${err.stack}`, { e: renderError(err) })) - .on('stalled', (jobId) => objectStorageLogger.warn(`stalled id=${jobId}`)); + .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -467,7 +510,8 @@ export class QueueProcessorService implements OnApplicationShutdown { this.dbQueueWorker.run(), this.deliverQueueWorker.run(), this.inboxQueueWorker.run(), - this.webhookDeliverQueueWorker.run(), + this.userWebhookDeliverQueueWorker.run(), + this.systemWebhookDeliverQueueWorker.run(), this.relationshipQueueWorker.run(), this.objectStorageQueueWorker.run(), this.endedPollNotificationQueueWorker.run(), @@ -481,7 +525,8 @@ export class QueueProcessorService implements OnApplicationShutdown { this.dbQueueWorker.close(), this.deliverQueueWorker.close(), this.inboxQueueWorker.close(), - this.webhookDeliverQueueWorker.close(), + this.userWebhookDeliverQueueWorker.close(), + this.systemWebhookDeliverQueueWorker.close(), this.relationshipQueueWorker.close(), this.objectStorageQueueWorker.close(), this.endedPollNotificationQueueWorker.close(), diff --git a/packages/backend/src/queue/const.ts b/packages/backend/src/queue/const.ts index 132e9166121c..67f689b61849 100644 --- a/packages/backend/src/queue/const.ts +++ b/packages/backend/src/queue/const.ts @@ -14,7 +14,8 @@ export const QUEUE = { DB: 'db', RELATIONSHIP: 'relationship', OBJECT_STORAGE: 'objectStorage', - WEBHOOK_DELIVER: 'webhookDeliver', + USER_WEBHOOK_DELIVER: 'userWebhookDeliver', + SYSTEM_WEBHOOK_DELIVER: 'systemWebhookDeliver', }; export function baseQueueOptions(config: Config, queueName: typeof QUEUE[keyof typeof QUEUE]): Bull.QueueOptions { diff --git a/packages/backend/src/queue/processors/SystemWebhookDeliverProcessorService.ts b/packages/backend/src/queue/processors/SystemWebhookDeliverProcessorService.ts new file mode 100644 index 000000000000..f6bef5268456 --- /dev/null +++ b/packages/backend/src/queue/processors/SystemWebhookDeliverProcessorService.ts @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import * as Bull from 'bullmq'; +import { DI } from '@/di-symbols.js'; +import type { SystemWebhooksRepository } from '@/models/_.js'; +import type { Config } from '@/config.js'; +import type Logger from '@/logger.js'; +import { HttpRequestService } from '@/core/HttpRequestService.js'; +import { StatusError } from '@/misc/status-error.js'; +import { bindThis } from '@/decorators.js'; +import { QueueLoggerService } from '../QueueLoggerService.js'; +import { SystemWebhookDeliverJobData } from '../types.js'; + +@Injectable() +export class SystemWebhookDeliverProcessorService { + private logger: Logger; + + constructor( + @Inject(DI.config) + private config: Config, + + @Inject(DI.systemWebhooksRepository) + private systemWebhooksRepository: SystemWebhooksRepository, + + private httpRequestService: HttpRequestService, + private queueLoggerService: QueueLoggerService, + ) { + this.logger = this.queueLoggerService.logger.createSubLogger('webhook'); + } + + @bindThis + public async process(job: Bull.Job): Promise { + try { + this.logger.debug(`delivering ${job.data.webhookId}`); + + const res = await this.httpRequestService.send(job.data.to, { + method: 'POST', + headers: { + 'User-Agent': 'Misskey-Hooks', + 'X-Misskey-Host': this.config.host, + 'X-Misskey-Hook-Id': job.data.webhookId, + 'X-Misskey-Hook-Secret': job.data.secret, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + server: this.config.url, + hookId: job.data.webhookId, + eventId: job.data.eventId, + createdAt: job.data.createdAt, + type: job.data.type, + body: job.data.content, + }), + }); + + this.systemWebhooksRepository.update({ id: job.data.webhookId }, { + latestSentAt: new Date(), + latestStatus: res.status, + }); + + return 'Success'; + } catch (res) { + this.logger.error(res as Error); + + this.systemWebhooksRepository.update({ id: job.data.webhookId }, { + latestSentAt: new Date(), + latestStatus: res instanceof StatusError ? res.statusCode : 1, + }); + + if (res instanceof StatusError) { + // 4xx + if (!res.isRetryable) { + throw new Bull.UnrecoverableError(`${res.statusCode} ${res.statusMessage}`); + } + + // 5xx etc. + throw new Error(`${res.statusCode} ${res.statusMessage}`); + } else { + // DNS error, socket error, timeout ... + throw res; + } + } + } +} diff --git a/packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts b/packages/backend/src/queue/processors/UserWebhookDeliverProcessorService.ts similarity index 92% rename from packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts rename to packages/backend/src/queue/processors/UserWebhookDeliverProcessorService.ts index 8c260c0137ce..9ec630ef7047 100644 --- a/packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/UserWebhookDeliverProcessorService.ts @@ -13,10 +13,10 @@ import { HttpRequestService } from '@/core/HttpRequestService.js'; import { StatusError } from '@/misc/status-error.js'; import { bindThis } from '@/decorators.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; -import type { WebhookDeliverJobData } from '../types.js'; +import { UserWebhookDeliverJobData } from '../types.js'; @Injectable() -export class WebhookDeliverProcessorService { +export class UserWebhookDeliverProcessorService { private logger: Logger; constructor( @@ -33,7 +33,7 @@ export class WebhookDeliverProcessorService { } @bindThis - public async process(job: Bull.Job): Promise { + public async process(job: Bull.Job): Promise { try { this.logger.debug(`delivering ${job.data.webhookId}`); diff --git a/packages/backend/src/queue/types.ts b/packages/backend/src/queue/types.ts index ce57ba745eb4..a4077a0547ea 100644 --- a/packages/backend/src/queue/types.ts +++ b/packages/backend/src/queue/types.ts @@ -106,7 +106,17 @@ export type EndedPollNotificationJobData = { noteId: MiNote['id']; }; -export type WebhookDeliverJobData = { +export type SystemWebhookDeliverJobData = { + type: string; + content: unknown; + webhookId: MiWebhook['id']; + to: string; + secret: string; + createdAt: number; + eventId: string; +}; + +export type UserWebhookDeliverJobData = { type: string; content: unknown; webhookId: MiWebhook['id']; diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index c645f4bcc61c..41576bedaae7 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -6,8 +6,13 @@ import { Module } from '@nestjs/common'; import { CoreModule } from '@/core/CoreModule.js'; -import * as ep___admin_meta from './endpoints/admin/meta.js'; +import * as ep___admin_abuseReport_notificationRecipient_list from '@/server/api/endpoints/admin/abuse-report/notification-recipient/list.js'; +import * as ep___admin_abuseReport_notificationRecipient_show from '@/server/api/endpoints/admin/abuse-report/notification-recipient/show.js'; +import * as ep___admin_abuseReport_notificationRecipient_create from '@/server/api/endpoints/admin/abuse-report/notification-recipient/create.js'; +import * as ep___admin_abuseReport_notificationRecipient_update from '@/server/api/endpoints/admin/abuse-report/notification-recipient/update.js'; +import * as ep___admin_abuseReport_notificationRecipient_delete from '@/server/api/endpoints/admin/abuse-report/notification-recipient/delete.js'; import * as ep___admin_abuseUserReports from './endpoints/admin/abuse-user-reports.js'; +import * as ep___admin_meta from './endpoints/admin/meta.js'; import * as ep___admin_accounts_create from './endpoints/admin/accounts/create.js'; import * as ep___admin_accounts_delete from './endpoints/admin/accounts/delete.js'; import * as ep___admin_accounts_findByEmail from './endpoints/admin/accounts/find-by-email.js'; @@ -82,6 +87,11 @@ import * as ep___admin_roles_assign from './endpoints/admin/roles/assign.js'; import * as ep___admin_roles_unassign from './endpoints/admin/roles/unassign.js'; import * as ep___admin_roles_updateDefaultPolicies from './endpoints/admin/roles/update-default-policies.js'; import * as ep___admin_roles_users from './endpoints/admin/roles/users.js'; +import * as ep___admin_systemWebhook_create from './endpoints/admin/system-webhook/create.js'; +import * as ep___admin_systemWebhook_delete from './endpoints/admin/system-webhook/delete.js'; +import * as ep___admin_systemWebhook_list from './endpoints/admin/system-webhook/list.js'; +import * as ep___admin_systemWebhook_show from './endpoints/admin/system-webhook/show.js'; +import * as ep___admin_systemWebhook_update from './endpoints/admin/system-webhook/update.js'; import * as ep___announcements from './endpoints/announcements.js'; import * as ep___announcements_show from './endpoints/announcements/show.js'; import * as ep___antennas_create from './endpoints/antennas/create.js'; @@ -381,6 +391,11 @@ import type { Provider } from '@nestjs/common'; const $admin_meta: Provider = { provide: 'ep:admin/meta', useClass: ep___admin_meta.default }; const $admin_abuseUserReports: Provider = { provide: 'ep:admin/abuse-user-reports', useClass: ep___admin_abuseUserReports.default }; +const $admin_abuseReport_notificationRecipient_list: Provider = { provide: 'ep:admin/abuse-report/notification-recipient/list', useClass: ep___admin_abuseReport_notificationRecipient_list.default }; +const $admin_abuseReport_notificationRecipient_show: Provider = { provide: 'ep:admin/abuse-report/notification-recipient/show', useClass: ep___admin_abuseReport_notificationRecipient_show.default }; +const $admin_abuseReport_notificationRecipient_create: Provider = { provide: 'ep:admin/abuse-report/notification-recipient/create', useClass: ep___admin_abuseReport_notificationRecipient_create.default }; +const $admin_abuseReport_notificationRecipient_update: Provider = { provide: 'ep:admin/abuse-report/notification-recipient/update', useClass: ep___admin_abuseReport_notificationRecipient_update.default }; +const $admin_abuseReport_notificationRecipient_delete: Provider = { provide: 'ep:admin/abuse-report/notification-recipient/delete', useClass: ep___admin_abuseReport_notificationRecipient_delete.default }; const $admin_accounts_create: Provider = { provide: 'ep:admin/accounts/create', useClass: ep___admin_accounts_create.default }; const $admin_accounts_delete: Provider = { provide: 'ep:admin/accounts/delete', useClass: ep___admin_accounts_delete.default }; const $admin_accounts_findByEmail: Provider = { provide: 'ep:admin/accounts/find-by-email', useClass: ep___admin_accounts_findByEmail.default }; @@ -455,6 +470,11 @@ const $admin_roles_assign: Provider = { provide: 'ep:admin/roles/assign', useCla const $admin_roles_unassign: Provider = { provide: 'ep:admin/roles/unassign', useClass: ep___admin_roles_unassign.default }; const $admin_roles_updateDefaultPolicies: Provider = { provide: 'ep:admin/roles/update-default-policies', useClass: ep___admin_roles_updateDefaultPolicies.default }; const $admin_roles_users: Provider = { provide: 'ep:admin/roles/users', useClass: ep___admin_roles_users.default }; +const $admin_systemWebhook_create: Provider = { provide: 'ep:admin/system-webhook/create', useClass: ep___admin_systemWebhook_create.default }; +const $admin_systemWebhook_delete: Provider = { provide: 'ep:admin/system-webhook/delete', useClass: ep___admin_systemWebhook_delete.default }; +const $admin_systemWebhook_list: Provider = { provide: 'ep:admin/system-webhook/list', useClass: ep___admin_systemWebhook_list.default }; +const $admin_systemWebhook_show: Provider = { provide: 'ep:admin/system-webhook/show', useClass: ep___admin_systemWebhook_show.default }; +const $admin_systemWebhook_update: Provider = { provide: 'ep:admin/system-webhook/update', useClass: ep___admin_systemWebhook_update.default }; const $announcements: Provider = { provide: 'ep:announcements', useClass: ep___announcements.default }; const $announcements_show: Provider = { provide: 'ep:announcements/show', useClass: ep___announcements_show.default }; const $antennas_create: Provider = { provide: 'ep:antennas/create', useClass: ep___antennas_create.default }; @@ -758,6 +778,11 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__ ApiLoggerService, $admin_meta, $admin_abuseUserReports, + $admin_abuseReport_notificationRecipient_list, + $admin_abuseReport_notificationRecipient_show, + $admin_abuseReport_notificationRecipient_create, + $admin_abuseReport_notificationRecipient_update, + $admin_abuseReport_notificationRecipient_delete, $admin_accounts_create, $admin_accounts_delete, $admin_accounts_findByEmail, @@ -832,6 +857,11 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__ $admin_roles_unassign, $admin_roles_updateDefaultPolicies, $admin_roles_users, + $admin_systemWebhook_create, + $admin_systemWebhook_delete, + $admin_systemWebhook_list, + $admin_systemWebhook_show, + $admin_systemWebhook_update, $announcements, $announcements_show, $antennas_create, @@ -1129,6 +1159,11 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__ exports: [ $admin_meta, $admin_abuseUserReports, + $admin_abuseReport_notificationRecipient_list, + $admin_abuseReport_notificationRecipient_show, + $admin_abuseReport_notificationRecipient_create, + $admin_abuseReport_notificationRecipient_update, + $admin_abuseReport_notificationRecipient_delete, $admin_accounts_create, $admin_accounts_delete, $admin_accounts_findByEmail, @@ -1203,6 +1238,11 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__ $admin_roles_unassign, $admin_roles_updateDefaultPolicies, $admin_roles_users, + $admin_systemWebhook_create, + $admin_systemWebhook_delete, + $admin_systemWebhook_list, + $admin_systemWebhook_show, + $admin_systemWebhook_update, $announcements, $announcements_show, $antennas_create, diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index a38c62f35a9d..3dfb7fdad4c2 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -6,8 +6,18 @@ import { permissions } from 'misskey-js'; import type { KeyOf, Schema } from '@/misc/json-schema.js'; -import * as ep___admin_meta from './endpoints/admin/meta.js'; +import * as ep___admin_abuseReport_notificationRecipient_list + from '@/server/api/endpoints/admin/abuse-report/notification-recipient/list.js'; +import * as ep___admin_abuseReport_notificationRecipient_show + from '@/server/api/endpoints/admin/abuse-report/notification-recipient/show.js'; +import * as ep___admin_abuseReport_notificationRecipient_create + from '@/server/api/endpoints/admin/abuse-report/notification-recipient/create.js'; +import * as ep___admin_abuseReport_notificationRecipient_update + from '@/server/api/endpoints/admin/abuse-report/notification-recipient/update.js'; +import * as ep___admin_abuseReport_notificationRecipient_delete + from '@/server/api/endpoints/admin/abuse-report/notification-recipient/delete.js'; import * as ep___admin_abuseUserReports from './endpoints/admin/abuse-user-reports.js'; +import * as ep___admin_meta from './endpoints/admin/meta.js'; import * as ep___admin_accounts_create from './endpoints/admin/accounts/create.js'; import * as ep___admin_accounts_delete from './endpoints/admin/accounts/delete.js'; import * as ep___admin_accounts_findByEmail from './endpoints/admin/accounts/find-by-email.js'; @@ -44,7 +54,8 @@ import * as ep___admin_emoji_setCategoryBulk from './endpoints/admin/emoji/set-c import * as ep___admin_emoji_setLicenseBulk from './endpoints/admin/emoji/set-license-bulk.js'; import * as ep___admin_emoji_update from './endpoints/admin/emoji/update.js'; import * as ep___admin_federation_deleteAllFiles from './endpoints/admin/federation/delete-all-files.js'; -import * as ep___admin_federation_refreshRemoteInstanceMetadata from './endpoints/admin/federation/refresh-remote-instance-metadata.js'; +import * as ep___admin_federation_refreshRemoteInstanceMetadata + from './endpoints/admin/federation/refresh-remote-instance-metadata.js'; import * as ep___admin_federation_removeAllFollowing from './endpoints/admin/federation/remove-all-following.js'; import * as ep___admin_federation_updateInstance from './endpoints/admin/federation/update-instance.js'; import * as ep___admin_getIndexStats from './endpoints/admin/get-index-stats.js'; @@ -82,6 +93,11 @@ import * as ep___admin_roles_assign from './endpoints/admin/roles/assign.js'; import * as ep___admin_roles_unassign from './endpoints/admin/roles/unassign.js'; import * as ep___admin_roles_updateDefaultPolicies from './endpoints/admin/roles/update-default-policies.js'; import * as ep___admin_roles_users from './endpoints/admin/roles/users.js'; +import * as ep___admin_systemWebhook_create from './endpoints/admin/system-webhook/create.js'; +import * as ep___admin_systemWebhook_delete from './endpoints/admin/system-webhook/delete.js'; +import * as ep___admin_systemWebhook_list from './endpoints/admin/system-webhook/list.js'; +import * as ep___admin_systemWebhook_show from './endpoints/admin/system-webhook/show.js'; +import * as ep___admin_systemWebhook_update from './endpoints/admin/system-webhook/update.js'; import * as ep___announcements from './endpoints/announcements.js'; import * as ep___announcements_show from './endpoints/announcements/show.js'; import * as ep___antennas_create from './endpoints/antennas/create.js'; @@ -379,6 +395,11 @@ import * as ep___reversi_verify from './endpoints/reversi/verify.js'; const eps = [ ['admin/meta', ep___admin_meta], ['admin/abuse-user-reports', ep___admin_abuseUserReports], + ['admin/abuse-report/notification-recipient/list', ep___admin_abuseReport_notificationRecipient_list], + ['admin/abuse-report/notification-recipient/show', ep___admin_abuseReport_notificationRecipient_show], + ['admin/abuse-report/notification-recipient/create', ep___admin_abuseReport_notificationRecipient_create], + ['admin/abuse-report/notification-recipient/update', ep___admin_abuseReport_notificationRecipient_update], + ['admin/abuse-report/notification-recipient/delete', ep___admin_abuseReport_notificationRecipient_delete], ['admin/accounts/create', ep___admin_accounts_create], ['admin/accounts/delete', ep___admin_accounts_delete], ['admin/accounts/find-by-email', ep___admin_accounts_findByEmail], @@ -453,6 +474,11 @@ const eps = [ ['admin/roles/unassign', ep___admin_roles_unassign], ['admin/roles/update-default-policies', ep___admin_roles_updateDefaultPolicies], ['admin/roles/users', ep___admin_roles_users], + ['admin/system-webhook/create', ep___admin_systemWebhook_create], + ['admin/system-webhook/delete', ep___admin_systemWebhook_delete], + ['admin/system-webhook/list', ep___admin_systemWebhook_list], + ['admin/system-webhook/show', ep___admin_systemWebhook_show], + ['admin/system-webhook/update', ep___admin_systemWebhook_update], ['announcements', ep___announcements], ['announcements/show', ep___announcements_show], ['antennas/create', ep___antennas_create], @@ -873,8 +899,12 @@ export interface IEndpoint { const endpoints: IEndpoint[] = (eps as [string, any]).map(([name, ep]) => { return { name: name, - get meta() { return ep.meta ?? {}; }, - get params() { return ep.paramDef; }, + get meta() { + return ep.meta ?? {}; + }, + get params() { + return ep.paramDef; + }, }; }); diff --git a/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/create.ts b/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/create.ts new file mode 100644 index 000000000000..bdfbcba51897 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/create.ts @@ -0,0 +1,122 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { ApiError } from '@/server/api/error.js'; +import { + AbuseReportNotificationRecipientEntityService, +} from '@/core/entities/AbuseReportNotificationRecipientEntityService.js'; +import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js'; +import { DI } from '@/di-symbols.js'; +import type { UserProfilesRepository } from '@/models/_.js'; + +export const meta = { + tags: ['admin', 'abuse-report', 'notification-recipient'], + + requireCredential: true, + requireModerator: true, + secure: true, + kind: 'write:admin:abuse-report:notification-recipient', + + res: { + type: 'object', + ref: 'AbuseReportNotificationRecipient', + }, + + errors: { + correlationCheckEmail: { + message: 'If "method" is email, "userId" must be set.', + code: 'CORRELATION_CHECK_EMAIL', + id: '348bb8ae-575a-6fe9-4327-5811999def8f', + httpStatusCode: 400, + }, + correlationCheckWebhook: { + message: 'If "method" is webhook, "systemWebhookId" must be set.', + code: 'CORRELATION_CHECK_WEBHOOK', + id: 'b0c15051-de2d-29ef-260c-9585cddd701a', + httpStatusCode: 400, + }, + emailAddressNotSet: { + message: 'Email address is not set.', + code: 'EMAIL_ADDRESS_NOT_SET', + id: '7cc1d85e-2f58-fc31-b644-3de8d0d3421f', + httpStatusCode: 400, + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + isActive: { + type: 'boolean', + }, + name: { + type: 'string', + minLength: 1, + maxLength: 255, + }, + method: { + type: 'string', + enum: ['email', 'webhook'], + }, + userId: { + type: 'string', + format: 'misskey:id', + }, + systemWebhookId: { + type: 'string', + format: 'misskey:id', + }, + }, + required: [ + 'isActive', + 'name', + 'method', + ], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + @Inject(DI.userProfilesRepository) + private userProfilesRepository: UserProfilesRepository, + private abuseReportNotificationService: AbuseReportNotificationService, + private abuseReportNotificationRecipientEntityService: AbuseReportNotificationRecipientEntityService, + ) { + super(meta, paramDef, async (ps, me) => { + if (ps.method === 'email') { + const userProfile = await this.userProfilesRepository.findOneBy({ userId: ps.userId }); + if (!ps.userId || !userProfile) { + throw new ApiError(meta.errors.correlationCheckEmail); + } + + if (!userProfile.email || !userProfile.emailVerified) { + throw new ApiError(meta.errors.emailAddressNotSet); + } + } + + if (ps.method === 'webhook' && !ps.systemWebhookId) { + throw new ApiError(meta.errors.correlationCheckWebhook); + } + + const userId = ps.method === 'email' ? ps.userId : null; + const systemWebhookId = ps.method === 'webhook' ? ps.systemWebhookId : null; + const result = await this.abuseReportNotificationService.createRecipient( + { + isActive: ps.isActive, + name: ps.name, + method: ps.method, + userId: userId ?? null, + systemWebhookId: systemWebhookId ?? null, + }, + me, + ); + + return this.abuseReportNotificationRecipientEntityService.pack(result); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/delete.ts b/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/delete.ts new file mode 100644 index 000000000000..b6dc44e09c9a --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/delete.ts @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js'; + +export const meta = { + tags: ['admin', 'abuse-report', 'notification-recipient'], + + requireCredential: true, + requireModerator: true, + secure: true, + kind: 'write:admin:abuse-report:notification-recipient', +} as const; + +export const paramDef = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'misskey:id', + }, + }, + required: [ + 'id', + ], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private abuseReportNotificationService: AbuseReportNotificationService, + ) { + super(meta, paramDef, async (ps, me) => { + await this.abuseReportNotificationService.deleteRecipient( + ps.id, + me, + ); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/list.ts b/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/list.ts new file mode 100644 index 000000000000..dad9161a8a74 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/list.ts @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { + AbuseReportNotificationRecipientEntityService, +} from '@/core/entities/AbuseReportNotificationRecipientEntityService.js'; +import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js'; + +export const meta = { + tags: ['admin', 'abuse-report', 'notification-recipient'], + + requireCredential: true, + requireModerator: true, + secure: true, + kind: 'read:admin:abuse-report:notification-recipient', + + res: { + type: 'array', + items: { + type: 'object', + ref: 'AbuseReportNotificationRecipient', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + method: { + type: 'array', + items: { + type: 'string', + enum: ['email', 'webhook'], + }, + }, + }, + required: [], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private abuseReportNotificationService: AbuseReportNotificationService, + private abuseReportNotificationRecipientEntityService: AbuseReportNotificationRecipientEntityService, + ) { + super(meta, paramDef, async (ps) => { + const recipients = await this.abuseReportNotificationService.fetchRecipients({ method: ps.method }); + return this.abuseReportNotificationRecipientEntityService.packMany(recipients); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/show.ts b/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/show.ts new file mode 100644 index 000000000000..557798f946e0 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/show.ts @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { + AbuseReportNotificationRecipientEntityService, +} from '@/core/entities/AbuseReportNotificationRecipientEntityService.js'; +import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js'; +import { ApiError } from '@/server/api/error.js'; + +export const meta = { + tags: ['admin', 'abuse-report', 'notification-recipient'], + + requireCredential: true, + requireModerator: true, + secure: true, + kind: 'read:admin:abuse-report:notification-recipient', + + res: { + type: 'object', + ref: 'AbuseReportNotificationRecipient', + }, + + errors: { + noSuchRecipient: { + message: 'No such recipient.', + code: 'NO_SUCH_RECIPIENT', + id: '013de6a8-f757-04cb-4d73-cc2a7e3368e4', + kind: 'server', + httpStatusCode: 404, + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'misskey:id', + }, + }, + required: ['id'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private abuseReportNotificationService: AbuseReportNotificationService, + private abuseReportNotificationRecipientEntityService: AbuseReportNotificationRecipientEntityService, + ) { + super(meta, paramDef, async (ps) => { + const recipients = await this.abuseReportNotificationService.fetchRecipients({ ids: [ps.id] }); + if (recipients.length === 0) { + throw new ApiError(meta.errors.noSuchRecipient); + } + + return this.abuseReportNotificationRecipientEntityService.pack(recipients[0]); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/update.ts b/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/update.ts new file mode 100644 index 000000000000..bd4b4852171c --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/abuse-report/notification-recipient/update.ts @@ -0,0 +1,128 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { ApiError } from '@/server/api/error.js'; +import { + AbuseReportNotificationRecipientEntityService, +} from '@/core/entities/AbuseReportNotificationRecipientEntityService.js'; +import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js'; +import { DI } from '@/di-symbols.js'; +import type { UserProfilesRepository } from '@/models/_.js'; + +export const meta = { + tags: ['admin', 'abuse-report', 'notification-recipient'], + + requireCredential: true, + requireModerator: true, + secure: true, + kind: 'write:admin:abuse-report:notification-recipient', + + res: { + type: 'object', + ref: 'AbuseReportNotificationRecipient', + }, + + errors: { + correlationCheckEmail: { + message: 'If "method" is email, "userId" must be set.', + code: 'CORRELATION_CHECK_EMAIL', + id: '348bb8ae-575a-6fe9-4327-5811999def8f', + httpStatusCode: 400, + }, + correlationCheckWebhook: { + message: 'If "method" is webhook, "systemWebhookId" must be set.', + code: 'CORRELATION_CHECK_WEBHOOK', + id: 'b0c15051-de2d-29ef-260c-9585cddd701a', + httpStatusCode: 400, + }, + emailAddressNotSet: { + message: 'Email address is not set.', + code: 'EMAIL_ADDRESS_NOT_SET', + id: '7cc1d85e-2f58-fc31-b644-3de8d0d3421f', + httpStatusCode: 400, + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'misskey:id', + }, + isActive: { + type: 'boolean', + }, + name: { + type: 'string', + minLength: 1, + maxLength: 255, + }, + method: { + type: 'string', + enum: ['email', 'webhook'], + }, + userId: { + type: 'string', + format: 'misskey:id', + }, + systemWebhookId: { + type: 'string', + format: 'misskey:id', + }, + }, + required: [ + 'id', + 'isActive', + 'name', + 'method', + ], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + @Inject(DI.userProfilesRepository) + private userProfilesRepository: UserProfilesRepository, + private abuseReportNotificationService: AbuseReportNotificationService, + private abuseReportNotificationRecipientEntityService: AbuseReportNotificationRecipientEntityService, + ) { + super(meta, paramDef, async (ps, me) => { + if (ps.method === 'email') { + const userProfile = await this.userProfilesRepository.findOneBy({ userId: ps.userId }); + if (!ps.userId || !userProfile) { + throw new ApiError(meta.errors.correlationCheckEmail); + } + + if (!userProfile.email || !userProfile.emailVerified) { + throw new ApiError(meta.errors.emailAddressNotSet); + } + } + + if (ps.method === 'webhook' && !ps.systemWebhookId) { + throw new ApiError(meta.errors.correlationCheckWebhook); + } + + const userId = ps.method === 'email' ? ps.userId : null; + const systemWebhookId = ps.method === 'webhook' ? ps.systemWebhookId : null; + const result = await this.abuseReportNotificationService.updateRecipient( + { + id: ps.id, + isActive: ps.isActive, + name: ps.name, + method: ps.method, + userId: userId ?? null, + systemWebhookId: systemWebhookId ?? null, + }, + me, + ); + + return this.abuseReportNotificationRecipientEntityService.pack(result); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/queue/stats.ts b/packages/backend/src/server/api/endpoints/admin/queue/stats.ts index 9694b3fa40a3..d7f9e4eaa301 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/stats.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/stats.ts @@ -5,7 +5,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, SystemQueue, WebhookDeliverQueue } from '@/core/QueueModule.js'; +import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, SystemQueue, UserWebhookDeliverQueue, SystemWebhookDeliverQueue } from '@/core/QueueModule.js'; export const meta = { tags: ['admin'], @@ -53,7 +53,8 @@ export default class extends Endpoint { // eslint- @Inject('queue:inbox') public inboxQueue: InboxQueue, @Inject('queue:db') public dbQueue: DbQueue, @Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue, - @Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue, + @Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue, + @Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue, ) { super(meta, paramDef, async (ps, me) => { const deliverJobCounts = await this.deliverQueue.getJobCounts(); diff --git a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts index 8b0456068b89..9b79100fcf50 100644 --- a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts +++ b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts @@ -5,12 +5,10 @@ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, AbuseUserReportsRepository } from '@/models/_.js'; -import { InstanceActorService } from '@/core/InstanceActorService.js'; -import { QueueService } from '@/core/QueueService.js'; -import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; +import type { AbuseUserReportsRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; -import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { ApiError } from '@/server/api/error.js'; +import { AbuseReportService } from '@/core/AbuseReportService.js'; export const meta = { tags: ['admin'], @@ -18,6 +16,16 @@ export const meta = { requireCredential: true, requireModerator: true, kind: 'write:admin:resolve-abuse-user-report', + + errors: { + noSuchAbuseReport: { + message: 'No such abuse report.', + code: 'NO_SUCH_ABUSE_REPORT', + id: 'ac3794dd-2ce4-d878-e546-73c60c06b398', + kind: 'server', + httpStatusCode: 404, + }, + }, } as const; export const paramDef = { @@ -29,47 +37,20 @@ export const paramDef = { required: ['reportId'], } as const; -// TODO: ロジックをサービスに切り出す - @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.abuseUserReportsRepository) private abuseUserReportsRepository: AbuseUserReportsRepository, - - private queueService: QueueService, - private instanceActorService: InstanceActorService, - private apRendererService: ApRendererService, - private moderationLogService: ModerationLogService, + private abuseReportService: AbuseReportService, ) { super(meta, paramDef, async (ps, me) => { const report = await this.abuseUserReportsRepository.findOneBy({ id: ps.reportId }); - - if (report == null) { - throw new Error('report not found'); + if (!report) { + throw new ApiError(meta.errors.noSuchAbuseReport); } - if (ps.forward && report.targetUserHost != null) { - const actor = await this.instanceActorService.getInstanceActor(); - const targetUser = await this.usersRepository.findOneByOrFail({ id: report.targetUserId }); - - this.queueService.deliver(actor, this.apRendererService.addContext(this.apRendererService.renderFlag(actor, targetUser.uri!, report.comment)), targetUser.inbox, false); - } - - await this.abuseUserReportsRepository.update(report.id, { - resolved: true, - assigneeId: me.id, - forwarded: ps.forward && report.targetUserHost != null, - }); - - this.moderationLogService.log(me, 'resolveAbuseReport', { - reportId: report.id, - report: report, - forwarded: ps.forward && report.targetUserHost != null, - }); + await this.abuseReportService.resolve([{ reportId: report.id, forward: ps.forward }], me); }); } } diff --git a/packages/backend/src/server/api/endpoints/admin/system-webhook/create.ts b/packages/backend/src/server/api/endpoints/admin/system-webhook/create.ts new file mode 100644 index 000000000000..28071e7a3382 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/system-webhook/create.ts @@ -0,0 +1,85 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js'; +import { systemWebhookEventTypes } from '@/models/SystemWebhook.js'; +import { SystemWebhookService } from '@/core/SystemWebhookService.js'; + +export const meta = { + tags: ['admin', 'system-webhook'], + + requireCredential: true, + requireModerator: true, + secure: true, + kind: 'write:admin:system-webhook', + + res: { + type: 'object', + ref: 'SystemWebhook', + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + isActive: { + type: 'boolean', + }, + name: { + type: 'string', + minLength: 1, + maxLength: 255, + }, + on: { + type: 'array', + items: { + type: 'string', + enum: systemWebhookEventTypes, + }, + }, + url: { + type: 'string', + minLength: 1, + maxLength: 1024, + }, + secret: { + type: 'string', + minLength: 1, + maxLength: 1024, + }, + }, + required: [ + 'isActive', + 'name', + 'on', + 'url', + 'secret', + ], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private systemWebhookService: SystemWebhookService, + private systemWebhookEntityService: SystemWebhookEntityService, + ) { + super(meta, paramDef, async (ps, me) => { + const result = await this.systemWebhookService.createSystemWebhook( + { + isActive: ps.isActive, + name: ps.name, + on: ps.on, + url: ps.url, + secret: ps.secret, + }, + me, + ); + + return this.systemWebhookEntityService.pack(result); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/system-webhook/delete.ts b/packages/backend/src/server/api/endpoints/admin/system-webhook/delete.ts new file mode 100644 index 000000000000..9cdfc7e70fec --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/system-webhook/delete.ts @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { SystemWebhookService } from '@/core/SystemWebhookService.js'; + +export const meta = { + tags: ['admin', 'system-webhook'], + + requireCredential: true, + requireModerator: true, + secure: true, + kind: 'write:admin:system-webhook', +} as const; + +export const paramDef = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'misskey:id', + }, + }, + required: [ + 'id', + ], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private systemWebhookService: SystemWebhookService, + ) { + super(meta, paramDef, async (ps, me) => { + await this.systemWebhookService.deleteSystemWebhook( + ps.id, + me, + ); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/system-webhook/list.ts b/packages/backend/src/server/api/endpoints/admin/system-webhook/list.ts new file mode 100644 index 000000000000..7a440a774ed3 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/system-webhook/list.ts @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js'; +import { systemWebhookEventTypes } from '@/models/SystemWebhook.js'; +import { SystemWebhookService } from '@/core/SystemWebhookService.js'; + +export const meta = { + tags: ['admin', 'system-webhook'], + + requireCredential: true, + requireModerator: true, + secure: true, + kind: 'write:admin:system-webhook', + + res: { + type: 'array', + items: { + type: 'object', + ref: 'SystemWebhook', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + isActive: { + type: 'boolean', + }, + on: { + type: 'array', + items: { + type: 'string', + enum: systemWebhookEventTypes, + }, + }, + }, + required: [], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private systemWebhookService: SystemWebhookService, + private systemWebhookEntityService: SystemWebhookEntityService, + ) { + super(meta, paramDef, async (ps) => { + const webhooks = await this.systemWebhookService.fetchSystemWebhooks({ + isActive: ps.isActive, + on: ps.on, + }); + return this.systemWebhookEntityService.packMany(webhooks); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/system-webhook/show.ts b/packages/backend/src/server/api/endpoints/admin/system-webhook/show.ts new file mode 100644 index 000000000000..75862c96a7d1 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/system-webhook/show.ts @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js'; +import { ApiError } from '@/server/api/error.js'; +import { SystemWebhookService } from '@/core/SystemWebhookService.js'; + +export const meta = { + tags: ['admin', 'system-webhook'], + + requireCredential: true, + requireModerator: true, + secure: true, + kind: 'write:admin:system-webhook', + + res: { + type: 'object', + ref: 'SystemWebhook', + }, + + errors: { + noSuchSystemWebhook: { + message: 'No such SystemWebhook.', + code: 'NO_SUCH_SYSTEM_WEBHOOK', + id: '38dd1ffe-04b4-6ff5-d8ba-4e6a6ae22c9d', + kind: 'server', + httpStatusCode: 404, + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'misskey:id', + }, + }, + required: ['id'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private systemWebhookService: SystemWebhookService, + private systemWebhookEntityService: SystemWebhookEntityService, + ) { + super(meta, paramDef, async (ps) => { + const webhooks = await this.systemWebhookService.fetchSystemWebhooks({ ids: [ps.id] }); + if (webhooks.length === 0) { + throw new ApiError(meta.errors.noSuchSystemWebhook); + } + + return this.systemWebhookEntityService.pack(webhooks[0]); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/system-webhook/update.ts b/packages/backend/src/server/api/endpoints/admin/system-webhook/update.ts new file mode 100644 index 000000000000..8d68bb8f87d8 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/system-webhook/update.ts @@ -0,0 +1,91 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js'; +import { systemWebhookEventTypes } from '@/models/SystemWebhook.js'; +import { SystemWebhookService } from '@/core/SystemWebhookService.js'; + +export const meta = { + tags: ['admin', 'system-webhook'], + + requireCredential: true, + requireModerator: true, + secure: true, + kind: 'write:admin:system-webhook', + + res: { + type: 'object', + ref: 'SystemWebhook', + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'misskey:id', + }, + isActive: { + type: 'boolean', + }, + name: { + type: 'string', + minLength: 1, + maxLength: 255, + }, + on: { + type: 'array', + items: { + type: 'string', + enum: systemWebhookEventTypes, + }, + }, + url: { + type: 'string', + minLength: 1, + maxLength: 1024, + }, + secret: { + type: 'string', + minLength: 1, + maxLength: 1024, + }, + }, + required: [ + 'id', + 'isActive', + 'name', + 'on', + 'url', + 'secret', + ], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private systemWebhookService: SystemWebhookService, + private systemWebhookEntityService: SystemWebhookEntityService, + ) { + super(meta, paramDef, async (ps, me) => { + const result = await this.systemWebhookService.updateSystemWebhook( + { + id: ps.id, + isActive: ps.isActive, + name: ps.name, + on: ps.on, + url: ps.url, + secret: ps.secret, + }, + me, + ); + + return this.systemWebhookEntityService.pack(result); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/users/report-abuse.ts b/packages/backend/src/server/api/endpoints/users/report-abuse.ts index 48e14b68cca5..5ff6de37d2ca 100644 --- a/packages/backend/src/server/api/endpoints/users/report-abuse.ts +++ b/packages/backend/src/server/api/endpoints/users/report-abuse.ts @@ -3,17 +3,11 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import sanitizeHtml from 'sanitize-html'; -import { Inject, Injectable } from '@nestjs/common'; -import type { AbuseUserReportsRepository } from '@/models/_.js'; -import { IdService } from '@/core/IdService.js'; +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; -import { MetaService } from '@/core/MetaService.js'; -import { EmailService } from '@/core/EmailService.js'; -import { DI } from '@/di-symbols.js'; import { GetterService } from '@/server/api/GetterService.js'; import { RoleService } from '@/core/RoleService.js'; +import { AbuseReportService } from '@/core/AbuseReportService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -57,60 +51,32 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.abuseUserReportsRepository) - private abuseUserReportsRepository: AbuseUserReportsRepository, - - private idService: IdService, - private metaService: MetaService, - private emailService: EmailService, private getterService: GetterService, private roleService: RoleService, - private globalEventService: GlobalEventService, + private abuseReportService: AbuseReportService, ) { super(meta, paramDef, async (ps, me) => { // Lookup user - const user = await this.getterService.getUser(ps.userId).catch(err => { + const targetUser = await this.getterService.getUser(ps.userId).catch(err => { if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); throw err; }); - if (user.id === me.id) { + if (targetUser.id === me.id) { throw new ApiError(meta.errors.cannotReportYourself); } - if (await this.roleService.isAdministrator(user)) { + if (await this.roleService.isAdministrator(targetUser)) { throw new ApiError(meta.errors.cannotReportAdmin); } - const report = await this.abuseUserReportsRepository.insertOne({ - id: this.idService.gen(), - targetUserId: user.id, - targetUserHost: user.host, + await this.abuseReportService.report([{ + targetUserId: targetUser.id, + targetUserHost: targetUser.host, reporterId: me.id, reporterHost: null, comment: ps.comment, - }); - - // Publish event to moderators - setImmediate(async () => { - const moderators = await this.roleService.getModerators(); - - for (const moderator of moderators) { - this.globalEventService.publishAdminStream(moderator.id, 'newAbuseUserReport', { - id: report.id, - targetUserId: report.targetUserId, - reporterId: report.reporterId, - comment: report.comment, - }); - } - - const meta = await this.metaService.fetch(); - if (meta.email) { - this.emailService.sendEmail(meta.email, 'New abuse report', - sanitizeHtml(ps.comment), - sanitizeHtml(ps.comment)); - } - }); + }]); }); } } diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index ab03489c0d76..f55790b6363b 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -25,7 +25,16 @@ import { getNoteSummary } from '@/misc/get-note-summary.js'; import { DI } from '@/di-symbols.js'; import * as Acct from '@/misc/acct.js'; import { MetaService } from '@/core/MetaService.js'; -import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, SystemQueue, WebhookDeliverQueue } from '@/core/QueueModule.js'; +import type { + DbQueue, + DeliverQueue, + EndedPollNotificationQueue, + InboxQueue, + ObjectStorageQueue, + SystemQueue, + UserWebhookDeliverQueue, + SystemWebhookDeliverQueue, +} from '@/core/QueueModule.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { PageEntityService } from '@/core/entities/PageEntityService.js'; @@ -111,7 +120,8 @@ export class ClientServerService { @Inject('queue:inbox') public inboxQueue: InboxQueue, @Inject('queue:db') public dbQueue: DbQueue, @Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue, - @Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue, + @Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue, + @Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue, ) { //this.createServer = this.createServer.bind(this); } @@ -239,7 +249,8 @@ export class ClientServerService { this.inboxQueue, this.dbQueue, this.objectStorageQueue, - this.webhookDeliverQueue, + this.userWebhookDeliverQueue, + this.systemWebhookDeliverQueue, ].map(q => new BullMQAdapter(q)), serverAdapter, }); diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 929070d0d290..ecbbee4eff1b 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -90,6 +90,12 @@ export const moderationLogTypes = [ 'deleteAvatarDecoration', 'unsetUserAvatar', 'unsetUserBanner', + 'createSystemWebhook', + 'updateSystemWebhook', + 'deleteSystemWebhook', + 'createAbuseReportNotificationRecipient', + 'updateAbuseReportNotificationRecipient', + 'deleteAbuseReportNotificationRecipient', ] as const; export type ModerationLogPayloads = { @@ -282,6 +288,32 @@ export type ModerationLogPayloads = { userHost: string | null; fileId: string; }; + createSystemWebhook: { + systemWebhookId: string; + webhook: any; + }; + updateSystemWebhook: { + systemWebhookId: string; + before: any; + after: any; + }; + deleteSystemWebhook: { + systemWebhookId: string; + webhook: any; + }; + createAbuseReportNotificationRecipient: { + recipientId: string; + recipient: any; + }; + updateAbuseReportNotificationRecipient: { + recipientId: string; + before: any; + after: any; + }; + deleteAbuseReportNotificationRecipient: { + recipientId: string; + recipient: any; + }; }; export type Serialized = { diff --git a/packages/backend/test/e2e/synalio/abuse-report.ts b/packages/backend/test/e2e/synalio/abuse-report.ts new file mode 100644 index 000000000000..b0cc3d13ecb4 --- /dev/null +++ b/packages/backend/test/e2e/synalio/abuse-report.ts @@ -0,0 +1,401 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { entities } from 'misskey-js'; +import { beforeEach, describe, test } from '@jest/globals'; +import Fastify from 'fastify'; +import { api, randomString, role, signup, startJobQueue, UserToken } from '../../utils.js'; +import type { INestApplicationContext } from '@nestjs/common'; + +const WEBHOOK_HOST = 'http://localhost:15080'; +const WEBHOOK_PORT = 15080; +process.env.NODE_ENV = 'test'; + +describe('[シナリオ] ユーザ通報', () => { + let queue: INestApplicationContext; + let admin: entities.SignupResponse; + let alice: entities.SignupResponse; + let bob: entities.SignupResponse; + + type SystemWebhookPayload = { + server: string; + hookId: string; + eventId: string; + createdAt: string; + type: string; + body: any; + } + + // ------------------------------------------------------------------------------------------- + + async function captureWebhook(postAction: () => Promise): Promise { + const fastify = Fastify(); + + let timeoutHandle: NodeJS.Timeout | null = null; + const result = await new Promise(async (resolve, reject) => { + fastify.all('/', async (req, res) => { + timeoutHandle && clearTimeout(timeoutHandle); + + const body = JSON.stringify(req.body); + res.status(200).send('ok'); + await fastify.close(); + resolve(body); + }); + + await fastify.listen({ port: WEBHOOK_PORT }); + + timeoutHandle = setTimeout(async () => { + await fastify.close(); + reject(new Error('timeout')); + }, 3000); + + try { + await postAction(); + } catch (e) { + await fastify.close(); + reject(e); + } + }); + + await fastify.close(); + + return JSON.parse(result) as T; + } + + async function createSystemWebhook(args?: Partial, credential?: UserToken): Promise { + const res = await api( + 'admin/system-webhook/create', + { + isActive: true, + name: randomString(), + on: ['abuseReport'], + url: WEBHOOK_HOST, + secret: randomString(), + ...args, + }, + credential ?? admin, + ); + return res.body; + } + + async function createAbuseReportNotificationRecipient(args?: Partial, credential?: UserToken): Promise { + const res = await api( + 'admin/abuse-report/notification-recipient/create', + { + isActive: true, + name: randomString(), + method: 'webhook', + ...args, + }, + credential ?? admin, + ); + return res.body; + } + + async function createAbuseReport(args?: Partial, credential?: UserToken): Promise { + const res = await api( + 'users/report-abuse', + { + userId: alice.id, + comment: randomString(), + ...args, + }, + credential ?? admin, + ); + return res.body; + } + + async function resolveAbuseReport(args?: Partial, credential?: UserToken): Promise { + const res = await api( + 'admin/resolve-abuse-user-report', + { + reportId: admin.id, + ...args, + }, + credential ?? admin, + ); + return res.body; + } + + // ------------------------------------------------------------------------------------------- + + beforeAll(async () => { + queue = await startJobQueue(); + admin = await signup({ username: 'admin' }); + alice = await signup({ username: 'alice' }); + bob = await signup({ username: 'bob' }); + + await role(admin, { isAdministrator: true }); + }, 1000 * 60 * 2); + + afterAll(async () => { + await queue.close(); + }); + + // ------------------------------------------------------------------------------------------- + + describe('SystemWebhook', () => { + beforeEach(async () => { + const webhooks = await api('admin/system-webhook/list', {}, admin); + for (const webhook of webhooks.body) { + await api('admin/system-webhook/delete', { id: webhook.id }, admin); + } + }); + + test('通報を受けた -> abuseReportが送出される', async () => { + const webhook = await createSystemWebhook({ + on: ['abuseReport'], + isActive: true, + }); + await createAbuseReportNotificationRecipient({ systemWebhookId: webhook.id }); + + // 通報(bob -> alice) + const abuse = { + userId: alice.id, + comment: randomString(), + }; + const webhookBody = await captureWebhook(async () => { + await createAbuseReport(abuse, bob); + }); + + console.log(JSON.stringify(webhookBody, null, 2)); + + expect(webhookBody.hookId).toBe(webhook.id); + expect(webhookBody.type).toBe('abuseReport'); + expect(webhookBody.body.targetUserId).toBe(alice.id); + expect(webhookBody.body.reporterId).toBe(bob.id); + expect(webhookBody.body.comment).toBe(abuse.comment); + }); + + test('通報を受けた -> abuseReportが送出される -> 解決 -> abuseReportResolvedが送出される', async () => { + const webhook = await createSystemWebhook({ + on: ['abuseReport', 'abuseReportResolved'], + isActive: true, + }); + await createAbuseReportNotificationRecipient({ systemWebhookId: webhook.id }); + + // 通報(bob -> alice) + const abuse = { + userId: alice.id, + comment: randomString(), + }; + const webhookBody1 = await captureWebhook(async () => { + await createAbuseReport(abuse, bob); + }); + + console.log(JSON.stringify(webhookBody1, null, 2)); + expect(webhookBody1.hookId).toBe(webhook.id); + expect(webhookBody1.type).toBe('abuseReport'); + expect(webhookBody1.body.targetUserId).toBe(alice.id); + expect(webhookBody1.body.reporterId).toBe(bob.id); + expect(webhookBody1.body.assigneeId).toBeNull(); + expect(webhookBody1.body.resolved).toBe(false); + expect(webhookBody1.body.comment).toBe(abuse.comment); + + // 解決 + const webhookBody2 = await captureWebhook(async () => { + await resolveAbuseReport({ + reportId: webhookBody1.body.id, + forward: false, + }, admin); + }); + + console.log(JSON.stringify(webhookBody2, null, 2)); + expect(webhookBody2.hookId).toBe(webhook.id); + expect(webhookBody2.type).toBe('abuseReportResolved'); + expect(webhookBody2.body.targetUserId).toBe(alice.id); + expect(webhookBody2.body.reporterId).toBe(bob.id); + expect(webhookBody2.body.assigneeId).toBe(admin.id); + expect(webhookBody2.body.resolved).toBe(true); + expect(webhookBody2.body.comment).toBe(abuse.comment); + }); + + test('通報を受けた -> abuseReportが未許可の場合は送出されない', async () => { + const webhook = await createSystemWebhook({ + on: [], + isActive: true, + }); + await createAbuseReportNotificationRecipient({ systemWebhookId: webhook.id }); + + // 通報(bob -> alice) + const abuse = { + userId: alice.id, + comment: randomString(), + }; + const webhookBody = await captureWebhook(async () => { + await createAbuseReport(abuse, bob); + }).catch(e => e.message); + + expect(webhookBody).toBe('timeout'); + }); + + test('通報を受けた -> abuseReportが未許可の場合は送出されない -> 解決 -> abuseReportResolvedが送出される', async () => { + const webhook = await createSystemWebhook({ + on: ['abuseReportResolved'], + isActive: true, + }); + await createAbuseReportNotificationRecipient({ systemWebhookId: webhook.id }); + + // 通報(bob -> alice) + const abuse = { + userId: alice.id, + comment: randomString(), + }; + const webhookBody1 = await captureWebhook(async () => { + await createAbuseReport(abuse, bob); + }).catch(e => e.message); + + expect(webhookBody1).toBe('timeout'); + + const abuseReportId = (await api('admin/abuse-user-reports', {}, admin)).body[0].id; + + // 解決 + const webhookBody2 = await captureWebhook(async () => { + await resolveAbuseReport({ + reportId: abuseReportId, + forward: false, + }, admin); + }); + + console.log(JSON.stringify(webhookBody2, null, 2)); + expect(webhookBody2.hookId).toBe(webhook.id); + expect(webhookBody2.type).toBe('abuseReportResolved'); + expect(webhookBody2.body.targetUserId).toBe(alice.id); + expect(webhookBody2.body.reporterId).toBe(bob.id); + expect(webhookBody2.body.assigneeId).toBe(admin.id); + expect(webhookBody2.body.resolved).toBe(true); + expect(webhookBody2.body.comment).toBe(abuse.comment); + }); + + test('通報を受けた -> abuseReportが送出される -> 解決 -> abuseReportResolvedが未許可の場合は送出されない', async () => { + const webhook = await createSystemWebhook({ + on: ['abuseReport'], + isActive: true, + }); + await createAbuseReportNotificationRecipient({ systemWebhookId: webhook.id }); + + // 通報(bob -> alice) + const abuse = { + userId: alice.id, + comment: randomString(), + }; + const webhookBody1 = await captureWebhook(async () => { + await createAbuseReport(abuse, bob); + }); + + console.log(JSON.stringify(webhookBody1, null, 2)); + expect(webhookBody1.hookId).toBe(webhook.id); + expect(webhookBody1.type).toBe('abuseReport'); + expect(webhookBody1.body.targetUserId).toBe(alice.id); + expect(webhookBody1.body.reporterId).toBe(bob.id); + expect(webhookBody1.body.assigneeId).toBeNull(); + expect(webhookBody1.body.resolved).toBe(false); + expect(webhookBody1.body.comment).toBe(abuse.comment); + + // 解決 + const webhookBody2 = await captureWebhook(async () => { + await resolveAbuseReport({ + reportId: webhookBody1.body.id, + forward: false, + }, admin); + }).catch(e => e.message); + + expect(webhookBody2).toBe('timeout'); + }); + + test('通報を受けた -> abuseReportが未許可の場合は送出されない -> 解決 -> abuseReportResolvedが未許可の場合は送出されない', async () => { + const webhook = await createSystemWebhook({ + on: [], + isActive: true, + }); + await createAbuseReportNotificationRecipient({ systemWebhookId: webhook.id }); + + // 通報(bob -> alice) + const abuse = { + userId: alice.id, + comment: randomString(), + }; + const webhookBody1 = await captureWebhook(async () => { + await createAbuseReport(abuse, bob); + }).catch(e => e.message); + + expect(webhookBody1).toBe('timeout'); + + const abuseReportId = (await api('admin/abuse-user-reports', {}, admin)).body[0].id; + + // 解決 + const webhookBody2 = await captureWebhook(async () => { + await resolveAbuseReport({ + reportId: abuseReportId, + forward: false, + }, admin); + }).catch(e => e.message); + + expect(webhookBody2).toBe('timeout'); + }); + + test('通報を受けた -> Webhookが無効の場合は送出されない', async () => { + const webhook = await createSystemWebhook({ + on: ['abuseReport', 'abuseReportResolved'], + isActive: false, + }); + await createAbuseReportNotificationRecipient({ systemWebhookId: webhook.id }); + + // 通報(bob -> alice) + const abuse = { + userId: alice.id, + comment: randomString(), + }; + const webhookBody1 = await captureWebhook(async () => { + await createAbuseReport(abuse, bob); + }).catch(e => e.message); + + expect(webhookBody1).toBe('timeout'); + + const abuseReportId = (await api('admin/abuse-user-reports', {}, admin)).body[0].id; + + // 解決 + const webhookBody2 = await captureWebhook(async () => { + await resolveAbuseReport({ + reportId: abuseReportId, + forward: false, + }, admin); + }).catch(e => e.message); + + expect(webhookBody2).toBe('timeout'); + }); + + test('通報を受けた -> 通知設定が無効の場合は送出されない', async () => { + const webhook = await createSystemWebhook({ + on: ['abuseReport', 'abuseReportResolved'], + isActive: true, + }); + await createAbuseReportNotificationRecipient({ systemWebhookId: webhook.id, isActive: false }); + + // 通報(bob -> alice) + const abuse = { + userId: alice.id, + comment: randomString(), + }; + const webhookBody1 = await captureWebhook(async () => { + await createAbuseReport(abuse, bob); + }).catch(e => e.message); + + expect(webhookBody1).toBe('timeout'); + + const abuseReportId = (await api('admin/abuse-user-reports', {}, admin)).body[0].id; + + // 解決 + const webhookBody2 = await captureWebhook(async () => { + await resolveAbuseReport({ + reportId: abuseReportId, + forward: false, + }, admin); + }).catch(e => e.message); + + expect(webhookBody2).toBe('timeout'); + }); + }); +}); diff --git a/packages/backend/test/unit/AbuseReportNotificationService.ts b/packages/backend/test/unit/AbuseReportNotificationService.ts new file mode 100644 index 000000000000..e971659070ea --- /dev/null +++ b/packages/backend/test/unit/AbuseReportNotificationService.ts @@ -0,0 +1,343 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { jest } from '@jest/globals'; +import { Test, TestingModule } from '@nestjs/testing'; +import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationService.js'; +import { + AbuseReportNotificationRecipientRepository, + MiAbuseReportNotificationRecipient, + MiSystemWebhook, + MiUser, + SystemWebhooksRepository, + UserProfilesRepository, + UsersRepository, +} from '@/models/_.js'; +import { DI } from '@/di-symbols.js'; +import { GlobalModule } from '@/GlobalModule.js'; +import { IdService } from '@/core/IdService.js'; +import { EmailService } from '@/core/EmailService.js'; +import { RoleService } from '@/core/RoleService.js'; +import { MetaService } from '@/core/MetaService.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { GlobalEventService } from '@/core/GlobalEventService.js'; +import { RecipientMethod } from '@/models/AbuseReportNotificationRecipient.js'; +import { SystemWebhookService } from '@/core/SystemWebhookService.js'; +import { randomString } from '../utils.js'; + +process.env.NODE_ENV = 'test'; + +describe('AbuseReportNotificationService', () => { + let app: TestingModule; + let service: AbuseReportNotificationService; + + // -------------------------------------------------------------------------------------- + + let usersRepository: UsersRepository; + let userProfilesRepository: UserProfilesRepository; + let systemWebhooksRepository: SystemWebhooksRepository; + let abuseReportNotificationRecipientRepository: AbuseReportNotificationRecipientRepository; + let idService: IdService; + let roleService: jest.Mocked; + let emailService: jest.Mocked; + let webhookService: jest.Mocked; + + // -------------------------------------------------------------------------------------- + + let root: MiUser; + let alice: MiUser; + let bob: MiUser; + let systemWebhook1: MiSystemWebhook; + let systemWebhook2: MiSystemWebhook; + + // -------------------------------------------------------------------------------------- + + async function createUser(data: Partial = {}) { + const user = await usersRepository + .insert({ + id: idService.gen(), + ...data, + }) + .then(x => usersRepository.findOneByOrFail(x.identifiers[0])); + + await userProfilesRepository.insert({ + userId: user.id, + }); + + return user; + } + + async function createWebhook(data: Partial = {}) { + return systemWebhooksRepository + .insert({ + id: idService.gen(), + name: randomString(), + on: ['abuseReport'], + url: 'https://example.com', + secret: randomString(), + ...data, + }) + .then(x => systemWebhooksRepository.findOneByOrFail(x.identifiers[0])); + } + + async function createRecipient(data: Partial = {}) { + return abuseReportNotificationRecipientRepository + .insert({ + id: idService.gen(), + isActive: true, + name: randomString(), + ...data, + }) + .then(x => abuseReportNotificationRecipientRepository.findOneByOrFail(x.identifiers[0])); + } + + // -------------------------------------------------------------------------------------- + + beforeAll(async () => { + app = await Test + .createTestingModule({ + imports: [ + GlobalModule, + ], + providers: [ + AbuseReportNotificationService, + IdService, + { + provide: RoleService, useFactory: () => ({ getModeratorIds: jest.fn() }), + }, + { + provide: SystemWebhookService, useFactory: () => ({ enqueueSystemWebhook: jest.fn() }), + }, + { + provide: EmailService, useFactory: () => ({ sendEmail: jest.fn() }), + }, + { + provide: MetaService, useFactory: () => ({ fetch: jest.fn() }), + }, + { + provide: ModerationLogService, useFactory: () => ({ log: () => Promise.resolve() }), + }, + { + provide: GlobalEventService, useFactory: () => ({ publishAdminStream: jest.fn() }), + }, + ], + }) + .compile(); + + usersRepository = app.get(DI.usersRepository); + userProfilesRepository = app.get(DI.userProfilesRepository); + systemWebhooksRepository = app.get(DI.systemWebhooksRepository); + abuseReportNotificationRecipientRepository = app.get(DI.abuseReportNotificationRecipientRepository); + + service = app.get(AbuseReportNotificationService); + idService = app.get(IdService); + roleService = app.get(RoleService) as jest.Mocked; + emailService = app.get(EmailService) as jest.Mocked; + webhookService = app.get(SystemWebhookService) as jest.Mocked; + + app.enableShutdownHooks(); + }); + + beforeEach(async () => { + root = await createUser({ username: 'root', usernameLower: 'root', isRoot: true }); + alice = await createUser({ username: 'alice', usernameLower: 'alice', isRoot: false }); + bob = await createUser({ username: 'bob', usernameLower: 'bob', isRoot: false }); + systemWebhook1 = await createWebhook(); + systemWebhook2 = await createWebhook(); + + roleService.getModeratorIds.mockResolvedValue([root.id, alice.id, bob.id]); + }); + + afterEach(async () => { + emailService.sendEmail.mockClear(); + webhookService.enqueueSystemWebhook.mockClear(); + + await usersRepository.delete({}); + await userProfilesRepository.delete({}); + await systemWebhooksRepository.delete({}); + await abuseReportNotificationRecipientRepository.delete({}); + }); + + afterAll(async () => { + await app.close(); + }); + + // -------------------------------------------------------------------------------------- + + describe('createRecipient', () => { + test('作成成功1', async () => { + const params = { + isActive: true, + name: randomString(), + method: 'email' as RecipientMethod, + userId: alice.id, + systemWebhookId: null, + }; + + const recipient1 = await service.createRecipient(params, root); + expect(recipient1).toMatchObject(params); + }); + + test('作成成功2', async () => { + const params = { + isActive: true, + name: randomString(), + method: 'webhook' as RecipientMethod, + userId: null, + systemWebhookId: systemWebhook1.id, + }; + + const recipient1 = await service.createRecipient(params, root); + expect(recipient1).toMatchObject(params); + }); + }); + + describe('updateRecipient', () => { + test('更新成功1', async () => { + const recipient1 = await createRecipient({ + method: 'email', + userId: alice.id, + }); + + const params = { + id: recipient1.id, + isActive: false, + name: randomString(), + method: 'email' as RecipientMethod, + userId: bob.id, + systemWebhookId: null, + }; + + const recipient2 = await service.updateRecipient(params, root); + expect(recipient2).toMatchObject(params); + }); + + test('更新成功2', async () => { + const recipient1 = await createRecipient({ + method: 'webhook', + systemWebhookId: systemWebhook1.id, + }); + + const params = { + id: recipient1.id, + isActive: false, + name: randomString(), + method: 'webhook' as RecipientMethod, + userId: null, + systemWebhookId: systemWebhook2.id, + }; + + const recipient2 = await service.updateRecipient(params, root); + expect(recipient2).toMatchObject(params); + }); + }); + + describe('deleteRecipient', () => { + test('削除成功1', async () => { + const recipient1 = await createRecipient({ + method: 'email', + userId: alice.id, + }); + + await service.deleteRecipient(recipient1.id, root); + + await expect(abuseReportNotificationRecipientRepository.findOneBy({ id: recipient1.id })).resolves.toBeNull(); + }); + }); + + describe('fetchRecipients', () => { + async function create() { + const recipient1 = await createRecipient({ + method: 'email', + userId: alice.id, + }); + const recipient2 = await createRecipient({ + method: 'email', + userId: bob.id, + }); + + const recipient3 = await createRecipient({ + method: 'webhook', + systemWebhookId: systemWebhook1.id, + }); + const recipient4 = await createRecipient({ + method: 'webhook', + systemWebhookId: systemWebhook2.id, + }); + + return [recipient1, recipient2, recipient3, recipient4]; + } + + test('フィルタなし', async () => { + const [recipient1, recipient2, recipient3, recipient4] = await create(); + + const recipients = await service.fetchRecipients({}); + expect(recipients).toEqual([recipient1, recipient2, recipient3, recipient4]); + }); + + test('フィルタなし(非モデレータは除外される)', async () => { + roleService.getModeratorIds.mockClear(); + roleService.getModeratorIds.mockResolvedValue([root.id, bob.id]); + + const [recipient1, recipient2, recipient3, recipient4] = await create(); + + const recipients = await service.fetchRecipients({}); + // aliceはモデレータではないので除外される + expect(recipients).toEqual([recipient2, recipient3, recipient4]); + }); + + test('フィルタなし(非モデレータでも除外されないオプション設定)', async () => { + roleService.getModeratorIds.mockClear(); + roleService.getModeratorIds.mockResolvedValue([root.id, bob.id]); + + const [recipient1, recipient2, recipient3, recipient4] = await create(); + + const recipients = await service.fetchRecipients({}, { removeUnauthorized: false }); + expect(recipients).toEqual([recipient1, recipient2, recipient3, recipient4]); + }); + + test('emailのみ', async () => { + const [recipient1, recipient2, recipient3, recipient4] = await create(); + + const recipients = await service.fetchRecipients({ method: ['email'] }); + expect(recipients).toEqual([recipient1, recipient2]); + }); + + test('webhookのみ', async () => { + const [recipient1, recipient2, recipient3, recipient4] = await create(); + + const recipients = await service.fetchRecipients({ method: ['webhook'] }); + expect(recipients).toEqual([recipient3, recipient4]); + }); + + test('すべて', async () => { + const [recipient1, recipient2, recipient3, recipient4] = await create(); + + const recipients = await service.fetchRecipients({ method: ['email', 'webhook'] }); + expect(recipients).toEqual([recipient1, recipient2, recipient3, recipient4]); + }); + + test('ID指定', async () => { + const [recipient1, recipient2, recipient3, recipient4] = await create(); + + const recipients = await service.fetchRecipients({ ids: [recipient1.id, recipient3.id] }); + expect(recipients).toEqual([recipient1, recipient3]); + }); + + test('ID指定(method=emailではないIDが混ざりこまない)', async () => { + const [recipient1, recipient2, recipient3, recipient4] = await create(); + + const recipients = await service.fetchRecipients({ ids: [recipient1.id, recipient3.id], method: ['email'] }); + expect(recipients).toEqual([recipient1]); + }); + + test('ID指定(method=webhookではないIDが混ざりこまない)', async () => { + const [recipient1, recipient2, recipient3, recipient4] = await create(); + + const recipients = await service.fetchRecipients({ ids: [recipient1.id, recipient3.id], method: ['webhook'] }); + expect(recipients).toEqual([recipient3]); + }); + }); +}); diff --git a/packages/backend/test/unit/RoleService.ts b/packages/backend/test/unit/RoleService.ts index ec441735d7e6..69fa4162fbac 100644 --- a/packages/backend/test/unit/RoleService.ts +++ b/packages/backend/test/unit/RoleService.ts @@ -3,8 +3,6 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { UserEntityService } from '@/core/entities/UserEntityService.js'; - process.env.NODE_ENV = 'test'; import { jest } from '@jest/globals'; @@ -13,7 +11,14 @@ import { Test } from '@nestjs/testing'; import * as lolex from '@sinonjs/fake-timers'; import { GlobalModule } from '@/GlobalModule.js'; import { RoleService } from '@/core/RoleService.js'; -import type { MiRole, MiUser, RoleAssignmentsRepository, RolesRepository, UsersRepository } from '@/models/_.js'; +import { + MiRole, + MiRoleAssignment, + MiUser, + RoleAssignmentsRepository, + RolesRepository, + UsersRepository, +} from '@/models/_.js'; import { DI } from '@/di-symbols.js'; import { MetaService } from '@/core/MetaService.js'; import { genAidx } from '@/misc/id/aidx.js'; @@ -23,6 +28,7 @@ import { GlobalEventService } from '@/core/GlobalEventService.js'; import { secureRndstr } from '@/misc/secure-rndstr.js'; import { NotificationService } from '@/core/NotificationService.js'; import { RoleCondFormulaValue } from '@/models/Role.js'; +import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { sleep } from '../utils.js'; import type { TestingModule } from '@nestjs/testing'; import type { MockFunctionMetadata } from 'jest-mock'; @@ -39,27 +45,27 @@ describe('RoleService', () => { let notificationService: jest.Mocked; let clock: lolex.InstalledClock; - function createUser(data: Partial = {}) { + async function createUser(data: Partial = {}) { const un = secureRndstr(16); - return usersRepository.insert({ + const x = await usersRepository.insert({ id: genAidx(Date.now()), username: un, usernameLower: un, ...data, - }) - .then(x => usersRepository.findOneByOrFail(x.identifiers[0])); + }); + return await usersRepository.findOneByOrFail(x.identifiers[0]); } - function createRole(data: Partial = {}) { - return rolesRepository.insert({ + async function createRole(data: Partial = {}) { + const x = await rolesRepository.insert({ id: genAidx(Date.now()), updatedAt: new Date(), lastUsedAt: new Date(), name: '', description: '', ...data, - }) - .then(x => rolesRepository.findOneByOrFail(x.identifiers[0])); + }); + return await rolesRepository.findOneByOrFail(x.identifiers[0]); } function createConditionalRole(condFormula: RoleCondFormulaValue, data: Partial = {}) { @@ -71,6 +77,20 @@ describe('RoleService', () => { }); } + async function assignRole(args: Partial) { + const id = genAidx(Date.now()); + const expiresAt = new Date(); + expiresAt.setDate(expiresAt.getDate() + 1); + + await roleAssignmentsRepository.insert({ + id, + expiresAt, + ...args, + }); + + return await roleAssignmentsRepository.findOneByOrFail({ id }); + } + function aidx() { return genAidx(Date.now()); } @@ -265,6 +285,96 @@ describe('RoleService', () => { }); }); + describe('getModeratorIds', () => { + test('includeAdmins = false, excludeExpire = false', async () => { + const [adminUser1, adminUser2, modeUser1, modeUser2, normalUser1, normalUser2] = await Promise.all([ + createUser(), createUser(), createUser(), createUser(), createUser(), createUser(), + ]); + + const role1 = await createRole({ name: 'admin', isAdministrator: true }); + const role2 = await createRole({ name: 'moderator', isModerator: true }); + const role3 = await createRole({ name: 'normal' }); + + await Promise.all([ + assignRole({ userId: adminUser1.id, roleId: role1.id }), + assignRole({ userId: adminUser2.id, roleId: role1.id, expiresAt: new Date(Date.now() - 1000) }), + assignRole({ userId: modeUser1.id, roleId: role2.id }), + assignRole({ userId: modeUser2.id, roleId: role2.id, expiresAt: new Date(Date.now() - 1000) }), + assignRole({ userId: normalUser1.id, roleId: role3.id }), + assignRole({ userId: normalUser2.id, roleId: role3.id, expiresAt: new Date(Date.now() - 1000) }), + ]); + + const result = await roleService.getModeratorIds(false, false); + expect(result).toEqual([modeUser1.id, modeUser2.id]); + }); + + test('includeAdmins = false, excludeExpire = true', async () => { + const [adminUser1, adminUser2, modeUser1, modeUser2, normalUser1, normalUser2] = await Promise.all([ + createUser(), createUser(), createUser(), createUser(), createUser(), createUser(), + ]); + + const role1 = await createRole({ name: 'admin', isAdministrator: true }); + const role2 = await createRole({ name: 'moderator', isModerator: true }); + const role3 = await createRole({ name: 'normal' }); + + await Promise.all([ + assignRole({ userId: adminUser1.id, roleId: role1.id }), + assignRole({ userId: adminUser2.id, roleId: role1.id, expiresAt: new Date(Date.now() - 1000) }), + assignRole({ userId: modeUser1.id, roleId: role2.id }), + assignRole({ userId: modeUser2.id, roleId: role2.id, expiresAt: new Date(Date.now() - 1000) }), + assignRole({ userId: normalUser1.id, roleId: role3.id }), + assignRole({ userId: normalUser2.id, roleId: role3.id, expiresAt: new Date(Date.now() - 1000) }), + ]); + + const result = await roleService.getModeratorIds(false, true); + expect(result).toEqual([modeUser1.id]); + }); + + test('includeAdmins = true, excludeExpire = false', async () => { + const [adminUser1, adminUser2, modeUser1, modeUser2, normalUser1, normalUser2] = await Promise.all([ + createUser(), createUser(), createUser(), createUser(), createUser(), createUser(), + ]); + + const role1 = await createRole({ name: 'admin', isAdministrator: true }); + const role2 = await createRole({ name: 'moderator', isModerator: true }); + const role3 = await createRole({ name: 'normal' }); + + await Promise.all([ + assignRole({ userId: adminUser1.id, roleId: role1.id }), + assignRole({ userId: adminUser2.id, roleId: role1.id, expiresAt: new Date(Date.now() - 1000) }), + assignRole({ userId: modeUser1.id, roleId: role2.id }), + assignRole({ userId: modeUser2.id, roleId: role2.id, expiresAt: new Date(Date.now() - 1000) }), + assignRole({ userId: normalUser1.id, roleId: role3.id }), + assignRole({ userId: normalUser2.id, roleId: role3.id, expiresAt: new Date(Date.now() - 1000) }), + ]); + + const result = await roleService.getModeratorIds(true, false); + expect(result).toEqual([adminUser1.id, adminUser2.id, modeUser1.id, modeUser2.id]); + }); + + test('includeAdmins = true, excludeExpire = true', async () => { + const [adminUser1, adminUser2, modeUser1, modeUser2, normalUser1, normalUser2] = await Promise.all([ + createUser(), createUser(), createUser(), createUser(), createUser(), createUser(), + ]); + + const role1 = await createRole({ name: 'admin', isAdministrator: true }); + const role2 = await createRole({ name: 'moderator', isModerator: true }); + const role3 = await createRole({ name: 'normal' }); + + await Promise.all([ + assignRole({ userId: adminUser1.id, roleId: role1.id }), + assignRole({ userId: adminUser2.id, roleId: role1.id, expiresAt: new Date(Date.now() - 1000) }), + assignRole({ userId: modeUser1.id, roleId: role2.id }), + assignRole({ userId: modeUser2.id, roleId: role2.id, expiresAt: new Date(Date.now() - 1000) }), + assignRole({ userId: normalUser1.id, roleId: role3.id }), + assignRole({ userId: normalUser2.id, roleId: role3.id, expiresAt: new Date(Date.now() - 1000) }), + ]); + + const result = await roleService.getModeratorIds(true, true); + expect(result).toEqual([adminUser1.id, modeUser1.id]); + }); + }); + describe('conditional role', () => { test('~かつ~', async () => { const [user1, user2, user3, user4] = await Promise.all([ diff --git a/packages/backend/test/unit/SystemWebhookService.ts b/packages/backend/test/unit/SystemWebhookService.ts new file mode 100644 index 000000000000..41b7f977ca8a --- /dev/null +++ b/packages/backend/test/unit/SystemWebhookService.ts @@ -0,0 +1,515 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { afterEach, beforeEach, describe, expect, jest } from '@jest/globals'; +import { Test, TestingModule } from '@nestjs/testing'; +import { MiUser } from '@/models/User.js'; +import { MiSystemWebhook, SystemWebhookEventType } from '@/models/SystemWebhook.js'; +import { SystemWebhooksRepository, UsersRepository } from '@/models/_.js'; +import { IdService } from '@/core/IdService.js'; +import { GlobalModule } from '@/GlobalModule.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { GlobalEventService } from '@/core/GlobalEventService.js'; +import { DI } from '@/di-symbols.js'; +import { QueueService } from '@/core/QueueService.js'; +import { LoggerService } from '@/core/LoggerService.js'; +import { SystemWebhookService } from '@/core/SystemWebhookService.js'; +import { randomString, sleep } from '../utils.js'; + +describe('SystemWebhookService', () => { + let app: TestingModule; + let service: SystemWebhookService; + + // -------------------------------------------------------------------------------------- + + let usersRepository: UsersRepository; + let systemWebhooksRepository: SystemWebhooksRepository; + let idService: IdService; + let queueService: jest.Mocked; + + // -------------------------------------------------------------------------------------- + + let root: MiUser; + + // -------------------------------------------------------------------------------------- + + async function createUser(data: Partial = {}) { + return await usersRepository + .insert({ + id: idService.gen(), + ...data, + }) + .then(x => usersRepository.findOneByOrFail(x.identifiers[0])); + } + + async function createWebhook(data: Partial = {}) { + return systemWebhooksRepository + .insert({ + id: idService.gen(), + name: randomString(), + on: ['abuseReport'], + url: 'https://example.com', + secret: randomString(), + ...data, + }) + .then(x => systemWebhooksRepository.findOneByOrFail(x.identifiers[0])); + } + + // -------------------------------------------------------------------------------------- + + async function beforeAllImpl() { + app = await Test + .createTestingModule({ + imports: [ + GlobalModule, + ], + providers: [ + SystemWebhookService, + IdService, + LoggerService, + GlobalEventService, + { + provide: QueueService, useFactory: () => ({ systemWebhookDeliver: jest.fn() }), + }, + { + provide: ModerationLogService, useFactory: () => ({ log: () => Promise.resolve() }), + }, + ], + }) + .compile(); + + usersRepository = app.get(DI.usersRepository); + systemWebhooksRepository = app.get(DI.systemWebhooksRepository); + + service = app.get(SystemWebhookService); + idService = app.get(IdService); + queueService = app.get(QueueService) as jest.Mocked; + + app.enableShutdownHooks(); + } + + async function afterAllImpl() { + await app.close(); + } + + async function beforeEachImpl() { + root = await createUser({ isRoot: true, username: 'root', usernameLower: 'root' }); + } + + async function afterEachImpl() { + await usersRepository.delete({}); + await systemWebhooksRepository.delete({}); + } + + // -------------------------------------------------------------------------------------- + + describe('アプリを毎回作り直す必要のないグループ', () => { + beforeAll(beforeAllImpl); + afterAll(afterAllImpl); + beforeEach(beforeEachImpl); + afterEach(afterEachImpl); + + describe('fetchSystemWebhooks', () => { + test('フィルタなし', async () => { + const webhook1 = await createWebhook({ + isActive: true, + on: ['abuseReport'], + }); + const webhook2 = await createWebhook({ + isActive: false, + on: ['abuseReport'], + }); + const webhook3 = await createWebhook({ + isActive: true, + on: ['abuseReportResolved'], + }); + const webhook4 = await createWebhook({ + isActive: false, + on: [], + }); + + const fetchedWebhooks = await service.fetchSystemWebhooks(); + expect(fetchedWebhooks).toEqual([webhook1, webhook2, webhook3, webhook4]); + }); + + test('activeのみ', async () => { + const webhook1 = await createWebhook({ + isActive: true, + on: ['abuseReport'], + }); + const webhook2 = await createWebhook({ + isActive: false, + on: ['abuseReport'], + }); + const webhook3 = await createWebhook({ + isActive: true, + on: ['abuseReportResolved'], + }); + const webhook4 = await createWebhook({ + isActive: false, + on: [], + }); + + const fetchedWebhooks = await service.fetchSystemWebhooks({ isActive: true }); + expect(fetchedWebhooks).toEqual([webhook1, webhook3]); + }); + + test('特定のイベントのみ', async () => { + const webhook1 = await createWebhook({ + isActive: true, + on: ['abuseReport'], + }); + const webhook2 = await createWebhook({ + isActive: false, + on: ['abuseReport'], + }); + const webhook3 = await createWebhook({ + isActive: true, + on: ['abuseReportResolved'], + }); + const webhook4 = await createWebhook({ + isActive: false, + on: [], + }); + + const fetchedWebhooks = await service.fetchSystemWebhooks({ on: ['abuseReport'] }); + expect(fetchedWebhooks).toEqual([webhook1, webhook2]); + }); + + test('activeな特定のイベントのみ', async () => { + const webhook1 = await createWebhook({ + isActive: true, + on: ['abuseReport'], + }); + const webhook2 = await createWebhook({ + isActive: false, + on: ['abuseReport'], + }); + const webhook3 = await createWebhook({ + isActive: true, + on: ['abuseReportResolved'], + }); + const webhook4 = await createWebhook({ + isActive: false, + on: [], + }); + + const fetchedWebhooks = await service.fetchSystemWebhooks({ on: ['abuseReport'], isActive: true }); + expect(fetchedWebhooks).toEqual([webhook1]); + }); + + test('ID指定', async () => { + const webhook1 = await createWebhook({ + isActive: true, + on: ['abuseReport'], + }); + const webhook2 = await createWebhook({ + isActive: false, + on: ['abuseReport'], + }); + const webhook3 = await createWebhook({ + isActive: true, + on: ['abuseReportResolved'], + }); + const webhook4 = await createWebhook({ + isActive: false, + on: [], + }); + + const fetchedWebhooks = await service.fetchSystemWebhooks({ ids: [webhook1.id, webhook4.id] }); + expect(fetchedWebhooks).toEqual([webhook1, webhook4]); + }); + + test('ID指定(他条件とANDになるか見たい)', async () => { + const webhook1 = await createWebhook({ + isActive: true, + on: ['abuseReport'], + }); + const webhook2 = await createWebhook({ + isActive: false, + on: ['abuseReport'], + }); + const webhook3 = await createWebhook({ + isActive: true, + on: ['abuseReportResolved'], + }); + const webhook4 = await createWebhook({ + isActive: false, + on: [], + }); + + const fetchedWebhooks = await service.fetchSystemWebhooks({ ids: [webhook1.id, webhook4.id], isActive: false }); + expect(fetchedWebhooks).toEqual([webhook4]); + }); + }); + + describe('createSystemWebhook', () => { + test('作成成功 ', async () => { + const params = { + isActive: true, + name: randomString(), + on: ['abuseReport'] as SystemWebhookEventType[], + url: 'https://example.com', + secret: randomString(), + }; + + const webhook = await service.createSystemWebhook(params, root); + expect(webhook).toMatchObject(params); + }); + }); + + describe('updateSystemWebhook', () => { + test('更新成功', async () => { + const webhook = await createWebhook({ + isActive: true, + on: ['abuseReport'], + }); + + const params = { + id: webhook.id, + isActive: false, + name: randomString(), + on: ['abuseReport'] as SystemWebhookEventType[], + url: randomString(), + secret: randomString(), + }; + + const updatedWebhook = await service.updateSystemWebhook(params, root); + expect(updatedWebhook).toMatchObject(params); + }); + }); + + describe('deleteSystemWebhook', () => { + test('削除成功', async () => { + const webhook = await createWebhook({ + isActive: true, + on: ['abuseReport'], + }); + + await service.deleteSystemWebhook(webhook.id, root); + + await expect(systemWebhooksRepository.findOneBy({ id: webhook.id })).resolves.toBeNull(); + }); + }); + }); + + describe('アプリを毎回作り直す必要があるグループ', () => { + beforeEach(async () => { + await beforeAllImpl(); + await beforeEachImpl(); + }); + + afterEach(async () => { + await afterEachImpl(); + await afterAllImpl(); + }); + + describe('enqueueSystemWebhook', () => { + test('キューに追加成功', async () => { + const webhook = await createWebhook({ + isActive: true, + on: ['abuseReport'], + }); + await service.enqueueSystemWebhook(webhook.id, 'abuseReport', { foo: 'bar' }); + + expect(queueService.systemWebhookDeliver).toHaveBeenCalled(); + }); + + test('非アクティブなWebhookはキューに追加されない', async () => { + const webhook = await createWebhook({ + isActive: false, + on: ['abuseReport'], + }); + await service.enqueueSystemWebhook(webhook.id, 'abuseReport', { foo: 'bar' }); + + expect(queueService.systemWebhookDeliver).not.toHaveBeenCalled(); + }); + + test('未許可のイベント種別が渡された場合はWebhookはキューに追加されない', async () => { + const webhook1 = await createWebhook({ + isActive: true, + on: [], + }); + const webhook2 = await createWebhook({ + isActive: true, + on: ['abuseReportResolved'], + }); + await service.enqueueSystemWebhook(webhook1.id, 'abuseReport', { foo: 'bar' }); + await service.enqueueSystemWebhook(webhook2.id, 'abuseReport', { foo: 'bar' }); + + expect(queueService.systemWebhookDeliver).not.toHaveBeenCalled(); + }); + }); + + describe('fetchActiveSystemWebhooks', () => { + describe('systemWebhookCreated', () => { + test('ActiveなWebhookが追加された時、キャッシュに追加されている', async () => { + const webhook = await service.createSystemWebhook( + { + isActive: true, + name: randomString(), + on: ['abuseReport'], + url: 'https://example.com', + secret: randomString(), + }, + root, + ); + + // redisでの配信経由で更新されるのでちょっと待つ + await sleep(500); + + const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); + expect(fetchedWebhooks).toEqual([webhook]); + }); + + test('NotActiveなWebhookが追加された時、キャッシュに追加されていない', async () => { + const webhook = await service.createSystemWebhook( + { + isActive: false, + name: randomString(), + on: ['abuseReport'], + url: 'https://example.com', + secret: randomString(), + }, + root, + ); + + // redisでの配信経由で更新されるのでちょっと待つ + await sleep(500); + + const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); + expect(fetchedWebhooks).toEqual([]); + }); + }); + + describe('systemWebhookUpdated', () => { + test('ActiveなWebhookが編集された時、キャッシュに反映されている', async () => { + const id = idService.gen(); + await createWebhook({ id }); + // キャッシュ作成 + const webhook1 = await service.fetchActiveSystemWebhooks(); + // 読み込まれていることをチェック + expect(webhook1.length).toEqual(1); + expect(webhook1[0].id).toEqual(id); + + const webhook2 = await service.updateSystemWebhook( + { + id, + isActive: true, + name: randomString(), + on: ['abuseReport'], + url: 'https://example.com', + secret: randomString(), + }, + root, + ); + + // redisでの配信経由で更新されるのでちょっと待つ + await sleep(500); + + const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); + expect(fetchedWebhooks).toEqual([webhook2]); + }); + + test('NotActiveなWebhookが編集された時、キャッシュに追加されない', async () => { + const id = idService.gen(); + await createWebhook({ id, isActive: false }); + // キャッシュ作成 + const webhook1 = await service.fetchActiveSystemWebhooks(); + // 読み込まれていないことをチェック + expect(webhook1.length).toEqual(0); + + const webhook2 = await service.updateSystemWebhook( + { + id, + isActive: false, + name: randomString(), + on: ['abuseReport'], + url: 'https://example.com', + secret: randomString(), + }, + root, + ); + + // redisでの配信経由で更新されるのでちょっと待つ + await sleep(500); + + const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); + expect(fetchedWebhooks.length).toEqual(0); + }); + + test('NotActiveなWebhookがActiveにされた時、キャッシュに追加されている', async () => { + const id = idService.gen(); + const baseWebhook = await createWebhook({ id, isActive: false }); + // キャッシュ作成 + const webhook1 = await service.fetchActiveSystemWebhooks(); + // 読み込まれていないことをチェック + expect(webhook1.length).toEqual(0); + + const webhook2 = await service.updateSystemWebhook( + { + ...baseWebhook, + isActive: true, + }, + root, + ); + + // redisでの配信経由で更新されるのでちょっと待つ + await sleep(500); + + const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); + expect(fetchedWebhooks).toEqual([webhook2]); + }); + + test('ActiveなWebhookがNotActiveにされた時、キャッシュから削除されている', async () => { + const id = idService.gen(); + const baseWebhook = await createWebhook({ id, isActive: true }); + // キャッシュ作成 + const webhook1 = await service.fetchActiveSystemWebhooks(); + // 読み込まれていることをチェック + expect(webhook1.length).toEqual(1); + expect(webhook1[0].id).toEqual(id); + + const webhook2 = await service.updateSystemWebhook( + { + ...baseWebhook, + isActive: false, + }, + root, + ); + + // redisでの配信経由で更新されるのでちょっと待つ + await sleep(500); + + const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); + expect(fetchedWebhooks.length).toEqual(0); + }); + }); + + describe('systemWebhookDeleted', () => { + test('キャッシュから削除されている', async () => { + const id = idService.gen(); + const baseWebhook = await createWebhook({ id, isActive: true }); + // キャッシュ作成 + const webhook1 = await service.fetchActiveSystemWebhooks(); + // 読み込まれていることをチェック + expect(webhook1.length).toEqual(1); + expect(webhook1[0].id).toEqual(id); + + const webhook2 = await service.deleteSystemWebhook( + id, + root, + ); + + // redisでの配信経由で更新されるのでちょっと待つ + await sleep(500); + + const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); + expect(fetchedWebhooks.length).toEqual(0); + }); + }); + }); + }); +}); diff --git a/packages/frontend/src/components/MkButton.vue b/packages/frontend/src/components/MkButton.vue index 3489255b9152..25b003ba5a59 100644 --- a/packages/frontend/src/components/MkButton.vue +++ b/packages/frontend/src/components/MkButton.vue @@ -11,6 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only :type="type" :name="name" :value="value" + :disabled="disabled" @click="emit('click', $event)" @mousedown="onMousedown" > @@ -55,6 +56,7 @@ const props = defineProps<{ asLike?: boolean; name?: string; value?: string; + disabled?: boolean; }>(); const emit = defineEmits<{ diff --git a/packages/frontend/src/components/MkDivider.vue b/packages/frontend/src/components/MkDivider.vue new file mode 100644 index 000000000000..e4e3af99e429 --- /dev/null +++ b/packages/frontend/src/components/MkDivider.vue @@ -0,0 +1,32 @@ + + + + + + + diff --git a/packages/frontend/src/components/MkSwitch.vue b/packages/frontend/src/components/MkSwitch.vue index a19b45448bb9..721ac357f414 100644 --- a/packages/frontend/src/components/MkSwitch.vue +++ b/packages/frontend/src/components/MkSwitch.vue @@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only @keydown.enter="toggle" > - + @@ -34,16 +34,19 @@ const props = defineProps<{ modelValue: boolean | Ref; disabled?: boolean; helpText?: string; + noBody?: boolean; }>(); const emit = defineEmits<{ (ev: 'update:modelValue', v: boolean): void; + (ev: 'change', v: boolean): void; }>(); const checked = toRefs(props).modelValue; const toggle = () => { if (props.disabled) return; emit('update:modelValue', !checked.value); + emit('change', !checked.value); }; diff --git a/packages/frontend/src/components/MkSystemWebhookEditor.impl.ts b/packages/frontend/src/components/MkSystemWebhookEditor.impl.ts new file mode 100644 index 000000000000..1222d3261db8 --- /dev/null +++ b/packages/frontend/src/components/MkSystemWebhookEditor.impl.ts @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { defineAsyncComponent } from 'vue'; +import * as os from '@/os.js'; + +export type SystemWebhookEventType = 'abuseReport' | 'abuseReportResolved'; + +export type MkSystemWebhookEditorProps = { + mode: 'create' | 'edit'; + id?: string; + requiredEvents?: SystemWebhookEventType[]; +}; + +export type MkSystemWebhookResult = { + id?: string; + isActive: boolean; + name: string; + on: SystemWebhookEventType[]; + url: string; + secret: string; +}; + +export async function showSystemWebhookEditorDialog(props: MkSystemWebhookEditorProps): Promise { + const { dispose, result } = await new Promise<{ dispose: () => void, result: MkSystemWebhookResult | null }>(async resolve => { + const res = await os.popup( + defineAsyncComponent(() => import('@/components/MkSystemWebhookEditor.vue')), + props, + { + submitted: (ev: MkSystemWebhookResult) => { + resolve({ dispose: res.dispose, result: ev }); + }, + closed: () => { + resolve({ dispose: res.dispose, result: null }); + }, + }, + ); + }); + + dispose(); + + return result; +} diff --git a/packages/frontend/src/components/MkSystemWebhookEditor.vue b/packages/frontend/src/components/MkSystemWebhookEditor.vue new file mode 100644 index 000000000000..007d841f001a --- /dev/null +++ b/packages/frontend/src/components/MkSystemWebhookEditor.vue @@ -0,0 +1,217 @@ + + + + + + + diff --git a/packages/frontend/src/pages/admin/abuse-report/notification-recipient.editor.vue b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.editor.vue new file mode 100644 index 000000000000..ffe9c620d637 --- /dev/null +++ b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.editor.vue @@ -0,0 +1,307 @@ + + + + + + + diff --git a/packages/frontend/src/pages/admin/abuse-report/notification-recipient.item.vue b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.item.vue new file mode 100644 index 000000000000..0b86808fafb1 --- /dev/null +++ b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.item.vue @@ -0,0 +1,114 @@ + + + + + + + diff --git a/packages/frontend/src/pages/admin/abuse-report/notification-recipient.vue b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.vue new file mode 100644 index 000000000000..a52f8eb7af94 --- /dev/null +++ b/packages/frontend/src/pages/admin/abuse-report/notification-recipient.vue @@ -0,0 +1,176 @@ + + + + + + + diff --git a/packages/frontend/src/pages/admin/abuses.vue b/packages/frontend/src/pages/admin/abuses.vue index d2f4a4b531e6..9a9fa472a598 100644 --- a/packages/frontend/src/pages/admin/abuses.vue +++ b/packages/frontend/src/pages/admin/abuses.vue @@ -7,30 +7,33 @@ SPDX-License-Identifier: AGPL-3.0-only -
-
-
-
- - - - - - - - - - - - - - - - - - -
- - - - -
-
+ + +
@@ -60,6 +61,7 @@ import MkPagination from '@/components/MkPagination.vue'; import XAbuseReport from '@/components/MkAbuseReport.vue'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; +import MkButton from '@/components/MkButton.vue'; const reports = shallowRef>(); @@ -80,7 +82,7 @@ const pagination = { }; function resolved(reportId) { - reports.value.removeItem(reportId); + reports.value?.removeItem(reportId); } const headerActions = computed(() => []); @@ -92,3 +94,26 @@ definePageMetadata(() => ({ icon: 'ti ti-exclamation-circle', })); + + diff --git a/packages/frontend/src/pages/admin/index.vue b/packages/frontend/src/pages/admin/index.vue index 794feae202ad..292f10da1a18 100644 --- a/packages/frontend/src/pages/admin/index.vue +++ b/packages/frontend/src/pages/admin/index.vue @@ -214,6 +214,11 @@ const menuDef = computed(() => [{ text: i18n.ts.externalServices, to: '/admin/external-services', active: currentPage.value?.route.name === 'external-services', + }, { + icon: 'ti ti-webhook', + text: 'Webhook', + to: '/admin/system-webhook', + active: currentPage.value?.route.name === 'system-webhook', }, { icon: 'ti ti-adjustments', text: i18n.ts.other, diff --git a/packages/frontend/src/pages/admin/modlog.ModLog.vue b/packages/frontend/src/pages/admin/modlog.ModLog.vue index e33c88272187..91f1c7c5e625 100644 --- a/packages/frontend/src/pages/admin/modlog.ModLog.vue +++ b/packages/frontend/src/pages/admin/modlog.ModLog.vue @@ -8,9 +8,35 @@ SPDX-License-Identifier: AGPL-3.0-only + +
raw diff --git a/packages/frontend/src/pages/admin/system-webhook.item.vue b/packages/frontend/src/pages/admin/system-webhook.item.vue new file mode 100644 index 000000000000..0c07122af33a --- /dev/null +++ b/packages/frontend/src/pages/admin/system-webhook.item.vue @@ -0,0 +1,117 @@ + + + + + + + diff --git a/packages/frontend/src/pages/admin/system-webhook.vue b/packages/frontend/src/pages/admin/system-webhook.vue new file mode 100644 index 000000000000..7a40eec94494 --- /dev/null +++ b/packages/frontend/src/pages/admin/system-webhook.vue @@ -0,0 +1,96 @@ + + + + + + + diff --git a/packages/frontend/src/router/definition.ts b/packages/frontend/src/router/definition.ts index c12ae0fa572b..8a443f627b23 100644 --- a/packages/frontend/src/router/definition.ts +++ b/packages/frontend/src/router/definition.ts @@ -471,6 +471,14 @@ const routes: RouteDef[] = [{ path: '/invites', name: 'invites', component: page(() => import('@/pages/admin/invites.vue')), + }, { + path: '/abuse-report-notification-recipient', + name: 'abuse-report-notification-recipient', + component: page(() => import('@/pages/admin/abuse-report/notification-recipient.vue')), + }, { + path: '/system-webhook', + name: 'system-webhook', + component: page(() => import('@/pages/admin/system-webhook.vue')), }, { path: '/', component: page(() => import('@/pages/_empty_.vue')), diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index 6ff711cabbb5..bea89f2a7c0a 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -6,6 +6,11 @@ import { EventEmitter } from 'eventemitter3'; +// Warning: (ae-forgotten-export) The symbol "components" needs to be exported by the entry point index.d.ts +// +// @public (undocumented) +type AbuseReportNotificationRecipient = components['schemas']['AbuseReportNotificationRecipient']; + // @public (undocumented) export type Acct = { username: string; @@ -21,13 +26,38 @@ declare namespace acct { } export { acct } -// Warning: (ae-forgotten-export) The symbol "components" needs to be exported by the entry point index.d.ts -// // @public (undocumented) type Ad = components['schemas']['Ad']; // Warning: (ae-forgotten-export) The symbol "operations" needs to be exported by the entry point index.d.ts // +// @public (undocumented) +type AdminAbuseReportNotificationRecipientCreateRequest = operations['admin___abuse-report___notification-recipient___create']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminAbuseReportNotificationRecipientCreateResponse = operations['admin___abuse-report___notification-recipient___create']['responses']['200']['content']['application/json']; + +// @public (undocumented) +type AdminAbuseReportNotificationRecipientDeleteRequest = operations['admin___abuse-report___notification-recipient___delete']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminAbuseReportNotificationRecipientListRequest = operations['admin___abuse-report___notification-recipient___list']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminAbuseReportNotificationRecipientListResponse = operations['admin___abuse-report___notification-recipient___list']['responses']['200']['content']['application/json']; + +// @public (undocumented) +type AdminAbuseReportNotificationRecipientShowRequest = operations['admin___abuse-report___notification-recipient___show']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminAbuseReportNotificationRecipientShowResponse = operations['admin___abuse-report___notification-recipient___show']['responses']['200']['content']['application/json']; + +// @public (undocumented) +type AdminAbuseReportNotificationRecipientUpdateRequest = operations['admin___abuse-report___notification-recipient___update']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminAbuseReportNotificationRecipientUpdateResponse = operations['admin___abuse-report___notification-recipient___update']['responses']['200']['content']['application/json']; + // @public (undocumented) type AdminAbuseUserReportsRequest = operations['admin___abuse-user-reports']['requestBody']['content']['application/json']; @@ -307,6 +337,33 @@ type AdminShowUsersResponse = operations['admin___show-users']['responses']['200 // @public (undocumented) type AdminSuspendUserRequest = operations['admin___suspend-user']['requestBody']['content']['application/json']; +// @public (undocumented) +type AdminSystemWebhookCreateRequest = operations['admin___system-webhook___create']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminSystemWebhookCreateResponse = operations['admin___system-webhook___create']['responses']['200']['content']['application/json']; + +// @public (undocumented) +type AdminSystemWebhookDeleteRequest = operations['admin___system-webhook___delete']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminSystemWebhookListRequest = operations['admin___system-webhook___list']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminSystemWebhookListResponse = operations['admin___system-webhook___list']['responses']['200']['content']['application/json']; + +// @public (undocumented) +type AdminSystemWebhookShowRequest = operations['admin___system-webhook___show']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminSystemWebhookShowResponse = operations['admin___system-webhook___show']['responses']['200']['content']['application/json']; + +// @public (undocumented) +type AdminSystemWebhookUpdateRequest = operations['admin___system-webhook___update']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminSystemWebhookUpdateResponse = operations['admin___system-webhook___update']['responses']['200']['content']['application/json']; + // @public (undocumented) type AdminUnsetUserAvatarRequest = operations['admin___unset-user-avatar']['requestBody']['content']['application/json']; @@ -1133,6 +1190,15 @@ declare namespace entities { AdminMetaResponse, AdminAbuseUserReportsRequest, AdminAbuseUserReportsResponse, + AdminAbuseReportNotificationRecipientListRequest, + AdminAbuseReportNotificationRecipientListResponse, + AdminAbuseReportNotificationRecipientShowRequest, + AdminAbuseReportNotificationRecipientShowResponse, + AdminAbuseReportNotificationRecipientCreateRequest, + AdminAbuseReportNotificationRecipientCreateResponse, + AdminAbuseReportNotificationRecipientUpdateRequest, + AdminAbuseReportNotificationRecipientUpdateResponse, + AdminAbuseReportNotificationRecipientDeleteRequest, AdminAccountsCreateRequest, AdminAccountsCreateResponse, AdminAccountsDeleteRequest, @@ -1228,6 +1294,15 @@ declare namespace entities { AdminRolesUpdateDefaultPoliciesRequest, AdminRolesUsersRequest, AdminRolesUsersResponse, + AdminSystemWebhookCreateRequest, + AdminSystemWebhookCreateResponse, + AdminSystemWebhookDeleteRequest, + AdminSystemWebhookListRequest, + AdminSystemWebhookListResponse, + AdminSystemWebhookShowRequest, + AdminSystemWebhookShowResponse, + AdminSystemWebhookUpdateRequest, + AdminSystemWebhookUpdateResponse, AnnouncementsRequest, AnnouncementsResponse, AnnouncementsShowRequest, @@ -1733,7 +1808,9 @@ declare namespace entities { ReversiGameDetailed, MetaLite, MetaDetailedOnly, - MetaDetailed + MetaDetailed, + SystemWebhook, + AbuseReportNotificationRecipient } } export { entities } @@ -2380,8 +2457,23 @@ type ModerationLog = { type: 'unsetUserAvatar'; info: ModerationLogPayloads['unsetUserAvatar']; } | { - type: 'unsetUserBanner'; - info: ModerationLogPayloads['unsetUserBanner']; + type: 'createSystemWebhook'; + info: ModerationLogPayloads['createSystemWebhook']; +} | { + type: 'updateSystemWebhook'; + info: ModerationLogPayloads['updateSystemWebhook']; +} | { + type: 'deleteSystemWebhook'; + info: ModerationLogPayloads['deleteSystemWebhook']; +} | { + type: 'createAbuseReportNotificationRecipient'; + info: ModerationLogPayloads['createAbuseReportNotificationRecipient']; +} | { + type: 'updateAbuseReportNotificationRecipient'; + info: ModerationLogPayloads['updateAbuseReportNotificationRecipient']; +} | { + type: 'deleteAbuseReportNotificationRecipient'; + info: ModerationLogPayloads['deleteAbuseReportNotificationRecipient']; }); // @public (undocumented) @@ -2921,6 +3013,9 @@ type SwUpdateRegistrationRequest = operations['sw___update-registration']['reque // @public (undocumented) type SwUpdateRegistrationResponse = operations['sw___update-registration']['responses']['200']['content']['application/json']; +// @public (undocumented) +type SystemWebhook = components['schemas']['SystemWebhook']; + // @public (undocumented) type TestRequest = operations['test']['requestBody']['content']['application/json']; diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts index 181f7274b7b6..e799d4a0c5e0 100644 --- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts +++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts @@ -25,6 +25,66 @@ declare module '../api.js' { credential?: string | null, ): Promise>; + /** + * No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + /** * No description provided. * @@ -840,6 +900,66 @@ declare module '../api.js' { credential?: string | null, ): Promise>; + /** + * No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + /** * No description provided. * diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index ab3baf16700d..20c8509d4c6f 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -4,6 +4,15 @@ import type { AdminMetaResponse, AdminAbuseUserReportsRequest, AdminAbuseUserReportsResponse, + AdminAbuseReportNotificationRecipientListRequest, + AdminAbuseReportNotificationRecipientListResponse, + AdminAbuseReportNotificationRecipientShowRequest, + AdminAbuseReportNotificationRecipientShowResponse, + AdminAbuseReportNotificationRecipientCreateRequest, + AdminAbuseReportNotificationRecipientCreateResponse, + AdminAbuseReportNotificationRecipientUpdateRequest, + AdminAbuseReportNotificationRecipientUpdateResponse, + AdminAbuseReportNotificationRecipientDeleteRequest, AdminAccountsCreateRequest, AdminAccountsCreateResponse, AdminAccountsDeleteRequest, @@ -99,6 +108,15 @@ import type { AdminRolesUpdateDefaultPoliciesRequest, AdminRolesUsersRequest, AdminRolesUsersResponse, + AdminSystemWebhookCreateRequest, + AdminSystemWebhookCreateResponse, + AdminSystemWebhookDeleteRequest, + AdminSystemWebhookListRequest, + AdminSystemWebhookListResponse, + AdminSystemWebhookShowRequest, + AdminSystemWebhookShowResponse, + AdminSystemWebhookUpdateRequest, + AdminSystemWebhookUpdateResponse, AnnouncementsRequest, AnnouncementsResponse, AnnouncementsShowRequest, @@ -558,6 +576,11 @@ import type { export type Endpoints = { 'admin/meta': { req: EmptyRequest; res: AdminMetaResponse }; 'admin/abuse-user-reports': { req: AdminAbuseUserReportsRequest; res: AdminAbuseUserReportsResponse }; + 'admin/abuse-report/notification-recipient/list': { req: AdminAbuseReportNotificationRecipientListRequest; res: AdminAbuseReportNotificationRecipientListResponse }; + 'admin/abuse-report/notification-recipient/show': { req: AdminAbuseReportNotificationRecipientShowRequest; res: AdminAbuseReportNotificationRecipientShowResponse }; + 'admin/abuse-report/notification-recipient/create': { req: AdminAbuseReportNotificationRecipientCreateRequest; res: AdminAbuseReportNotificationRecipientCreateResponse }; + 'admin/abuse-report/notification-recipient/update': { req: AdminAbuseReportNotificationRecipientUpdateRequest; res: AdminAbuseReportNotificationRecipientUpdateResponse }; + 'admin/abuse-report/notification-recipient/delete': { req: AdminAbuseReportNotificationRecipientDeleteRequest; res: EmptyResponse }; 'admin/accounts/create': { req: AdminAccountsCreateRequest; res: AdminAccountsCreateResponse }; 'admin/accounts/delete': { req: AdminAccountsDeleteRequest; res: EmptyResponse }; 'admin/accounts/find-by-email': { req: AdminAccountsFindByEmailRequest; res: AdminAccountsFindByEmailResponse }; @@ -632,6 +655,11 @@ export type Endpoints = { 'admin/roles/unassign': { req: AdminRolesUnassignRequest; res: EmptyResponse }; 'admin/roles/update-default-policies': { req: AdminRolesUpdateDefaultPoliciesRequest; res: EmptyResponse }; 'admin/roles/users': { req: AdminRolesUsersRequest; res: AdminRolesUsersResponse }; + 'admin/system-webhook/create': { req: AdminSystemWebhookCreateRequest; res: AdminSystemWebhookCreateResponse }; + 'admin/system-webhook/delete': { req: AdminSystemWebhookDeleteRequest; res: EmptyResponse }; + 'admin/system-webhook/list': { req: AdminSystemWebhookListRequest; res: AdminSystemWebhookListResponse }; + 'admin/system-webhook/show': { req: AdminSystemWebhookShowRequest; res: AdminSystemWebhookShowResponse }; + 'admin/system-webhook/update': { req: AdminSystemWebhookUpdateRequest; res: AdminSystemWebhookUpdateResponse }; 'announcements': { req: AnnouncementsRequest; res: AnnouncementsResponse }; 'announcements/show': { req: AnnouncementsShowRequest; res: AnnouncementsShowResponse }; 'antennas/create': { req: AntennasCreateRequest; res: AntennasCreateResponse }; diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index 02ca932d8a38..357b5e9eaf68 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -7,6 +7,15 @@ export type EmptyResponse = Record | undefined; export type AdminMetaResponse = operations['admin___meta']['responses']['200']['content']['application/json']; export type AdminAbuseUserReportsRequest = operations['admin___abuse-user-reports']['requestBody']['content']['application/json']; export type AdminAbuseUserReportsResponse = operations['admin___abuse-user-reports']['responses']['200']['content']['application/json']; +export type AdminAbuseReportNotificationRecipientListRequest = operations['admin___abuse-report___notification-recipient___list']['requestBody']['content']['application/json']; +export type AdminAbuseReportNotificationRecipientListResponse = operations['admin___abuse-report___notification-recipient___list']['responses']['200']['content']['application/json']; +export type AdminAbuseReportNotificationRecipientShowRequest = operations['admin___abuse-report___notification-recipient___show']['requestBody']['content']['application/json']; +export type AdminAbuseReportNotificationRecipientShowResponse = operations['admin___abuse-report___notification-recipient___show']['responses']['200']['content']['application/json']; +export type AdminAbuseReportNotificationRecipientCreateRequest = operations['admin___abuse-report___notification-recipient___create']['requestBody']['content']['application/json']; +export type AdminAbuseReportNotificationRecipientCreateResponse = operations['admin___abuse-report___notification-recipient___create']['responses']['200']['content']['application/json']; +export type AdminAbuseReportNotificationRecipientUpdateRequest = operations['admin___abuse-report___notification-recipient___update']['requestBody']['content']['application/json']; +export type AdminAbuseReportNotificationRecipientUpdateResponse = operations['admin___abuse-report___notification-recipient___update']['responses']['200']['content']['application/json']; +export type AdminAbuseReportNotificationRecipientDeleteRequest = operations['admin___abuse-report___notification-recipient___delete']['requestBody']['content']['application/json']; export type AdminAccountsCreateRequest = operations['admin___accounts___create']['requestBody']['content']['application/json']; export type AdminAccountsCreateResponse = operations['admin___accounts___create']['responses']['200']['content']['application/json']; export type AdminAccountsDeleteRequest = operations['admin___accounts___delete']['requestBody']['content']['application/json']; @@ -102,6 +111,15 @@ export type AdminRolesUnassignRequest = operations['admin___roles___unassign'][' export type AdminRolesUpdateDefaultPoliciesRequest = operations['admin___roles___update-default-policies']['requestBody']['content']['application/json']; export type AdminRolesUsersRequest = operations['admin___roles___users']['requestBody']['content']['application/json']; export type AdminRolesUsersResponse = operations['admin___roles___users']['responses']['200']['content']['application/json']; +export type AdminSystemWebhookCreateRequest = operations['admin___system-webhook___create']['requestBody']['content']['application/json']; +export type AdminSystemWebhookCreateResponse = operations['admin___system-webhook___create']['responses']['200']['content']['application/json']; +export type AdminSystemWebhookDeleteRequest = operations['admin___system-webhook___delete']['requestBody']['content']['application/json']; +export type AdminSystemWebhookListRequest = operations['admin___system-webhook___list']['requestBody']['content']['application/json']; +export type AdminSystemWebhookListResponse = operations['admin___system-webhook___list']['responses']['200']['content']['application/json']; +export type AdminSystemWebhookShowRequest = operations['admin___system-webhook___show']['requestBody']['content']['application/json']; +export type AdminSystemWebhookShowResponse = operations['admin___system-webhook___show']['responses']['200']['content']['application/json']; +export type AdminSystemWebhookUpdateRequest = operations['admin___system-webhook___update']['requestBody']['content']['application/json']; +export type AdminSystemWebhookUpdateResponse = operations['admin___system-webhook___update']['responses']['200']['content']['application/json']; export type AnnouncementsRequest = operations['announcements']['requestBody']['content']['application/json']; export type AnnouncementsResponse = operations['announcements']['responses']['200']['content']['application/json']; export type AnnouncementsShowRequest = operations['announcements___show']['requestBody']['content']['application/json']; diff --git a/packages/misskey-js/src/autogen/models.ts b/packages/misskey-js/src/autogen/models.ts index a6e5fbe6890e..04574849d44d 100644 --- a/packages/misskey-js/src/autogen/models.ts +++ b/packages/misskey-js/src/autogen/models.ts @@ -51,3 +51,5 @@ export type ReversiGameDetailed = components['schemas']['ReversiGameDetailed']; export type MetaLite = components['schemas']['MetaLite']; export type MetaDetailedOnly = components['schemas']['MetaDetailedOnly']; export type MetaDetailed = components['schemas']['MetaDetailed']; +export type SystemWebhook = components['schemas']['SystemWebhook']; +export type AbuseReportNotificationRecipient = components['schemas']['AbuseReportNotificationRecipient']; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 2c80676f3ed3..bdcc1dfd778e 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -30,6 +30,56 @@ export type paths = { */ post: operations['admin___abuse-user-reports']; }; + '/admin/abuse-report/notification-recipient/list': { + /** + * admin/abuse-report/notification-recipient/list + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient* + */ + post: operations['admin___abuse-report___notification-recipient___list']; + }; + '/admin/abuse-report/notification-recipient/show': { + /** + * admin/abuse-report/notification-recipient/show + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient* + */ + post: operations['admin___abuse-report___notification-recipient___show']; + }; + '/admin/abuse-report/notification-recipient/create': { + /** + * admin/abuse-report/notification-recipient/create + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient* + */ + post: operations['admin___abuse-report___notification-recipient___create']; + }; + '/admin/abuse-report/notification-recipient/update': { + /** + * admin/abuse-report/notification-recipient/update + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient* + */ + post: operations['admin___abuse-report___notification-recipient___update']; + }; + '/admin/abuse-report/notification-recipient/delete': { + /** + * admin/abuse-report/notification-recipient/delete + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient* + */ + post: operations['admin___abuse-report___notification-recipient___delete']; + }; '/admin/accounts/create': { /** * admin/accounts/create @@ -697,6 +747,56 @@ export type paths = { */ post: operations['admin___roles___users']; }; + '/admin/system-webhook/create': { + /** + * admin/system-webhook/create + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + post: operations['admin___system-webhook___create']; + }; + '/admin/system-webhook/delete': { + /** + * admin/system-webhook/delete + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + post: operations['admin___system-webhook___delete']; + }; + '/admin/system-webhook/list': { + /** + * admin/system-webhook/list + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + post: operations['admin___system-webhook___list']; + }; + '/admin/system-webhook/show': { + /** + * admin/system-webhook/show + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + post: operations['admin___system-webhook___show']; + }; + '/admin/system-webhook/update': { + /** + * admin/system-webhook/update + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + post: operations['admin___system-webhook___update']; + }; '/announcements': { /** * announcements @@ -4859,6 +4959,32 @@ export type components = { cacheRemoteSensitiveFiles: boolean; }; MetaDetailed: components['schemas']['MetaLite'] & components['schemas']['MetaDetailedOnly']; + SystemWebhook: { + id: string; + isActive: boolean; + /** Format: date-time */ + updatedAt: string; + /** Format: date-time */ + latestSentAt: string | null; + latestStatus: number | null; + name: string; + on: ('abuseReport' | 'abuseReportResolved')[]; + url: string; + secret: string; + }; + AbuseReportNotificationRecipient: { + id: string; + isActive: boolean; + /** Format: date-time */ + updatedAt: string; + name: string; + /** @enum {string} */ + method: 'email' | 'webhook'; + userId?: string; + user?: components['schemas']['UserLite']; + systemWebhookId?: string; + systemWebhook?: components['schemas']['SystemWebhook']; + }; }; responses: never; parameters: never; @@ -5126,17 +5252,17 @@ export type operations = { }; }; /** - * admin/accounts/create + * admin/abuse-report/notification-recipient/list * @description No description provided. * - * **Credential required**: *No* + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient* */ - admin___accounts___create: { + 'admin___abuse-report___notification-recipient___list': { requestBody: { content: { 'application/json': { - username: string; - password: string; + method?: ('email' | 'webhook')[]; }; }; }; @@ -5144,7 +5270,7 @@ export type operations = { /** @description OK (with results) */ 200: { content: { - 'application/json': components['schemas']['MeDetailed']; + 'application/json': components['schemas']['AbuseReportNotificationRecipient'][]; }; }; /** @description Client error */ @@ -5180,24 +5306,27 @@ export type operations = { }; }; /** - * admin/accounts/delete + * admin/abuse-report/notification-recipient/show * @description No description provided. * - * **Credential required**: *Yes* / **Permission**: *write:admin:account* + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *read:admin:abuse-report:notification-recipient* */ - admin___accounts___delete: { + 'admin___abuse-report___notification-recipient___show': { requestBody: { content: { 'application/json': { /** Format: misskey:id */ - userId: string; + id: string; }; }; }; responses: { - /** @description OK (without any results) */ - 204: { - content: never; + /** @description OK (with results) */ + 200: { + content: { + 'application/json': components['schemas']['AbuseReportNotificationRecipient']; + }; }; /** @description Client error */ 400: { @@ -5232,16 +5361,24 @@ export type operations = { }; }; /** - * admin/accounts/find-by-email + * admin/abuse-report/notification-recipient/create * @description No description provided. * - * **Credential required**: *Yes* / **Permission**: *read:admin:account* + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient* */ - 'admin___accounts___find-by-email': { + 'admin___abuse-report___notification-recipient___create': { requestBody: { content: { 'application/json': { - email: string; + isActive: boolean; + name: string; + /** @enum {string} */ + method: 'email' | 'webhook'; + /** Format: misskey:id */ + userId?: string; + /** Format: misskey:id */ + systemWebhookId?: string; }; }; }; @@ -5249,7 +5386,7 @@ export type operations = { /** @description OK (with results) */ 200: { content: { - 'application/json': components['schemas']['UserDetailedNotMe']; + 'application/json': components['schemas']['AbuseReportNotificationRecipient']; }; }; /** @description Client error */ @@ -5285,24 +5422,26 @@ export type operations = { }; }; /** - * admin/ad/create + * admin/abuse-report/notification-recipient/update * @description No description provided. * - * **Credential required**: *Yes* / **Permission**: *write:admin:ad* + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient* */ - admin___ad___create: { + 'admin___abuse-report___notification-recipient___update': { requestBody: { content: { 'application/json': { - url: string; - memo: string; - place: string; - priority: string; - ratio: number; - expiresAt: number; - startsAt: number; - imageUrl: string; - dayOfWeek: number; + /** Format: misskey:id */ + id: string; + isActive: boolean; + name: string; + /** @enum {string} */ + method: 'email' | 'webhook'; + /** Format: misskey:id */ + userId?: string; + /** Format: misskey:id */ + systemWebhookId?: string; }; }; }; @@ -5310,7 +5449,7 @@ export type operations = { /** @description OK (with results) */ 200: { content: { - 'application/json': components['schemas']['Ad']; + 'application/json': components['schemas']['AbuseReportNotificationRecipient']; }; }; /** @description Client error */ @@ -5346,12 +5485,13 @@ export type operations = { }; }; /** - * admin/ad/delete + * admin/abuse-report/notification-recipient/delete * @description No description provided. * - * **Credential required**: *Yes* / **Permission**: *write:admin:ad* + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:abuse-report:notification-recipient* */ - admin___ad___delete: { + 'admin___abuse-report___notification-recipient___delete': { requestBody: { content: { 'application/json': { @@ -5398,23 +5538,17 @@ export type operations = { }; }; /** - * admin/ad/list + * admin/accounts/create * @description No description provided. * - * **Credential required**: *Yes* / **Permission**: *read:admin:ad* + * **Credential required**: *No* */ - admin___ad___list: { + admin___accounts___create: { requestBody: { content: { 'application/json': { - /** @default 10 */ - limit?: number; - /** Format: misskey:id */ - sinceId?: string; - /** Format: misskey:id */ - untilId?: string; - /** @default null */ - publishing?: boolean | null; + username: string; + password: string; }; }; }; @@ -5422,7 +5556,7 @@ export type operations = { /** @description OK (with results) */ 200: { content: { - 'application/json': components['schemas']['Ad'][]; + 'application/json': components['schemas']['MeDetailed']; }; }; /** @description Client error */ @@ -5458,26 +5592,17 @@ export type operations = { }; }; /** - * admin/ad/update + * admin/accounts/delete * @description No description provided. * - * **Credential required**: *Yes* / **Permission**: *write:admin:ad* + * **Credential required**: *Yes* / **Permission**: *write:admin:account* */ - admin___ad___update: { + admin___accounts___delete: { requestBody: { content: { 'application/json': { /** Format: misskey:id */ - id: string; - memo: string; - url: string; - imageUrl: string; - place: string; - priority: string; - ratio: number; - expiresAt: number; - startsAt: number; - dayOfWeek: number; + userId: string; }; }; }; @@ -5519,39 +5644,16 @@ export type operations = { }; }; /** - * admin/announcements/create + * admin/accounts/find-by-email * @description No description provided. * - * **Credential required**: *Yes* / **Permission**: *write:admin:announcements* + * **Credential required**: *Yes* / **Permission**: *read:admin:account* */ - admin___announcements___create: { + 'admin___accounts___find-by-email': { requestBody: { content: { 'application/json': { - title: string; - text: string; - imageUrl: string | null; - /** - * @default info - * @enum {string} - */ - icon?: 'info' | 'warning' | 'error' | 'success'; - /** - * @default normal - * @enum {string} - */ - display?: 'normal' | 'banner' | 'dialog'; - /** @default false */ - forExistingUsers?: boolean; - /** @default false */ - silence?: boolean; - /** @default false */ - needConfirmationToRead?: boolean; - /** - * Format: misskey:id - * @default null - */ - userId?: string | null; + email: string; }; }; }; @@ -5559,20 +5661,7 @@ export type operations = { /** @description OK (with results) */ 200: { content: { - 'application/json': { - /** - * Format: id - * @example xxxxxxxxxx - */ - id: string; - /** Format: date-time */ - createdAt: string; - /** Format: date-time */ - updatedAt: string | null; - title: string; - text: string; - imageUrl: string | null; - }; + 'application/json': components['schemas']['UserDetailedNotMe']; }; }; /** @description Client error */ @@ -5608,24 +5697,33 @@ export type operations = { }; }; /** - * admin/announcements/delete + * admin/ad/create * @description No description provided. * - * **Credential required**: *Yes* / **Permission**: *write:admin:announcements* + * **Credential required**: *Yes* / **Permission**: *write:admin:ad* */ - admin___announcements___delete: { + admin___ad___create: { requestBody: { content: { 'application/json': { - /** Format: misskey:id */ - id: string; + url: string; + memo: string; + place: string; + priority: string; + ratio: number; + expiresAt: number; + startsAt: number; + imageUrl: string; + dayOfWeek: number; }; }; }; responses: { - /** @description OK (without any results) */ - 204: { - content: never; + /** @description OK (with results) */ + 200: { + content: { + 'application/json': components['schemas']['Ad']; + }; }; /** @description Client error */ 400: { @@ -5660,32 +5758,346 @@ export type operations = { }; }; /** - * admin/announcements/list + * admin/ad/delete * @description No description provided. * - * **Credential required**: *Yes* / **Permission**: *read:admin:announcements* + * **Credential required**: *Yes* / **Permission**: *write:admin:ad* */ - admin___announcements___list: { + admin___ad___delete: { requestBody: { content: { 'application/json': { - /** @default 10 */ - limit?: number; - /** Format: misskey:id */ - sinceId?: string; - /** Format: misskey:id */ - untilId?: string; /** Format: misskey:id */ - userId?: string | null; + id: string; }; }; }; responses: { - /** @description OK (with results) */ - 200: { - content: { - 'application/json': ({ - /** + /** @description OK (without any results) */ + 204: { + content: never; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; + /** + * admin/ad/list + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:ad* + */ + admin___ad___list: { + requestBody: { + content: { + 'application/json': { + /** @default 10 */ + limit?: number; + /** Format: misskey:id */ + sinceId?: string; + /** Format: misskey:id */ + untilId?: string; + /** @default null */ + publishing?: boolean | null; + }; + }; + }; + responses: { + /** @description OK (with results) */ + 200: { + content: { + 'application/json': components['schemas']['Ad'][]; + }; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; + /** + * admin/ad/update + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *write:admin:ad* + */ + admin___ad___update: { + requestBody: { + content: { + 'application/json': { + /** Format: misskey:id */ + id: string; + memo: string; + url: string; + imageUrl: string; + place: string; + priority: string; + ratio: number; + expiresAt: number; + startsAt: number; + dayOfWeek: number; + }; + }; + }; + responses: { + /** @description OK (without any results) */ + 204: { + content: never; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; + /** + * admin/announcements/create + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *write:admin:announcements* + */ + admin___announcements___create: { + requestBody: { + content: { + 'application/json': { + title: string; + text: string; + imageUrl: string | null; + /** + * @default info + * @enum {string} + */ + icon?: 'info' | 'warning' | 'error' | 'success'; + /** + * @default normal + * @enum {string} + */ + display?: 'normal' | 'banner' | 'dialog'; + /** @default false */ + forExistingUsers?: boolean; + /** @default false */ + silence?: boolean; + /** @default false */ + needConfirmationToRead?: boolean; + /** + * Format: misskey:id + * @default null + */ + userId?: string | null; + }; + }; + }; + responses: { + /** @description OK (with results) */ + 200: { + content: { + 'application/json': { + /** + * Format: id + * @example xxxxxxxxxx + */ + id: string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string | null; + title: string; + text: string; + imageUrl: string | null; + }; + }; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; + /** + * admin/announcements/delete + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *write:admin:announcements* + */ + admin___announcements___delete: { + requestBody: { + content: { + 'application/json': { + /** Format: misskey:id */ + id: string; + }; + }; + }; + responses: { + /** @description OK (without any results) */ + 204: { + content: never; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; + /** + * admin/announcements/list + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:announcements* + */ + admin___announcements___list: { + requestBody: { + content: { + 'application/json': { + /** @default 10 */ + limit?: number; + /** Format: misskey:id */ + sinceId?: string; + /** Format: misskey:id */ + untilId?: string; + /** Format: misskey:id */ + userId?: string | null; + }; + }; + }; + responses: { + /** @description OK (with results) */ + 200: { + content: { + 'application/json': ({ + /** * Format: id * @example xxxxxxxxxx */ @@ -9615,6 +10027,287 @@ export type operations = { }; }; }; + /** + * admin/system-webhook/create + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + 'admin___system-webhook___create': { + requestBody: { + content: { + 'application/json': { + isActive: boolean; + name: string; + on: ('abuseReport' | 'abuseReportResolved')[]; + url: string; + secret: string; + }; + }; + }; + responses: { + /** @description OK (with results) */ + 200: { + content: { + 'application/json': components['schemas']['SystemWebhook']; + }; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; + /** + * admin/system-webhook/delete + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + 'admin___system-webhook___delete': { + requestBody: { + content: { + 'application/json': { + /** Format: misskey:id */ + id: string; + }; + }; + }; + responses: { + /** @description OK (without any results) */ + 204: { + content: never; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; + /** + * admin/system-webhook/list + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + 'admin___system-webhook___list': { + requestBody: { + content: { + 'application/json': { + isActive?: boolean; + on?: ('abuseReport' | 'abuseReportResolved')[]; + }; + }; + }; + responses: { + /** @description OK (with results) */ + 200: { + content: { + 'application/json': components['schemas']['SystemWebhook'][]; + }; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; + /** + * admin/system-webhook/show + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + 'admin___system-webhook___show': { + requestBody: { + content: { + 'application/json': { + /** Format: misskey:id */ + id: string; + }; + }; + }; + responses: { + /** @description OK (with results) */ + 200: { + content: { + 'application/json': components['schemas']['SystemWebhook']; + }; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; + /** + * admin/system-webhook/update + * @description No description provided. + * + * **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties. + * **Credential required**: *Yes* / **Permission**: *write:admin:system-webhook* + */ + 'admin___system-webhook___update': { + requestBody: { + content: { + 'application/json': { + /** Format: misskey:id */ + id: string; + isActive: boolean; + name: string; + on: ('abuseReport' | 'abuseReportResolved')[]; + url: string; + secret: string; + }; + }; + }; + responses: { + /** @description OK (with results) */ + 200: { + content: { + 'application/json': components['schemas']['SystemWebhook']; + }; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; /** * announcements * @description No description provided. diff --git a/packages/misskey-js/src/consts.ts b/packages/misskey-js/src/consts.ts index fd6ef4d68ded..03b906929006 100644 --- a/packages/misskey-js/src/consts.ts +++ b/packages/misskey-js/src/consts.ts @@ -325,4 +325,30 @@ export type ModerationLogPayloads = { userHost: string | null; fileId: string; }; + createSystemWebhook: { + systemWebhookId: string; + webhook: any; + }; + updateSystemWebhook: { + systemWebhookId: string; + before: any; + after: any; + }; + deleteSystemWebhook: { + systemWebhookId: string; + webhook: any; + }; + createAbuseReportNotificationRecipient: { + recipientId: string; + recipient: any; + }; + updateAbuseReportNotificationRecipient: { + recipientId: string; + before: any; + after: any; + }; + deleteAbuseReportNotificationRecipient: { + recipientId: string; + recipient: any; + }; }; diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts index 35503d6d6fff..7a84cb6a1a63 100644 --- a/packages/misskey-js/src/entities.ts +++ b/packages/misskey-js/src/entities.ts @@ -132,8 +132,23 @@ export type ModerationLog = { type: 'unsetUserAvatar'; info: ModerationLogPayloads['unsetUserAvatar']; } | { - type: 'unsetUserBanner'; - info: ModerationLogPayloads['unsetUserBanner']; + type: 'createSystemWebhook'; + info: ModerationLogPayloads['createSystemWebhook']; +} | { + type: 'updateSystemWebhook'; + info: ModerationLogPayloads['updateSystemWebhook']; +} | { + type: 'deleteSystemWebhook'; + info: ModerationLogPayloads['deleteSystemWebhook']; +} | { + type: 'createAbuseReportNotificationRecipient'; + info: ModerationLogPayloads['createAbuseReportNotificationRecipient']; +} | { + type: 'updateAbuseReportNotificationRecipient'; + info: ModerationLogPayloads['updateAbuseReportNotificationRecipient']; +} | { + type: 'deleteAbuseReportNotificationRecipient'; + info: ModerationLogPayloads['deleteAbuseReportNotificationRecipient']; }); export type ServerStats = { From 9849aab40283cbde2184e74d4795aec8ef8ccba3 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Sat, 8 Jun 2024 18:00:54 +0900 Subject: [PATCH 017/268] test(#10336): add `components/MkC.*` stories (#13830) * test(storybook): add `components/MkC.*` stories * test(storybook): add some tests * test: add sleep * test: comment-out flaky test * test(storybook): add test for `MkChannelFollowButton` * chore(storybook): tweak sleep duration in `MkChannelFollowButton` story test * fix(chromatic): add delay to `MkChannelList` * chore: replace `mswDecorator` with `mswLoader` * fix(storybook): tweak some parameters * chore: serve static files * fix(chromatic): add delay to `MkCwButton` * chore: delete logging for debug * fix: add right click in `MkContextMenu` play * refactor: remove unused imports --- packages/frontend/.storybook/fakes.ts | 60 +++++++++ packages/frontend/.storybook/generate.tsx | 2 +- packages/frontend/.storybook/main.ts | 1 + packages/frontend/.storybook/preview.ts | 4 +- packages/frontend/package.json | 2 + .../MkChannelFollowButton.stories.impl.ts | 77 ++++++++++++ .../src/components/MkChannelFollowButton.vue | 5 +- .../components/MkChannelList.stories.impl.ts | 65 ++++++++++ .../MkChannelPreview.stories.impl.ts | 43 +++++++ .../src/components/MkChart.stories.impl.ts | 117 ++++++++++++++++++ packages/frontend/src/components/MkChart.vue | 90 ++++++++------ .../components/MkChartLegend.stories.impl.ts | 7 ++ .../components/MkChartTooltip.stories.impl.ts | 7 ++ .../components/MkClickerGame.stories.impl.ts | 79 ++++++++++++ .../frontend/src/components/MkClickerGame.vue | 2 +- .../components/MkClipPreview.stories.impl.ts | 43 +++++++ .../components/MkCode.core.stories.impl.ts | 7 ++ .../src/components/MkCode.stories.impl.ts | 44 +++++++ .../components/MkCodeEditor.stories.impl.ts | 62 ++++++++++ .../components/MkCodeInline.stories.impl.ts | 37 ++++++ .../components/MkColorInput.stories.impl.ts | 50 ++++++++ .../components/MkContainer.stories.impl.ts | 7 ++ .../components/MkContextMenu.stories.impl.ts | 58 +++++++++ .../MkCropperDialog.stories.impl.ts | 75 +++++++++++ ...kCustomEmojiDetailedDialog.stories.impl.ts | 38 ++++++ .../src/components/MkCwButton.stories.impl.ts | 89 +++++++++++++ packages/frontend/src/scripts/test-utils.ts | 10 ++ pnpm-lock.yaml | 88 +++++++------ 28 files changed, 1083 insertions(+), 86 deletions(-) create mode 100644 packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts create mode 100644 packages/frontend/src/components/MkChannelList.stories.impl.ts create mode 100644 packages/frontend/src/components/MkChannelPreview.stories.impl.ts create mode 100644 packages/frontend/src/components/MkChart.stories.impl.ts create mode 100644 packages/frontend/src/components/MkChartLegend.stories.impl.ts create mode 100644 packages/frontend/src/components/MkChartTooltip.stories.impl.ts create mode 100644 packages/frontend/src/components/MkClickerGame.stories.impl.ts create mode 100644 packages/frontend/src/components/MkClipPreview.stories.impl.ts create mode 100644 packages/frontend/src/components/MkCode.core.stories.impl.ts create mode 100644 packages/frontend/src/components/MkCode.stories.impl.ts create mode 100644 packages/frontend/src/components/MkCodeEditor.stories.impl.ts create mode 100644 packages/frontend/src/components/MkCodeInline.stories.impl.ts create mode 100644 packages/frontend/src/components/MkColorInput.stories.impl.ts create mode 100644 packages/frontend/src/components/MkContainer.stories.impl.ts create mode 100644 packages/frontend/src/components/MkContextMenu.stories.impl.ts create mode 100644 packages/frontend/src/components/MkCropperDialog.stories.impl.ts create mode 100644 packages/frontend/src/components/MkCustomEmojiDetailedDialog.stories.impl.ts create mode 100644 packages/frontend/src/components/MkCwButton.stories.impl.ts diff --git a/packages/frontend/.storybook/fakes.ts b/packages/frontend/.storybook/fakes.ts index 3a24ccb248ed..fdb155261bdc 100644 --- a/packages/frontend/.storybook/fakes.ts +++ b/packages/frontend/.storybook/fakes.ts @@ -22,6 +22,66 @@ export function abuseUserReport() { }; } +export function channel(id = 'somechannelid', name = 'Some Channel', bannerUrl: string | null = 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/fedi.jpg?raw=true'): entities.Channel { + return { + id, + createdAt: '2016-12-28T22:49:51.000Z', + lastNotedAt: '2016-12-28T22:49:51.000Z', + name, + description: null, + userId: null, + bannerUrl, + pinnedNoteIds: [], + color: '#000', + isArchived: false, + usersCount: 1, + notesCount: 1, + isSensitive: false, + allowRenoteToExternal: false, + }; +} + +export function clip(id = 'someclipid', name = 'Some Clip'): entities.Clip { + return { + id, + createdAt: '2016-12-28T22:49:51.000Z', + lastClippedAt: null, + userId: 'someuserid', + user: { + id: 'someuserid', + name: 'Misskey User', + username: 'miskist', + host: 'misskey-hub.net', + avatarUrl: 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/about-icon.png?raw=true', + avatarBlurhash: 'eQFRshof5NWBRi},juayfPju53WB?0ofs;s*a{ofjuay^SoMEJR%ay', + avatarDecorations: [], + emojis: {}, + badgeRoles: [], + onlineStatus: 'unknown', + }, + notesCount: undefined, + name, + description: 'Some clip description', + isPublic: false, + favoritedCount: 0, + }; +} + +export function emojiDetailed(id = 'someemojiid', name = 'some_emoji'): entities.EmojiDetailed { + return { + id, + aliases: ['alias1', 'alias2'], + name, + category: 'emojiCategory', + host: null, + url: '/client-assets/about-icon.png', + license: null, + isSensitive: false, + localOnly: false, + roleIdsThatCanBeUsedThisEmojiAsReaction: ['roleId1', 'roleId2'], + }; +} + export function galleryPost(isSensitive = false) { return { id: 'somepostid', diff --git a/packages/frontend/.storybook/generate.tsx b/packages/frontend/.storybook/generate.tsx index d74c83a50007..d21eea9d1713 100644 --- a/packages/frontend/.storybook/generate.tsx +++ b/packages/frontend/.storybook/generate.tsx @@ -397,7 +397,7 @@ function toStories(component: string): Promise { const globs = await Promise.all([ glob('src/components/global/Mk*.vue'), glob('src/components/global/RouterView.vue'), - glob('src/components/Mk{A,B}*.vue'), + glob('src/components/Mk[A-C]*.vue'), glob('src/components/MkDigitalClock.vue'), glob('src/components/MkGalleryPostPreview.vue'), glob('src/components/MkSignupServerRules.vue'), diff --git a/packages/frontend/.storybook/main.ts b/packages/frontend/.storybook/main.ts index d3822942cd46..9f318cf449b9 100644 --- a/packages/frontend/.storybook/main.ts +++ b/packages/frontend/.storybook/main.ts @@ -15,6 +15,7 @@ const _dirname = fileURLToPath(new URL('.', import.meta.url)); const config = { stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], + staticDirs: [{ from: '../assets', to: '/client-assets' }], addons: [ getAbsolutePath('@storybook/addon-essentials'), getAbsolutePath('@storybook/addon-interactions'), diff --git a/packages/frontend/.storybook/preview.ts b/packages/frontend/.storybook/preview.ts index 982a2979ac8c..73ee007fb8b7 100644 --- a/packages/frontend/.storybook/preview.ts +++ b/packages/frontend/.storybook/preview.ts @@ -7,7 +7,7 @@ import { FORCE_REMOUNT } from '@storybook/core-events'; import { addons } from '@storybook/preview-api'; import { type Preview, setup } from '@storybook/vue3'; import isChromatic from 'chromatic/isChromatic'; -import { initialize, mswDecorator } from 'msw-storybook-addon'; +import { initialize, mswLoader } from 'msw-storybook-addon'; import { userDetailed } from './fakes.js'; import locale from './locale.js'; import { commonHandlers, onUnhandledRequest } from './mocks.js'; @@ -122,7 +122,6 @@ const preview = { } return story; }, - mswDecorator, (Story, context) => { return { setup() { @@ -137,6 +136,7 @@ const preview = { }; }, ], + loaders: [mswLoader], parameters: { controls: { exclude: /^__/, diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 56b824c0c5c0..66940a160103 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -104,6 +104,7 @@ "@types/node": "20.12.7", "@types/punycode": "2.1.4", "@types/sanitize-html": "2.11.0", + "@types/seedrandom": "3.0.8", "@types/throttle-debounce": "5.0.2", "@types/tinycolor2": "1.4.6", "@types/uuid": "9.0.8", @@ -128,6 +129,7 @@ "prettier": "3.2.5", "react": "18.3.1", "react-dom": "18.3.1", + "seedrandom": "3.0.5", "start-server-and-test": "2.0.3", "storybook": "8.0.9", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", diff --git a/packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts b/packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts new file mode 100644 index 000000000000..b99620da22f6 --- /dev/null +++ b/packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts @@ -0,0 +1,77 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable import/no-default-export */ +import { StoryObj } from '@storybook/vue3'; +import { HttpResponse, http } from 'msw'; +import { action } from '@storybook/addon-actions'; +import { expect, userEvent, within } from '@storybook/test'; +import { channel } from '../../.storybook/fakes.js'; +import { commonHandlers } from '../../.storybook/mocks.js'; +import MkChannelFollowButton from './MkChannelFollowButton.vue'; +import { semaphore } from '@/scripts/test-utils.js'; +import { i18n } from '@/i18n.js'; + +function sleep(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +const s = semaphore(); +export const Default = { + render(args) { + return { + components: { + MkChannelFollowButton, + }, + setup() { + return { + args, + }; + }, + computed: { + props() { + return { + ...this.args, + }; + }, + }, + template: '', + }; + }, + args: { + channel: channel(), + full: true, + }, + async play({ canvasElement }) { + await s.acquire(); + await sleep(1000); + const canvas = within(canvasElement); + const buttonElement = canvas.getByRole('button'); + await expect(buttonElement).toHaveTextContent(i18n.ts.follow); + await userEvent.click(buttonElement); + await sleep(1000); + await expect(buttonElement).toHaveTextContent(i18n.ts.unfollow); + await sleep(100); + await userEvent.click(buttonElement); + s.release(); + }, + parameters: { + layout: 'centered', + msw: { + handlers: [ + ...commonHandlers, + http.post('/api/channels/follow', async ({ request }) => { + action('POST /api/channels/follow')(await request.json()); + return HttpResponse.json({}); + }), + http.post('/api/channels/unfollow', async ({ request }) => { + action('POST /api/channels/unfollow')(await request.json()); + return HttpResponse.json({}); + }), + ], + }, + }, +} satisfies StoryObj; diff --git a/packages/frontend/src/components/MkChannelFollowButton.vue b/packages/frontend/src/components/MkChannelFollowButton.vue index 6b1b380e4118..841d37a56847 100644 --- a/packages/frontend/src/components/MkChannelFollowButton.vue +++ b/packages/frontend/src/components/MkChannelFollowButton.vue @@ -26,17 +26,18 @@ SPDX-License-Identifier: AGPL-3.0-only diff --git a/packages/frontend/src/widgets/WidgetProfile.vue b/packages/frontend/src/widgets/WidgetProfile.vue index a5578d4de62a..ae39098305b3 100644 --- a/packages/frontend/src/widgets/WidgetProfile.vue +++ b/packages/frontend/src/widgets/WidgetProfile.vue @@ -82,16 +82,19 @@ defineExpose({ .body { text-overflow: ellipsis; overflow: clip; + margin-left: -10px; + padding: 10px; } .name { color: #fff; - filter: drop-shadow(0 0 4px #000); + filter: drop-shadow(0 0 4px #000) drop-shadow(0 0 0.1px rgba(0, 0, 0, 0.5)); font-weight: bold; } .username { color: #fff; - filter: drop-shadow(0 0 4px #000); + filter: drop-shadow(0 0 4px #000) drop-shadow(0 0 0.1px rgba(0, 0, 0, 0.5)); + font-weight: normal; } From ac12ab8629f0a0172250f949a98ee1efb1d0890d Mon Sep 17 00:00:00 2001 From: Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> Date: Sat, 22 Jun 2024 12:51:02 +0900 Subject: [PATCH 049/268] =?UTF-8?q?fix(backend):=20=E3=83=95=E3=82=A3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=AE=E3=83=8E=E3=83=BC=E3=83=88=E3=81=AE?= =?UTF-8?q?MFM=E3=81=AFHTML=E3=81=AB=E3=83=AC=E3=83=B3=E3=83=80=E3=83=BC?= =?UTF-8?q?=E3=81=97=E3=81=A6=E3=81=8B=E3=82=89=E8=BF=94=E3=81=99=20(#1400?= =?UTF-8?q?6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backend): フィードのノートのMFMはHTMLにレンダーしてから返す (test wip) * chore: beforeEachを使う? * fix: プレーンテキストにフォールバックしてMFMが含まれていないか調べる方針を実装 * fix: application/jsonだとパースされるのでその作用をキャンセル * build: fix lint error * docs: update CHANGELOG.md --------- Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> --- CHANGELOG.md | 1 + packages/backend/src/server/web/FeedService.ts | 6 +++++- packages/backend/test/e2e/fetch-resource.ts | 17 +++++++++++++++++ packages/backend/test/utils.ts | 5 +++-- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5eb698385b2..ab9f5f800052 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Server - チャート生成時にinstance.suspentionStateに置き換えられたinstance.isSuspendedが参照されてしまう問題を修正 - Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949) +- Fix: ユーザーのフィードページのMFMをHTMLに展開するように (#14006) - Fix: アンテナ・クリップ・リスト・ウェブフックがロールポリシーの上限より一つ多く作れてしまうのを修正 (#14036) - Fix: notRespondingSinceが実装される前に不通になったインスタンスが自動的に配信停止にならない (#14059) - Fix: FTT有効時、タイムライン用エンドポイントで`sinceId`にキャッシュ内最古のものより古いものを指定した場合に正しく結果が返ってこない問題を修正 diff --git a/packages/backend/src/server/web/FeedService.ts b/packages/backend/src/server/web/FeedService.ts index 10e3ed26820c..9d810ddc846b 100644 --- a/packages/backend/src/server/web/FeedService.ts +++ b/packages/backend/src/server/web/FeedService.ts @@ -14,6 +14,8 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; +import { MfmService } from "@/core/MfmService.js"; +import { parse as mfmParse } from 'mfm-js'; @Injectable() export class FeedService { @@ -33,6 +35,7 @@ export class FeedService { private userEntityService: UserEntityService, private driveFileEntityService: DriveFileEntityService, private idService: IdService, + private mfmService: MfmService, ) { } @@ -76,13 +79,14 @@ export class FeedService { id: In(note.fileIds), }) : []; const file = files.find(file => file.type.startsWith('image/')); + const text = note.text; feed.addItem({ title: `New note by ${author.name}`, link: `${this.config.url}/notes/${note.id}`, date: this.idService.parse(note.id).date, description: note.cw ?? undefined, - content: note.text ?? undefined, + content: text ? this.mfmService.toHtml(mfmParse(text), JSON.parse(note.mentionedRemoteUsers)) ?? undefined : undefined, image: file ? this.driveFileEntityService.getPublicUrl(file) : undefined, }); } diff --git a/packages/backend/test/e2e/fetch-resource.ts b/packages/backend/test/e2e/fetch-resource.ts index 4851ed14be6a..7efd688ec279 100644 --- a/packages/backend/test/e2e/fetch-resource.ts +++ b/packages/backend/test/e2e/fetch-resource.ts @@ -153,6 +153,23 @@ describe('Webリソース', () => { path: path('nonexisting'), status: 404, })); + + describe(' has entry such ', () => { + beforeEach(() => { + post(alice, { text: "**a**" }) + }); + + test('MFMを含まない。', async () => { + const content = await simpleGet(path(alice.username), "*/*", undefined, res => res.text()); + const _body: unknown = content.body; + // JSONフィードのときは改めて文字列化する + const body: string = typeof (_body) === "object" ? JSON.stringify(_body) : _body as string; + + if (body.includes("**a**")) { + throw new Error("MFM shouldn't be included"); + } + }); + }) }); describe.each([{ path: '/api/foo' }])('$path', ({ path }) => { diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts index 86814fffe0e4..aad4ab37c93c 100644 --- a/packages/backend/test/utils.ts +++ b/packages/backend/test/utils.ts @@ -17,6 +17,7 @@ import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/val import { entities } from '../src/postgres.js'; import { loadConfig } from '../src/config.js'; import type * as misskey from 'misskey-js'; +import { type Response } from 'node-fetch'; export { server as startServer, jobQueue as startJobQueue } from '@/boot/common.js'; @@ -454,7 +455,7 @@ export type SimpleGetResponse = { type: string | null, location: string | null }; -export const simpleGet = async (path: string, accept = '*/*', cookie: any = undefined): Promise => { +export const simpleGet = async (path: string, accept = '*/*', cookie: any = undefined, bodyExtractor: (res: Response) => Promise = _ => Promise.resolve(null)): Promise => { const res = await relativeFetch(path, { headers: { Accept: accept, @@ -482,7 +483,7 @@ export const simpleGet = async (path: string, accept = '*/*', cookie: any = unde const body = jsonTypes.includes(res.headers.get('content-type') ?? '') ? await res.json() : htmlTypes.includes(res.headers.get('content-type') ?? '') ? new JSDOM(await res.text()) : - null; + await bodyExtractor(res); return { status: res.status, From b50eb511b0cf6fb05d37c3370726f940c1438a99 Mon Sep 17 00:00:00 2001 From: yupix Date: Sat, 22 Jun 2024 14:52:27 +0900 Subject: [PATCH 050/268] =?UTF-8?q?refactor:=20api/*/update=E7=B3=BB?= =?UTF-8?q?=E3=81=AE=E5=BF=85=E9=A0=88=E3=82=AD=E3=83=BC=E3=82=92=E6=9C=80?= =?UTF-8?q?=E4=BD=8E=E9=99=90=E3=81=AB=20(#13824)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: clips/updateの必須キーをclipIdのみに * refactor: admin/roles/update の必須キーをroleIdのみに * feat: pages/update の必須キーをpageIdのみに * refactor: gallery/posts/update の必須キーをpostidのみに * feat: misskey-jsの型を更新 * feat: i/webhooks/updateの必須キーをwebhookIdのみに * feat: admin/ad/updateの必須キーをidのみに * feat: misskey-jsの型を更新 * chore: update CHANGELOG.md * docs: update CHANGELOG.md * fix: secretが更新できなくなる場合がある Co-authored-by: zyoshoka <107108195+zyoshoka@users.noreply.github.com> * Update packages/backend/src/server/api/endpoints/gallery/posts/update.ts --------- Co-authored-by: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> --- CHANGELOG.md | 6 ++ .../server/api/endpoints/admin/ad/update.ts | 6 +- .../api/endpoints/admin/roles/update.ts | 14 ---- .../src/server/api/endpoints/clips/update.ts | 4 +- .../api/endpoints/gallery/posts/update.ts | 26 ++++--- .../server/api/endpoints/i/webhooks/update.ts | 6 +- .../src/server/api/endpoints/pages/update.ts | 23 ++---- packages/misskey-js/src/autogen/types.ts | 71 +++++++++---------- 8 files changed, 71 insertions(+), 85 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab9f5f800052..c1af63ad2388 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,12 @@ - Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949) - Fix: ユーザーのフィードページのMFMをHTMLに展開するように (#14006) - Fix: アンテナ・クリップ・リスト・ウェブフックがロールポリシーの上限より一つ多く作れてしまうのを修正 (#14036) +- Enhance: エンドポイント`clips/update`の必須項目を`clipId`のみに +- Enhance: エンドポイント`admin/roles/update`の必須項目を`roleId`のみに +- Enhance: エンドポイント`pages/update`の必須項目を`pageId`のみに +- Enhance: エンドポイント`gallery/posts/update`の必須項目を`postId`のみに +- Enhance: エンドポイント`i/webhook/update`の必須項目を`webhookId`のみに +- Enhance: エンドポイント`admin/ad/update`の必須項目を`id`のみに - Fix: notRespondingSinceが実装される前に不通になったインスタンスが自動的に配信停止にならない (#14059) - Fix: FTT有効時、タイムライン用エンドポイントで`sinceId`にキャッシュ内最古のものより古いものを指定した場合に正しく結果が返ってこない問題を修正 diff --git a/packages/backend/src/server/api/endpoints/admin/ad/update.ts b/packages/backend/src/server/api/endpoints/admin/ad/update.ts index 62358457ff76..4e3d731acac9 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/update.ts @@ -40,7 +40,7 @@ export const paramDef = { startsAt: { type: 'integer' }, dayOfWeek: { type: 'integer' }, }, - required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'dayOfWeek'], + required: ['id'], } as const; @Injectable() @@ -63,8 +63,8 @@ export default class extends Endpoint { // eslint- ratio: ps.ratio, memo: ps.memo, imageUrl: ps.imageUrl, - expiresAt: new Date(ps.expiresAt), - startsAt: new Date(ps.startsAt), + expiresAt: ps.expiresAt ? new Date(ps.expiresAt) : undefined, + startsAt: ps.startsAt ? new Date(ps.startsAt) : undefined, dayOfWeek: ps.dayOfWeek, }); diff --git a/packages/backend/src/server/api/endpoints/admin/roles/update.ts b/packages/backend/src/server/api/endpoints/admin/roles/update.ts index 5242e0be2f96..465ad7aaafbf 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/update.ts @@ -6,7 +6,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RolesRepository } from '@/models/_.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '@/server/api/error.js'; import { RoleService } from '@/core/RoleService.js'; @@ -50,19 +49,6 @@ export const paramDef = { }, required: [ 'roleId', - 'name', - 'description', - 'color', - 'iconUrl', - 'target', - 'condFormula', - 'isPublic', - 'isModerator', - 'isAdministrator', - 'asBadge', - 'canEditMembersByModerator', - 'displayOrder', - 'policies', ], } as const; diff --git a/packages/backend/src/server/api/endpoints/clips/update.ts b/packages/backend/src/server/api/endpoints/clips/update.ts index 3b44ba81b3e6..603a3ccf3dc5 100644 --- a/packages/backend/src/server/api/endpoints/clips/update.ts +++ b/packages/backend/src/server/api/endpoints/clips/update.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { Inject, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { ClipEntityService } from '@/core/entities/ClipEntityService.js'; import { ClipService } from '@/core/ClipService.js'; @@ -41,7 +41,7 @@ export const paramDef = { isPublic: { type: 'boolean' }, description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 }, }, - required: ['clipId', 'name'], + required: ['clipId'], } as const; @Injectable() diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts index 2f977784ec28..5243ee960314 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts @@ -47,7 +47,7 @@ export const paramDef = { } }, isSensitive: { type: 'boolean', default: false }, }, - required: ['postId', 'title', 'fileIds'], + required: ['postId'], } as const; @Injectable() @@ -62,15 +62,19 @@ export default class extends Endpoint { // eslint- private galleryPostEntityService: GalleryPostEntityService, ) { super(meta, paramDef, async (ps, me) => { - const files = (await Promise.all(ps.fileIds.map(fileId => - this.driveFilesRepository.findOneBy({ - id: fileId, - userId: me.id, - }), - ))).filter(x => x != null); - - if (files.length === 0) { - throw new Error(); + let files: Array | undefined; + + if (ps.fileIds) { + files = (await Promise.all(ps.fileIds.map(fileId => + this.driveFilesRepository.findOneBy({ + id: fileId, + userId: me.id, + }), + ))).filter(x => x != null); + + if (files.length === 0) { + throw new Error(); + } } await this.galleryPostsRepository.update({ @@ -81,7 +85,7 @@ export default class extends Endpoint { // eslint- title: ps.title, description: ps.description, isSensitive: ps.isSensitive, - fileIds: files.map(file => file.id), + fileIds: files ? files.map(file => file.id) : undefined, }); const post = await this.galleryPostsRepository.findOneByOrFail({ id: ps.postId }); diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/update.ts b/packages/backend/src/server/api/endpoints/i/webhooks/update.ts index 6e380d76f89e..07a25bd82aad 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/update.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/update.ts @@ -34,13 +34,13 @@ export const paramDef = { webhookId: { type: 'string', format: 'misskey:id' }, name: { type: 'string', minLength: 1, maxLength: 100 }, url: { type: 'string', minLength: 1, maxLength: 1024 }, - secret: { type: 'string', maxLength: 1024, default: '' }, + secret: { type: 'string', nullable: true, maxLength: 1024 }, on: { type: 'array', items: { type: 'string', enum: webhookEventTypes, } }, active: { type: 'boolean' }, }, - required: ['webhookId', 'name', 'url', 'on', 'active'], + required: ['webhookId'], } as const; // TODO: ロジックをサービスに切り出す @@ -66,7 +66,7 @@ export default class extends Endpoint { // eslint- await this.webhooksRepository.update(webhook.id, { name: ps.name, url: ps.url, - secret: ps.secret, + secret: ps.secret === null ? '' : ps.secret, on: ps.on, active: ps.active, }); diff --git a/packages/backend/src/server/api/endpoints/pages/update.ts b/packages/backend/src/server/api/endpoints/pages/update.ts index b8e5e70a25a4..f11bbbcb1a47 100644 --- a/packages/backend/src/server/api/endpoints/pages/update.ts +++ b/packages/backend/src/server/api/endpoints/pages/update.ts @@ -70,7 +70,7 @@ export const paramDef = { alignCenter: { type: 'boolean' }, hideTitleWhenPinned: { type: 'boolean' }, }, - required: ['pageId', 'title', 'name', 'content', 'variables', 'script'], + required: ['pageId'], } as const; @Injectable() @@ -91,9 +91,8 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.accessDenied); } - let eyeCatchingImage = null; if (ps.eyeCatchingImageId != null) { - eyeCatchingImage = await this.driveFilesRepository.findOneBy({ + const eyeCatchingImage = await this.driveFilesRepository.findOneBy({ id: ps.eyeCatchingImageId, userId: me.id, }); @@ -116,23 +115,15 @@ export default class extends Endpoint { // eslint- await this.pagesRepository.update(page.id, { updatedAt: new Date(), title: ps.title, - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - name: ps.name === undefined ? page.name : ps.name, + name: ps.name, summary: ps.summary === undefined ? page.summary : ps.summary, content: ps.content, variables: ps.variables, script: ps.script, - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter, - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned, - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - font: ps.font === undefined ? page.font : ps.font, - eyeCatchingImageId: ps.eyeCatchingImageId === null - ? null - : ps.eyeCatchingImageId === undefined - ? page.eyeCatchingImageId - : eyeCatchingImage!.id, + alignCenter: ps.alignCenter, + hideTitleWhenPinned: ps.hideTitleWhenPinned, + font: ps.font, + eyeCatchingImageId: ps.eyeCatchingImageId, }); }); } diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index bdcc1dfd778e..72aca4dee298 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -5881,15 +5881,15 @@ export type operations = { 'application/json': { /** Format: misskey:id */ id: string; - memo: string; - url: string; - imageUrl: string; - place: string; - priority: string; - ratio: number; - expiresAt: number; - startsAt: number; - dayOfWeek: number; + memo?: string; + url?: string; + imageUrl?: string; + place?: string; + priority?: string; + ratio?: number; + expiresAt?: number; + startsAt?: number; + dayOfWeek?: number; }; }; }; @@ -9744,21 +9744,21 @@ export type operations = { 'application/json': { /** Format: misskey:id */ roleId: string; - name: string; - description: string; - color: string | null; - iconUrl: string | null; + name?: string; + description?: string; + color?: string | null; + iconUrl?: string | null; /** @enum {string} */ - target: 'manual' | 'conditional'; - condFormula: Record; - isPublic: boolean; - isModerator: boolean; - isAdministrator: boolean; + target?: 'manual' | 'conditional'; + condFormula?: Record; + isPublic?: boolean; + isModerator?: boolean; + isAdministrator?: boolean; isExplorable?: boolean; - asBadge: boolean; - canEditMembersByModerator: boolean; - displayOrder: number; - policies: Record; + asBadge?: boolean; + canEditMembersByModerator?: boolean; + displayOrder?: number; + policies?: Record; }; }; }; @@ -13400,7 +13400,7 @@ export type operations = { 'application/json': { /** Format: misskey:id */ clipId: string; - name: string; + name?: string; isPublic?: boolean; description?: string | null; }; @@ -16247,9 +16247,9 @@ export type operations = { 'application/json': { /** Format: misskey:id */ postId: string; - title: string; + title?: string; description?: string | null; - fileIds: string[]; + fileIds?: string[]; /** @default false */ isSensitive?: boolean; }; @@ -20030,12 +20030,11 @@ export type operations = { 'application/json': { /** Format: misskey:id */ webhookId: string; - name: string; - url: string; - /** @default */ - secret?: string; - on: ('mention' | 'unfollow' | 'follow' | 'followed' | 'note' | 'reply' | 'renote' | 'reaction')[]; - active: boolean; + name?: string; + url?: string; + secret?: string | null; + on?: ('mention' | 'unfollow' | 'follow' | 'followed' | 'note' | 'reply' | 'renote' | 'reaction')[]; + active?: boolean; }; }; }; @@ -23404,16 +23403,16 @@ export type operations = { 'application/json': { /** Format: misskey:id */ pageId: string; - title: string; - name: string; + title?: string; + name?: string; summary?: string | null; - content: { + content?: { [key: string]: unknown; }[]; - variables: { + variables?: { [key: string]: unknown; }[]; - script: string; + script?: string; /** Format: misskey:id */ eyeCatchingImageId?: string | null; /** @enum {string} */ From faeab96e01c7c7be5dfc85716b4a0b05b93f50ab Mon Sep 17 00:00:00 2001 From: Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> Date: Sat, 22 Jun 2024 14:55:24 +0900 Subject: [PATCH 051/268] ci: add quote (#13990) --- .github/workflows/storybook.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index c52883ffdde9..daa76509c831 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -88,7 +88,7 @@ jobs: if [ "$BRANCH" = "misskey-dev:$HEAD_REF" ]; then BRANCH="$HEAD_REF" fi - pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name $BRANCH $(echo "$CHROMATIC_PARAMETER") + pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name "$BRANCH" $(echo "$CHROMATIC_PARAMETER") env: HEAD_REF: ${{ github.event.pull_request.head.ref }} CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} From bf403aa656627fc4b29aed329aa044d42a791acf 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: Sat, 22 Jun 2024 15:35:54 +0900 Subject: [PATCH 052/268] =?UTF-8?q?fix(frontend):=20=E3=83=99=E3=83=BC?= =?UTF-8?q?=E3=82=B9=E3=83=AD=E3=83=BC=E3=83=AB=E3=82=92=E7=B7=A8=E9=9B=86?= =?UTF-8?q?=E3=81=97=E3=81=A6=E3=82=82UI=E4=B8=8A=E3=81=A7=E3=81=AF?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=81=8C=E5=8F=8D=E6=98=A0=E3=81=95=E3=82=8C?= =?UTF-8?q?=E3=81=AA=E3=81=84=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=20(#13995)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(frontend): ベースロールを変更してもUI上では変更が反映されない問題を修正 * Update CHANGELOG.md --- CHANGELOG.md | 1 + packages/frontend/src/pages/admin/roles.vue | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1af63ad2388..a913e4250083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Fix: `/about#federation` ページなどで各インスタンスのチャートが表示されなくなっていた問題を修正 - Fix: ユーザーページの追加情報のラベルを投稿者のサーバーの絵文字で表示する (#13968) - Fix: リバーシの対局を正しく共有できないことがある問題を修正 +- Fix: コントロールパネルでベースロールのポリシーを編集してもUI上では変更が反映されない問題を修正 ### Server - チャート生成時にinstance.suspentionStateに置き換えられたinstance.isSuspendedが参照されてしまう問題を修正 diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue index 9753d9f6cb7a..50323e3de558 100644 --- a/packages/frontend/src/pages/admin/roles.vue +++ b/packages/frontend/src/pages/admin/roles.vue @@ -243,7 +243,7 @@ import * as os from '@/os.js'; import { misskeyApi } from '@/scripts/misskey-api.js'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; -import { instance } from '@/instance.js'; +import { instance, fetchInstance } from '@/instance.js'; import MkFoldableSection from '@/components/MkFoldableSection.vue'; import { ROLE_POLICIES } from '@/const.js'; import { useRouter } from '@/router/supplier.js'; @@ -267,6 +267,7 @@ async function updateBaseRole() { await os.apiWithDialog('admin/roles/update-default-policies', { policies, }); + fetchInstance(true); } function create() { From 7c22a64b8c505f6e6c9da0fec16902fcd9af773f 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: Sat, 22 Jun 2024 16:52:27 +0900 Subject: [PATCH 053/268] =?UTF-8?q?fix(backend):=20=E8=87=AA=E5=88=86?= =?UTF-8?q?=E4=BB=A5=E5=A4=96=E3=81=AE=E3=82=AF=E3=83=AA=E3=83=83=E3=83=97?= =?UTF-8?q?=E5=86=85=E3=81=AE=E3=83=8E=E3=83=BC=E3=83=88=E5=80=8B=E6=95=B0?= =?UTF-8?q?=E3=81=8C=E8=A6=8B=E3=81=88=E3=82=8B=E3=81=AE=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=20(#14065)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backend): 自分以外のクリップ内のノート個数が見えることがあるのを修正 * Update Changelog * fix --- CHANGELOG.md | 1 + packages/backend/src/core/entities/ClipEntityService.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a913e4250083..e4c4cfe1f0dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ - Enhance: エンドポイント`admin/ad/update`の必須項目を`id`のみに - Fix: notRespondingSinceが実装される前に不通になったインスタンスが自動的に配信停止にならない (#14059) - Fix: FTT有効時、タイムライン用エンドポイントで`sinceId`にキャッシュ内最古のものより古いものを指定した場合に正しく結果が返ってこない問題を修正 +- Fix: 自分以外のクリップ内のノート個数が見えることがあるのを修正 ## 2024.5.0 diff --git a/packages/backend/src/core/entities/ClipEntityService.ts b/packages/backend/src/core/entities/ClipEntityService.ts index 3855a2843688..d91564590692 100644 --- a/packages/backend/src/core/entities/ClipEntityService.ts +++ b/packages/backend/src/core/entities/ClipEntityService.ts @@ -53,7 +53,7 @@ export class ClipEntityService { isPublic: clip.isPublic, favoritedCount: await this.clipFavoritesRepository.countBy({ clipId: clip.id }), isFavorited: meId ? await this.clipFavoritesRepository.exists({ where: { clipId: clip.id, userId: meId } }) : undefined, - notesCount: meId ? await this.clipNotesRepository.countBy({ clipId: clip.id }) : undefined, + notesCount: (meId === clip.userId) ? await this.clipNotesRepository.countBy({ clipId: clip.id }) : undefined, }); } From 9368eb3038d5f655b924d53800daaa7e54e08c47 Mon Sep 17 00:00:00 2001 From: Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> Date: Sat, 22 Jun 2024 19:40:55 +0900 Subject: [PATCH 054/268] refactor: say bye to the weird groupBy friends (#13975) * refactor(frontend): say bye to the weird groupBy friends * refactor(backend): say bye to the weird groupBy friends --- packages/backend/src/misc/prelude/array.ts | 38 ---------------------- packages/frontend/src/scripts/array.ts | 38 ---------------------- 2 files changed, 76 deletions(-) diff --git a/packages/backend/src/misc/prelude/array.ts b/packages/backend/src/misc/prelude/array.ts index dbfe1fff18c6..f741a0c91339 100644 --- a/packages/backend/src/misc/prelude/array.ts +++ b/packages/backend/src/misc/prelude/array.ts @@ -65,44 +65,6 @@ export function maximum(xs: number[]): number { return Math.max(...xs); } -/** - * Splits an array based on the equivalence relation. - * The concatenation of the result is equal to the argument. - */ -export function groupBy(f: EndoRelation, xs: T[]): T[][] { - const groups = [] as T[][]; - for (const x of xs) { - const lastGroup = groups.at(-1); - if (lastGroup !== undefined && f(lastGroup[0], x)) { - lastGroup.push(x); - } else { - groups.push([x]); - } - } - return groups; -} - -/** - * Splits an array based on the equivalence relation induced by the function. - * The concatenation of the result is equal to the argument. - */ -export function groupOn(f: (x: T) => S, xs: T[]): T[][] { - return groupBy((a, b) => f(a) === f(b), xs); -} - -export function groupByX(collections: T[], keySelector: (x: T) => string) { - return collections.reduce((obj: Record, item: T) => { - const key = keySelector(item); - if (!Object.prototype.hasOwnProperty.call(obj, key)) { - obj[key] = []; - } - - obj[key].push(item); - - return obj; - }, {}); -} - /** * Compare two arrays by lexicographical order */ diff --git a/packages/frontend/src/scripts/array.ts b/packages/frontend/src/scripts/array.ts index b3d76e149f43..f2feb29dfc57 100644 --- a/packages/frontend/src/scripts/array.ts +++ b/packages/frontend/src/scripts/array.ts @@ -77,44 +77,6 @@ export function maximum(xs: number[]): number { return Math.max(...xs); } -/** - * Splits an array based on the equivalence relation. - * The concatenation of the result is equal to the argument. - */ -export function groupBy(f: EndoRelation, xs: T[]): T[][] { - const groups = [] as T[][]; - for (const x of xs) { - const lastGroup = groups.at(-1); - if (lastGroup !== undefined && f(lastGroup[0], x)) { - lastGroup.push(x); - } else { - groups.push([x]); - } - } - return groups; -} - -/** - * Splits an array based on the equivalence relation induced by the function. - * The concatenation of the result is equal to the argument. - */ -export function groupOn(f: (x: T) => S, xs: T[]): T[][] { - return groupBy((a, b) => f(a) === f(b), xs); -} - -export function groupByX(collections: T[], keySelector: (x: T) => string) { - return collections.reduce((obj: Record, item: T) => { - const key = keySelector(item); - if (typeof obj[key] === 'undefined') { - obj[key] = []; - } - - obj[key].push(item); - - return obj; - }, {}); -} - /** * Compare two arrays by lexicographical order */ From b8b4dc50384aa3f146d90b10d7f13f87a4a2232c Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Sat, 22 Jun 2024 19:45:08 +0900 Subject: [PATCH 055/268] build: install pnpm with corepack on docker build (#13926) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * build: install pnpm with corepack on build * docs(changelog): Dockerコンテナの立ち上げ時に`pnpm`のインストールで固まることがある問題 --- CHANGELOG.md | 1 + Dockerfile | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4c4cfe1f0dc..ca74d7171920 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### General - Feat: 通報を受けた際、または解決した際に、予め登録した宛先に通知を飛ばせるように(mail or webhook) #13705 - Fix: 配信停止したインスタンス一覧が見れなくなる問題を修正 +- Fix: Dockerコンテナの立ち上げ時に`pnpm`のインストールで固まることがある問題 ### Client - Fix: `/about#federation` ページなどで各インスタンスのチャートが表示されなくなっていた問題を修正 diff --git a/Dockerfile b/Dockerfile index 9fc2d611cd82..d6ca6b8cdffb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -82,6 +82,10 @@ RUN apt-get update \ USER misskey WORKDIR /misskey +# add package.json to add pnpm +COPY --chown=misskey:misskey ./package.json ./package.json +RUN corepack install + COPY --chown=misskey:misskey --from=target-builder /misskey/node_modules ./node_modules COPY --chown=misskey:misskey --from=target-builder /misskey/packages/backend/node_modules ./packages/backend/node_modules COPY --chown=misskey:misskey --from=target-builder /misskey/packages/misskey-js/node_modules ./packages/misskey-js/node_modules From 00b213373bd3f60a6144344ab8cbda08418ca1e4 Mon Sep 17 00:00:00 2001 From: woxtu Date: Sat, 22 Jun 2024 19:46:29 +0900 Subject: [PATCH 056/268] Remove @types/node-fetch (#13948) --- packages/backend/package.json | 1 - pnpm-lock.yaml | 11 ----------- 2 files changed, 12 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 15134b1ca8b8..0467ab0bee8a 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -207,7 +207,6 @@ "@types/mime-types": "2.1.4", "@types/ms": "0.7.34", "@types/node": "20.12.7", - "@types/node-fetch": "3.0.3", "@types/nodemailer": "6.4.15", "@types/oauth": "0.9.4", "@types/oauth2orize": "1.11.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1281f7eefe90..09df15853b80 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -586,9 +586,6 @@ importers: '@types/node': specifier: 20.12.7 version: 20.12.7 - '@types/node-fetch': - specifier: 3.0.3 - version: 3.0.3 '@types/nodemailer': specifier: 6.4.15 version: 6.4.15 @@ -4625,10 +4622,6 @@ packages: '@types/node-fetch@2.6.4': resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} - '@types/node-fetch@3.0.3': - resolution: {integrity: sha512-HhggYPH5N+AQe/OmN6fmhKmRRt2XuNJow+R3pQwJxOOF9GuwM7O2mheyGeIrs5MOIeNjDEdgdoyHBOrFeJBR3g==} - deprecated: This is a stub types definition. node-fetch provides its own type definitions, so you do not need this installed. - '@types/node@18.17.15': resolution: {integrity: sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA==} @@ -16025,10 +16018,6 @@ snapshots: '@types/node': 20.12.7 form-data: 3.0.1 - '@types/node-fetch@3.0.3': - dependencies: - node-fetch: 3.3.2 - '@types/node@18.17.15': {} '@types/node@20.11.5': From 961cb6c5eeb7745dc156327d2041241b70098b70 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Sat, 22 Jun 2024 19:49:38 +0900 Subject: [PATCH 057/268] fix(backend): fix creating reactions bugs (#13901) * fix(backend): add fallback for empty string when creating reaction * fix(backend): prohibit reactions to Renote * test(backend): add some tests for `notes/reactions/create` endpoint * Update CHANGELOG.md * lint * Update CHANGELOG.md --------- Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> --- CHANGELOG.md | 2 + packages/backend/src/core/ReactionService.ts | 8 ++- .../api/endpoints/notes/reactions/create.ts | 7 +++ packages/backend/test/e2e/endpoints.ts | 61 +++++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca74d7171920..354bbd20fd67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ - Fix: notRespondingSinceが実装される前に不通になったインスタンスが自動的に配信停止にならない (#14059) - Fix: FTT有効時、タイムライン用エンドポイントで`sinceId`にキャッシュ内最古のものより古いものを指定した場合に正しく結果が返ってこない問題を修正 - Fix: 自分以外のクリップ内のノート個数が見えることがあるのを修正 +- Fix: 空文字列のリアクションはフォールバックされるように +- Fix: リノートにリアクションできないように ## 2024.5.0 diff --git a/packages/backend/src/core/ReactionService.ts b/packages/backend/src/core/ReactionService.ts index cb0b079df0dd..64c7b2ed032c 100644 --- a/packages/backend/src/core/ReactionService.ts +++ b/packages/backend/src/core/ReactionService.ts @@ -29,6 +29,7 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { RoleService } from '@/core/RoleService.js'; import { FeaturedService } from '@/core/FeaturedService.js'; import { trackPromise } from '@/misc/promise-tracker.js'; +import { isQuote, isRenote } from '@/misc/is-renote.js'; const FALLBACK = '\u2764'; const PER_NOTE_REACTION_USER_PAIR_CACHE_MAX = 16; @@ -117,11 +118,16 @@ export class ReactionService { throw new IdentifiableError('68e9d2d1-48bf-42c2-b90a-b20e09fd3d48', 'Note not accessible for you.'); } + // Check if note is Renote + if (isRenote(note) && !isQuote(note)) { + throw new IdentifiableError('12c35529-3c79-4327-b1cc-e2cf63a71925', 'You cannot react to Renote.'); + } + let reaction = _reaction ?? FALLBACK; if (note.reactionAcceptance === 'likeOnly' || ((note.reactionAcceptance === 'likeOnlyForRemote' || note.reactionAcceptance === 'nonSensitiveOnlyForLocalLikeOnlyForRemote') && (user.host != null))) { reaction = '\u2764'; - } else if (_reaction) { + } else if (_reaction != null) { const custom = reaction.match(isCustomEmojiRegexp); if (custom) { const reacterHost = this.utilityService.toPunyNullable(user.host); diff --git a/packages/backend/src/server/api/endpoints/notes/reactions/create.ts b/packages/backend/src/server/api/endpoints/notes/reactions/create.ts index b9899608bf16..0f0dcca605ab 100644 --- a/packages/backend/src/server/api/endpoints/notes/reactions/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/reactions/create.ts @@ -36,6 +36,12 @@ export const meta = { code: 'YOU_HAVE_BEEN_BLOCKED', id: '20ef5475-9f38-4e4c-bd33-de6d979498ec', }, + + cannotReactToRenote: { + message: 'You cannot react to Renote.', + code: 'CANNOT_REACT_TO_RENOTE', + id: 'eaccdc08-ddef-43fe-908f-d108faad57f5', + }, }, } as const; @@ -62,6 +68,7 @@ export default class extends Endpoint { // eslint- await this.reactionService.create(me, note, ps.reaction).catch(err => { if (err.id === '51c42bb4-931a-456b-bff7-e5a8a70dd298') throw new ApiError(meta.errors.alreadyReacted); if (err.id === 'e70412a4-7197-4726-8e74-f3e0deb92aa7') throw new ApiError(meta.errors.youHaveBeenBlocked); + if (err.id === '12c35529-3c79-4327-b1cc-e2cf63a71925') throw new ApiError(meta.errors.cannotReactToRenote); throw err; }); return; diff --git a/packages/backend/test/e2e/endpoints.ts b/packages/backend/test/e2e/endpoints.ts index bc89dc37f4d8..de5e8ba95e34 100644 --- a/packages/backend/test/e2e/endpoints.ts +++ b/packages/backend/test/e2e/endpoints.ts @@ -266,6 +266,67 @@ describe('Endpoints', () => { assert.strictEqual(res.status, 400); }); + test('リノートにリアクションできない', async () => { + const bobNote = await post(bob, { text: 'hi' }); + const bobRenote = await post(bob, { renoteId: bobNote.id }); + + const res = await api('notes/reactions/create', { + noteId: bobRenote.id, + reaction: '🚀', + }, alice); + + assert.strictEqual(res.status, 400); + assert.strictEqual(res.body.error.code, 'CANNOT_REACT_TO_RENOTE'); + }); + + test('引用にリアクションできる', async () => { + const bobNote = await post(bob, { text: 'hi' }); + const bobRenote = await post(bob, { text: 'hi again', renoteId: bobNote.id }); + + const res = await api('notes/reactions/create', { + noteId: bobRenote.id, + reaction: '🚀', + }, alice); + + assert.strictEqual(res.status, 204); + }); + + test('空文字列のリアクションは\u2764にフォールバックされる', async () => { + const bobNote = await post(bob, { text: 'hi' }); + + const res = await api('notes/reactions/create', { + noteId: bobNote.id, + reaction: '', + }, alice); + + assert.strictEqual(res.status, 204); + + const reaction = await api('notes/reactions', { + noteId: bobNote.id, + }); + + assert.strictEqual(reaction.body.length, 1); + assert.strictEqual(reaction.body[0].type, '\u2764'); + }); + + test('絵文字ではない文字列のリアクションは\u2764にフォールバックされる', async () => { + const bobNote = await post(bob, { text: 'hi' }); + + const res = await api('notes/reactions/create', { + noteId: bobNote.id, + reaction: 'Hello!', + }, alice); + + assert.strictEqual(res.status, 204); + + const reaction = await api('notes/reactions', { + noteId: bobNote.id, + }); + + assert.strictEqual(reaction.body.length, 1); + assert.strictEqual(reaction.body[0].type, '\u2764'); + }); + test('空のパラメータで怒られる', async () => { // @ts-expect-error param must not be empty const res = await api('notes/reactions/create', {}, alice); From 2acbec6891a94dc9291b3e0c3d2e24d13367ba1c Mon Sep 17 00:00:00 2001 From: Ibuki Sugiyama Date: Sat, 22 Jun 2024 19:50:32 +0900 Subject: [PATCH 058/268] enhance: update datasaver switch titles (#12834) --- locales/ja-JP.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 3ac1ce82a3b7..0d89d33abeec 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2599,16 +2599,16 @@ _externalResourceInstaller: _dataSaver: _media: - title: "メディアの読み込み" + title: "メディアの読み込みを無効化" description: "画像・動画が自動で読み込まれるのを防止します。隠れている画像・動画はタップすると読み込まれます。" _avatar: - title: "アイコン画像" + title: "アイコン画像のアニメーションを無効化" description: "アイコン画像のアニメーションが停止します。アニメーション画像は通常の画像よりファイルサイズが大きいことがあるので、データ通信量をさらに削減できます。" _urlPreview: - title: "URLプレビューのサムネイル" + title: "URLプレビューのサムネイルを非表示" description: "URLプレビューのサムネイル画像が読み込まれなくなります。" _code: - title: "コードハイライト" + title: "コードハイライトを非表示" description: "MFMなどでコードハイライト記法が使われている場合、タップするまで読み込まれなくなります。コードハイライトではハイライトする言語ごとにその定義ファイルを読み込む必要がありますが、それらが自動で読み込まれなくなるため、通信量の削減が見込めます。" _hemisphere: From b269c431686b04fbfc256c5a1fe621bc70f7ea06 Mon Sep 17 00:00:00 2001 From: woxtu Date: Sun, 23 Jun 2024 01:00:12 +0900 Subject: [PATCH 059/268] Fix type annotations (#14071) --- packages/frontend/src/filters/user.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/filters/user.ts b/packages/frontend/src/filters/user.ts index b713d4178954..a87766764dae 100644 --- a/packages/frontend/src/filters/user.ts +++ b/packages/frontend/src/filters/user.ts @@ -6,7 +6,7 @@ import * as Misskey from 'misskey-js'; import { url } from '@/config.js'; -export const acct = (user: misskey.Acct) => { +export const acct = (user: Misskey.Acct) => { return Misskey.acct.toString(user); }; @@ -14,6 +14,6 @@ export const userName = (user: Misskey.entities.User) => { return user.name || user.username; }; -export const userPage = (user: misskey.Acct, path?, absolute = false) => { +export const userPage = (user: Misskey.Acct, path?: string, absolute = false) => { return `${absolute ? url : ''}/@${acct(user)}${(path ? `/${path}` : '')}`; }; From b95a0457a94b135df9b9511ef77558d1a81962f6 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: Sun, 23 Jun 2024 19:04:01 +0900 Subject: [PATCH 060/268] fix(frontend): run `pnpm build-assets` (#14077) --- locales/index.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/index.d.ts b/locales/index.d.ts index acdc1fc421c3..ebd980ed8555 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -9761,7 +9761,7 @@ export interface Locale extends ILocale { "_dataSaver": { "_media": { /** - * メディアの読み込み + * メディアの読み込みを無効化 */ "title": string; /** @@ -9771,7 +9771,7 @@ export interface Locale extends ILocale { }; "_avatar": { /** - * アイコン画像 + * アイコン画像のアニメーションを無効化 */ "title": string; /** @@ -9781,7 +9781,7 @@ export interface Locale extends ILocale { }; "_urlPreview": { /** - * URLプレビューのサムネイル + * URLプレビューのサムネイルを非表示 */ "title": string; /** @@ -9791,7 +9791,7 @@ export interface Locale extends ILocale { }; "_code": { /** - * コードハイライト + * コードハイライトを非表示 */ "title": string; /** From 634764e1a6e06ea9c117b720d58685fe99cae81a Mon Sep 17 00:00:00 2001 From: woxtu Date: Mon, 24 Jun 2024 21:32:12 +0900 Subject: [PATCH 061/268] refactor(frontend): Remove unused directives (#14085) --- packages/frontend/src/components/MkCaptcha.vue | 1 - packages/frontend/src/i18n.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/frontend/src/components/MkCaptcha.vue b/packages/frontend/src/components/MkCaptcha.vue index c64bb47e771b..c5b6e0caede7 100644 --- a/packages/frontend/src/components/MkCaptcha.vue +++ b/packages/frontend/src/components/MkCaptcha.vue @@ -104,7 +104,6 @@ async function requestRender() { }); } else if (props.provider === 'mcaptcha' && props.instanceUrl && props.sitekey) { const { default: Widget } = await import('@mcaptcha/vanilla-glue'); - // @ts-expect-error avoid typecheck error new Widget({ siteKey: { instanceUrl: new URL(props.instanceUrl), diff --git a/packages/frontend/src/i18n.ts b/packages/frontend/src/i18n.ts index cc9faddb2098..10d6adbcd0ca 100644 --- a/packages/frontend/src/i18n.ts +++ b/packages/frontend/src/i18n.ts @@ -11,6 +11,5 @@ import { I18n } from '@/scripts/i18n.js'; export const i18n = markRaw(new I18n(locale)); export function updateI18n(newLocale: Locale) { - // @ts-expect-error -- private field i18n.locale = newLocale; } From 1c5d0cf5364ed841bd181b75682503a648a90bd6 Mon Sep 17 00:00:00 2001 From: yupix Date: Wed, 26 Jun 2024 10:25:18 +0900 Subject: [PATCH 062/268] =?UTF-8?q?feat:=20=E3=82=A2=E3=83=B3=E3=83=86?= =?UTF-8?q?=E3=83=8A=E3=81=AE=E7=B7=A8=E9=9B=86=E7=94=BB=E9=9D=A2=E3=81=AE?= =?UTF-8?q?=E3=83=9C=E3=82=BF=E3=83=B3=E3=81=ABgap=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=20(#14091)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + packages/frontend/src/pages/my-antennas/editor.vue | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 354bbd20fd67..290b13ab366d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Fix: ユーザーページの追加情報のラベルを投稿者のサーバーの絵文字で表示する (#13968) - Fix: リバーシの対局を正しく共有できないことがある問題を修正 - Fix: コントロールパネルでベースロールのポリシーを編集してもUI上では変更が反映されない問題を修正 +- Fix: アンテナの編集画面のボタンに隙間を追加 ### Server - チャート生成時にinstance.suspentionStateに置き換えられたinstance.isSuspendedが参照されてしまう問題を修正 diff --git a/packages/frontend/src/pages/my-antennas/editor.vue b/packages/frontend/src/pages/my-antennas/editor.vue index 2949bfc02cec..02e8f9826520 100644 --- a/packages/frontend/src/pages/my-antennas/editor.vue +++ b/packages/frontend/src/pages/my-antennas/editor.vue @@ -41,8 +41,10 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.withFileAntenna }}
- {{ i18n.ts.save }} - {{ i18n.ts.delete }} +
+ {{ i18n.ts.save }} + {{ i18n.ts.delete }} +
From 77012f2f2925c93978a3a5844d1adddd330d777b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AC=E3=82=8B=E3=81=8D=E3=82=83=E3=81=A3=E3=81=A8?= Date: Thu, 27 Jun 2024 10:40:46 +0900 Subject: [PATCH 063/268] =?UTF-8?q?fix(frontend):=20=E3=83=86=E3=83=BC?= =?UTF-8?q?=E3=83=9E=E3=83=97=E3=83=AC=E3=83=93=E3=83=A5=E3=83=BC=E3=81=8C?= =?UTF-8?q?=E8=A6=8B=E3=82=8C=E3=81=AA=E3=81=84=E5=95=8F=E9=A1=8C=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20(#14097)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(frontend): テーマプレビューが見れない問題を修正 * fix: MkPreview.vue, preview.vue --- .../frontend/src/components/MkPreview.vue | 150 ++++++++++++++++++ packages/frontend/src/pages/preview.vue | 26 +++ packages/frontend/src/router/definition.ts | 3 + 3 files changed, 179 insertions(+) create mode 100644 packages/frontend/src/components/MkPreview.vue create mode 100644 packages/frontend/src/pages/preview.vue diff --git a/packages/frontend/src/components/MkPreview.vue b/packages/frontend/src/components/MkPreview.vue new file mode 100644 index 000000000000..d950d66c6e8d --- /dev/null +++ b/packages/frontend/src/components/MkPreview.vue @@ -0,0 +1,150 @@ + + + + + + + diff --git a/packages/frontend/src/pages/preview.vue b/packages/frontend/src/pages/preview.vue new file mode 100644 index 000000000000..8e07b190aa6c --- /dev/null +++ b/packages/frontend/src/pages/preview.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/packages/frontend/src/router/definition.ts b/packages/frontend/src/router/definition.ts index 8a443f627b23..12ab633af12b 100644 --- a/packages/frontend/src/router/definition.ts +++ b/packages/frontend/src/router/definition.ts @@ -251,6 +251,9 @@ const routes: RouteDef[] = [{ }, { path: '/scratchpad', component: page(() => import('@/pages/scratchpad.vue')), +}, { + path: '/preview', + component: page(() => import('@/pages/preview.vue')), }, { path: '/auth/:token', component: page(() => import('@/pages/auth.vue')), From 0e512d4ff6d2a7c56ac6295bf26d1101a3b6a317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AC=E3=82=8B=E3=81=8D=E3=82=83=E3=81=A3=E3=81=A8?= Date: Thu, 27 Jun 2024 18:23:47 +0900 Subject: [PATCH 064/268] update: CHANGELOG.md for #14097 (#14099) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 290b13ab366d..3a28c9ef640a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Fix: リバーシの対局を正しく共有できないことがある問題を修正 - Fix: コントロールパネルでベースロールのポリシーを編集してもUI上では変更が反映されない問題を修正 - Fix: アンテナの編集画面のボタンに隙間を追加 +- Fix: テーマプレビューが見れない問題を修正 ### Server - チャート生成時にinstance.suspentionStateに置き換えられたinstance.isSuspendedが参照されてしまう問題を修正 From 4096dabe1e4b6ebb43e47fbee19954fb92adbdc7 Mon Sep 17 00:00:00 2001 From: woxtu Date: Thu, 27 Jun 2024 21:59:19 +0900 Subject: [PATCH 065/268] Add null checking (#14089) --- packages/frontend/src/components/MkFollowButton.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/frontend/src/components/MkFollowButton.vue b/packages/frontend/src/components/MkFollowButton.vue index 636e61db8f4b..6a4081079c08 100644 --- a/packages/frontend/src/components/MkFollowButton.vue +++ b/packages/frontend/src/components/MkFollowButton.vue @@ -121,6 +121,8 @@ async function onClick() { }); hasPendingFollowRequestFromYou.value = true; + if ($i == null) return; + claimAchievement('following1'); if ($i.followingCount >= 10) { From a6edd50a5d292e29e6292754a7be95205ac7dbc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AC=E3=82=8B=E3=81=8D=E3=82=83=E3=81=A3=E3=81=A8?= Date: Fri, 28 Jun 2024 11:16:12 +0900 Subject: [PATCH 066/268] =?UTF-8?q?chore(docker-compose):=20=E6=8E=A8?= =?UTF-8?q?=E5=A5=A8=E3=81=AE=E5=90=8D=E5=89=8D=E3=81=AB=E3=81=99=E3=82=8B?= =?UTF-8?q?=20(#14096)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(docker-compose): 推奨の名前にする https://github.com/compose-spec/compose-spec/blob/5c18e329d5a15a15e4b636ed093b256b96615e33/spec.md#compose-file * yaml to yml * fix * fix --- .devcontainer/{docker-compose.yml => compose.yml} | 2 -- .devcontainer/devcontainer.json | 2 +- .dockerignore | 4 ++-- .github/workflows/dockle.yml | 2 +- .gitignore | 4 ++-- CONTRIBUTING.md | 2 +- docker-compose.local-db.yml => compose.local-db.yml | 2 -- docker-compose_example.yml => compose_example.yml | 2 -- packages/backend/test/{docker-compose.yml => compose.yml} | 2 -- 9 files changed, 7 insertions(+), 15 deletions(-) rename .devcontainer/{docker-compose.yml => compose.yml} (98%) rename docker-compose.local-db.yml => compose.local-db.yml (98%) rename docker-compose_example.yml => compose_example.yml (99%) rename packages/backend/test/{docker-compose.yml => compose.yml} (94%) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/compose.yml similarity index 98% rename from .devcontainer/docker-compose.yml rename to .devcontainer/compose.yml index a52d086fb6fc..d02d2a8f4a89 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: app: build: diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 344edbd65d93..7ea23e314ea4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,6 @@ { "name": "Misskey", - "dockerComposeFile": "docker-compose.yml", + "dockerComposeFile": "compose.yml", "service": "app", "workspaceFolder": "/workspace", "features": { diff --git a/.dockerignore b/.dockerignore index 1de0c7982bcd..7dbb06e1d0e6 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,7 +7,7 @@ Dockerfile build/ built/ db/ -docker-compose.yml +.devcontainer/compose.yml node_modules/ packages/*/node_modules redis/ @@ -28,4 +28,4 @@ fluent-emojis/ .idea/ packages/*/.vscode/ -packages/backend/test/docker-compose.yml +packages/backend/test/compose.yml diff --git a/.github/workflows/dockle.yml b/.github/workflows/dockle.yml index 968971dd8d25..c3dba4213d31 100644 --- a/.github/workflows/dockle.yml +++ b/.github/workflows/dockle.yml @@ -22,7 +22,7 @@ jobs: sudo dpkg -i dockle.deb - run: | cp .config/docker_example.env .config/docker.env - cp ./docker-compose_example.yml ./docker-compose.yml + cp ./compose_example.yml ./compose.yml - run: | docker compose up -d web docker tag "$(docker compose images web | awk 'OFS=":" {print $4}' | tail -n +2)" misskey-web:latest diff --git a/.gitignore b/.gitignore index bdc14fea0aba..3466984cf648 100644 --- a/.gitignore +++ b/.gitignore @@ -35,8 +35,8 @@ coverage !/.config/example.yml !/.config/docker_example.yml !/.config/docker_example.env -docker-compose.yml -!/.devcontainer/docker-compose.yml +.devcontainer/compose.yml +!/.devcontainer/compose.yml # misskey /build diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dcb625626d6f..06c2d2f21daf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -165,7 +165,7 @@ cp .github/misskey/test.yml .config/ ``` Prepare DB/Redis for testing. ``` -docker compose -f packages/backend/test/docker-compose.yml up +docker compose -f packages/backend/test/compose.yaml up ``` Alternatively, prepare an empty (data can be erased) DB and edit `.config/test.yml`. diff --git a/docker-compose.local-db.yml b/compose.local-db.yml similarity index 98% rename from docker-compose.local-db.yml rename to compose.local-db.yml index 16ba4b49e179..3835cb23dbad 100644 --- a/docker-compose.local-db.yml +++ b/compose.local-db.yml @@ -1,5 +1,3 @@ -version: "3" - # このconfigは、 dockerでMisskey本体を起動せず、 redisとpostgresql などだけを起動します services: diff --git a/docker-compose_example.yml b/compose_example.yml similarity index 99% rename from docker-compose_example.yml rename to compose_example.yml index 5cebbe416467..75d0d3a59ca2 100644 --- a/docker-compose_example.yml +++ b/compose_example.yml @@ -1,5 +1,3 @@ -version: "3" - services: web: build: . diff --git a/packages/backend/test/docker-compose.yml b/packages/backend/test/compose.yml similarity index 94% rename from packages/backend/test/docker-compose.yml rename to packages/backend/test/compose.yml index f2d899075808..6593fc33dd6c 100644 --- a/packages/backend/test/docker-compose.yml +++ b/packages/backend/test/compose.yml @@ -1,5 +1,3 @@ -version: "3" - services: redistest: image: redis:7 From f1b1e2a7cca3d69eb6162d4c16746968d855ea40 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Tue, 2 Jul 2024 10:57:20 +0900 Subject: [PATCH 067/268] fix(storybook): prevent infinite remount of component (#14101) * fix(storybook): prevent infinite remount of component * fix: disable flaky `.toMatch()` test --- packages/frontend/.storybook/preview.ts | 6 +- .../MkChannelFollowButton.stories.impl.ts | 6 -- .../components/MkClickerGame.stories.impl.ts | 12 ++- .../src/components/MkCwButton.stories.impl.ts | 10 --- .../src/components/global/MkA.stories.impl.ts | 2 - .../components/global/MkAd.stories.impl.ts | 87 +++++++------------ packages/frontend/src/scripts/test-utils.ts | 10 --- 7 files changed, 41 insertions(+), 92 deletions(-) diff --git a/packages/frontend/.storybook/preview.ts b/packages/frontend/.storybook/preview.ts index 73ee007fb8b7..d000a282328f 100644 --- a/packages/frontend/.storybook/preview.ts +++ b/packages/frontend/.storybook/preview.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { FORCE_REMOUNT } from '@storybook/core-events'; +import { FORCE_RE_RENDER, FORCE_REMOUNT } from '@storybook/core-events'; import { addons } from '@storybook/preview-api'; import { type Preview, setup } from '@storybook/vue3'; import isChromatic from 'chromatic/isChromatic'; @@ -16,7 +16,7 @@ import '../src/style.scss'; const appInitialized = Symbol(); -let lastStory = null; +let lastStory: string | null = null; let moduleInitialized = false; let unobserve = () => {}; let misskeyOS = null; @@ -110,7 +110,7 @@ const preview = { }).catch(() => {}); Promise.all([resetIndexedDBPromise, resetDefaultStorePromise]).then(() => { initLocalStorage(); - channel.emit(FORCE_REMOUNT, { storyId: context.id }); + channel.emit(FORCE_RE_RENDER, { storyId: context.id }); }); } const story = Story(); diff --git a/packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts b/packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts index b99620da22f6..b9770670dcdd 100644 --- a/packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts +++ b/packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts @@ -12,14 +12,12 @@ import { expect, userEvent, within } from '@storybook/test'; import { channel } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkChannelFollowButton from './MkChannelFollowButton.vue'; -import { semaphore } from '@/scripts/test-utils.js'; import { i18n } from '@/i18n.js'; function sleep(ms: number) { return new Promise(resolve => setTimeout(resolve, ms)); } -const s = semaphore(); export const Default = { render(args) { return { @@ -46,17 +44,13 @@ export const Default = { full: true, }, async play({ canvasElement }) { - await s.acquire(); - await sleep(1000); const canvas = within(canvasElement); const buttonElement = canvas.getByRole('button'); await expect(buttonElement).toHaveTextContent(i18n.ts.follow); await userEvent.click(buttonElement); await sleep(1000); await expect(buttonElement).toHaveTextContent(i18n.ts.unfollow); - await sleep(100); await userEvent.click(buttonElement); - s.release(); }, parameters: { layout: 'centered', diff --git a/packages/frontend/src/components/MkClickerGame.stories.impl.ts b/packages/frontend/src/components/MkClickerGame.stories.impl.ts index 8378010f8bf7..36313f965daa 100644 --- a/packages/frontend/src/components/MkClickerGame.stories.impl.ts +++ b/packages/frontend/src/components/MkClickerGame.stories.impl.ts @@ -8,7 +8,7 @@ import { StoryObj } from '@storybook/vue3'; import { HttpResponse, http } from 'msw'; import { action } from '@storybook/addon-actions'; -import { expect, within } from '@storybook/test'; +import { expect, userEvent, within } from '@storybook/test'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkClickerGame from './MkClickerGame.vue'; @@ -41,12 +41,10 @@ export const Default = { await sleep(1000); const canvas = within(canvasElement); const count = canvas.getByTestId('count'); - // NOTE: flaky なので N/A も通しておく - await expect(count).toHaveTextContent(/^(0|N\/A)$/); - // FIXME: flaky - // const buttonElement = canvas.getByRole('button'); - // await userEvent.click(buttonElement); - // await expect(count).toHaveTextContent('1'); + await expect(count).toHaveTextContent('0'); + const buttonElement = canvas.getByRole('button'); + await userEvent.click(buttonElement); + await expect(count).toHaveTextContent('1'); }, parameters: { layout: 'centered', diff --git a/packages/frontend/src/components/MkCwButton.stories.impl.ts b/packages/frontend/src/components/MkCwButton.stories.impl.ts index 05c6001552ba..5d6ea56da9f9 100644 --- a/packages/frontend/src/components/MkCwButton.stories.impl.ts +++ b/packages/frontend/src/components/MkCwButton.stories.impl.ts @@ -11,13 +11,6 @@ import { expect, userEvent, within } from '@storybook/test'; import { file } from '../../.storybook/fakes.js'; import MkCwButton from './MkCwButton.vue'; import { i18n } from '@/i18n.js'; -import { semaphore } from '@/scripts/test-utils.js'; - -function sleep(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - -const s = semaphore(); export const Default = { render(args) { @@ -54,8 +47,6 @@ export const Default = { text: 'Some CW content', }, async play({ canvasElement }) { - await s.acquire(); - await sleep(1000); const canvas = within(canvasElement); const buttonElement = canvas.getByRole('button'); await expect(buttonElement).toHaveTextContent(i18n.ts._cw.show); @@ -63,7 +54,6 @@ export const Default = { await userEvent.click(buttonElement); await expect(buttonElement).toHaveTextContent(i18n.ts._cw.hide); await userEvent.click(buttonElement); - s.release(); }, parameters: { chromatic: { diff --git a/packages/frontend/src/components/global/MkA.stories.impl.ts b/packages/frontend/src/components/global/MkA.stories.impl.ts index c1d8cf0ca6b2..02e5a7f98c1c 100644 --- a/packages/frontend/src/components/global/MkA.stories.impl.ts +++ b/packages/frontend/src/components/global/MkA.stories.impl.ts @@ -35,12 +35,10 @@ export const Default = { // FIXME: 通るけどその後落ちるのでコメントアウト // await expect(a.href).toMatch(/^https?:\/\/.*#test$/); await userEvent.pointer({ keys: '[MouseRight]', target: a }); - await tick(); const menu = canvas.getByRole('menu'); await expect(menu).toBeInTheDocument(); await userEvent.click(a); a.blur(); - await tick(); await expect(menu).not.toBeInTheDocument(); }, args: { diff --git a/packages/frontend/src/components/global/MkAd.stories.impl.ts b/packages/frontend/src/components/global/MkAd.stories.impl.ts index aef26ab92d64..8c0b7ef52fc1 100644 --- a/packages/frontend/src/components/global/MkAd.stories.impl.ts +++ b/packages/frontend/src/components/global/MkAd.stories.impl.ts @@ -9,12 +9,6 @@ import { StoryObj } from '@storybook/vue3'; import MkAd from './MkAd.vue'; import { i18n } from '@/i18n.js'; -let lock: Promise | undefined; - -function sleep(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - const common = { render(args) { return { @@ -37,56 +31,41 @@ const common = { }; }, async play({ canvasElement, args }) { - if (lock) { - console.warn('This test is unexpectedly running twice in parallel, fix it!'); - console.warn('See also: https://github.com/misskey-dev/misskey/issues/11267'); - await lock; + const canvas = within(canvasElement); + const a = canvas.getByRole('link'); + // FIXME: 通るけどその後落ちるのでコメントアウト + // await expect(a.href).toMatch(/^https?:\/\/.*#test$/); + const img = within(a).getByRole('img'); + await expect(img).toBeInTheDocument(); + let buttons = canvas.getAllByRole('button'); + await expect(buttons).toHaveLength(1); + const i = buttons[0]; + await expect(i).toBeInTheDocument(); + await userEvent.click(i); + await expect(canvasElement).toHaveTextContent(i18n.ts._ad.back); + await expect(a).not.toBeInTheDocument(); + await expect(i).not.toBeInTheDocument(); + buttons = canvas.getAllByRole('button'); + const hasReduceFrequency = args.specify?.ratio !== 0; + await expect(buttons).toHaveLength(hasReduceFrequency ? 2 : 1); + const reduce = hasReduceFrequency ? buttons[0] : null; + const back = buttons[hasReduceFrequency ? 1 : 0]; + if (reduce) { + await expect(reduce).toBeInTheDocument(); + await expect(reduce).toHaveTextContent(i18n.ts._ad.reduceFrequencyOfThisAd); } - - let resolve: (value?: any) => void; - lock = new Promise(r => resolve = r); - - try { - // NOTE: sleep しないと何故か落ちる - await sleep(100); - const canvas = within(canvasElement); - const a = canvas.getByRole('link'); - // await expect(a.href).toMatch(/^https?:\/\/.*#test$/); - const img = within(a).getByRole('img'); - await expect(img).toBeInTheDocument(); - let buttons = canvas.getAllByRole('button'); - await expect(buttons).toHaveLength(1); - const i = buttons[0]; - await expect(i).toBeInTheDocument(); - await userEvent.click(i); - await expect(canvasElement).toHaveTextContent(i18n.ts._ad.back); - await expect(a).not.toBeInTheDocument(); - await expect(i).not.toBeInTheDocument(); - buttons = canvas.getAllByRole('button'); - const hasReduceFrequency = args.specify?.ratio !== 0; - await expect(buttons).toHaveLength(hasReduceFrequency ? 2 : 1); - const reduce = hasReduceFrequency ? buttons[0] : null; - const back = buttons[hasReduceFrequency ? 1 : 0]; - if (reduce) { - await expect(reduce).toBeInTheDocument(); - await expect(reduce).toHaveTextContent(i18n.ts._ad.reduceFrequencyOfThisAd); - } - await expect(back).toBeInTheDocument(); - await expect(back).toHaveTextContent(i18n.ts._ad.back); - await userEvent.click(back); - await waitFor(() => expect(canvas.queryByRole('img')).toBeTruthy()); - if (reduce) { - await expect(reduce).not.toBeInTheDocument(); - } - await expect(back).not.toBeInTheDocument(); - const aAgain = canvas.getByRole('link'); - await expect(aAgain).toBeInTheDocument(); - const imgAgain = within(aAgain).getByRole('img'); - await expect(imgAgain).toBeInTheDocument(); - } finally { - resolve!(); - lock = undefined; + await expect(back).toBeInTheDocument(); + await expect(back).toHaveTextContent(i18n.ts._ad.back); + await userEvent.click(back); + await waitFor(() => expect(canvas.queryByRole('img')).toBeTruthy()); + if (reduce) { + await expect(reduce).not.toBeInTheDocument(); } + await expect(back).not.toBeInTheDocument(); + const aAgain = canvas.getByRole('link'); + await expect(aAgain).toBeInTheDocument(); + const imgAgain = within(aAgain).getByRole('img'); + await expect(imgAgain).toBeInTheDocument(); }, args: { prefer: [], diff --git a/packages/frontend/src/scripts/test-utils.ts b/packages/frontend/src/scripts/test-utils.ts index a32315f4df58..52bb2d94e0e8 100644 --- a/packages/frontend/src/scripts/test-utils.ts +++ b/packages/frontend/src/scripts/test-utils.ts @@ -7,13 +7,3 @@ export async function tick(): Promise { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition await new Promise((globalThis.requestIdleCallback ?? setTimeout) as never); } - -/** - * @see https://github.com/misskey-dev/misskey/issues/11267 - */ -export function semaphore(counter = 0, waiting: (() => void)[] = []) { - return { - acquire: () => ++counter > 1 && new Promise(resolve => waiting.push(resolve)), - release: () => --counter && waiting.pop()?.(), - }; -} From 427648c4b8c5b7699c92afa95a14097bb9329ee8 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Tue, 2 Jul 2024 11:38:34 +0900 Subject: [PATCH 068/268] update deps (#14057) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wip * locales/index.jsのymlファイル取得ロジックを調節 * regenerate pnpm-lock.yaml * fix(backend): typecheck fails * chore(deps): bump ip-cidr from 4.0.0 to 4.0.1 in /packages/backend * chore: migrate ESLint configs to flat config (#14094) * chore: migrate ESLint configs to flat config * fix: update paths * fix: frontend lint fails * refactor(misskey-js): lint build.js * update deps --------- Co-authored-by: samunohito <46447427+samunohito@users.noreply.github.com> Co-authored-by: zyoshoka Co-authored-by: zyoshoka <107108195+zyoshoka@users.noreply.github.com> --- .github/workflows/lint.yml | 4 +- locales/index.js | 6 +- package.json | 20 +- packages/backend/.eslintignore | 4 - packages/backend/.eslintrc.cjs | 32 - packages/backend/eslint.config.js | 46 + packages/backend/package.json | 98 +- packages/backend/test-server/.eslintrc.cjs | 32 - packages/backend/test-server/eslint.config.js | 43 + packages/backend/test/.eslintrc.cjs | 11 - packages/backend/test/eslint.config.js | 22 + packages/frontend/.eslintrc.cjs | 82 - packages/frontend/eslint.config.js | 95 + packages/frontend/package.json | 116 +- packages/frontend/tsconfig.json | 1 - packages/misskey-bubble-game/.eslintignore | 8 - packages/misskey-bubble-game/.eslintrc.cjs | 9 - packages/misskey-bubble-game/eslint.config.js | 27 + packages/misskey-bubble-game/package.json | 4 +- packages/misskey-js/.eslintignore | 8 - packages/misskey-js/.eslintrc.cjs | 9 - packages/misskey-js/build.js | 32 +- packages/misskey-js/eslint.config.js | 28 + packages/misskey-js/generator/.eslintrc.cjs | 9 - .../misskey-js/generator/eslint.config.js | 17 + packages/misskey-js/generator/package.json | 4 +- packages/misskey-js/package.json | 24 +- packages/misskey-reversi/.eslintignore | 8 - packages/misskey-reversi/.eslintrc.cjs | 10 - packages/misskey-reversi/eslint.config.js | 23 + packages/misskey-reversi/package.json | 4 +- packages/shared/.eslintrc.js | 7 - packages/shared/eslint.config.js | 28 + packages/shared/package.json | 3 + packages/sw/.eslintrc.cjs | 20 - packages/sw/eslint.config.js | 32 + packages/sw/package.json | 10 +- pnpm-lock.yaml | 9003 +++++++++-------- scripts/changelog-checker/.eslintrc.cjs | 9 - scripts/changelog-checker/eslint.config.js | 17 + 40 files changed, 5555 insertions(+), 4410 deletions(-) delete mode 100644 packages/backend/.eslintignore delete mode 100644 packages/backend/.eslintrc.cjs create mode 100644 packages/backend/eslint.config.js delete mode 100644 packages/backend/test-server/.eslintrc.cjs create mode 100644 packages/backend/test-server/eslint.config.js delete mode 100644 packages/backend/test/.eslintrc.cjs create mode 100644 packages/backend/test/eslint.config.js delete mode 100644 packages/frontend/.eslintrc.cjs create mode 100644 packages/frontend/eslint.config.js delete mode 100644 packages/misskey-bubble-game/.eslintignore delete mode 100644 packages/misskey-bubble-game/.eslintrc.cjs create mode 100644 packages/misskey-bubble-game/eslint.config.js delete mode 100644 packages/misskey-js/.eslintignore delete mode 100644 packages/misskey-js/.eslintrc.cjs create mode 100644 packages/misskey-js/eslint.config.js delete mode 100644 packages/misskey-js/generator/.eslintrc.cjs create mode 100644 packages/misskey-js/generator/eslint.config.js delete mode 100644 packages/misskey-reversi/.eslintignore delete mode 100644 packages/misskey-reversi/.eslintrc.cjs create mode 100644 packages/misskey-reversi/eslint.config.js delete mode 100644 packages/shared/.eslintrc.js create mode 100644 packages/shared/eslint.config.js create mode 100644 packages/shared/package.json delete mode 100644 packages/sw/.eslintrc.cjs create mode 100644 packages/sw/eslint.config.js delete mode 100644 scripts/changelog-checker/.eslintrc.cjs create mode 100644 scripts/changelog-checker/eslint.config.js diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 76616ec5a71a..1a1b30168a9a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,14 +10,14 @@ on: - packages/frontend/** - packages/sw/** - packages/misskey-js/** - - packages/shared/.eslintrc.js + - packages/shared/eslint.config.js pull_request: paths: - packages/backend/** - packages/frontend/** - packages/sw/** - packages/misskey-js/** - - packages/shared/.eslintrc.js + - packages/shared/eslint.config.js jobs: pnpm_install: diff --git a/locales/index.js b/locales/index.js index 650e55233776..c2738884eb34 100644 --- a/locales/index.js +++ b/locales/index.js @@ -52,7 +52,11 @@ const primaries = { const clean = (text) => text.replace(new RegExp(String.fromCodePoint(0x08), 'g'), ''); export function build() { - const locales = languages.reduce((a, c) => (a[c] = yaml.load(clean(fs.readFileSync(new URL(`${c}.yml`, import.meta.url), 'utf-8'))) || {}, a), {}); + // vitestの挙動を調整するため、一度ローカル変数化する必要がある + // https://github.com/vitest-dev/vitest/issues/3988#issuecomment-1686599577 + // https://github.com/misskey-dev/misskey/pull/14057#issuecomment-2192833785 + const metaUrl = import.meta.url; + const locales = languages.reduce((a, c) => (a[c] = yaml.load(clean(fs.readFileSync(new URL(`${c}.yml`, metaUrl), 'utf-8'))) || {}, a), {}); // 空文字列が入ることがあり、フォールバックが動作しなくなるのでプロパティごと消す const removeEmpty = (obj) => { diff --git a/package.json b/package.json index 5adce65415eb..bf8415d21217 100644 --- a/package.json +++ b/package.json @@ -55,20 +55,22 @@ "js-yaml": "4.1.0", "postcss": "8.4.38", "tar": "6.2.1", - "terser": "5.30.3", - "typescript": "5.5.2", - "esbuild": "0.20.2", + "terser": "5.31.1", + "typescript": "5.5.3", + "esbuild": "0.22.0", "glob": "10.3.12" }, "devDependencies": { - "@types/node": "20.12.7", - "@typescript-eslint/eslint-plugin": "7.7.1", - "@typescript-eslint/parser": "7.7.1", + "@misskey-dev/eslint-plugin": "2.0.2", + "@types/node": "20.14.9", + "@typescript-eslint/eslint-plugin": "7.15.0", + "@typescript-eslint/parser": "7.15.0", "cross-env": "7.0.3", - "cypress": "13.7.3", - "eslint": "8.57.0", + "cypress": "13.13.0", + "eslint": "9.6.0", + "globals": "15.7.0", "ncp": "2.0.0", - "start-server-and-test": "2.0.3" + "start-server-and-test": "2.0.4" }, "optionalDependencies": { "@tensorflow/tfjs-core": "4.4.0" diff --git a/packages/backend/.eslintignore b/packages/backend/.eslintignore deleted file mode 100644 index 790eb90145b4..000000000000 --- a/packages/backend/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -/built -/.eslintrc.js -/@types/**/* diff --git a/packages/backend/.eslintrc.cjs b/packages/backend/.eslintrc.cjs deleted file mode 100644 index f9fe4814e671..000000000000 --- a/packages/backend/.eslintrc.cjs +++ /dev/null @@ -1,32 +0,0 @@ -module.exports = { - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json', './test/tsconfig.json'], - }, - extends: [ - '../shared/.eslintrc.js', - ], - rules: { - 'import/order': ['warn', { - 'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'], - 'pathGroups': [ - { - 'pattern': '@/**', - 'group': 'external', - 'position': 'after' - } - ], - }], - 'no-restricted-globals': [ - 'error', - { - 'name': '__dirname', - 'message': 'Not in ESModule. Use `import.meta.url` instead.' - }, - { - 'name': '__filename', - 'message': 'Not in ESModule. Use `import.meta.url` instead.' - } - ] - }, -}; diff --git a/packages/backend/eslint.config.js b/packages/backend/eslint.config.js new file mode 100644 index 000000000000..318b7fd340f3 --- /dev/null +++ b/packages/backend/eslint.config.js @@ -0,0 +1,46 @@ +import tsParser from '@typescript-eslint/parser'; +import sharedConfig from '../shared/eslint.config.js'; + +export default [ + ...sharedConfig, + { + ignores: ['**/node_modules', 'built', '@types/**/*'], + }, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parserOptions: { + parser: tsParser, + project: ['./tsconfig.json', './test/tsconfig.json'], + sourceType: 'module', + tsconfigRootDir: import.meta.dirname, + }, + }, + rules: { + 'import/order': ['warn', { + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + 'object', + 'type', + ], + pathGroups: [{ + pattern: '@/**', + group: 'external', + position: 'after', + }], + }], + 'no-restricted-globals': ['error', { + name: '__dirname', + message: 'Not in ESModule. Use `import.meta.url` instead.', + }, { + name: '__filename', + message: 'Not in ESModule. Use `import.meta.url` instead.', + }], + }, + }, +]; diff --git a/packages/backend/package.json b/packages/backend/package.json index 0467ab0bee8a..22fdc5cf1681 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -65,43 +65,43 @@ "utf-8-validate": "6.0.3" }, "dependencies": { - "@aws-sdk/client-s3": "3.412.0", - "@aws-sdk/lib-storage": "3.412.0", - "@bull-board/api": "5.17.0", - "@bull-board/fastify": "5.17.0", - "@bull-board/ui": "5.17.0", + "@aws-sdk/client-s3": "3.600.0", + "@aws-sdk/lib-storage": "3.600.0", + "@bull-board/api": "5.20.5", + "@bull-board/fastify": "5.20.5", + "@bull-board/ui": "5.20.5", "@discordapp/twemoji": "15.0.3", "@fastify/accepts": "4.3.0", "@fastify/cookie": "9.3.1", "@fastify/cors": "9.0.1", "@fastify/express": "3.0.0", "@fastify/http-proxy": "9.5.0", - "@fastify/multipart": "8.2.0", - "@fastify/static": "7.0.3", + "@fastify/multipart": "8.3.0", + "@fastify/static": "7.0.4", "@fastify/view": "9.1.0", "@misskey-dev/sharp-read-bmp": "1.2.0", "@misskey-dev/summaly": "5.1.0", - "@napi-rs/canvas": "^0.1.52", - "@nestjs/common": "10.3.8", - "@nestjs/core": "10.3.8", - "@nestjs/testing": "10.3.8", + "@napi-rs/canvas": "^0.1.53", + "@nestjs/common": "10.3.10", + "@nestjs/core": "10.3.10", + "@nestjs/testing": "10.3.10", "@peertube/http-signature": "1.7.0", - "@sentry/node": "^8.5.0", - "@sentry/profiling-node": "^8.5.0", + "@sentry/node": "8.13.0", + "@sentry/profiling-node": "8.13.0", "@simplewebauthn/server": "10.0.0", "@sinonjs/fake-timers": "11.2.2", "@smithy/node-http-handler": "2.5.0", "@swc/cli": "0.3.12", - "@swc/core": "1.4.17", + "@swc/core": "1.6.6", "@twemoji/parser": "15.1.1", "accepts": "1.3.8", - "ajv": "8.13.0", + "ajv": "8.16.0", "archiver": "7.0.1", "async-mutex": "0.5.0", "bcryptjs": "2.4.3", "blurhash": "2.0.5", "body-parser": "1.20.2", - "bullmq": "5.7.8", + "bullmq": "5.8.3", "cacheable-lookup": "7.0.0", "cbor": "9.0.2", "chalk": "5.3.0", @@ -112,27 +112,27 @@ "content-disposition": "0.5.4", "date-fns": "2.30.0", "deep-email-validator": "0.1.21", - "fastify": "4.26.2", + "fastify": "4.28.1", "fastify-raw-body": "4.3.0", "feed": "4.2.2", "file-type": "19.0.0", - "fluent-ffmpeg": "2.1.2", + "fluent-ffmpeg": "2.1.3", "form-data": "4.0.0", - "got": "14.2.1", + "got": "14.4.1", "happy-dom": "10.0.3", "hpagent": "1.2.0", "htmlescape": "1.1.1", "http-link-header": "1.1.3", "ioredis": "5.4.1", - "ip-cidr": "3.1.0", + "ip-cidr": "4.0.1", "ipaddr.js": "2.2.0", - "is-svg": "5.0.0", + "is-svg": "5.0.1", "js-yaml": "4.1.0", - "jsdom": "24.0.0", + "jsdom": "24.1.0", "json5": "2.2.3", "jsonld": "8.3.2", "jsrsasign": "11.1.0", - "meilisearch": "0.38.0", + "meilisearch": "0.41.0", "mfm-js": "0.24.0", "microformats-parser": "2.0.2", "mime-types": "2.1.35", @@ -142,24 +142,24 @@ "nanoid": "5.0.7", "nested-property": "4.0.0", "node-fetch": "3.3.2", - "nodemailer": "6.9.13", + "nodemailer": "6.9.14", "nsfwjs": "2.4.2", "oauth": "0.10.0", "oauth2orize": "1.12.0", "oauth2orize-pkce": "0.1.2", "os-utils": "0.0.14", - "otpauth": "9.2.3", + "otpauth": "9.3.1", "parse5": "7.1.2", - "pg": "8.11.5", + "pg": "8.12.0", "pkce-challenge": "4.1.0", "probe-image-size": "7.2.3", "promise-limit": "2.7.0", - "pug": "3.0.2", + "pug": "3.0.3", "punycode": "2.3.1", "qrcode": "1.5.3", "random-seed": "0.3.0", "ratelimiter": "3.4.1", - "re2": "1.21.2", + "re2": "1.21.3", "redis-lock": "0.1.4", "reflect-metadata": "0.2.2", "rename": "1.0.4", @@ -167,27 +167,26 @@ "rxjs": "7.8.1", "sanitize-html": "2.13.0", "secure-json-parse": "2.7.0", - "sharp": "0.33.3", + "sharp": "0.33.4", "slacc": "0.0.10", "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", - "systeminformation": "5.22.7", + "systeminformation": "5.22.11", "tinycolor2": "1.6.0", "tmp": "0.2.3", - "tsc-alias": "1.8.8", + "tsc-alias": "1.8.10", "tsconfig-paths": "4.2.0", "typeorm": "0.3.20", - "typescript": "5.5.2", + "typescript": "5.5.3", "ulid": "2.3.0", "vary": "1.1.2", "web-push": "3.6.7", - "ws": "8.17.0", + "ws": "8.17.1", "xev": "3.0.2" }, "devDependencies": { "@jest/globals": "29.7.0", - "@misskey-dev/eslint-plugin": "1.0.0", - "@nestjs/platform-express": "10.3.8", + "@nestjs/platform-express": "10.3.10", "@simplewebauthn/types": "10.0.0", "@swc/jest": "0.2.36", "@types/accepts": "1.3.7", @@ -197,21 +196,21 @@ "@types/color-convert": "2.0.3", "@types/content-disposition": "0.5.8", "@types/fluent-ffmpeg": "2.1.24", - "@types/htmlescape": "^1.1.3", - "@types/http-link-header": "1.0.5", + "@types/htmlescape": "1.1.3", + "@types/http-link-header": "1.0.7", "@types/jest": "29.5.12", "@types/js-yaml": "4.0.9", - "@types/jsdom": "21.1.6", - "@types/jsonld": "1.5.13", + "@types/jsdom": "21.1.7", + "@types/jsonld": "1.5.14", "@types/jsrsasign": "10.5.14", "@types/mime-types": "2.1.4", "@types/ms": "0.7.34", - "@types/node": "20.12.7", + "@types/node": "20.14.9", "@types/nodemailer": "6.4.15", - "@types/oauth": "0.9.4", + "@types/oauth": "0.9.5", "@types/oauth2orize": "1.11.5", "@types/oauth2orize-pkce": "0.1.2", - "@types/pg": "8.11.5", + "@types/pg": "8.11.6", "@types/pug": "2.0.10", "@types/punycode": "2.1.4", "@types/qrcode": "1.5.5", @@ -227,18 +226,17 @@ "@types/vary": "1.1.3", "@types/web-push": "3.6.3", "@types/ws": "8.5.10", - "@typescript-eslint/eslint-plugin": "7.7.1", - "@typescript-eslint/parser": "7.7.1", - "aws-sdk-client-mock": "3.0.1", + "@typescript-eslint/eslint-plugin": "7.15.0", + "@typescript-eslint/parser": "7.15.0", + "aws-sdk-client-mock": "4.0.1", "cross-env": "7.0.3", - "eslint": "8.57.0", "eslint-plugin-import": "2.29.1", - "execa": "8.0.1", - "fkill": "^9.0.0", + "execa": "9.2.0", + "fkill": "9.0.0", "jest": "29.7.0", "jest-mock": "29.7.0", - "nodemon": "3.1.0", + "nodemon": "3.1.4", "pid-port": "1.0.0", - "simple-oauth2": "5.0.0" + "simple-oauth2": "5.0.1" } } diff --git a/packages/backend/test-server/.eslintrc.cjs b/packages/backend/test-server/.eslintrc.cjs deleted file mode 100644 index c261741a36a1..000000000000 --- a/packages/backend/test-server/.eslintrc.cjs +++ /dev/null @@ -1,32 +0,0 @@ -module.exports = { - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - extends: [ - '../../shared/.eslintrc.js', - ], - rules: { - 'import/order': ['warn', { - 'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'], - 'pathGroups': [ - { - 'pattern': '@/**', - 'group': 'external', - 'position': 'after' - } - ], - }], - 'no-restricted-globals': [ - 'error', - { - 'name': '__dirname', - 'message': 'Not in ESModule. Use `import.meta.url` instead.' - }, - { - 'name': '__filename', - 'message': 'Not in ESModule. Use `import.meta.url` instead.' - } - ] - }, -}; diff --git a/packages/backend/test-server/eslint.config.js b/packages/backend/test-server/eslint.config.js new file mode 100644 index 000000000000..b9c16d469fc3 --- /dev/null +++ b/packages/backend/test-server/eslint.config.js @@ -0,0 +1,43 @@ +import tsParser from '@typescript-eslint/parser'; +import sharedConfig from '../../shared/eslint.config.js'; + +export default [ + ...sharedConfig, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parserOptions: { + parser: tsParser, + project: ['./tsconfig.json'], + sourceType: 'module', + tsconfigRootDir: import.meta.dirname, + }, + }, + rules: { + 'import/order': ['warn', { + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + 'object', + 'type', + ], + pathGroups: [{ + pattern: '@/**', + group: 'external', + position: 'after', + }], + }], + 'no-restricted-globals': ['error', { + name: '__dirname', + message: 'Not in ESModule. Use `import.meta.url` instead.', + }, { + name: '__filename', + message: 'Not in ESModule. Use `import.meta.url` instead.', + }], + }, + }, +]; diff --git a/packages/backend/test/.eslintrc.cjs b/packages/backend/test/.eslintrc.cjs deleted file mode 100644 index 41ecea0c3fba..000000000000 --- a/packages/backend/test/.eslintrc.cjs +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - extends: ['../.eslintrc.cjs'], - env: { - node: true, - jest: true, - }, -}; diff --git a/packages/backend/test/eslint.config.js b/packages/backend/test/eslint.config.js new file mode 100644 index 000000000000..a0f43babadfb --- /dev/null +++ b/packages/backend/test/eslint.config.js @@ -0,0 +1,22 @@ +import globals from 'globals'; +import tsParser from '@typescript-eslint/parser'; +import sharedConfig from '../../shared/eslint.config.js'; + +export default [ + ...sharedConfig, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + globals: { + ...globals.node, + ...globals.jest, + }, + parserOptions: { + parser: tsParser, + project: ['./tsconfig.json'], + sourceType: 'module', + tsconfigRootDir: import.meta.dirname, + }, + }, + }, +]; diff --git a/packages/frontend/.eslintrc.cjs b/packages/frontend/.eslintrc.cjs deleted file mode 100644 index fd562e1c4053..000000000000 --- a/packages/frontend/.eslintrc.cjs +++ /dev/null @@ -1,82 +0,0 @@ -module.exports = { - root: true, - env: { - 'node': false, - }, - parser: 'vue-eslint-parser', - parserOptions: { - 'parser': '@typescript-eslint/parser', - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - extraFileExtensions: ['.vue'], - }, - extends: [ - '../shared/.eslintrc.js', - 'plugin:vue/vue3-recommended', - ], - rules: { - '@typescript-eslint/no-empty-interface': [ - 'error', - { - 'allowSingleExtends': true, - }, - ], - // window の禁止理由: グローバルスコープと衝突し、予期せぬ結果を招くため - // e の禁止理由: error や event など、複数のキーワードの頭文字であり分かりにくいため - 'id-denylist': ['error', 'window', 'e'], - 'no-shadow': ['warn'], - 'vue/attributes-order': ['error', { - 'alphabetical': false, - }], - 'vue/no-use-v-if-with-v-for': ['error', { - 'allowUsingIterationVar': false, - }], - 'vue/no-ref-as-operand': 'error', - 'vue/no-multi-spaces': ['error', { - 'ignoreProperties': false, - }], - 'vue/no-v-html': 'warn', - 'vue/order-in-components': 'error', - 'vue/html-indent': ['warn', 'tab', { - 'attribute': 1, - 'baseIndent': 0, - 'closeBracket': 0, - 'alignAttributesVertically': true, - 'ignores': [], - }], - 'vue/html-closing-bracket-spacing': ['warn', { - 'startTag': 'never', - 'endTag': 'never', - 'selfClosingTag': 'never', - }], - 'vue/multi-word-component-names': 'warn', - 'vue/require-v-for-key': 'warn', - 'vue/no-unused-components': 'warn', - 'vue/no-unused-vars': 'warn', - 'vue/no-dupe-keys': 'warn', - 'vue/valid-v-for': 'warn', - 'vue/return-in-computed-property': 'warn', - 'vue/no-setup-props-reactivity-loss': 'warn', - 'vue/max-attributes-per-line': 'off', - 'vue/html-self-closing': 'off', - 'vue/singleline-html-element-content-newline': 'off', - 'vue/v-on-event-hyphenation': ['error', 'never', { autofix: true }], - 'vue/attribute-hyphenation': ['error', 'never'], - }, - globals: { - // Node.js - 'module': false, - 'require': false, - '__dirname': false, - - // Misskey - '_DEV_': false, - '_LANGS_': false, - '_VERSION_': false, - '_ENV_': false, - '_PERF_PREFIX_': false, - '_DATA_TRANSFER_DRIVE_FILE_': false, - '_DATA_TRANSFER_DRIVE_FOLDER_': false, - '_DATA_TRANSFER_DECK_COLUMN_': false, - }, -}; diff --git a/packages/frontend/eslint.config.js b/packages/frontend/eslint.config.js new file mode 100644 index 000000000000..dd8f03dac510 --- /dev/null +++ b/packages/frontend/eslint.config.js @@ -0,0 +1,95 @@ +import globals from 'globals'; +import tsParser from '@typescript-eslint/parser'; +import parser from 'vue-eslint-parser'; +import pluginVue from 'eslint-plugin-vue'; +import pluginMisskey from '@misskey-dev/eslint-plugin'; +import sharedConfig from '../shared/eslint.config.js'; + +export default [ + ...sharedConfig, + { + files: ['src/**/*.vue'], + ...pluginMisskey.configs.typescript, + }, + ...pluginVue.configs['flat/recommended'], + { + files: ['src/**/*.{ts,vue}'], + languageOptions: { + globals: { + ...Object.fromEntries(Object.entries(globals.node).map(([key]) => [key, 'off'])), + ...globals.browser, + + // Node.js + module: false, + require: false, + __dirname: false, + + // Misskey + _DEV_: false, + _LANGS_: false, + _VERSION_: false, + _ENV_: false, + _PERF_PREFIX_: false, + _DATA_TRANSFER_DRIVE_FILE_: false, + _DATA_TRANSFER_DRIVE_FOLDER_: false, + _DATA_TRANSFER_DECK_COLUMN_: false, + }, + parser, + parserOptions: { + extraFileExtensions: ['.vue'], + parser: tsParser, + project: ['./tsconfig.json'], + sourceType: 'module', + tsconfigRootDir: import.meta.dirname, + }, + }, + rules: { + '@typescript-eslint/no-empty-interface': ['error', { + allowSingleExtends: true, + }], + // window の禁止理由: グローバルスコープと衝突し、予期せぬ結果を招くため + // e の禁止理由: error や event など、複数のキーワードの頭文字であり分かりにくいため + 'id-denylist': ['error', 'window', 'e'], + 'no-shadow': ['warn'], + 'vue/attributes-order': ['error', { + alphabetical: false, + }], + 'vue/no-use-v-if-with-v-for': ['error', { + allowUsingIterationVar: false, + }], + 'vue/no-ref-as-operand': 'error', + 'vue/no-multi-spaces': ['error', { + ignoreProperties: false, + }], + 'vue/no-v-html': 'warn', + 'vue/order-in-components': 'error', + 'vue/html-indent': ['warn', 'tab', { + attribute: 1, + baseIndent: 0, + closeBracket: 0, + alignAttributesVertically: true, + ignores: [], + }], + 'vue/html-closing-bracket-spacing': ['warn', { + startTag: 'never', + endTag: 'never', + selfClosingTag: 'never', + }], + 'vue/multi-word-component-names': 'warn', + 'vue/require-v-for-key': 'warn', + 'vue/no-unused-components': 'warn', + 'vue/no-unused-vars': 'warn', + 'vue/no-dupe-keys': 'warn', + 'vue/valid-v-for': 'warn', + 'vue/return-in-computed-property': 'warn', + 'vue/no-setup-props-reactivity-loss': 'warn', + 'vue/max-attributes-per-line': 'off', + 'vue/html-self-closing': 'off', + 'vue/singleline-html-element-content-newline': 'off', + 'vue/v-on-event-hyphenation': ['error', 'never', { + autofix: true, + }], + 'vue/attribute-hyphenation': ['error', 'never'], + }, + }, +]; diff --git a/packages/frontend/package.json b/packages/frontend/package.json index a63d97658b02..743722c2312f 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -22,24 +22,24 @@ "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@misskey-dev/browser-image-resizer": "2024.1.0", "@rollup/plugin-json": "6.1.0", - "@rollup/plugin-replace": "5.0.5", + "@rollup/plugin-replace": "5.0.7", "@rollup/pluginutils": "5.1.0", "@syuilo/aiscript": "0.18.0", "@tabler/icons-webfont": "3.3.0", "@twemoji/parser": "15.1.1", - "@vitejs/plugin-vue": "5.0.4", - "@vue/compiler-sfc": "3.4.26", + "@vitejs/plugin-vue": "5.0.5", + "@vue/compiler-sfc": "3.4.31", "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.9", "astring": "1.8.6", "broadcast-channel": "7.0.0", "buraha": "0.0.1", "canvas-confetti": "1.9.3", - "chart.js": "4.4.2", + "chart.js": "4.4.3", "chartjs-adapter-date-fns": "3.0.0", "chartjs-chart-matrix": "2.0.1", "chartjs-plugin-gradient": "0.6.1", "chartjs-plugin-zoom": "2.0.1", - "chromatic": "11.3.0", + "chromatic": "11.5.4", "compare-versions": "6.1.0", "cropperjs": "2.0.0-beta.5", "date-fns": "2.30.0", @@ -55,89 +55,87 @@ "misskey-bubble-game": "workspace:*", "misskey-js": "workspace:*", "misskey-reversi": "workspace:*", - "photoswipe": "5.4.3", + "photoswipe": "5.4.4", "punycode": "2.3.1", - "rollup": "4.17.2", + "rollup": "4.18.0", "sanitize-html": "2.13.0", - "sass": "1.76.0", - "shiki": "1.4.0", + "sass": "1.77.6", + "shiki": "1.10.0", "strict-event-emitter-types": "2.0.0", "textarea-caret": "3.1.0", - "three": "0.164.1", - "throttle-debounce": "5.0.0", + "three": "0.165.0", + "throttle-debounce": "5.0.2", "tinycolor2": "1.6.0", - "tsc-alias": "1.8.8", + "tsc-alias": "1.8.10", "tsconfig-paths": "4.2.0", - "typescript": "5.5.2", - "uuid": "9.0.1", - "v-code-diff": "1.11.0", - "vite": "5.2.11", - "vue": "3.4.26", + "typescript": "5.5.3", + "uuid": "10.0.0", + "v-code-diff": "1.12.0", + "vite": "5.3.2", + "vue": "3.4.31", "vuedraggable": "next" }, "devDependencies": { - "@misskey-dev/eslint-plugin": "1.0.0", "@misskey-dev/summaly": "5.1.0", - "@storybook/addon-actions": "8.0.9", - "@storybook/addon-essentials": "8.0.9", - "@storybook/addon-interactions": "8.0.9", - "@storybook/addon-links": "8.0.9", - "@storybook/addon-mdx-gfm": "8.0.9", - "@storybook/addon-storysource": "8.0.9", - "@storybook/blocks": "8.0.9", - "@storybook/components": "8.0.9", - "@storybook/core-events": "8.0.9", - "@storybook/manager-api": "8.0.9", - "@storybook/preview-api": "8.0.9", - "@storybook/react": "8.0.9", - "@storybook/react-vite": "8.0.9", - "@storybook/test": "8.0.9", - "@storybook/theming": "8.0.9", - "@storybook/types": "8.0.9", - "@storybook/vue3": "8.0.9", - "@storybook/vue3-vite": "8.0.9", - "@testing-library/vue": "8.0.3", + "@storybook/addon-actions": "8.1.11", + "@storybook/addon-essentials": "8.1.11", + "@storybook/addon-interactions": "8.1.11", + "@storybook/addon-links": "8.1.11", + "@storybook/addon-mdx-gfm": "8.1.11", + "@storybook/addon-storysource": "8.1.11", + "@storybook/blocks": "8.1.11", + "@storybook/components": "8.1.11", + "@storybook/core-events": "8.1.11", + "@storybook/manager-api": "8.1.11", + "@storybook/preview-api": "8.1.11", + "@storybook/react": "8.1.11", + "@storybook/react-vite": "8.1.11", + "@storybook/test": "8.1.11", + "@storybook/theming": "8.1.11", + "@storybook/types": "8.1.11", + "@storybook/vue3": "8.1.11", + "@storybook/vue3-vite": "8.1.11", + "@testing-library/vue": "8.1.0", "@types/escape-regexp": "0.0.3", "@types/estree": "1.0.5", "@types/matter-js": "0.19.6", - "@types/micromatch": "4.0.7", - "@types/node": "20.12.7", + "@types/micromatch": "4.0.9", + "@types/node": "20.14.9", "@types/punycode": "2.1.4", "@types/sanitize-html": "2.11.0", "@types/seedrandom": "3.0.8", "@types/throttle-debounce": "5.0.2", "@types/tinycolor2": "1.4.6", - "@types/uuid": "9.0.8", + "@types/uuid": "10.0.0", "@types/ws": "8.5.10", - "@typescript-eslint/eslint-plugin": "7.7.1", - "@typescript-eslint/parser": "7.7.1", - "@vitest/coverage-v8": "0.34.6", - "@vue/runtime-core": "3.4.26", - "acorn": "8.11.3", + "@typescript-eslint/eslint-plugin": "7.15.0", + "@typescript-eslint/parser": "7.15.0", + "@vitest/coverage-v8": "1.6.0", + "@vue/runtime-core": "3.4.31", + "acorn": "8.12.0", "cross-env": "7.0.3", - "cypress": "13.8.1", - "eslint": "8.57.0", + "cypress": "13.13.0", "eslint-plugin-import": "2.29.1", - "eslint-plugin-vue": "9.25.0", + "eslint-plugin-vue": "9.26.0", "fast-glob": "3.3.2", "happy-dom": "10.0.3", "intersection-observer": "0.12.2", - "micromatch": "4.0.5", - "msw": "2.2.14", - "msw-storybook-addon": "2.0.1", - "nodemon": "3.1.0", - "prettier": "3.2.5", + "micromatch": "4.0.7", + "msw": "2.3.1", + "msw-storybook-addon": "2.0.2", + "nodemon": "3.1.4", + "prettier": "3.3.2", "react": "18.3.1", "react-dom": "18.3.1", "seedrandom": "3.0.5", - "start-server-and-test": "2.0.3", - "storybook": "8.0.9", + "start-server-and-test": "2.0.4", + "storybook": "8.1.11", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", "vite-plugin-turbosnap": "1.0.3", - "vitest": "0.34.6", + "vitest": "1.6.0", "vitest-fetch-mock": "0.2.2", - "vue-component-type-helpers": "2.0.16", - "vue-eslint-parser": "9.4.2", - "vue-tsc": "2.0.16" + "vue-component-type-helpers": "2.0.24", + "vue-eslint-parser": "9.4.3", + "vue-tsc": "2.0.24" } } diff --git a/packages/frontend/tsconfig.json b/packages/frontend/tsconfig.json index 187a2473baf3..fe4d20289492 100644 --- a/packages/frontend/tsconfig.json +++ b/packages/frontend/tsconfig.json @@ -44,7 +44,6 @@ }, "compileOnSave": false, "include": [ - ".eslintrc.js", "./**/*.ts", "./**/*.vue" ], diff --git a/packages/misskey-bubble-game/.eslintignore b/packages/misskey-bubble-game/.eslintignore deleted file mode 100644 index 52ea8b3362e9..000000000000 --- a/packages/misskey-bubble-game/.eslintignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules -/built -/coverage -/.eslintrc.js -/jest.config.ts -/test -/test-d -build.js diff --git a/packages/misskey-bubble-game/.eslintrc.cjs b/packages/misskey-bubble-game/.eslintrc.cjs deleted file mode 100644 index e2e31e9e331e..000000000000 --- a/packages/misskey-bubble-game/.eslintrc.cjs +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - extends: [ - '../shared/.eslintrc.js', - ], -}; diff --git a/packages/misskey-bubble-game/eslint.config.js b/packages/misskey-bubble-game/eslint.config.js new file mode 100644 index 000000000000..86c21a22a3a7 --- /dev/null +++ b/packages/misskey-bubble-game/eslint.config.js @@ -0,0 +1,27 @@ +import tsParser from '@typescript-eslint/parser'; +import sharedConfig from '../shared/eslint.config.js'; + +export default [ + ...sharedConfig, + { + ignores: [ + '**/node_modules', + 'built', + 'coverage', + 'jest.config.ts', + 'test', + 'test-d', + ], + }, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parserOptions: { + parser: tsParser, + project: ['./tsconfig.json'], + sourceType: 'module', + tsconfigRootDir: import.meta.dirname, + }, + }, + }, +]; diff --git a/packages/misskey-bubble-game/package.json b/packages/misskey-bubble-game/package.json index a3aad147a984..528eb00b7460 100644 --- a/packages/misskey-bubble-game/package.json +++ b/packages/misskey-bubble-game/package.json @@ -17,18 +17,16 @@ "scripts": { "build": "node ./build.js", "watch": "nodemon -w package.json -e json --exec \"node ./build.js --watch\"", - "eslint": "eslint . --ext .js,.jsx,.ts,.tsx", + "eslint": "eslint './**/*.{js,jsx,ts,tsx}'", "typecheck": "tsc --noEmit", "lint": "pnpm typecheck && pnpm eslint" }, "devDependencies": { - "@misskey-dev/eslint-plugin": "1.0.0", "@types/matter-js": "0.19.6", "@types/seedrandom": "3.0.8", "@types/node": "20.11.5", "@typescript-eslint/eslint-plugin": "7.1.0", "@typescript-eslint/parser": "7.1.0", - "eslint": "8.57.0", "nodemon": "3.0.2", "execa": "8.0.1", "typescript": "5.3.3", diff --git a/packages/misskey-js/.eslintignore b/packages/misskey-js/.eslintignore deleted file mode 100644 index 52ea8b3362e9..000000000000 --- a/packages/misskey-js/.eslintignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules -/built -/coverage -/.eslintrc.js -/jest.config.ts -/test -/test-d -build.js diff --git a/packages/misskey-js/.eslintrc.cjs b/packages/misskey-js/.eslintrc.cjs deleted file mode 100644 index e2e31e9e331e..000000000000 --- a/packages/misskey-js/.eslintrc.cjs +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - extends: [ - '../shared/.eslintrc.js', - ], -}; diff --git a/packages/misskey-js/build.js b/packages/misskey-js/build.js index 0b79f4b9159b..a13d9c1186c8 100644 --- a/packages/misskey-js/build.js +++ b/packages/misskey-js/build.js @@ -1,32 +1,32 @@ -import * as esbuild from "esbuild"; -import { build } from "esbuild"; -import { globSync } from "glob"; -import { execa } from "execa"; -import fs from "node:fs"; -import { fileURLToPath } from "node:url"; -import { dirname } from "node:path"; +import fs from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { dirname } from 'node:path'; +import * as esbuild from 'esbuild'; +import { build } from 'esbuild'; +import { globSync } from 'glob'; +import { execa } from 'execa'; const _filename = fileURLToPath(import.meta.url); const _dirname = dirname(_filename); const _package = JSON.parse(fs.readFileSync(_dirname + '/package.json', 'utf-8')); -const entryPoints = globSync("./src/**/**.{ts,tsx}"); +const entryPoints = globSync('./src/**/**.{ts,tsx}'); /** @type {import('esbuild').BuildOptions} */ const options = { entryPoints, minify: process.env.NODE_ENV === 'production', - outdir: "./built", - target: "es2022", - platform: "browser", - format: "esm", + outdir: './built', + target: 'es2022', + platform: 'browser', + format: 'esm', sourcemap: 'linked', }; // built配下をすべて削除する fs.rmSync('./built', { recursive: true, force: true }); -if (process.argv.map(arg => arg.toLowerCase()).includes("--watch")) { +if (process.argv.map(arg => arg.toLowerCase()).includes('--watch')) { await watchSrc(); } else { await buildSrc(); @@ -36,7 +36,7 @@ async function buildSrc() { console.log(`[${_package.name}] start building...`); await build(options) - .then(it => { + .then(() => { console.log(`[${_package.name}] build succeeded.`); }) .catch((err) => { @@ -65,7 +65,7 @@ function buildDts() { { stdout: process.stdout, stderr: process.stderr, - } + }, ); } @@ -86,7 +86,7 @@ async function watchSrc() { }, }]; - console.log(`[${_package.name}] start watching...`) + console.log(`[${_package.name}] start watching...`); const context = await esbuild.context({ ...options, plugins }); await context.watch(); diff --git a/packages/misskey-js/eslint.config.js b/packages/misskey-js/eslint.config.js new file mode 100644 index 000000000000..e34e7510b29e --- /dev/null +++ b/packages/misskey-js/eslint.config.js @@ -0,0 +1,28 @@ +import tsParser from '@typescript-eslint/parser'; +import sharedConfig from '../shared/eslint.config.js'; + +export default [ + ...sharedConfig, + { + ignores: [ + '**/node_modules', + 'built', + 'coverage', + 'jest.config.ts', + 'test', + 'test-d', + 'generator', + ], + }, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parserOptions: { + parser: tsParser, + project: ['./tsconfig.json'], + sourceType: 'module', + tsconfigRootDir: import.meta.dirname, + }, + }, + }, +]; diff --git a/packages/misskey-js/generator/.eslintrc.cjs b/packages/misskey-js/generator/.eslintrc.cjs deleted file mode 100644 index 6a8b31da9cc6..000000000000 --- a/packages/misskey-js/generator/.eslintrc.cjs +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - extends: [ - '../../shared/.eslintrc.js', - ], -}; diff --git a/packages/misskey-js/generator/eslint.config.js b/packages/misskey-js/generator/eslint.config.js new file mode 100644 index 000000000000..4bf78c3b910d --- /dev/null +++ b/packages/misskey-js/generator/eslint.config.js @@ -0,0 +1,17 @@ +import tsParser from '@typescript-eslint/parser'; +import sharedConfig from '../../shared/eslint.config.js'; + +export default [ + ...sharedConfig, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parserOptions: { + parser: tsParser, + project: ['./tsconfig.json'], + sourceType: 'module', + tsconfigRootDir: import.meta.dirname, + }, + }, + }, +]; diff --git a/packages/misskey-js/generator/package.json b/packages/misskey-js/generator/package.json index a1c0f41cb285..4a02bcd8ff7c 100644 --- a/packages/misskey-js/generator/package.json +++ b/packages/misskey-js/generator/package.json @@ -4,15 +4,13 @@ "description": "Misskey TypeGenerator", "type": "module", "scripts": { - "generate": "tsx src/generator.ts && eslint ./built/**/* --ext .ts --fix" + "generate": "tsx src/generator.ts && eslint ./built/**/*.ts --fix" }, "devDependencies": { - "@misskey-dev/eslint-plugin": "^1.0.0", "@readme/openapi-parser": "2.5.0", "@types/node": "20.9.1", "@typescript-eslint/eslint-plugin": "6.11.0", "@typescript-eslint/parser": "6.11.0", - "eslint": "8.53.0", "openapi-types": "12.1.3", "openapi-typescript": "6.7.3", "ts-case-convert": "2.0.2", diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index b99d0dd260cd..00342d3dbc6c 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -22,7 +22,7 @@ "tsd": "tsd", "api": "pnpm api-extractor run --local --verbose", "api-prod": "pnpm api-extractor run --verbose", - "eslint": "eslint . --ext .js,.jsx,.ts,.tsx", + "eslint": "eslint './**/*.{js,jsx,ts,tsx}'", "typecheck": "tsc --noEmit", "lint": "pnpm typecheck && pnpm eslint", "jest": "jest --coverage --detectOpenHandles", @@ -35,25 +35,23 @@ "directory": "packages/misskey-js" }, "devDependencies": { - "@microsoft/api-extractor": "7.43.1", - "@misskey-dev/eslint-plugin": "1.0.0", + "@microsoft/api-extractor": "7.47.0", "@swc/jest": "0.2.36", "@types/jest": "29.5.12", - "@types/node": "20.12.7", - "@typescript-eslint/eslint-plugin": "7.7.1", - "@typescript-eslint/parser": "7.7.1", - "eslint": "8.57.0", + "@types/node": "20.14.9", + "@typescript-eslint/eslint-plugin": "7.15.0", + "@typescript-eslint/parser": "7.15.0", "jest": "29.7.0", "jest-fetch-mock": "3.0.3", "jest-websocket-mock": "2.5.0", "mock-socket": "9.3.1", "ncp": "2.0.0", - "nodemon": "3.1.0", - "execa": "8.0.1", - "tsd": "0.30.7", - "typescript": "5.5.2", - "esbuild": "0.19.11", - "glob": "10.3.12" + "nodemon": "3.1.4", + "execa": "9.2.0", + "tsd": "0.31.1", + "typescript": "5.5.3", + "esbuild": "0.22.0", + "glob": "10.4.2" }, "files": [ "built" diff --git a/packages/misskey-reversi/.eslintignore b/packages/misskey-reversi/.eslintignore deleted file mode 100644 index 52ea8b3362e9..000000000000 --- a/packages/misskey-reversi/.eslintignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules -/built -/coverage -/.eslintrc.js -/jest.config.ts -/test -/test-d -build.js diff --git a/packages/misskey-reversi/.eslintrc.cjs b/packages/misskey-reversi/.eslintrc.cjs deleted file mode 100644 index db37a0109871..000000000000 --- a/packages/misskey-reversi/.eslintrc.cjs +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - root: true, - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - extends: [ - '../shared/.eslintrc.js', - ], -}; diff --git a/packages/misskey-reversi/eslint.config.js b/packages/misskey-reversi/eslint.config.js new file mode 100644 index 000000000000..3f81df714508 --- /dev/null +++ b/packages/misskey-reversi/eslint.config.js @@ -0,0 +1,23 @@ +import tsParser from '@typescript-eslint/parser'; +import sharedConfig from '../shared/eslint.config.js'; + +export default [ + ...sharedConfig, + { + ignores: [ + '**/node_modules', + 'built', + ], + }, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parserOptions: { + parser: tsParser, + project: ['./tsconfig.json'], + sourceType: 'module', + tsconfigRootDir: import.meta.dirname, + }, + }, + }, +]; diff --git a/packages/misskey-reversi/package.json b/packages/misskey-reversi/package.json index 45a61208610d..c6db6e6221ae 100644 --- a/packages/misskey-reversi/package.json +++ b/packages/misskey-reversi/package.json @@ -17,16 +17,14 @@ "scripts": { "build": "node ./build.js", "watch": "nodemon -w package.json -e json --exec \"node ./build.js --watch\"", - "eslint": "eslint . --ext .js,.jsx,.ts,.tsx", + "eslint": "eslint './**/*.{js,jsx,ts,tsx}'", "typecheck": "tsc --noEmit", "lint": "pnpm typecheck && pnpm eslint" }, "devDependencies": { - "@misskey-dev/eslint-plugin": "1.0.0", "@types/node": "20.11.5", "@typescript-eslint/eslint-plugin": "7.1.0", "@typescript-eslint/parser": "7.1.0", - "eslint": "8.57.0", "execa": "8.0.1", "nodemon": "3.0.2", "typescript": "5.3.3", diff --git a/packages/shared/.eslintrc.js b/packages/shared/.eslintrc.js deleted file mode 100644 index 58247877ae27..000000000000 --- a/packages/shared/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - root: true, - ignorePatterns: ['**/.eslintrc.cjs'], - extends: [ - 'plugin:@misskey-dev/recommended', - ], -}; diff --git a/packages/shared/eslint.config.js b/packages/shared/eslint.config.js new file mode 100644 index 000000000000..e9d27c4a7288 --- /dev/null +++ b/packages/shared/eslint.config.js @@ -0,0 +1,28 @@ +import globals from 'globals'; +import pluginMisskey from '@misskey-dev/eslint-plugin'; + +export default [ + ...pluginMisskey.configs['recommended'], + { + files: ['**/*.cjs'], + languageOptions: { + parserOptions: { + sourceType: 'commonjs', + }, + }, + }, + { + files: ['**/*.js', '**/*.jsx'], + languageOptions: { + parserOptions: { + sourceType: 'module', + }, + }, + }, + { + files: ['build.js'], + languageOptions: { + globals: globals.node, + }, + }, +]; diff --git a/packages/shared/package.json b/packages/shared/package.json new file mode 100644 index 000000000000..bedb411a9124 --- /dev/null +++ b/packages/shared/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/packages/sw/.eslintrc.cjs b/packages/sw/.eslintrc.cjs deleted file mode 100644 index b1fd6b5edc80..000000000000 --- a/packages/sw/.eslintrc.cjs +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - root: true, - env: { - node: false, - }, - parserOptions: { - parser: '@typescript-eslint/parser', - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - extends: ['../shared/.eslintrc.js'], - globals: { - require: false, - _DEV_: false, - _LANGS_: false, - _VERSION_: false, - _ENV_: false, - _PERF_PREFIX_: false, - }, -}; diff --git a/packages/sw/eslint.config.js b/packages/sw/eslint.config.js new file mode 100644 index 000000000000..c62a2eadc6d5 --- /dev/null +++ b/packages/sw/eslint.config.js @@ -0,0 +1,32 @@ +import globals from 'globals'; +import tsParser from '@typescript-eslint/parser'; +import sharedConfig from '../shared/eslint.config.js'; + +export default [ + ...sharedConfig, + { + ignores: ['build.js'], + languageOptions: { + globals: { + ...Object.fromEntries(Object.entries(globals.node).map(([key]) => [key, 'off'])), + require: false, + _DEV_: false, + _LANGS_: false, + _VERSION_: false, + _ENV_: false, + _PERF_PREFIX_: false, + }, + }, + }, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parserOptions: { + parser: tsParser, + project: ['./tsconfig.json'], + sourceType: 'module', + tsconfigRootDir: import.meta.dirname, + }, + }, + }, +]; diff --git a/packages/sw/package.json b/packages/sw/package.json index 2deda4736904..bcd642ffc44b 100644 --- a/packages/sw/package.json +++ b/packages/sw/package.json @@ -9,18 +9,16 @@ "lint": "pnpm typecheck && pnpm eslint" }, "dependencies": { - "esbuild": "0.20.2", + "esbuild": "0.22.0", "idb-keyval": "6.2.1", "misskey-js": "workspace:*" }, "devDependencies": { - "@misskey-dev/eslint-plugin": "1.0.0", - "@typescript-eslint/parser": "7.7.1", + "@typescript-eslint/parser": "7.15.0", "@typescript/lib-webworker": "npm:@types/serviceworker@0.0.67", - "eslint": "8.57.0", "eslint-plugin-import": "2.29.1", - "nodemon": "3.1.0", - "typescript": "5.5.2" + "nodemon": "3.1.4", + "typescript": "5.5.3" }, "type": "module" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 09df15853b80..10968f3e8240 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,8 +16,8 @@ importers: specifier: 6.1.2 version: 6.1.2(postcss@8.4.38) esbuild: - specifier: 0.20.2 - version: 0.20.2 + specifier: 0.22.0 + version: 0.22.0 execa: specifier: 8.0.1 version: 8.0.1 @@ -40,58 +40,64 @@ importers: specifier: 6.2.1 version: 6.2.1 terser: - specifier: 5.30.3 - version: 5.30.3 + specifier: 5.31.1 + version: 5.31.1 typescript: - specifier: 5.5.2 - version: 5.5.2 + specifier: 5.5.3 + version: 5.5.3 optionalDependencies: '@tensorflow/tfjs-core': specifier: 4.4.0 version: 4.4.0(encoding@0.1.13) devDependencies: + '@misskey-dev/eslint-plugin': + specifier: 2.0.2 + version: 2.0.2(@eslint/compat@1.1.0)(@typescript-eslint/eslint-plugin@7.15.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3))(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0))(eslint@9.6.0)(globals@15.7.0) '@types/node': - specifier: 20.12.7 - version: 20.12.7 + specifier: 20.14.9 + version: 20.14.9 '@typescript-eslint/eslint-plugin': - specifier: 7.7.1 - version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2) + specifier: 7.15.0 + version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3) '@typescript-eslint/parser': - specifier: 7.7.1 - version: 7.7.1(eslint@8.57.0)(typescript@5.5.2) + specifier: 7.15.0 + version: 7.15.0(eslint@9.6.0)(typescript@5.5.3) cross-env: specifier: 7.0.3 version: 7.0.3 cypress: - specifier: 13.7.3 - version: 13.7.3 + specifier: 13.13.0 + version: 13.13.0 eslint: - specifier: 8.57.0 - version: 8.57.0 + specifier: 9.6.0 + version: 9.6.0 + globals: + specifier: 15.7.0 + version: 15.7.0 ncp: specifier: 2.0.0 version: 2.0.0 start-server-and-test: - specifier: 2.0.3 - version: 2.0.3 + specifier: 2.0.4 + version: 2.0.4 packages/backend: dependencies: '@aws-sdk/client-s3': - specifier: 3.412.0 - version: 3.412.0 + specifier: 3.600.0 + version: 3.600.0 '@aws-sdk/lib-storage': - specifier: 3.412.0 - version: 3.412.0(@aws-sdk/client-s3@3.412.0) + specifier: 3.600.0 + version: 3.600.0(@aws-sdk/client-s3@3.600.0) '@bull-board/api': - specifier: 5.17.0 - version: 5.17.0(@bull-board/ui@5.17.0) + specifier: 5.20.5 + version: 5.20.5(@bull-board/ui@5.20.5) '@bull-board/fastify': - specifier: 5.17.0 - version: 5.17.0 + specifier: 5.20.5 + version: 5.20.5 '@bull-board/ui': - specifier: 5.17.0 - version: 5.17.0 + specifier: 5.20.5 + version: 5.20.5 '@discordapp/twemoji': specifier: 15.0.3 version: 15.0.3 @@ -111,11 +117,11 @@ importers: specifier: 9.5.0 version: 9.5.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) '@fastify/multipart': - specifier: 8.2.0 - version: 8.2.0 + specifier: 8.3.0 + version: 8.3.0 '@fastify/static': - specifier: 7.0.3 - version: 7.0.3 + specifier: 7.0.4 + version: 7.0.4 '@fastify/view': specifier: 9.1.0 version: 9.1.0 @@ -126,26 +132,26 @@ importers: specifier: 5.1.0 version: 5.1.0 '@napi-rs/canvas': - specifier: ^0.1.52 - version: 0.1.52 + specifier: ^0.1.53 + version: 0.1.53 '@nestjs/common': - specifier: 10.3.8 - version: 10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1) + specifier: 10.3.10 + version: 10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': - specifier: 10.3.8 - version: 10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.8)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) + specifier: 10.3.10 + version: 10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/testing': - specifier: 10.3.8 - version: 10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.8)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.8)) + specifier: 10.3.10 + version: 10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10)) '@peertube/http-signature': specifier: 1.7.0 version: 1.7.0 '@sentry/node': - specifier: ^8.5.0 - version: 8.5.0 + specifier: 8.13.0 + version: 8.13.0 '@sentry/profiling-node': - specifier: ^8.5.0 - version: 8.5.0 + specifier: 8.13.0 + version: 8.13.0 '@simplewebauthn/server': specifier: 10.0.0 version: 10.0.0(encoding@0.1.13) @@ -157,10 +163,10 @@ importers: version: 2.5.0 '@swc/cli': specifier: 0.3.12 - version: 0.3.12(@swc/core@1.4.17)(chokidar@3.5.3) + version: 0.3.12(@swc/core@1.6.6)(chokidar@3.5.3) '@swc/core': - specifier: 1.4.17 - version: 1.4.17 + specifier: 1.6.6 + version: 1.6.6 '@twemoji/parser': specifier: 15.1.1 version: 15.1.1 @@ -168,8 +174,8 @@ importers: specifier: 1.3.8 version: 1.3.8 ajv: - specifier: 8.13.0 - version: 8.13.0 + specifier: 8.16.0 + version: 8.16.0 archiver: specifier: 7.0.1 version: 7.0.1 @@ -186,8 +192,8 @@ importers: specifier: 1.20.2 version: 1.20.2 bullmq: - specifier: 5.7.8 - version: 5.7.8 + specifier: 5.8.3 + version: 5.8.3 cacheable-lookup: specifier: 7.0.0 version: 7.0.0 @@ -219,8 +225,8 @@ importers: specifier: 0.1.21 version: 0.1.21 fastify: - specifier: 4.26.2 - version: 4.26.2 + specifier: 4.28.1 + version: 4.28.1 fastify-raw-body: specifier: 4.3.0 version: 4.3.0 @@ -231,14 +237,14 @@ importers: specifier: 19.0.0 version: 19.0.0 fluent-ffmpeg: - specifier: 2.1.2 - version: 2.1.2 + specifier: 2.1.3 + version: 2.1.3 form-data: specifier: 4.0.0 version: 4.0.0 got: - specifier: 14.2.1 - version: 14.2.1 + specifier: 14.4.1 + version: 14.4.1 happy-dom: specifier: 10.0.3 version: 10.0.3 @@ -255,20 +261,20 @@ importers: specifier: 5.4.1 version: 5.4.1 ip-cidr: - specifier: 3.1.0 - version: 3.1.0 + specifier: 4.0.1 + version: 4.0.1 ipaddr.js: specifier: 2.2.0 version: 2.2.0 is-svg: - specifier: 5.0.0 - version: 5.0.0 + specifier: 5.0.1 + version: 5.0.1 js-yaml: specifier: 4.1.0 version: 4.1.0 jsdom: - specifier: 24.0.0 - version: 24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) + specifier: 24.1.0 + version: 24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) json5: specifier: 2.2.3 version: 2.2.3 @@ -279,8 +285,8 @@ importers: specifier: 11.1.0 version: 11.1.0 meilisearch: - specifier: 0.38.0 - version: 0.38.0(encoding@0.1.13) + specifier: 0.41.0 + version: 0.41.0(encoding@0.1.13) mfm-js: specifier: 0.24.0 version: 0.24.0 @@ -309,8 +315,8 @@ importers: specifier: 3.3.2 version: 3.3.2 nodemailer: - specifier: 6.9.13 - version: 6.9.13 + specifier: 6.9.14 + version: 6.9.14 nsfwjs: specifier: 2.4.2 version: 2.4.2(@tensorflow/tfjs@4.4.0(encoding@0.1.13)(seedrandom@3.0.5)) @@ -327,14 +333,14 @@ importers: specifier: 0.0.14 version: 0.0.14 otpauth: - specifier: 9.2.3 - version: 9.2.3 + specifier: 9.3.1 + version: 9.3.1 parse5: specifier: 7.1.2 version: 7.1.2 pg: - specifier: 8.11.5 - version: 8.11.5 + specifier: 8.12.0 + version: 8.12.0 pkce-challenge: specifier: 4.1.0 version: 4.1.0 @@ -345,8 +351,8 @@ importers: specifier: 2.7.0 version: 2.7.0 pug: - specifier: 3.0.2 - version: 3.0.2 + specifier: 3.0.3 + version: 3.0.3 punycode: specifier: 2.3.1 version: 2.3.1 @@ -360,8 +366,8 @@ importers: specifier: 3.4.1 version: 3.4.1 re2: - specifier: 1.21.2 - version: 1.21.2 + specifier: 1.21.3 + version: 1.21.3 redis-lock: specifier: 0.1.4 version: 0.1.4 @@ -384,8 +390,8 @@ importers: specifier: 2.7.0 version: 2.7.0 sharp: - specifier: 0.33.3 - version: 0.33.3 + specifier: 0.33.4 + version: 0.33.4 slacc: specifier: 0.0.10 version: 0.0.10 @@ -396,8 +402,8 @@ importers: specifier: 2.1.0 version: 2.1.0 systeminformation: - specifier: 5.22.7 - version: 5.22.7 + specifier: 5.22.11 + version: 5.22.11 tinycolor2: specifier: 1.6.0 version: 1.6.0 @@ -405,17 +411,17 @@ importers: specifier: 0.2.3 version: 0.2.3 tsc-alias: - specifier: 1.8.8 - version: 1.8.8 + specifier: 1.8.10 + version: 1.8.10 tsconfig-paths: specifier: 4.2.0 version: 4.2.0 typeorm: specifier: 0.3.20 - version: 0.3.20(ioredis@5.4.1)(pg@8.11.5) + version: 0.3.20(ioredis@5.4.1)(pg@8.12.0) typescript: - specifier: 5.5.2 - version: 5.5.2 + specifier: 5.5.3 + version: 5.5.3 ulid: specifier: 2.3.0 version: 2.3.0 @@ -426,8 +432,8 @@ importers: specifier: 3.6.7 version: 3.6.7 ws: - specifier: 8.17.0 - version: 8.17.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) + specifier: 8.17.1 + version: 8.17.1(bufferutil@4.0.7)(utf-8-validate@6.0.3) xev: specifier: 3.0.2 version: 3.0.2 @@ -523,18 +529,15 @@ importers: '@jest/globals': specifier: 29.7.0 version: 29.7.0 - '@misskey-dev/eslint-plugin': - specifier: 1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0))(eslint@8.57.0) '@nestjs/platform-express': - specifier: 10.3.8 - version: 10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.8) + specifier: 10.3.10 + version: 10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10) '@simplewebauthn/types': specifier: 10.0.0 version: 10.0.0 '@swc/jest': specifier: 0.2.36 - version: 0.2.36(@swc/core@1.4.17) + version: 0.2.36(@swc/core@1.6.6) '@types/accepts': specifier: 1.3.7 version: 1.3.7 @@ -557,11 +560,11 @@ importers: specifier: 2.1.24 version: 2.1.24 '@types/htmlescape': - specifier: ^1.1.3 + specifier: 1.1.3 version: 1.1.3 '@types/http-link-header': - specifier: 1.0.5 - version: 1.0.5 + specifier: 1.0.7 + version: 1.0.7 '@types/jest': specifier: 29.5.12 version: 29.5.12 @@ -569,11 +572,11 @@ importers: specifier: 4.0.9 version: 4.0.9 '@types/jsdom': - specifier: 21.1.6 - version: 21.1.6 + specifier: 21.1.7 + version: 21.1.7 '@types/jsonld': - specifier: 1.5.13 - version: 1.5.13 + specifier: 1.5.14 + version: 1.5.14 '@types/jsrsasign': specifier: 10.5.14 version: 10.5.14 @@ -584,14 +587,14 @@ importers: specifier: 0.7.34 version: 0.7.34 '@types/node': - specifier: 20.12.7 - version: 20.12.7 + specifier: 20.14.9 + version: 20.14.9 '@types/nodemailer': specifier: 6.4.15 version: 6.4.15 '@types/oauth': - specifier: 0.9.4 - version: 0.9.4 + specifier: 0.9.5 + version: 0.9.5 '@types/oauth2orize': specifier: 1.11.5 version: 1.11.5 @@ -599,8 +602,8 @@ importers: specifier: 0.1.2 version: 0.1.2 '@types/pg': - specifier: 8.11.5 - version: 8.11.5 + specifier: 8.11.6 + version: 8.11.6 '@types/pug': specifier: 2.0.10 version: 2.0.10 @@ -647,44 +650,41 @@ importers: specifier: 8.5.10 version: 8.5.10 '@typescript-eslint/eslint-plugin': - specifier: 7.7.1 - version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2) + specifier: 7.15.0 + version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3) '@typescript-eslint/parser': - specifier: 7.7.1 - version: 7.7.1(eslint@8.57.0)(typescript@5.5.2) + specifier: 7.15.0 + version: 7.15.0(eslint@9.6.0)(typescript@5.5.3) aws-sdk-client-mock: - specifier: 3.0.1 - version: 3.0.1 + specifier: 4.0.1 + version: 4.0.1 cross-env: specifier: 7.0.3 version: 7.0.3 - eslint: - specifier: 8.57.0 - version: 8.57.0 eslint-plugin-import: specifier: 2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0) + version: 2.29.1(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0) execa: - specifier: 8.0.1 - version: 8.0.1 + specifier: 9.2.0 + version: 9.2.0 fkill: - specifier: ^9.0.0 + specifier: 9.0.0 version: 9.0.0 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.12.7) + version: 29.7.0(@types/node@20.14.9) jest-mock: specifier: 29.7.0 version: 29.7.0 nodemon: - specifier: 3.1.0 - version: 3.1.0 + specifier: 3.1.4 + version: 3.1.4 pid-port: specifier: 1.0.0 version: 1.0.0 simple-oauth2: - specifier: 5.0.0 - version: 5.0.0 + specifier: 5.0.1 + version: 5.0.1 packages/frontend: dependencies: @@ -702,13 +702,13 @@ importers: version: 2024.1.0 '@rollup/plugin-json': specifier: 6.1.0 - version: 6.1.0(rollup@4.17.2) + version: 6.1.0(rollup@4.18.0) '@rollup/plugin-replace': - specifier: 5.0.5 - version: 5.0.5(rollup@4.17.2) + specifier: 5.0.7 + version: 5.0.7(rollup@4.18.0) '@rollup/pluginutils': specifier: 5.1.0 - version: 5.1.0(rollup@4.17.2) + version: 5.1.0(rollup@4.18.0) '@syuilo/aiscript': specifier: 0.18.0 version: 0.18.0 @@ -719,11 +719,11 @@ importers: specifier: 15.1.1 version: 15.1.1 '@vitejs/plugin-vue': - specifier: 5.0.4 - version: 5.0.4(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.5.2)) + specifier: 5.0.5 + version: 5.0.5(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1))(vue@3.4.31(typescript@5.5.3)) '@vue/compiler-sfc': - specifier: 3.4.26 - version: 3.4.26 + specifier: 3.4.31 + version: 3.4.31 aiscript-vscode: specifier: github:aiscript-dev/aiscript-vscode#v0.1.9 version: https://codeload.github.com/aiscript-dev/aiscript-vscode/tar.gz/34bf4e1530efcf1efa855bd04e2dab39735e1b02 @@ -740,23 +740,23 @@ importers: specifier: 1.9.3 version: 1.9.3 chart.js: - specifier: 4.4.2 - version: 4.4.2 + specifier: 4.4.3 + version: 4.4.3 chartjs-adapter-date-fns: specifier: 3.0.0 - version: 3.0.0(chart.js@4.4.2)(date-fns@2.30.0) + version: 3.0.0(chart.js@4.4.3)(date-fns@2.30.0) chartjs-chart-matrix: specifier: 2.0.1 - version: 2.0.1(chart.js@4.4.2) + version: 2.0.1(chart.js@4.4.3) chartjs-plugin-gradient: specifier: 0.6.1 - version: 0.6.1(chart.js@4.4.2) + version: 0.6.1(chart.js@4.4.3) chartjs-plugin-zoom: specifier: 2.0.1 - version: 2.0.1(chart.js@4.4.2) + version: 2.0.1(chart.js@4.4.3) chromatic: - specifier: 11.3.0 - version: 11.3.0 + specifier: 11.5.4 + version: 11.5.4 compare-versions: specifier: 6.1.0 version: 6.1.0 @@ -803,23 +803,23 @@ importers: specifier: workspace:* version: link:../misskey-reversi photoswipe: - specifier: 5.4.3 - version: 5.4.3 + specifier: 5.4.4 + version: 5.4.4 punycode: specifier: 2.3.1 version: 2.3.1 rollup: - specifier: 4.17.2 - version: 4.17.2 + specifier: 4.18.0 + version: 4.18.0 sanitize-html: specifier: 2.13.0 version: 2.13.0 sass: - specifier: 1.76.0 - version: 1.76.0 + specifier: 1.77.6 + version: 1.77.6 shiki: - specifier: 1.4.0 - version: 1.4.0 + specifier: 1.10.0 + version: 1.10.0 strict-event-emitter-types: specifier: 2.0.0 version: 2.0.0 @@ -827,102 +827,99 @@ importers: specifier: 3.1.0 version: 3.1.0 three: - specifier: 0.164.1 - version: 0.164.1 + specifier: 0.165.0 + version: 0.165.0 throttle-debounce: - specifier: 5.0.0 - version: 5.0.0 + specifier: 5.0.2 + version: 5.0.2 tinycolor2: specifier: 1.6.0 version: 1.6.0 tsc-alias: - specifier: 1.8.8 - version: 1.8.8 + specifier: 1.8.10 + version: 1.8.10 tsconfig-paths: specifier: 4.2.0 version: 4.2.0 typescript: - specifier: 5.5.2 - version: 5.5.2 + specifier: 5.5.3 + version: 5.5.3 uuid: - specifier: 9.0.1 - version: 9.0.1 + specifier: 10.0.0 + version: 10.0.0 v-code-diff: - specifier: 1.11.0 - version: 1.11.0(vue@3.4.26(typescript@5.5.2)) + specifier: 1.12.0 + version: 1.12.0(vue@3.4.31(typescript@5.5.3)) vite: - specifier: 5.2.11 - version: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) + specifier: 5.3.2 + version: 5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1) vue: - specifier: 3.4.26 - version: 3.4.26(typescript@5.5.2) + specifier: 3.4.31 + version: 3.4.31(typescript@5.5.3) vuedraggable: specifier: next - version: 4.1.0(vue@3.4.26(typescript@5.5.2)) + version: 4.1.0(vue@3.4.31(typescript@5.5.3)) devDependencies: - '@misskey-dev/eslint-plugin': - specifier: 1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0))(eslint@8.57.0) '@misskey-dev/summaly': specifier: 5.1.0 version: 5.1.0 '@storybook/addon-actions': - specifier: 8.0.9 - version: 8.0.9 + specifier: 8.1.11 + version: 8.1.11 '@storybook/addon-essentials': - specifier: 8.0.9 - version: 8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 8.1.11 + version: 8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@storybook/addon-interactions': - specifier: 8.0.9 - version: 8.0.9(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.12.7))(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3)) + specifier: 8.1.11 + version: 8.1.11(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.14.9))(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1)) '@storybook/addon-links': - specifier: 8.0.9 - version: 8.0.9(react@18.3.1) + specifier: 8.1.11 + version: 8.1.11(react@18.3.1) '@storybook/addon-mdx-gfm': - specifier: 8.0.9 - version: 8.0.9 + specifier: 8.1.11 + version: 8.1.11 '@storybook/addon-storysource': - specifier: 8.0.9 - version: 8.0.9 + specifier: 8.1.11 + version: 8.1.11 '@storybook/blocks': - specifier: 8.0.9 - version: 8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 8.1.11 + version: 8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@storybook/components': - specifier: 8.0.9 - version: 8.0.9(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 8.1.11 + version: 8.1.11(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@storybook/core-events': - specifier: 8.0.9 - version: 8.0.9 + specifier: 8.1.11 + version: 8.1.11 '@storybook/manager-api': - specifier: 8.0.9 - version: 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 8.1.11 + version: 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@storybook/preview-api': - specifier: 8.0.9 - version: 8.0.9 + specifier: 8.1.11 + version: 8.1.11 '@storybook/react': - specifier: 8.0.9 - version: 8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.2) + specifier: 8.1.11 + version: 8.1.11(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.3) '@storybook/react-vite': - specifier: 8.0.9 - version: 8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.17.2)(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) + specifier: 8.1.11 + version: 8.1.11(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.18.0)(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1)) '@storybook/test': - specifier: 8.0.9 - version: 8.0.9(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.12.7))(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3)) + specifier: 8.1.11 + version: 8.1.11(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.14.9))(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1)) '@storybook/theming': - specifier: 8.0.9 - version: 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 8.1.11 + version: 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@storybook/types': - specifier: 8.0.9 - version: 8.0.9 + specifier: 8.1.11 + version: 8.1.11 '@storybook/vue3': - specifier: 8.0.9 - version: 8.0.9(encoding@0.1.13)(vue@3.4.26(typescript@5.5.2)) + specifier: 8.1.11 + version: 8.1.11(encoding@0.1.13)(prettier@3.3.2)(vue@3.4.31(typescript@5.5.3)) '@storybook/vue3-vite': - specifier: 8.0.9 - version: 8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.5.2)) + specifier: 8.1.11 + version: 8.1.11(bufferutil@4.0.7)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1))(vue@3.4.31(typescript@5.5.3)) '@testing-library/vue': - specifier: 8.0.3 - version: 8.0.3(@vue/compiler-sfc@3.4.26)(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.5.2)))(vue@3.4.26(typescript@5.5.2)) + specifier: 8.1.0 + version: 8.1.0(@vue/compiler-sfc@3.4.31)(@vue/server-renderer@3.4.29(vue@3.4.31(typescript@5.5.3)))(vue@3.4.31(typescript@5.5.3)) '@types/escape-regexp': specifier: 0.0.3 version: 0.0.3 @@ -933,11 +930,11 @@ importers: specifier: 0.19.6 version: 0.19.6 '@types/micromatch': - specifier: 4.0.7 - version: 4.0.7 + specifier: 4.0.9 + version: 4.0.9 '@types/node': - specifier: 20.12.7 - version: 20.12.7 + specifier: 20.14.9 + version: 20.14.9 '@types/punycode': specifier: 2.1.4 version: 2.1.4 @@ -954,41 +951,38 @@ importers: specifier: 1.4.6 version: 1.4.6 '@types/uuid': - specifier: 9.0.8 - version: 9.0.8 + specifier: 10.0.0 + version: 10.0.0 '@types/ws': specifier: 8.5.10 version: 8.5.10 '@typescript-eslint/eslint-plugin': - specifier: 7.7.1 - version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2) + specifier: 7.15.0 + version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3) '@typescript-eslint/parser': - specifier: 7.7.1 - version: 7.7.1(eslint@8.57.0)(typescript@5.5.2) + specifier: 7.15.0 + version: 7.15.0(eslint@9.6.0)(typescript@5.5.3) '@vitest/coverage-v8': - specifier: 0.34.6 - version: 0.34.6(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3)) + specifier: 1.6.0 + version: 1.6.0(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1)) '@vue/runtime-core': - specifier: 3.4.26 - version: 3.4.26 + specifier: 3.4.31 + version: 3.4.31 acorn: - specifier: 8.11.3 - version: 8.11.3 + specifier: 8.12.0 + version: 8.12.0 cross-env: specifier: 7.0.3 version: 7.0.3 cypress: - specifier: 13.8.1 - version: 13.8.1 - eslint: - specifier: 8.57.0 - version: 8.57.0 + specifier: 13.13.0 + version: 13.13.0 eslint-plugin-import: specifier: 2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0) + version: 2.29.1(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0) eslint-plugin-vue: - specifier: 9.25.0 - version: 9.25.0(eslint@8.57.0) + specifier: 9.26.0 + version: 9.26.0(eslint@9.6.0) fast-glob: specifier: 3.3.2 version: 3.3.2 @@ -999,20 +993,20 @@ importers: specifier: 0.12.2 version: 0.12.2 micromatch: - specifier: 4.0.5 - version: 4.0.5 + specifier: 4.0.7 + version: 4.0.7 msw: - specifier: 2.2.14 - version: 2.2.14(typescript@5.5.2) + specifier: 2.3.1 + version: 2.3.1(typescript@5.5.3) msw-storybook-addon: - specifier: 2.0.1 - version: 2.0.1(msw@2.2.14(typescript@5.5.2)) + specifier: 2.0.2 + version: 2.0.2(msw@2.3.1(typescript@5.5.3)) nodemon: - specifier: 3.1.0 - version: 3.1.0 + specifier: 3.1.4 + version: 3.1.4 prettier: - specifier: 3.2.5 - version: 3.2.5 + specifier: 3.3.2 + version: 3.3.2 react: specifier: 18.3.1 version: 18.3.1 @@ -1023,32 +1017,32 @@ importers: specifier: 3.0.5 version: 3.0.5 start-server-and-test: - specifier: 2.0.3 - version: 2.0.3 + specifier: 2.0.4 + version: 2.0.4 storybook: - specifier: 8.0.9 - version: 8.0.9(@babel/preset-env@7.23.5(@babel/core@7.24.0))(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3) + specifier: 8.1.11 + version: 8.1.11(@babel/preset-env@7.24.7(@babel/core@7.24.7))(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3) storybook-addon-misskey-theme: specifier: github:misskey-dev/storybook-addon-misskey-theme - version: https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/components@8.0.9(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/core-events@8.0.9)(@storybook/manager-api@8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/preview-api@8.0.9)(@storybook/theming@8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/types@8.0.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/components@8.1.11(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/core-events@8.1.11)(@storybook/manager-api@8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/preview-api@8.1.11)(@storybook/theming@8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/types@8.1.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) vite-plugin-turbosnap: specifier: 1.0.3 version: 1.0.3 vitest: - specifier: 0.34.6 - version: 0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3) + specifier: 1.6.0 + version: 1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1) vitest-fetch-mock: specifier: 0.2.2 - version: 0.2.2(encoding@0.1.13)(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3)) + version: 0.2.2(encoding@0.1.13)(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1)) vue-component-type-helpers: - specifier: 2.0.16 - version: 2.0.16 + specifier: 2.0.24 + version: 2.0.24 vue-eslint-parser: - specifier: 9.4.2 - version: 9.4.2(eslint@8.57.0) + specifier: 9.4.3 + version: 9.4.3(eslint@9.6.0) vue-tsc: - specifier: 2.0.16 - version: 2.0.16(typescript@5.5.2) + specifier: 2.0.24 + version: 2.0.24(typescript@5.5.3) packages/misskey-bubble-game: dependencies: @@ -1062,9 +1056,6 @@ importers: specifier: 3.0.5 version: 3.0.5 devDependencies: - '@misskey-dev/eslint-plugin': - specifier: 1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3))(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0))(eslint@8.57.0) '@types/matter-js': specifier: 0.19.6 version: 0.19.6 @@ -1076,16 +1067,13 @@ importers: version: 3.0.8 '@typescript-eslint/eslint-plugin': specifier: 7.1.0 - version: 7.1.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3) + version: 7.1.0(@typescript-eslint/parser@7.1.0(eslint@9.6.0)(typescript@5.3.3))(eslint@9.6.0)(typescript@5.3.3) '@typescript-eslint/parser': specifier: 7.1.0 - version: 7.1.0(eslint@8.57.0)(typescript@5.3.3) + version: 7.1.0(eslint@9.6.0)(typescript@5.3.3) esbuild: specifier: 0.19.11 version: 0.19.11 - eslint: - specifier: 8.57.0 - version: 8.57.0 execa: specifier: 8.0.1 version: 8.0.1 @@ -1109,41 +1097,35 @@ importers: version: 4.4.0 devDependencies: '@microsoft/api-extractor': - specifier: 7.43.1 - version: 7.43.1(@types/node@20.12.7) - '@misskey-dev/eslint-plugin': - specifier: 1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0))(eslint@8.57.0) + specifier: 7.47.0 + version: 7.47.0(@types/node@20.14.9) '@swc/jest': specifier: 0.2.36 - version: 0.2.36(@swc/core@1.4.17) + version: 0.2.36(@swc/core@1.6.6) '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: 20.12.7 - version: 20.12.7 + specifier: 20.14.9 + version: 20.14.9 '@typescript-eslint/eslint-plugin': - specifier: 7.7.1 - version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2) + specifier: 7.15.0 + version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3) '@typescript-eslint/parser': - specifier: 7.7.1 - version: 7.7.1(eslint@8.57.0)(typescript@5.5.2) + specifier: 7.15.0 + version: 7.15.0(eslint@9.6.0)(typescript@5.5.3) esbuild: - specifier: 0.19.11 - version: 0.19.11 - eslint: - specifier: 8.57.0 - version: 8.57.0 + specifier: 0.22.0 + version: 0.22.0 execa: - specifier: 8.0.1 - version: 8.0.1 + specifier: 9.2.0 + version: 9.2.0 glob: - specifier: 10.3.12 - version: 10.3.12 + specifier: 10.4.2 + version: 10.4.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.12.7) + version: 29.7.0(@types/node@20.14.9) jest-fetch-mock: specifier: 3.0.3 version: 3.0.3(encoding@0.1.13) @@ -1157,20 +1139,17 @@ importers: specifier: 2.0.0 version: 2.0.0 nodemon: - specifier: 3.1.0 - version: 3.1.0 + specifier: 3.1.4 + version: 3.1.4 tsd: - specifier: 0.30.7 - version: 0.30.7 + specifier: 0.31.1 + version: 0.31.1 typescript: - specifier: 5.5.2 - version: 5.5.2 + specifier: 5.5.3 + version: 5.5.3 packages/misskey-js/generator: devDependencies: - '@misskey-dev/eslint-plugin': - specifier: ^1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint@8.53.0)(typescript@5.3.3))(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint@8.53.0))(eslint@8.53.0) '@readme/openapi-parser': specifier: 2.5.0 version: 2.5.0(openapi-types@12.1.3) @@ -1179,13 +1158,10 @@ importers: version: 20.9.1 '@typescript-eslint/eslint-plugin': specifier: 6.11.0 - version: 6.11.0(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint@8.53.0)(typescript@5.3.3) + version: 6.11.0(@typescript-eslint/parser@6.11.0(eslint@9.6.0)(typescript@5.3.3))(eslint@9.6.0)(typescript@5.3.3) '@typescript-eslint/parser': specifier: 6.11.0 - version: 6.11.0(eslint@8.53.0)(typescript@5.3.3) - eslint: - specifier: 8.53.0 - version: 8.53.0 + version: 6.11.0(eslint@9.6.0)(typescript@5.3.3) openapi-types: specifier: 12.1.3 version: 12.1.3 @@ -1208,24 +1184,18 @@ importers: specifier: 1.2.2 version: 1.2.2 devDependencies: - '@misskey-dev/eslint-plugin': - specifier: 1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3))(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0))(eslint@8.57.0) '@types/node': specifier: 20.11.5 version: 20.11.5 '@typescript-eslint/eslint-plugin': specifier: 7.1.0 - version: 7.1.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3) + version: 7.1.0(@typescript-eslint/parser@7.1.0(eslint@9.6.0)(typescript@5.3.3))(eslint@9.6.0)(typescript@5.3.3) '@typescript-eslint/parser': specifier: 7.1.0 - version: 7.1.0(eslint@8.57.0)(typescript@5.3.3) + version: 7.1.0(eslint@9.6.0)(typescript@5.3.3) esbuild: specifier: 0.19.11 version: 0.19.11 - eslint: - specifier: 8.57.0 - version: 8.57.0 execa: specifier: 8.0.1 version: 8.0.1 @@ -1242,8 +1212,8 @@ importers: packages/sw: dependencies: esbuild: - specifier: 0.20.2 - version: 0.20.2 + specifier: 0.22.0 + version: 0.22.0 idb-keyval: specifier: 6.2.1 version: 6.2.1 @@ -1251,27 +1221,21 @@ importers: specifier: workspace:* version: link:../misskey-js devDependencies: - '@misskey-dev/eslint-plugin': - specifier: 1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0))(eslint@8.57.0) '@typescript-eslint/parser': - specifier: 7.7.1 - version: 7.7.1(eslint@8.57.0)(typescript@5.5.2) + specifier: 7.15.0 + version: 7.15.0(eslint@9.6.0)(typescript@5.5.3) '@typescript/lib-webworker': specifier: npm:@types/serviceworker@0.0.67 version: '@types/serviceworker@0.0.67' - eslint: - specifier: 8.57.0 - version: 8.57.0 eslint-plugin-import: specifier: 2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0) + version: 2.29.1(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0) nodemon: - specifier: 3.1.0 - version: 3.1.0 + specifier: 3.1.4 + version: 3.1.4 typescript: - specifier: 5.5.2 - version: 5.5.2 + specifier: 5.5.3 + version: 5.5.3 packages: @@ -1302,221 +1266,239 @@ packages: resolution: {integrity: sha512-Xk1sIhyNC/esHGGVjL/niHLowM0csl/kFO5uawBy4IrWwy0o1G8LGt3jP6nmWGz+USxeeqbihAmp/oVZju6wug==} hasBin: true - '@aws-crypto/crc32@3.0.0': - resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==} + '@aws-crypto/crc32@5.2.0': + resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} + engines: {node: '>=16.0.0'} - '@aws-crypto/crc32c@3.0.0': - resolution: {integrity: sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==} + '@aws-crypto/crc32c@5.2.0': + resolution: {integrity: sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==} - '@aws-crypto/ie11-detection@3.0.0': - resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} + '@aws-crypto/sha1-browser@5.2.0': + resolution: {integrity: sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==} - '@aws-crypto/sha1-browser@3.0.0': - resolution: {integrity: sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==} + '@aws-crypto/sha256-browser@5.2.0': + resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} - '@aws-crypto/sha256-browser@3.0.0': - resolution: {integrity: sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==} + '@aws-crypto/sha256-js@5.2.0': + resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} + engines: {node: '>=16.0.0'} - '@aws-crypto/sha256-js@3.0.0': - resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} + '@aws-crypto/supports-web-crypto@5.2.0': + resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} - '@aws-crypto/supports-web-crypto@3.0.0': - resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} + '@aws-crypto/util@5.2.0': + resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-crypto/util@3.0.0': - resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} + '@aws-sdk/client-s3@3.600.0': + resolution: {integrity: sha512-iYoKbJTputbf+ubkX6gSK/y/4uJEBRaXZ18jykLdBQ8UJuGrk2gqvV8h7OlGAhToCeysmmMqM0vDWyLt6lP8nw==} + engines: {node: '>=16.0.0'} - '@aws-sdk/client-s3@3.412.0': - resolution: {integrity: sha512-sNrlx9sSBmFUCqMgTznwk9Fee3PJat0nZ3RIDR5Crhsld/eexxrqb6TYKsxzFfBfXTL/oPh+/S5driRV2xsB8A==} - engines: {node: '>=14.0.0'} + '@aws-sdk/client-sso-oidc@3.600.0': + resolution: {integrity: sha512-7+I8RWURGfzvChyNQSyj5/tKrqRbzRl7H+BnTOf/4Vsw1nFOi5ROhlhD4X/Y0QCTacxnaoNcIrqnY7uGGvVRzw==} + engines: {node: '>=16.0.0'} - '@aws-sdk/client-sso@3.410.0': - resolution: {integrity: sha512-MC9GrgwtlOuSL2WS3DRM3dQ/5y+49KSMMJRH6JiEcU5vE0dX/OtEcX+VfEwpi73x5pSfIjm7xnzjzOFx+sQBIg==} - engines: {node: '>=14.0.0'} + '@aws-sdk/client-sso@3.598.0': + resolution: {integrity: sha512-nOI5lqPYa+YZlrrzwAJywJSw3MKVjvu6Ge2fCqQUNYMfxFB0NAaDFnl0EPjXi+sEbtCuz/uWE77poHbqiZ+7Iw==} + engines: {node: '>=16.0.0'} - '@aws-sdk/client-sts@3.410.0': - resolution: {integrity: sha512-e6VMrBJtnTxxUXwDmkADGIvyppmDMFf4+cGGA68tVCUm1cFNlCI6M/67bVSIPN/WVKAAfhEL5O2vVXCM7aatYg==} - engines: {node: '>=14.0.0'} + '@aws-sdk/client-sts@3.600.0': + resolution: {integrity: sha512-KQG97B7LvTtTiGmjlrG1LRAY8wUvCQzrmZVV5bjrJ/1oXAU7DITYwVbSJeX9NWg6hDuSk0VE3MFwIXS2SvfLIA==} + engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-env@3.410.0': - resolution: {integrity: sha512-c7TB9LbN0PkFOsXI0lcRJnqPNOmc4VBvrHf8jP/BkTDg4YUoKQKOFd4d0SqzODmlZiAyoMQVZTR4ISZo95Zj4Q==} - engines: {node: '>=14.0.0'} + '@aws-sdk/core@3.598.0': + resolution: {integrity: sha512-HaSjt7puO5Cc7cOlrXFCW0rtA0BM9lvzjl56x0A20Pt+0wxXGeTOZZOkXQIepbrFkV2e/HYukuT9e99vXDm59g==} + engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-ini@3.410.0': - resolution: {integrity: sha512-D8rcr5bRCFD0f42MPQ7K6TWZq5d3pfqrKINL1/bpfkK5BJbvq1BGYmR88UC6CLpTRtZ1LHY2HgYG0fp/2zjjww==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-env@3.598.0': + resolution: {integrity: sha512-vi1khgn7yXzLCcgSIzQrrtd2ilUM0dWodxj3PQ6BLfP0O+q1imO3hG1nq7DVyJtq7rFHs6+9N8G4mYvTkxby2w==} + engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-node@3.410.0': - resolution: {integrity: sha512-0wmVm33T/j1FS7MZ/j+WsPlgSc0YnCXnpbWSov1Mn6R86SHI2b2JhdIPRRE4XbGfyW2QGNUl2CwoZVaqhXeF5g==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-http@3.598.0': + resolution: {integrity: sha512-N7cIafi4HVlQvEgvZSo1G4T9qb/JMLGMdBsDCT5XkeJrF0aptQWzTFH0jIdZcLrMYvzPcuEyO3yCBe6cy/ba0g==} + engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-process@3.410.0': - resolution: {integrity: sha512-BMju1hlDCDNkkSZpKF5SQ8G0WCLRj6/Jvw9QmudLHJuVwYJXEW1r2AsVMg98OZ3hB9G+MAvHruHZIbMiNmUMXQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-ini@3.598.0': + resolution: {integrity: sha512-/ppcIVUbRwDIwJDoYfp90X3+AuJo2mvE52Y1t2VSrvUovYn6N4v95/vXj6LS8CNDhz2jvEJYmu+0cTMHdhI6eA==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sts': ^3.598.0 - '@aws-sdk/credential-provider-sso@3.410.0': - resolution: {integrity: sha512-zEaoY/sY+KYTlQUkp9dvveAHf175b8RIt0DsQkDrRPtrg/RBHR00r5rFvz9+nrwsR8546RaBU7h/zzTaQGhmcA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-node@3.600.0': + resolution: {integrity: sha512-1pC7MPMYD45J7yFjA90SxpR0yaSvy+yZiq23aXhAPZLYgJBAxHLu0s0mDCk/piWGPh8+UGur5K0bVdx4B1D5hw==} + engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-web-identity@3.410.0': - resolution: {integrity: sha512-cE0l8LmEHdWbDkdPNgrfdYSgp4/cIVXrjUKI1QCATA729CrHZ/OQjB/maOBOrMHO9YTiggko887NkslVvwVB7w==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-process@3.598.0': + resolution: {integrity: sha512-rM707XbLW8huMk722AgjVyxu2tMZee++fNA8TJVNgs1Ma02Wx6bBrfIvlyK0rCcIRb0WdQYP6fe3Xhiu4e8IBA==} + engines: {node: '>=16.0.0'} - '@aws-sdk/lib-storage@3.412.0': - resolution: {integrity: sha512-uAdVtNuip06rJOs28zVrYXLNeHfKraxvJRTzTA+DW1dXkzh70GTKqDKHWH9IJkW/xMTE6wGSM+fDs8jsMOn/yA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-sso@3.598.0': + resolution: {integrity: sha512-5InwUmrAuqQdOOgxTccRayMMkSmekdLk6s+az9tmikq0QFAHUCtofI+/fllMXSR9iL6JbGYi1940+EUmS4pHJA==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.598.0': + resolution: {integrity: sha512-GV5GdiMbz5Tz9JO4NJtRoFXjW0GPEujA0j+5J/B723rTN+REHthJu48HdBKouHGhdzkDWkkh1bu52V02Wprw8w==} + engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-s3': ^3.0.0 + '@aws-sdk/client-sts': ^3.598.0 - '@aws-sdk/middleware-bucket-endpoint@3.410.0': - resolution: {integrity: sha512-pUGrpFgCKf9fDHu01JJhhw+MUImheS0HFlZwNG37OMubkxUAbCdmYGewGxfTCUvWyZJtx9bVjrSu6gG7w+RARg==} - engines: {node: '>=14.0.0'} + '@aws-sdk/lib-storage@3.600.0': + resolution: {integrity: sha512-jjgGMmFykXBAs8YO3ghgnVSjM/uf99jvVQqKJfDjwXUCLPrsZqk14v2WcDCWAXzeAroDvIOVQO1V/RR8fK18Pw==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-s3': ^3.600.0 - '@aws-sdk/middleware-expect-continue@3.410.0': - resolution: {integrity: sha512-e5YqGCNmW99GZjEPPujJ02RlEZql19U40oORysBhVF7mKz8BBvF3s8l37tvu37oxebDEkh1u/2cm2+ggOXxLjQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-bucket-endpoint@3.598.0': + resolution: {integrity: sha512-PM7BcFfGUSkmkT6+LU9TyJiB4S8yI7dfuKQDwK5ZR3P7MKaK4Uj4yyDiv0oe5xvkF6+O2+rShj+eh8YuWkOZ/Q==} + engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.410.0': - resolution: {integrity: sha512-IK7KlvEKtrQVBfmAp/MmGd0wbWLuN2GZwwfAmsU0qFb0f5vOVUbKDsu6tudtDKCBG9uXyTEsx3/QGvoK2zDy+g==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-expect-continue@3.598.0': + resolution: {integrity: sha512-ZuHW18kaeHR8TQyhEOYMr8VwiIh0bMvF7J1OTqXHxDteQIavJWA3CbfZ9sgS4XGtrBZDyHJhjZKeCfLhN2rq3w==} + engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-host-header@3.410.0': - resolution: {integrity: sha512-ED/OVcyITln5rrxnajZP+V0PN1nug+gSDHJDqdDo/oLy7eiDr/ZWn3nlWW7WcMplQ1/Jnb+hK0UetBp/25XooA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-flexible-checksums@3.598.0': + resolution: {integrity: sha512-xukAzds0GQXvMEY9G6qt+CzwVzTx8NyKKh04O2Q+nOch6QQ8Rs+2kTRy3Z4wQmXq2pK9hlOWb5nXA7HWpmz6Ng==} + engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-location-constraint@3.410.0': - resolution: {integrity: sha512-jAftSpOpw/5AdpOJ/cGiXCb+Vv22KXR5QZmxmllUDsnlm18672tpRaI2plmu/1d98CVvqhY61eSklFMrIf2c4w==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-host-header@3.598.0': + resolution: {integrity: sha512-WiaG059YBQwQraNejLIi0gMNkX7dfPZ8hDIhvMr5aVPRbaHH8AYF3iNSsXYCHvA2Cfa1O9haYXsuMF9flXnCmA==} + engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-logger@3.410.0': - resolution: {integrity: sha512-YtmKYCVtBfScq3/UFJk+aSZOktKJBNZL9DaSc2aPcy/goCVsYDOkGwtHk0jIkC1JRSNCkVTqL7ya60sSr8zaQQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-location-constraint@3.598.0': + resolution: {integrity: sha512-8oybQxN3F1ISOMULk7JKJz5DuAm5hCUcxMW9noWShbxTJuStNvuHf/WLUzXrf8oSITyYzIHPtf8VPlKR7I3orQ==} + engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-recursion-detection@3.410.0': - resolution: {integrity: sha512-KWaes5FLzRqj28vaIEE4Bimpga2E596WdPF2HaH6zsVMJddoRDsc3ZX9ZhLOGrXzIO1RqBd0QxbLrM0S/B2aOQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-logger@3.598.0': + resolution: {integrity: sha512-bxBjf/VYiu3zfu8SYM2S9dQQc3tz5uBAOcPz/Bt8DyyK3GgOpjhschH/2XuUErsoUO1gDJqZSdGOmuHGZQn00Q==} + engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-sdk-s3@3.410.0': - resolution: {integrity: sha512-K2sG2V1ZkezYMCIy3uMt0MwtflcfIwLptwm0iFLaYitiINZQ1tcslk9ggAjyTHg0rslDSI4/zjkhy8VHFOV7HA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-recursion-detection@3.598.0': + resolution: {integrity: sha512-vjT9BeFY9FeN0f8hm2l6F53tI0N5bUq6RcDkQXKNabXBnQxKptJRad6oP2X5y3FoVfBLOuDkQgiC2940GIPxtQ==} + engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-sdk-sts@3.410.0': - resolution: {integrity: sha512-YfBpctDocRR4CcROoDueJA7D+aMLBV8nTFfmVNdLLLgyuLZ/AUR11VQSu1lf9gQZKl8IpKE/BLf2fRE/qV1ZuA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-sdk-s3@3.598.0': + resolution: {integrity: sha512-5AGtLAh9wyK6ANPYfaKTqJY1IFJyePIxsEbxa7zS6REheAqyVmgJFaGu3oQ5XlxfGr5Uq59tFTRkyx26G1HkHA==} + engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-signing@3.410.0': - resolution: {integrity: sha512-KBAZ/eoAJUSJv5us2HsKwK2OszG2s9FEyKpEhgnHLcbbKzW873zHBH5GcOGEQu4AWArTy2ndzJu3FF+9/J9hJQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-signing@3.598.0': + resolution: {integrity: sha512-XKb05DYx/aBPqz6iCapsCbIl8aD8EihTuPCs51p75QsVfbQoVr4TlFfIl5AooMSITzojdAQqxt021YtvxjtxIQ==} + engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-ssec@3.410.0': - resolution: {integrity: sha512-DNsjVTXoxIh+PuW9o45CFaMiconbuZRm19MC3NA1yNCaCj3ZxD5OdXAutq6UjQdrx8UG4EjUlCJEEvBKmboITw==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-ssec@3.598.0': + resolution: {integrity: sha512-f0p2xP8IC1uJ5e/tND1l81QxRtRFywEdnbtKCE0H6RSn4UIt2W3Dohe1qQDbnh27okF0PkNW6BJGdSAz3p7qbA==} + engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-user-agent@3.410.0': - resolution: {integrity: sha512-ZayDtLfvCZUohSxQc/49BfoU/y6bDHLfLdyyUJbJ54Sv8zQcrmdyKvCBFUZwE6tHQgAmv9/ZT18xECMl+xiONA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-user-agent@3.598.0': + resolution: {integrity: sha512-4tjESlHG5B5MdjUaLK7tQs/miUtHbb6deauQx8ryqSBYOhfHVgb1ZnzvQR0bTrhpqUg0WlybSkDaZAICf9xctg==} + engines: {node: '>=16.0.0'} - '@aws-sdk/signature-v4-multi-region@3.412.0': - resolution: {integrity: sha512-ijxOeYpNDuk2T940S9HYcZ1C+wTP9vqp1Cw37zw9whVY2mKV3Vr7i+44D4FQ5HhWULgdwhjD7IctbNxPIPzUZQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/region-config-resolver@3.598.0': + resolution: {integrity: sha512-oYXhmTokSav4ytmWleCr3rs/1nyvZW/S0tdi6X7u+dLNL5Jee+uMxWGzgOrWK6wrQOzucLVjS4E/wA11Kv2GTw==} + engines: {node: '>=16.0.0'} - '@aws-sdk/token-providers@3.410.0': - resolution: {integrity: sha512-d5Nc0xydkH/X0LA1HDyhGY5sEv4LuADFk+QpDtT8ogLilcre+b1jpdY8Sih/gd1KoGS1H+d1tz2hSGwUHAbUbw==} - engines: {node: '>=14.0.0'} + '@aws-sdk/signature-v4-multi-region@3.598.0': + resolution: {integrity: sha512-1r/EyTrO1gSa1FirnR8V7mabr7gk+l+HkyTI0fcTSr8ucB7gmYyW6WjkY8JCz13VYHFK62usCEDS7yoJoJOzTA==} + engines: {node: '>=16.0.0'} - '@aws-sdk/types@3.410.0': - resolution: {integrity: sha512-D7iaUCszv/v04NDaZUmCmekamy6VD/lKozm/3gS9+dkfU6cC2CsNoUfPV8BlV6dPdw0oWgF91am3I1stdvfVrQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/token-providers@3.598.0': + resolution: {integrity: sha512-TKY1EVdHVBnZqpyxyTHdpZpa1tUpb6nxVeRNn1zWG8QB5MvH4ALLd/jR+gtmWDNQbIG4cVuBOZFVL8hIYicKTA==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sso-oidc': ^3.598.0 - '@aws-sdk/types@3.413.0': - resolution: {integrity: sha512-j1xib0f/TazIFc5ySIKOlT1ujntRbaoG4LJFeEezz4ji03/wSJMI8Vi4KjzpBp8J1tTu0oRDnsxRIGixsUBeYQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/types@3.598.0': + resolution: {integrity: sha512-742uRl6z7u0LFmZwDrFP6r1wlZcgVPw+/TilluDJmCAR8BgRw3IR+743kUXKBGd8QZDRW2n6v/PYsi/AWCDDMQ==} + engines: {node: '>=16.0.0'} - '@aws-sdk/util-arn-parser@3.310.0': - resolution: {integrity: sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/util-arn-parser@3.568.0': + resolution: {integrity: sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==} + engines: {node: '>=16.0.0'} - '@aws-sdk/util-endpoints@3.410.0': - resolution: {integrity: sha512-iNiqJyC7N3+8zFwnXUqcWSxrZecVZLToo1iTQQdeYL2af1IcOtRgb7n8jpAI/hmXhBSx2+3RI+Y7pxyFo1vu+w==} - engines: {node: '>=14.0.0'} + '@aws-sdk/util-endpoints@3.598.0': + resolution: {integrity: sha512-Qo9UoiVVZxcOEdiOMZg3xb1mzkTxrhd4qSlg5QQrfWPJVx/QOg+Iy0NtGxPtHtVZNHZxohYwDwV/tfsnDSE2gQ==} + engines: {node: '>=16.0.0'} '@aws-sdk/util-locate-window@3.208.0': resolution: {integrity: sha512-iua1A2+P7JJEDHVgvXrRJSvsnzG7stYSGQnBVphIUlemwl6nN5D+QrgbjECtrbxRz8asYFHSzhdhECqN+tFiBg==} engines: {node: '>=14.0.0'} - '@aws-sdk/util-user-agent-browser@3.410.0': - resolution: {integrity: sha512-i1G/XGpXGMRT2zEiAhi1xucJsfCWk8nNYjk/LbC0sA+7B9Huri96YAzVib12wkHPsJQvZxZC6CpQDIHWm4lXMA==} + '@aws-sdk/util-user-agent-browser@3.598.0': + resolution: {integrity: sha512-36Sxo6F+ykElaL1mWzWjlg+1epMpSe8obwhCN1yGE7Js9ywy5U6k6l+A3q3YM9YRbm740sNxncbwLklMvuhTKw==} - '@aws-sdk/util-user-agent-node@3.410.0': - resolution: {integrity: sha512-bK70t1jHRl8HrJXd4hEIwc5PBZ7U0w+81AKFnanIVKZwZedd6nLibUXDTK14z/Jp2GFcBqd4zkt2YLGkRt/U4A==} - engines: {node: '>=14.0.0'} + '@aws-sdk/util-user-agent-node@3.598.0': + resolution: {integrity: sha512-oyWGcOlfTdzkC6SVplyr0AGh54IMrDxbhg5RxJ5P+V4BKfcDoDcZV9xenUk9NsOi9MuUjxMumb9UJGkDhM1m0A==} + engines: {node: '>=16.0.0'} peerDependencies: aws-crt: '>=1.0.0' peerDependenciesMeta: aws-crt: optional: true - '@aws-sdk/util-utf8-browser@3.259.0': - resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} - - '@aws-sdk/xml-builder@3.310.0': - resolution: {integrity: sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw==} - engines: {node: '>=14.0.0'} + '@aws-sdk/xml-builder@3.598.0': + resolution: {integrity: sha512-ZIa2RK7CHFTZ4gwK77WRtsZ6vF7xwRXxJ8KQIxK2duhoTVcn0xYxpFLdW9WZZZvdP9GIF3Loqvf8DRdeU5Jc7Q==} + engines: {node: '>=16.0.0'} '@babel/code-frame@7.23.5': resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.23.5': resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.24.7': + resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==} + engines: {node: '>=6.9.0'} + '@babel/core@7.23.5': resolution: {integrity: sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==} engines: {node: '>=6.9.0'} - '@babel/core@7.24.0': - resolution: {integrity: sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==} + '@babel/core@7.24.7': + resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==} engines: {node: '>=6.9.0'} '@babel/generator@7.23.5': resolution: {integrity: sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.23.6': - resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + '@babel/generator@7.24.7': + resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.22.5': - resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + '@babel/helper-annotate-as-pure@7.24.7': + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} engines: {node: '>=6.9.0'} - '@babel/helper-builder-binary-assignment-operator-visitor@7.22.15': - resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} + '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': + resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.22.15': resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.23.6': - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + '@babel/helper-compilation-targets@7.24.7': + resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.23.5': - resolution: {integrity: sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==} + '@babel/helper-create-class-features-plugin@7.24.7': + resolution: {integrity: sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-create-regexp-features-plugin@7.22.15': - resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} + '@babel/helper-create-regexp-features-plugin@7.24.7': + resolution: {integrity: sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.4.3': - resolution: {integrity: sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==} + '@babel/helper-define-polyfill-provider@0.6.2': + resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -1524,44 +1506,70 @@ packages: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} + '@babel/helper-environment-visitor@7.24.7': + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-function-name@7.23.0': resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} + '@babel/helper-function-name@7.24.7': + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} + engines: {node: '>=6.9.0'} + '@babel/helper-hoist-variables@7.22.5': resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.23.0': - resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} + '@babel/helper-hoist-variables@7.24.7': + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.24.7': + resolution: {integrity: sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==} engines: {node: '>=6.9.0'} '@babel/helper-module-imports@7.22.15': resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.23.3': resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.22.5': - resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + '@babel/helper-module-transforms@7.24.7': + resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.24.7': + resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} engines: {node: '>=6.9.0'} '@babel/helper-plugin-utils@7.22.5': resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} engines: {node: '>=6.9.0'} - '@babel/helper-remap-async-to-generator@7.22.20': - resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} + '@babel/helper-plugin-utils@7.24.7': + resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.24.7': + resolution: {integrity: sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.22.20': - resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} + '@babel/helper-replace-supers@7.24.7': + resolution: {integrity: sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1570,71 +1578,101 @@ packages: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': - resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} engines: {node: '>=6.9.0'} '@babel/helper-split-export-declaration@7.22.6': resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.23.4': resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.24.7': + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.22.20': resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.23.5': resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.22.20': - resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==} + '@babel/helper-validator-option@7.24.7': + resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.24.7': + resolution: {integrity: sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==} engines: {node: '>=6.9.0'} '@babel/helpers@7.23.5': resolution: {integrity: sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.24.0': - resolution: {integrity: sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==} + '@babel/helpers@7.24.7': + resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==} engines: {node: '>=6.9.0'} '@babel/highlight@7.23.4': resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.23.9': resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.24.0': - resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==} + '@babel/parser@7.24.5': + resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.24.5': - resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} + '@babel/parser@7.24.7': + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3': - resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7': + resolution: {integrity: sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.7': + resolution: {integrity: sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3': - resolution: {integrity: sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==} + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7': + resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.3': - resolution: {integrity: sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.7': + resolution: {integrity: sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1682,14 +1720,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-assertions@7.23.3': - resolution: {integrity: sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==} + '@babel/plugin-syntax-import-assertions@7.24.7': + resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.23.3': - resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==} + '@babel/plugin-syntax-import-attributes@7.24.7': + resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1764,92 +1802,92 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-arrow-functions@7.23.3': - resolution: {integrity: sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==} + '@babel/plugin-transform-arrow-functions@7.24.7': + resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.23.4': - resolution: {integrity: sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==} + '@babel/plugin-transform-async-generator-functions@7.24.7': + resolution: {integrity: sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.23.3': - resolution: {integrity: sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==} + '@babel/plugin-transform-async-to-generator@7.24.7': + resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.23.3': - resolution: {integrity: sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==} + '@babel/plugin-transform-block-scoped-functions@7.24.7': + resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.23.4': - resolution: {integrity: sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==} + '@babel/plugin-transform-block-scoping@7.24.7': + resolution: {integrity: sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.23.3': - resolution: {integrity: sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==} + '@babel/plugin-transform-class-properties@7.24.7': + resolution: {integrity: sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.23.4': - resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==} + '@babel/plugin-transform-class-static-block@7.24.7': + resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.23.5': - resolution: {integrity: sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==} + '@babel/plugin-transform-classes@7.24.7': + resolution: {integrity: sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.23.3': - resolution: {integrity: sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==} + '@babel/plugin-transform-computed-properties@7.24.7': + resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.23.3': - resolution: {integrity: sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==} + '@babel/plugin-transform-destructuring@7.24.7': + resolution: {integrity: sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.23.3': - resolution: {integrity: sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==} + '@babel/plugin-transform-dotall-regex@7.24.7': + resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-keys@7.23.3': - resolution: {integrity: sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==} + '@babel/plugin-transform-duplicate-keys@7.24.7': + resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dynamic-import@7.23.4': - resolution: {integrity: sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==} + '@babel/plugin-transform-dynamic-import@7.24.7': + resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.23.3': - resolution: {integrity: sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==} + '@babel/plugin-transform-exponentiation-operator@7.24.7': + resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-export-namespace-from@7.23.4': - resolution: {integrity: sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==} + '@babel/plugin-transform-export-namespace-from@7.24.7': + resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1860,176 +1898,176 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-for-of@7.23.3': - resolution: {integrity: sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==} + '@babel/plugin-transform-for-of@7.24.7': + resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-function-name@7.23.3': - resolution: {integrity: sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==} + '@babel/plugin-transform-function-name@7.24.7': + resolution: {integrity: sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-json-strings@7.23.4': - resolution: {integrity: sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==} + '@babel/plugin-transform-json-strings@7.24.7': + resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-literals@7.23.3': - resolution: {integrity: sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==} + '@babel/plugin-transform-literals@7.24.7': + resolution: {integrity: sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-logical-assignment-operators@7.23.4': - resolution: {integrity: sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==} + '@babel/plugin-transform-logical-assignment-operators@7.24.7': + resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-member-expression-literals@7.23.3': - resolution: {integrity: sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==} + '@babel/plugin-transform-member-expression-literals@7.24.7': + resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-amd@7.23.3': - resolution: {integrity: sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==} + '@babel/plugin-transform-modules-amd@7.24.7': + resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.23.3': - resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} + '@babel/plugin-transform-modules-commonjs@7.24.7': + resolution: {integrity: sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.23.3': - resolution: {integrity: sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==} + '@babel/plugin-transform-modules-systemjs@7.24.7': + resolution: {integrity: sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-umd@7.23.3': - resolution: {integrity: sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==} + '@babel/plugin-transform-modules-umd@7.24.7': + resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.22.5': - resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} + '@babel/plugin-transform-named-capturing-groups-regex@7.24.7': + resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-new-target@7.23.3': - resolution: {integrity: sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==} + '@babel/plugin-transform-new-target@7.24.7': + resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.23.4': - resolution: {integrity: sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==} + '@babel/plugin-transform-nullish-coalescing-operator@7.24.7': + resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.23.4': - resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==} + '@babel/plugin-transform-numeric-separator@7.24.7': + resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.23.4': - resolution: {integrity: sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==} + '@babel/plugin-transform-object-rest-spread@7.24.7': + resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-super@7.23.3': - resolution: {integrity: sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==} + '@babel/plugin-transform-object-super@7.24.7': + resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-catch-binding@7.23.4': - resolution: {integrity: sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==} + '@babel/plugin-transform-optional-catch-binding@7.24.7': + resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.23.4': - resolution: {integrity: sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==} + '@babel/plugin-transform-optional-chaining@7.24.7': + resolution: {integrity: sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.23.3': - resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==} + '@babel/plugin-transform-parameters@7.24.7': + resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-methods@7.23.3': - resolution: {integrity: sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==} + '@babel/plugin-transform-private-methods@7.24.7': + resolution: {integrity: sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.23.4': - resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==} + '@babel/plugin-transform-private-property-in-object@7.24.7': + resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-property-literals@7.23.3': - resolution: {integrity: sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==} + '@babel/plugin-transform-property-literals@7.24.7': + resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.23.3': - resolution: {integrity: sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==} + '@babel/plugin-transform-regenerator@7.24.7': + resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-reserved-words@7.23.3': - resolution: {integrity: sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==} + '@babel/plugin-transform-reserved-words@7.24.7': + resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-shorthand-properties@7.23.3': - resolution: {integrity: sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==} + '@babel/plugin-transform-shorthand-properties@7.24.7': + resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.23.3': - resolution: {integrity: sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==} + '@babel/plugin-transform-spread@7.24.7': + resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-sticky-regex@7.23.3': - resolution: {integrity: sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==} + '@babel/plugin-transform-sticky-regex@7.24.7': + resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-template-literals@7.23.3': - resolution: {integrity: sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==} + '@babel/plugin-transform-template-literals@7.24.7': + resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typeof-symbol@7.23.3': - resolution: {integrity: sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==} + '@babel/plugin-transform-typeof-symbol@7.24.7': + resolution: {integrity: sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2040,32 +2078,32 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-escapes@7.23.3': - resolution: {integrity: sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==} + '@babel/plugin-transform-unicode-escapes@7.24.7': + resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-property-regex@7.23.3': - resolution: {integrity: sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==} + '@babel/plugin-transform-unicode-property-regex@7.24.7': + resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-regex@7.23.3': - resolution: {integrity: sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==} + '@babel/plugin-transform-unicode-regex@7.24.7': + resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-sets-regex@7.23.3': - resolution: {integrity: sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==} + '@babel/plugin-transform-unicode-sets-regex@7.24.7': + resolution: {integrity: sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.23.5': - resolution: {integrity: sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==} + '@babel/preset-env@7.24.7': + resolution: {integrity: sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2108,12 +2146,16 @@ packages: resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} engines: {node: '>=6.9.0'} + '@babel/template@7.24.7': + resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.23.5': resolution: {integrity: sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.24.0': - resolution: {integrity: sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==} + '@babel/traverse@7.24.7': + resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} engines: {node: '>=6.9.0'} '@babel/types@7.23.5': @@ -2124,22 +2166,26 @@ packages: resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} engines: {node: '>=6.9.0'} + '@babel/types@7.24.7': + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + engines: {node: '>=6.9.0'} + '@base2/pretty-print-object@1.0.1': resolution: {integrity: sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==} '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@bull-board/api@5.17.0': - resolution: {integrity: sha512-qU+AiZIaYa//rkt1x7jDowtYa8u7/dLsDfEWgenZMkgvUszZ1kxJszdCtGapsDTVyPmnXgTRxpOWcR6sAYwSNQ==} + '@bull-board/api@5.20.5': + resolution: {integrity: sha512-YI95JK5A4/K4KB5VWbQn/CYNB+AO5cZ/BnZ77LxAhsaJ3ssHBN3Au0n3Z4wD7O+78+W3ON9uqGjKnHV6rXBGcQ==} peerDependencies: - '@bull-board/ui': 5.17.0 + '@bull-board/ui': 5.20.5 - '@bull-board/fastify@5.17.0': - resolution: {integrity: sha512-73YrPc7ERTWSOQRgBP6a7BPscWfcHd8U+Zq0auMdL/KkjPhG9GxapbfnovGZDDahJL/p/4YQb6ULu03zdtOrEA==} + '@bull-board/fastify@5.20.5': + resolution: {integrity: sha512-tdMR97xbzEzBbMJiJQreJHGdhfOocQn61K/WqM9I038Dk1dBHM5phQJxRJhspvwEJV4jwAayNOZbzuETI7QKwA==} - '@bull-board/ui@5.17.0': - resolution: {integrity: sha512-Vj+yWPjrjx3Iqh2N/ZBDhK2d2yJD44dfvIxm+SnXQb4ne312j117TpViInceysxGtbbAOlAW6hq6JvsDoRl7KQ==} + '@bull-board/ui@5.20.5': + resolution: {integrity: sha512-RV9VlW4qVL1A0Dewpsor4z7ZL9D56OW9LcRYjvXrIU5FSzvTvYKofmrUYoVrNQDs6jGMwJic+dMiW9K8GUU15A==} '@bundled-es-modules/cookie@2.0.0': resolution: {integrity: sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==} @@ -2219,12 +2265,18 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.20.2': - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.22.0': + resolution: {integrity: sha512-uvQR2crZ/zgzSHDvdygHyNI+ze9zwS8mqz0YtGXotSqvEE0UkYE9s+FZKQNTt1VtT719mfP3vHrUdCpxBNQZhQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.18.20': resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -2237,12 +2289,18 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.20.2': - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.22.0': + resolution: {integrity: sha512-UKhPb3o2gAB/bfXcl58ZXTn1q2oVu1rEu/bKrCtmm+Nj5MKUbrOwR5WAixE2v+lk0amWuwPvhnPpBRLIGiq7ig==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.18.20': resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -2255,12 +2313,18 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.20.2': - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.22.0': + resolution: {integrity: sha512-PBnyP+r8vJE4ifxsWys9l+Mc2UY/yYZOpX82eoyGISXXb3dRr0M21v+s4fgRKWMFPMSf/iyowqPW/u7ScSUkjQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -2273,12 +2337,18 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.20.2': - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.22.0': + resolution: {integrity: sha512-IjTYtvIrjhR41Ijy2dDPgYjQHWG/x/A4KXYbs1fiU3efpRdoxMChK3oEZV6GPzVEzJqxFgcuBaiX1kwEvWUxSw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -2291,12 +2361,18 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.20.2': - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.22.0': + resolution: {integrity: sha512-mqt+Go4y9wRvEz81bhKd9RpHsQR1LwU8Xm6jZRUV/xpM7cIQFbFH6wBCLPTNsdELBvfoHeumud7X78jQQJv2TA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -2309,12 +2385,18 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.20.2': - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.22.0': + resolution: {integrity: sha512-vTaTQ9OgYc3VTaWtOE5pSuDT6H3d/qSRFRfSBbnxFfzAvYoB3pqKXA0LEbi/oT8GUOEAutspfRMqPj2ezdFaMw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -2327,12 +2409,18 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.20.2': - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.22.0': + resolution: {integrity: sha512-0e1ZgoobJzaGnR4reD7I9rYZ7ttqdh1KPvJWnquUoDJhL0rYwdneeLailBzd2/4g/U5p4e5TIHEWa68NF2hFpQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -2345,12 +2433,18 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.20.2': - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.22.0': + resolution: {integrity: sha512-BFgyYwlCwRWyPQJtkzqq2p6pJbiiWgp0P9PNf7a5FQ1itKY4czPuOMAlFVItirSmEpRPCeImuwePNScZS0pL5Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -2363,12 +2457,18 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.20.2': - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.22.0': + resolution: {integrity: sha512-V/K2rctCUgC0PCXpN7AqT4hoazXKgIYugFGu/myk2+pfe6jTW2guz/TBwq4cZ7ESqusR/IzkcQaBkcjquuBWsw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -2381,12 +2481,18 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.20.2': - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.22.0': + resolution: {integrity: sha512-KEMWiA9aGuPUD4BH5yjlhElLgaRXe+Eri6gKBoDazoPBTo1BXc/e6IW5FcJO9DoL19FBeCxgONyh95hLDNepIg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -2399,12 +2505,18 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.20.2': - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.22.0': + resolution: {integrity: sha512-r2ZZqkOMOrpUhzNwxI7uLAHIDwkfeqmTnrv1cjpL/rjllPWszgqmprd/om9oviKXUBpMqHbXmppvjAYgISb26Q==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -2417,12 +2529,18 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.20.2': - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.22.0': + resolution: {integrity: sha512-qaowLrV/YOMAL2RfKQ4C/VaDzAuLDuylM2sd/LH+4OFirMl6CuDpRlCq4u49ZBaVV8pkI/Y+hTdiibvQRhojCA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -2435,12 +2553,18 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.20.2': - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.22.0': + resolution: {integrity: sha512-hgrezzjQTRxjkQ5k08J6rtZN5PNnkWx/Rz6Kmj9gnsdCAX1I4Dn4ZPqvFRkXo55Q3pnVQJBwbdtrTO7tMGtyVA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -2453,12 +2577,18 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.20.2': - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.22.0': + resolution: {integrity: sha512-ewxg6FLLUio883XgSjfULEmDl3VPv/TYNnRprVAS3QeGFLdCYdx1tIudBcd7n9jIdk82v1Ajov4jx87qW7h9+g==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -2471,12 +2601,18 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.20.2': - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.22.0': + resolution: {integrity: sha512-Az5XbgSJC2lE8XK8pdcutsf9RgdafWdTpUK/+6uaDdfkviw/B4JCwAfh1qVeRWwOohwdsl4ywZrWBNWxwrPLFg==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -2489,12 +2625,18 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.20.2': - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.22.0': + resolution: {integrity: sha512-8j4a2ChT9+V34NNNY9c/gMldutaJFmfMacTPq4KfNKwv2fitBCLYjee7c+Vxaha2nUhPK7cXcZpJtJ3+Y7ZdVQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -2507,12 +2649,18 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.20.2': - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.22.0': + resolution: {integrity: sha512-JUQyOnpbAkkRFOk/AhsEemz5TfWN4FJZxVObUlnlNCbe7QBl61ZNfM4cwBXayQA6laMJMUcqLHaYQHAB6YQ95Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -2525,12 +2673,24 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.20.2': - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.22.0': + resolution: {integrity: sha512-11PoCoHXo4HFNbLsXuMB6bpMPWGDiw7xETji6COdJss4SQZLvcgNoeSqWtATRm10Jj1uEHiaIk4N0PiN6x4Fcg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.22.0': + resolution: {integrity: sha512-Ezlhu/YyITmXwKSB+Zu/QqD7cxrjrpiw85cc0Rbd3AWr2wsgp+dWbWOE8MqHaLW9NKMZvuL0DhbJbvzR7F6Zvg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -2543,12 +2703,18 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.20.2': - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.22.0': + resolution: {integrity: sha512-ufjdW5tFJGUjlH9j/5cCE9lrwRffyZh+T4vYvoDKoYsC6IXbwaFeV/ENxeNXcxotF0P8CDzoICXVSbJaGBhkrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -2561,15 +2727,21 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.20.2': - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} + '@esbuild/sunos-x64@0.22.0': + resolution: {integrity: sha512-zY6ly/AoSmKnmNTowDJsK5ehra153/5ZhqxNLfq9NRsTTltetr+yHHcQ4RW7QDqw4JC8A1uC1YmeSfK9NRcK1w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.18.20': + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -2579,12 +2751,18 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.20.2': - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.22.0': + resolution: {integrity: sha512-Kml5F7tv/1Maam0pbbCrvkk9vj046dPej30kFzlhXnhuCtYYBP6FGy/cLbc5yUT1lkZznGLf2OvuvmLjscO5rw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -2597,12 +2775,18 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.20.2': - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.22.0': + resolution: {integrity: sha512-IOgwn+mYTM3RrcydP4Og5IpXh+ftN8oF+HELTXSmbWBlujuci4Qa3DTeO+LEErceisI7KUSfEIiX+WOUlpELkw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -2615,12 +2799,18 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.20.2': - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.22.0': + resolution: {integrity: sha512-4bDHJrk2WHBXJPhy1y80X7/5b5iZTZP3LGcKIlAP1J+KqZ4zQAPMLEzftGyjjfcKbA4JDlPt/+2R/F1ZTeRgrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2635,17 +2825,25 @@ packages: resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/compat@1.1.0': + resolution: {integrity: sha512-s9Wi/p25+KbzxKlDm3VshQdImhWk+cbdblhwGNnyCU5lpSwtWa4v7VQCxSki0FAUrGA3s8nCWgYzAH41mwQVKQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@8.53.0': - resolution: {integrity: sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/config-array@0.17.0': + resolution: {integrity: sha512-A68TBu6/1mHHuc5YJL0U0VVeGNiklLAL6rRmhTCP2B5XjWLMnrX+HkO+IAXyHvks5cyyY1jjK5ITPQ1HGS2EVA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@8.57.0': - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.6.0': + resolution: {integrity: sha512-D9B0/3vNg44ZeWbYMpBoXqNP4j6eQD5vNwIlGAuFRRzK/WtT/jvDQW3Bi9kkf3PMDMlM7Yi+73VLUsn5bJcl8A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@fal-works/esbuild-plugin-global-externals@2.1.2': resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} @@ -2685,8 +2883,8 @@ packages: '@fastify/http-proxy@9.5.0': resolution: {integrity: sha512-1iqIdV10d5k9YtfHq9ylX5zt1NiM50fG+rIX40qt00R694sqWso3ukyTFZVk33SDoSiBW8roB7n11RUVUoN+Ag==} - '@fastify/multipart@8.2.0': - resolution: {integrity: sha512-OZ8nsyyoS2TV7Yeu3ZdrdDGsKUTAbfjrKC9jSxGgT2qdgek+BxpWX31ZubTrWMNZyU5xwk4ox6AvTjAbYWjrWg==} + '@fastify/multipart@8.3.0': + resolution: {integrity: sha512-A8h80TTyqUzaMVH0Cr9Qcm6RxSkVqmhK/MVBYHYeRRSUbUYv08WecjWKSlG2aSnD4aGI841pVxAjC+G1GafUeQ==} '@fastify/reply-from@9.0.1': resolution: {integrity: sha512-q9vFNUiXZTY1x8omDPe59os2MYq+3y7KgO/kZoXpZlnud+45Nd8Ot/svEvrUATzjkizIggfS4K8LR9zXDyZZKg==} @@ -2697,8 +2895,8 @@ packages: '@fastify/static@6.12.0': resolution: {integrity: sha512-KK1B84E6QD/FcQWxDI2aiUCwHxMJBI1KeCUzm1BwYpPY1b742+jeKruGHP2uOluuM6OkBPI8CIANrXcCRtC2oQ==} - '@fastify/static@7.0.3': - resolution: {integrity: sha512-2tmTdF+uFCykasutaO6k4/wOt7eXyi7m3dGuCPo5micXzv0qt6ttb/nWnDYL/BlXjYGfp1JI4a1gyluTIylvQA==} + '@fastify/static@7.0.4': + resolution: {integrity: sha512-p2uKtaf8BMOZWLs6wu+Ihg7bWNBdjNgCwDza4MJtTqg+5ovKmcbgbR9Xs5/smZ1YISfzKOCNYmZV8LaCj+eJ1Q==} '@fastify/view@8.2.0': resolution: {integrity: sha512-hBSiBofCnJNlPHEMZWpO1SL84eqOaqujJ1hR3jntFyZZCkweH5jMs12DKYyGesjVll7SJFRRxPUBB8kmUmneRQ==} @@ -2716,11 +2914,8 @@ packages: '@hapi/bourne@3.0.0': resolution: {integrity: sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==} - '@hapi/hoek@10.0.1': - resolution: {integrity: sha512-CvlW7jmOhWzuqOqiJQ3rQVLMcREh0eel4IBnxDx2FAcK8g7qoJRQK4L1CPBASoCY6y8e6zuCy3f2g+HWdkzcMw==} - - '@hapi/hoek@11.0.2': - resolution: {integrity: sha512-aKmlCO57XFZ26wso4rJsW4oTUnrgTFw2jh3io7CAtO9w4UltBNwRXvXIVzzyfkaaLRo3nluP/19msA8vDUUuKw==} + '@hapi/hoek@11.0.4': + resolution: {integrity: sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ==} '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} @@ -2734,14 +2929,6 @@ packages: '@hexagon/base64@1.1.27': resolution: {integrity: sha512-PdUmzpvcUM3Rh39kvz9RdbPVYhMjBjdV7Suw7ZduP7urRLsZR8l5tzgSWKm7TExwBYDFwTnYrZbnE0rQ3N5NLQ==} - '@humanwhocodes/config-array@0.11.13': - resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} - engines: {node: '>=10.10.0'} - - '@humanwhocodes/config-array@0.11.14': - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} - '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} @@ -2750,20 +2937,18 @@ packages: resolution: {integrity: sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==} engines: {node: '>=10.10.0'} - '@humanwhocodes/object-schema@2.0.1': - resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} - - '@humanwhocodes/object-schema@2.0.2': - resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + '@humanwhocodes/retry@0.3.0': + resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} + engines: {node: '>=18.18'} - '@img/sharp-darwin-arm64@0.33.3': - resolution: {integrity: sha512-FaNiGX1MrOuJ3hxuNzWgsT/mg5OHG/Izh59WW2mk1UwYHUwtfbhk5QNKYZgxf0pLOhx9ctGiGa2OykD71vOnSw==} + '@img/sharp-darwin-arm64@0.33.4': + resolution: {integrity: sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.33.3': - resolution: {integrity: sha512-2QeSl7QDK9ru//YBT4sQkoq7L0EAJZA3rtV+v9p8xTKl4U1bUqTIaCnoC7Ctx2kCjQgwFXDasOtPTCT8eCTXvw==} + '@img/sharp-darwin-x64@0.33.4': + resolution: {integrity: sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [darwin] @@ -2816,55 +3001,55 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.33.3': - resolution: {integrity: sha512-Zf+sF1jHZJKA6Gor9hoYG2ljr4wo9cY4twaxgFDvlG0Xz9V7sinsPp8pFd1XtlhTzYo0IhDbl3rK7P6MzHpnYA==} + '@img/sharp-linux-arm64@0.33.4': + resolution: {integrity: sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.33.3': - resolution: {integrity: sha512-Q7Ee3fFSC9P7vUSqVEF0zccJsZ8GiiCJYGWDdhEjdlOeS9/jdkyJ6sUSPj+bL8VuOYFSbofrW0t/86ceVhx32w==} + '@img/sharp-linux-arm@0.33.4': + resolution: {integrity: sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==} engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm] os: [linux] - '@img/sharp-linux-s390x@0.33.3': - resolution: {integrity: sha512-vFk441DKRFepjhTEH20oBlFrHcLjPfI8B0pMIxGm3+yilKyYeHEVvrZhYFdqIseSclIqbQ3SnZMwEMWonY5XFA==} - engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + '@img/sharp-linux-s390x@0.33.4': + resolution: {integrity: sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==} + engines: {glibc: '>=2.31', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.33.3': - resolution: {integrity: sha512-Q4I++herIJxJi+qmbySd072oDPRkCg/SClLEIDh5IL9h1zjhqjv82H0Seupd+q2m0yOfD+/fJnjSoDFtKiHu2g==} + '@img/sharp-linux-x64@0.33.4': + resolution: {integrity: sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.33.3': - resolution: {integrity: sha512-qnDccehRDXadhM9PM5hLvcPRYqyFCBN31kq+ErBSZtZlsAc1U4Z85xf/RXv1qolkdu+ibw64fUDaRdktxTNP9A==} + '@img/sharp-linuxmusl-arm64@0.33.4': + resolution: {integrity: sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==} engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.33.3': - resolution: {integrity: sha512-Jhchim8kHWIU/GZ+9poHMWRcefeaxFIs9EBqf9KtcC14Ojk6qua7ghKiPs0sbeLbLj/2IGBtDcxHyjCdYWkk2w==} + '@img/sharp-linuxmusl-x64@0.33.4': + resolution: {integrity: sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==} engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.33.3': - resolution: {integrity: sha512-68zivsdJ0koE96stdUfM+gmyaK/NcoSZK5dV5CAjES0FUXS9lchYt8LAB5rTbM7nlWtxaU/2GON0HVN6/ZYJAQ==} + '@img/sharp-wasm32@0.33.4': + resolution: {integrity: sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [wasm32] - '@img/sharp-win32-ia32@0.33.3': - resolution: {integrity: sha512-CyimAduT2whQD8ER4Ux7exKrtfoaUiVr7HG0zZvO0XTFn2idUWljjxv58GxNTkFb8/J9Ub9AqITGkJD6ZginxQ==} + '@img/sharp-win32-ia32@0.33.4': + resolution: {integrity: sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.33.3': - resolution: {integrity: sha512-viT4fUIDKnli3IfOephGnolMzhz5VaTvDRkYqtZxOMIoMQ4MrAziO7pT1nVnOt2FAm7qW5aa+CCc13aEY6Le0g==} + '@img/sharp-win32-x64@0.33.4': + resolution: {integrity: sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [win32] @@ -2982,8 +3167,8 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@joshwooding/vite-plugin-react-docgen-typescript@0.3.0': - resolution: {integrity: sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA==} + '@joshwooding/vite-plugin-react-docgen-typescript@0.3.1': + resolution: {integrity: sha512-pdoMZ9QaPnVlSM+SdU/wgg0nyD/8wQ7y90ttO2CMCyrrm7RxveYIJ5eNfjPaoMFqW41LZra7QO9j+xV4Y18Glw==} peerDependencies: typescript: '>= 4.3.x' vite: ^3.0.0 || ^4.0.0 || ^5.0.0 @@ -2995,6 +3180,10 @@ packages: resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.0': resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} @@ -3003,6 +3192,10 @@ packages: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + '@jridgewell/source-map@0.3.5': resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} @@ -3015,6 +3208,9 @@ packages: '@jridgewell/trace-mapping@0.3.18': resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jsdevtools/ono@7.1.3': resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} @@ -3048,29 +3244,31 @@ packages: '@types/react': '>=16' react: '>=16' - '@microsoft/api-extractor-model@7.28.14': - resolution: {integrity: sha512-Bery/c8A8SsKPSvA82cTTuy/+OcxZbLRmKhPkk91/AJOQzxZsShcrmHFAGeiEqSIrv1nPZ3tKq9kfMLdCHmsqg==} + '@microsoft/api-extractor-model@7.29.2': + resolution: {integrity: sha512-hAYajOjQan3uslhKJRwvvHIdLJ+ZByKqdSsJ/dgHFxPtEbdKpzMDO8zuW4K5gkSMYl5D0LbNwxkhxr51P2zsmw==} - '@microsoft/api-extractor@7.43.1': - resolution: {integrity: sha512-ohg40SsvFFgzHFAtYq5wKJc8ZDyY46bphjtnSvhSSlXpPTG7GHwyyXkn48UZiUCBwr2WC7TRC1Jfwz7nreuiyQ==} + '@microsoft/api-extractor@7.47.0': + resolution: {integrity: sha512-LT8yvcWNf76EpDC+8/ArTVSYePvuDQ+YbAUrsTcpg3ptiZ93HIcMCozP/JOxDt+rrsFfFHcpfoselKfPyRI0GQ==} hasBin: true - '@microsoft/tsdoc-config@0.16.2': - resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} + '@microsoft/tsdoc-config@0.17.0': + resolution: {integrity: sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==} - '@microsoft/tsdoc@0.14.2': - resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + '@microsoft/tsdoc@0.15.0': + resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==} '@misskey-dev/browser-image-resizer@2024.1.0': resolution: {integrity: sha512-4EnO0zLW5NDtng3Gaz5MuT761uiuoOuplwX18wBqgj8w56LTU5BjLn/vbHwDIIe0j2gwqDYhMb7bDjmr1/Fomg==} - '@misskey-dev/eslint-plugin@1.0.0': - resolution: {integrity: sha512-dh6UbcrNDVg5DD8k8Qh4ab30OPpuEYIlJCqaBV/lkIV8wNN/AfCJ2V7iTP8V8KjryM4t+sf5IqzQLQnT0mWI4A==} + '@misskey-dev/eslint-plugin@2.0.2': + resolution: {integrity: sha512-bnTqxCSP0CIN0xSpIGib13bz+K8/3e4h8OlQjuCPlhZF7oFwtn339EZM8yJkHg6gdfciV8KOr3gzlLyG3jiVEQ==} peerDependencies: - '@typescript-eslint/eslint-plugin': '>= 6' - '@typescript-eslint/parser': '>= 6' - eslint: '>= 3' + '@eslint/compat': '>= 1' + '@typescript-eslint/eslint-plugin': '>= 7' + '@typescript-eslint/parser': '>= 7' + eslint: '>= 8' eslint-plugin-import: '>= 2' + globals: '>= 15' '@misskey-dev/sharp-read-bmp@1.2.0': resolution: {integrity: sha512-er4pRakXzHYfEgOFAFfQagqDouG+wLm+kwNq1I30oSdIHDa0wM3KjFpfIGQ25Fks4GcmOl1s7Zh6xoQu5dNjTw==} @@ -3116,73 +3314,73 @@ packages: resolution: {integrity: sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==} engines: {node: '>=18'} - '@mswjs/interceptors@0.26.15': - resolution: {integrity: sha512-HM47Lu1YFmnYHKMBynFfjCp0U/yRskHj/8QEJW0CBEPOlw8Gkmjfll+S9b8M7V5CNDw2/ciRxjjnWeaCiblSIQ==} + '@mswjs/interceptors@0.29.1': + resolution: {integrity: sha512-3rDakgJZ77+RiQUuSK69t1F0m8BQKA8Vh5DCS5V0DWvNY67zob2JhhQrhCO0AKLGINTRSFd1tBaHcJTkhefoSw==} engines: {node: '>=18'} - '@napi-rs/canvas-android-arm64@0.1.52': - resolution: {integrity: sha512-x/K471KbASPVh5mfBUxokza66J0FNIlOgMNANWAf5C8HiATb487KecEhSkUQvvTS3WLYC9uSqIPHFgwF+tir3w==} + '@napi-rs/canvas-android-arm64@0.1.53': + resolution: {integrity: sha512-2YhxfVsZguATlRWE0fZdTx35SE9+r5D7HV5GPNDataZOKmHf+zZ5//dspuuBSbOriQdoicaFrgXKCUqI0pK3WQ==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@napi-rs/canvas-darwin-arm64@0.1.52': - resolution: {integrity: sha512-4OgVRD7TW02q5Q7lWLLjT+pYJ9ZHkQUTBOuXbPQ5wB0Wnh3RIq/aMY6thoXDZDzdR5vV3a5TUtbZUJ0aqLq3NA==} + '@napi-rs/canvas-darwin-arm64@0.1.53': + resolution: {integrity: sha512-ls+CWLMusf4RAGo5BvIIzA6dNcc0elwVp6LKjHfQECHA8KKmvdB58YuE5BQcTlb2rzk0SEKtBC/Th3NI2oNdfg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@napi-rs/canvas-darwin-x64@0.1.52': - resolution: {integrity: sha512-3fgeGJ3j2X6Mtmn0QYf3iA+A6y1ePnsayakc2emEokzf03ErrPczONw3vjnTQo53JLPMzEnfPGAffdktU/ssPA==} + '@napi-rs/canvas-darwin-x64@0.1.53': + resolution: {integrity: sha512-ZAgcoCH5+5OKS2P8Lxx+jbkAPKkyLD2x6OvSrHg1U6ppdxmLA+CkJlRl8w45HCXwuyIiP7OeymECRtiNYTwznQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.52': - resolution: {integrity: sha512-aaDEEK5XwHUrPt0q4SR8l7Va0vtn50KmSs+itxP+o7RNk3Nuch8fINHOXyhMyhwNYgv1tfiJVyHsJhD0E6lXGA==} + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.53': + resolution: {integrity: sha512-p9km/3C/loDxu3AvA8/vtpIS1BGMd/Ehkl2Iu/v/Gw8N/KUIt3HUvTS7AKApyVE28bxTfq96wJQjtcT8jzDncw==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@napi-rs/canvas-linux-arm64-gnu@0.1.52': - resolution: {integrity: sha512-tzuwM7Amt5mkrp4csQjYWkFzwFdiCm7RNdJ5usX8syzKSXmozqWzLHjzo/2ozdSQNUy6wyzRrxkG4Rh6g0OpOA==} + '@napi-rs/canvas-linux-arm64-gnu@0.1.53': + resolution: {integrity: sha512-QKK+sykEiYwjwd+ogyLcpcnH38DNZ8KViBlnfEpoGA2Wa+21/cWQKfMxnbgb/rbvm5tazJinZcihFvH577WQ5g==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@napi-rs/canvas-linux-arm64-musl@0.1.52': - resolution: {integrity: sha512-HQCtJlDT0dFp3uUZVzZOZ1VLMO7lbLRc548MjMxPpojit2ZdGopFzJ8jDSr4iszHrTO1SM1AxPaCM3pRvCAtjw==} + '@napi-rs/canvas-linux-arm64-musl@0.1.53': + resolution: {integrity: sha512-2N41U0X8RnrTKzpTtPv1ozlYkJtPsUdbfF3uP/KEd/BsULGd8Y8ghkGMS6CM+821au4ex0dPrWOOdT9wC1rSqQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@napi-rs/canvas-linux-x64-gnu@0.1.52': - resolution: {integrity: sha512-z5sBEw0PVWPH/MIQL8hOR8C3YYVlu8lqtRUcYajigMfXAhbMiNqDWTjuIWGMz3nIydDjZmn8KTxw/D4a0HFPqQ==} + '@napi-rs/canvas-linux-x64-gnu@0.1.53': + resolution: {integrity: sha512-7XjuTvDKCODtf/vMwF43VGDrjfgwYKgS91ggdcX3UrJaBYWyWu/+eqNvNj+zdXSe/0x+YOjf5jG4m8xIXdBMQA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@napi-rs/canvas-linux-x64-musl@0.1.52': - resolution: {integrity: sha512-G1+JdWFhHLyHhULJS51xTEhB7EL0ZiAUQwQaRi4/w75OOYDQ91O+o4miaxDHiV0hZuxBhHtZU6ftV2Zl3RMguw==} + '@napi-rs/canvas-linux-x64-musl@0.1.53': + resolution: {integrity: sha512-970WEvB8vmj+uxvgdBZ+AGFV7uq9GJhXrqG5PGQ5lWciHX0P0d/OhS2F7TITgFR0LsKDQZ7XQgzMxsYOfwZ0FQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@napi-rs/canvas-win32-x64-msvc@0.1.52': - resolution: {integrity: sha512-hMI626VsCC/wv29qHF78N7TSG+auatOp08DHln0Zdif5y1NJ14NU/rNUhzlTW8Zc6ssw+AMDJ3KKYYWYYg1aoA==} + '@napi-rs/canvas-win32-x64-msvc@0.1.53': + resolution: {integrity: sha512-rLFQCSJaWg/sv54Aap9nAhaodi4Vyb4un50EgW+PNkk8icMziU6KLRKirGBdQr9ZdxnshAPeQXD1g2ArStujKA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@napi-rs/canvas@0.1.52': - resolution: {integrity: sha512-xeW9EghZLDPZuqWJ4l1+eG3ld0i9J7SpV2zlgi34MPt/FE9K2XWGCfnLr0gHGOBkcI3YOVhI13I0HqRAkMPdVw==} + '@napi-rs/canvas@0.1.53': + resolution: {integrity: sha512-XsEZi97+kKykmAiPpY+IpZoHxJY1srqFZp8jDt1/RySzC0kB0iZYt/VMIFqQKpLCARZjD7SOAz2AULtwYlesCA==} engines: {node: '>= 10'} '@ndelangen/get-tarball@3.0.7': resolution: {integrity: sha512-NqGfTZIZpRFef1GoVaShSSRwDC3vde3ThtTeqFdcYd6ipKqnfEVhjK2hUeHjCQUcptyZr2TONqcloFXM+5QBrQ==} - '@nestjs/common@10.3.8': - resolution: {integrity: sha512-P+vPEIvqx2e+fonsYVlFXKvoChyJ8Tq+lfpqdVFqblovHbFr3kZ/nYX0cPs+XuW6bnRT8tz0SSR9XBGU43kJhw==} + '@nestjs/common@10.3.10': + resolution: {integrity: sha512-H8k0jZtxk1IdtErGDmxFRy0PfcOAUg41Prrqpx76DQusGGJjsaovs1zjXVD1rZWaVYchfT1uczJ6L4Kio10VNg==} peerDependencies: class-transformer: '*' class-validator: '*' @@ -3194,8 +3392,8 @@ packages: class-validator: optional: true - '@nestjs/core@10.3.8': - resolution: {integrity: sha512-AxF4tpYLDNn5Wfb3C4bNaaHJ4pREH5FJrSisR2A5zkYpQFORFs0Tc36lOFPMwBTy8Iv2wUwWLUVc5ftBnxEv4w==} + '@nestjs/core@10.3.10': + resolution: {integrity: sha512-ZbQ4jovQyzHtCGCrzK5NdtW1SYO2fHSsgSY1+/9WdruYCUra+JDkWEXgZ4M3Hv480Dl3OXehAmY1wCOojeMyMQ==} peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/microservices': ^10.0.0 @@ -3211,14 +3409,14 @@ packages: '@nestjs/websockets': optional: true - '@nestjs/platform-express@10.3.8': - resolution: {integrity: sha512-sifLoxgEJvAgbim1UuW6wyScMfkS9SVQRH+lN33N/9ZvZSjO6NSDLOe+wxqsnZkia+QrjFC0qy0ITRAsggfqbg==} + '@nestjs/platform-express@10.3.10': + resolution: {integrity: sha512-wK2ow3CZI2KFqWeEpPmoR300OB6BcBLxARV1EiClJLCj4S1mZsoCmS0YWgpk3j1j6mo0SI8vNLi/cC2iZPEPQA==} peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/core': ^10.0.0 - '@nestjs/testing@10.3.8': - resolution: {integrity: sha512-hpX9das2TdFTKQ4/2ojhjI6YgXtCfXRKui3A4Qaj54VVzc5+mtK502Jj18Vzji98o9MVS6skmYu+S/UvW3U6Fw==} + '@nestjs/testing@10.3.10': + resolution: {integrity: sha512-i3HAtVQJijxNxJq1k39aelyJlyEIBRONys7IipH/4r8W0J+M1V+y5EKDOyi4j1SdNSb/vmNyWpZ2/ewZjl3kRA==} peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/core': ^10.0.0 @@ -3230,6 +3428,10 @@ packages: '@nestjs/platform-express': optional: true + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -3273,19 +3475,19 @@ packages: '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@opentelemetry/api-logs@0.51.1': - resolution: {integrity: sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==} + '@opentelemetry/api-logs@0.52.1': + resolution: {integrity: sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==} engines: {node: '>=14'} - '@opentelemetry/api@1.8.0': - resolution: {integrity: sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==} + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@1.24.1': - resolution: {integrity: sha512-R5r6DO4kgEOVBxFXhXjwospLQkv+sYxwCfjvoZBe7Zm6KKXAV9kDSJhi/D1BweowdZmO+sdbENLs374gER8hpQ==} + '@opentelemetry/context-async-hooks@1.25.1': + resolution: {integrity: sha512-UW/ge9zjvAEmRWVapOP0qyCvPulWU6cQxGxDbWEFfGOj1VBBZAuOqTo3X6yWmDTD3Xe15ysCZChHncr2xFMIfQ==} engines: {node: '>=14'} peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.9.0' + '@opentelemetry/api': '>=1.0.0 <1.10.0' '@opentelemetry/core@1.24.1': resolution: {integrity: sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==} @@ -3293,86 +3495,98 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.9.0' - '@opentelemetry/instrumentation-connect@0.36.0': - resolution: {integrity: sha512-k9++bmJZ9zDEs3u3DnKTn2l7QTiNFg3gPx7G9rW0TPnP+xZoBSBTrEcGYBaqflQlrFG23Q58+X1sM2ayWPv5Fg==} + '@opentelemetry/core@1.25.1': + resolution: {integrity: sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/instrumentation-connect@0.37.0': + resolution: {integrity: sha512-SeQktDIH5rNzjiEiazWiJAIXkmnLOnNV7wwHpahrqE0Ph+Z3heqMfxRtoMtbdJSIYLfcNZYO51AjxZ00IXufdw==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-express@0.40.1': + resolution: {integrity: sha512-+RKMvVe2zw3kIXRup9c1jFu3T4d0fs5aKy015TpiMyoCKX1UMu3Z0lfgYtuyiSTANvg5hZnDbWmQmqSPj9VTvg==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-express@0.39.0': - resolution: {integrity: sha512-AG8U7z7D0JcBu/7dDcwb47UMEzj9/FMiJV2iQZqrsZnxR3FjB9J9oIH2iszJYci2eUdp2WbdvtpD9RV/zmME5A==} + '@opentelemetry/instrumentation-fastify@0.37.0': + resolution: {integrity: sha512-WRjwzNZgupSzbEYvo9s+QuHJRqZJjVdNxSEpGBwWK8RKLlHGwGVAu0gcc2gPamJWUJsGqPGvahAPWM18ZkWj6A==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-fastify@0.36.1': - resolution: {integrity: sha512-3Nfm43PI0I+3EX+1YbSy6xbDu276R1Dh1tqAk68yd4yirnIh52Kd5B+nJ8CgHA7o3UKakpBjj6vSzi5vNCzJIA==} + '@opentelemetry/instrumentation-graphql@0.41.0': + resolution: {integrity: sha512-R/gXeljgIhaRDKquVkKYT5QHPnFouM8ooyePZEP0kqyaVAedtR1V7NfAUJbxfTG5fBQa5wdmLjvu63+tzRXZCA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-graphql@0.40.0': - resolution: {integrity: sha512-LVRdEHWACWOczv2imD+mhUrLMxsEjPPi32vIZJT57zygR5aUiA4em8X3aiGOCycgbMWkIu8xOSGSxdx3JmzN+w==} + '@opentelemetry/instrumentation-hapi@0.39.0': + resolution: {integrity: sha512-ik2nA9Yj2s2ay+aNY+tJsKCsEx6Tsc2g/MK0iWBW5tibwrWKTy1pdVt5sB3kd5Gkimqj23UV5+FH2JFcQLeKug==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-hapi@0.38.0': - resolution: {integrity: sha512-ZcOqEuwuutTDYIjhDIStix22ECblG/i9pHje23QGs4Q4YS4RMaZ5hKCoQJxW88Z4K7T53rQkdISmoXFKDV8xMg==} + '@opentelemetry/instrumentation-http@0.52.1': + resolution: {integrity: sha512-dG/aevWhaP+7OLv4BQQSEKMJv8GyeOp3Wxl31NHqE8xo9/fYMfEljiZphUHIfyg4gnZ9swMyWjfOQs5GUQe54Q==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-http@0.51.1': - resolution: {integrity: sha512-6b3nZnFFEz/3xZ6w8bVxctPUWIPWiXuPQ725530JgxnN1cvYFd8CJ75PrHZNjynmzSSnqBkN3ef4R9N+RpMh8Q==} + '@opentelemetry/instrumentation-ioredis@0.41.0': + resolution: {integrity: sha512-rxiLloU8VyeJGm5j2fZS8ShVdB82n7VNP8wTwfUQqDwRfHCnkzGr+buKoxuhGD91gtwJ91RHkjHA1Eg6RqsUTg==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-ioredis@0.40.0': - resolution: {integrity: sha512-Jv/fH7KhpWe4KBirsiqeUJIYrsdR2iu2l4nWhfOlRvaZ+zYIiLEzTQR6QhBbyRoAbU4OuYJzjWusOmmpGBnwng==} + '@opentelemetry/instrumentation-koa@0.41.0': + resolution: {integrity: sha512-mbPnDt7ELvpM2S0vixYUsde7122lgegLOJQxx8iJQbB8YHal/xnTh9v7IfArSVzIDo+E+080hxZyUZD4boOWkw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-koa@0.40.0': - resolution: {integrity: sha512-dJc3H/bKMcgUYcQpLF+1IbmUKus0e5Fnn/+ru/3voIRHwMADT3rFSUcGLWSczkg68BCgz0vFWGDTvPtcWIFr7A==} + '@opentelemetry/instrumentation-mongodb@0.45.0': + resolution: {integrity: sha512-xnZP9+ayeB1JJyNE9cIiwhOJTzNEsRhXVdLgfzmrs48Chhhk026mQdM5CITfyXSCfN73FGAIB8d91+pflJEfWQ==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mongodb@0.43.0': - resolution: {integrity: sha512-bMKej7Y76QVUD3l55Q9YqizXybHUzF3pujsBFjqbZrRn2WYqtsDtTUlbCK7fvXNPwFInqZ2KhnTqd0gwo8MzaQ==} + '@opentelemetry/instrumentation-mongoose@0.39.0': + resolution: {integrity: sha512-J1r66A7zJklPPhMtrFOO7/Ud2p0Pv5u8+r23Cd1JUH6fYPmftNJVsLp2urAt6PHK4jVqpP/YegN8wzjJ2mZNPQ==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mongoose@0.38.1': - resolution: {integrity: sha512-zaeiasdnRjXe6VhYCBMdkmAVh1S5MmXC/0spet+yqoaViGnYst/DOxPvhwg3yT4Yag5crZNWsVXnA538UjP6Ow==} + '@opentelemetry/instrumentation-mysql2@0.39.0': + resolution: {integrity: sha512-Iypuq2z6TCfriAXCIZjRq8GTFCKhQv5SpXbmI+e60rYdXw8NHtMH4NXcGF0eKTuoCsC59IYSTUvDQYDKReaszA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mysql2@0.38.1': - resolution: {integrity: sha512-qkpHMgWSDTYVB1vlZ9sspf7l2wdS5DDq/rbIepDwX5BA0N0068JTQqh0CgAh34tdFqSCnWXIhcyOXC2TtRb0sg==} + '@opentelemetry/instrumentation-mysql@0.39.0': + resolution: {integrity: sha512-8snHPh83rhrDf31v9Kq0Nf+ts8hdr7NguuszRqZomZBHgE0+UyXZSkXHAAFZoBPPRMGyM68uaFE5hVtFl+wOcA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mysql@0.38.1': - resolution: {integrity: sha512-+iBAawUaTfX/HAlvySwozx0C2B6LBfNPXX1W8Z2On1Uva33AGkw2UjL9XgIg1Pj4eLZ9R4EoJ/aFz+Xj4E/7Fw==} + '@opentelemetry/instrumentation-nestjs-core@0.38.0': + resolution: {integrity: sha512-M381Df1dM8aqihZz2yK+ugvMFK5vlHG/835dc67Sx2hH4pQEQYDA2PpFPTgc9AYYOydQaj7ClFQunESimjXDgg==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-nestjs-core@0.37.1': - resolution: {integrity: sha512-ebYQjHZEmGHWEALwwDGhSQVLBaurFnuLIkZD5igPXrt7ohfF4lc5/4al1LO+vKc0NHk8SJWStuRueT86ISA8Vg==} + '@opentelemetry/instrumentation-pg@0.42.0': + resolution: {integrity: sha512-sjgcM8CswYy8zxHgXv4RAZ09DlYhQ+9TdlourUs63Df/ek5RrB1ZbjznqW7PB6c3TyJJmX6AVtPTjAsROovEjA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-pg@0.41.0': - resolution: {integrity: sha512-BSlhpivzBD77meQNZY9fS4aKgydA8AJBzv2dqvxXFy/Hq64b7HURgw/ztbmwFeYwdF5raZZUifiiNSMLpOJoSA==} + '@opentelemetry/instrumentation-redis-4@0.40.0': + resolution: {integrity: sha512-0ieQYJb6yl35kXA75LQUPhHtGjtQU9L85KlWa7d4ohBbk/iQKZ3X3CFl5jC5vNMq/GGPB3+w3IxNvALlHtrp7A==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -3383,8 +3597,8 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation@0.51.1': - resolution: {integrity: sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==} + '@opentelemetry/instrumentation@0.52.1': + resolution: {integrity: sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -3399,22 +3613,32 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.9.0' + '@opentelemetry/resources@1.25.1': + resolution: {integrity: sha512-pkZT+iFYIZsVn6+GzM0kSX+u3MSLCY9md+lIJOoKl/P+gJFfxJte/60Usdp8Ce4rOs8GduUpSPNe1ddGyDT1sQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/sdk-metrics@1.24.1': resolution: {integrity: sha512-FrAqCbbGao9iKI+Mgh+OsC9+U2YMoXnlDHe06yH7dvavCKzE3S892dGtX54+WhSFVxHR/TMRVJiK/CV93GR0TQ==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.9.0' - '@opentelemetry/sdk-trace-base@1.24.1': - resolution: {integrity: sha512-zz+N423IcySgjihl2NfjBf0qw1RWe11XIAWVrTNOSSI6dtSPJiVom2zipFB2AEEtJWpv0Iz6DY6+TjnyTV5pWg==} + '@opentelemetry/sdk-trace-base@1.25.1': + resolution: {integrity: sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==} engines: {node: '>=14'} peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.9.0' + '@opentelemetry/api': '>=1.0.0 <1.10.0' '@opentelemetry/semantic-conventions@1.24.1': resolution: {integrity: sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==} engines: {node: '>=14'} + '@opentelemetry/semantic-conventions@1.25.1': + resolution: {integrity: sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==} + engines: {node: '>=14'} + '@opentelemetry/sql-common@0.40.1': resolution: {integrity: sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==} engines: {node: '>=14'} @@ -3444,23 +3668,167 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@prisma/instrumentation@5.14.0': - resolution: {integrity: sha512-DeybWvIZzu/mUsOYP9MVd6AyBj+MP7xIMrcuIn25MX8FiQX39QBnET5KhszTAip/ToctUuDwSJ46QkIoyo3RFA==} + '@prisma/instrumentation@5.16.0': + resolution: {integrity: sha512-MVzNRW2ikWvVNnMIEgQMcwWxpFD+XF2U2h0Qz7MjutRqJxrhWexWV2aSi2OXRaU8UL5wzWw7pnjdKUzYhWauLg==} + + '@radix-ui/primitive@1.1.0': + resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} + + '@radix-ui/react-compose-refs@1.1.0': + resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.0': + resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.1': + resolution: {integrity: sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.0': + resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.0': + resolution: {integrity: sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.0': + resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.0': + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-portal@1.1.1': + resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.0': + resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.0.0': + resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.1.0': + resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.0': + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.1.0': + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@radix-ui/react-compose-refs@1.0.1': - resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} + '@radix-ui/react-use-escape-keydown@1.1.0': + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} peerDependencies: '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true - '@radix-ui/react-slot@1.0.2': - resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} + '@radix-ui/react-use-layout-effect@1.1.0': + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} peerDependencies: '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true @@ -3489,8 +3857,8 @@ packages: rollup: optional: true - '@rollup/plugin-replace@5.0.5': - resolution: {integrity: sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ==} + '@rollup/plugin-replace@5.0.7': + resolution: {integrity: sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -3507,88 +3875,88 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.17.2': - resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==} + '@rollup/rollup-android-arm-eabi@4.18.0': + resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.17.2': - resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==} + '@rollup/rollup-android-arm64@4.18.0': + resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.17.2': - resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==} + '@rollup/rollup-darwin-arm64@4.18.0': + resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.17.2': - resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==} + '@rollup/rollup-darwin-x64@4.18.0': + resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': - resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==} + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.17.2': - resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==} + '@rollup/rollup-linux-arm-musleabihf@4.18.0': + resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.17.2': - resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==} + '@rollup/rollup-linux-arm64-gnu@4.18.0': + resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.17.2': - resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==} + '@rollup/rollup-linux-arm64-musl@4.18.0': + resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': - resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==} + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.17.2': - resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==} + '@rollup/rollup-linux-riscv64-gnu@4.18.0': + resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.17.2': - resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==} + '@rollup/rollup-linux-s390x-gnu@4.18.0': + resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.17.2': - resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==} + '@rollup/rollup-linux-x64-gnu@4.18.0': + resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.17.2': - resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==} + '@rollup/rollup-linux-x64-musl@4.18.0': + resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.17.2': - resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==} + '@rollup/rollup-win32-arm64-msvc@4.18.0': + resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.17.2': - resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==} + '@rollup/rollup-win32-ia32-msvc@4.18.0': + resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.17.2': - resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==} + '@rollup/rollup-win32-x64-msvc@4.18.0': + resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==} cpu: [x64] os: [win32] - '@rushstack/node-core-library@4.1.0': - resolution: {integrity: sha512-qz4JFBZJCf1YN5cAXa1dP6Mki/HrsQxc/oYGAGx29dF2cwF2YMxHoly0FBhMw3IEnxo5fMj0boVfoHVBkpkx/w==} + '@rushstack/node-core-library@5.4.1': + resolution: {integrity: sha512-WNnwdS8r9NZ/2K3u29tNoSRldscFa7SxU0RT+82B6Dy2I4Hl2MeCSKm4EXLXPKeNzLGvJ1cqbUhTLviSF8E6iA==} peerDependencies: '@types/node': '*' peerDependenciesMeta: @@ -3598,50 +3966,53 @@ packages: '@rushstack/rig-package@0.5.2': resolution: {integrity: sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==} - '@rushstack/terminal@0.10.1': - resolution: {integrity: sha512-C6Vi/m/84IYJTkfzmXr1+W8Wi3MmBjVF/q3za91Gb3VYjKbpALHVxY6FgH625AnDe5Z0Kh4MHKWA3Z7bqgAezA==} + '@rushstack/terminal@0.13.0': + resolution: {integrity: sha512-Ou44Q2s81BqJu3dpYedAX54am9vn245F0HzqVrfJCMQk5pGgoKKOBOjkbfZC9QKcGNaECh6pwH2s5noJt7X6ew==} peerDependencies: '@types/node': '*' peerDependenciesMeta: '@types/node': optional: true - '@rushstack/ts-command-line@4.19.2': - resolution: {integrity: sha512-cqmXXmBEBlzo9WtyUrHtF9e6kl0LvBY7aTSVX4jfnBfXWZQWnPq9JTFPlQZ+L/ZwjZ4HrNwQsOVvhe9oOucZkw==} + '@rushstack/ts-command-line@4.22.0': + resolution: {integrity: sha512-Qj28t6MO3HRgAZ72FDeFsrpdE6wBWxF3VENgvrXh7JF2qIT+CrXiOJIesW80VFZB9QwObSpkB1ilx794fGQg6g==} + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - '@sentry/core@8.5.0': - resolution: {integrity: sha512-SO3ddBzGdha+Oflp+IKwBxj+7ds1q69OAT3VsypTd+WUFQdI9DIhR92Bjf+QQZCIzUNOi79VWOh3aOi3f6hMnw==} + '@sentry/core@8.13.0': + resolution: {integrity: sha512-N9Qg4ZGxZWp8eb2eUUHVVKgjBLtFIjS805nG92s6yJmkvOpKm6mLtcUaT/iDf3Hta6nG+xRkhbE3r+Z4cbXG8w==} engines: {node: '>=14.18'} - '@sentry/node@8.5.0': - resolution: {integrity: sha512-t9cHAx/wLJYtdVf2XlzKlRJGvwdAp1wjzG0tC4E1Znx74OuUS1cFNo5WrGuOi0/YcWSxiJaxBvtUcsWK86fIgw==} + '@sentry/node@8.13.0': + resolution: {integrity: sha512-OeZ7K90RhyxfwfreerIi4cszzHrPRRH36STJno2+p3sIGbG5VScOccqXzYEOAqHpByxnti4KQN34BLAT2BFOEA==} engines: {node: '>=14.18'} - '@sentry/opentelemetry@8.5.0': - resolution: {integrity: sha512-AbxFUNjuTKQ9ugZrssmGtPxWkBr4USNoP7GjaaGCNwNzvIVYCa+i8dv7BROJiW2lsxNAremULEbh+nbVmhGxDA==} + '@sentry/opentelemetry@8.13.0': + resolution: {integrity: sha512-NYn/HNE/SxFXe8pfnxJknhrrRzYRMHNssCoi5M1CeR5G7F2BGxxVmaGsd8j0WyTCpUS4i97G4vhYtDGxHvWN6w==} engines: {node: '>=14.18'} peerDependencies: - '@opentelemetry/api': ^1.8.0 - '@opentelemetry/core': ^1.24.1 - '@opentelemetry/instrumentation': ^0.51.1 - '@opentelemetry/sdk-trace-base': ^1.23.0 - '@opentelemetry/semantic-conventions': ^1.23.0 + '@opentelemetry/api': ^1.9.0 + '@opentelemetry/core': ^1.25.1 + '@opentelemetry/instrumentation': ^0.52.1 + '@opentelemetry/sdk-trace-base': ^1.25.1 + '@opentelemetry/semantic-conventions': ^1.25.1 - '@sentry/profiling-node@8.5.0': - resolution: {integrity: sha512-nEXJqVNfZWYi4PakQXBZCJeH59UlnBv+zaYftDNUUXttCmzRXpL1ujNm5mJrJHlWjV7tgIFw02HW3nh2yyKOkw==} + '@sentry/profiling-node@8.13.0': + resolution: {integrity: sha512-6qirN71xlMahcm4m25XZLnjQdvs0EaFym/9MdLqcsAa3gAHZtw6h+IDapUzBWRXVOrU1OR5oQdh2tlFthsDtew==} engines: {node: '>=14.18'} hasBin: true - '@sentry/types@8.5.0': - resolution: {integrity: sha512-eDgkSmKI4+XL0QZm4H3j/n1RgnrbnjXZmjj+LsfccRZQwbPu9bWlc8q7Y7Ty1gOsoUpX+TecNLp2a8CRID4KHA==} + '@sentry/types@8.13.0': + resolution: {integrity: sha512-r63s/H5gvQnQM9tTGBXz2xErUbxZALh4e2Lg/1aHj4zIvGLBjA2z5qWsh6TEZYbpmgAyGShLDr6+rWeUVf9yBQ==} engines: {node: '>=14.18'} - '@sentry/utils@8.5.0': - resolution: {integrity: sha512-fdrCzo8SAYiw9JBhkJPqYqJkDXZ/wICzN7+zcXIuzKNhE1hdoFjeKcPnpUI3bKZCG6e3hT1PTYQXhVw7GIZV9w==} + '@sentry/utils@8.13.0': + resolution: {integrity: sha512-PxV0v9VbGWH9zP37P5w2msLUFDr287nYjoY2XVF+RSolyiTs1CQNI5ZMUO3o4MsSac/dpXxjyrZXQd72t/jRYA==} engines: {node: '>=14.18'} - '@shikijs/core@1.4.0': - resolution: {integrity: sha512-CxpKLntAi64h3j+TwWqVIQObPTED0FyXLHTTh3MKXtqiQNn2JGcMQQ362LftDbc9kYbDtrksNMNoVmVXzKFYUQ==} + '@shikijs/core@1.10.0': + resolution: {integrity: sha512-BZcr6FCmPfP6TXaekvujZcnkFmJHZ/Yglu97r/9VjzVndQA56/F4WjUKtJRQUnK59Wi7p/UTAOekMfCJv7jnYg==} '@sideway/address@4.1.4': resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==} @@ -3670,10 +4041,18 @@ packages: resolution: {integrity: sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==} engines: {node: '>=14.16'} - '@sindresorhus/is@6.1.0': - resolution: {integrity: sha512-BuvU07zq3tQ/2SIgBsEuxKYDyDjC0n7Zir52bpHy2xnBbW81+po43aLFPLbeV3HRAheFbGud1qgcqSYfhtHMAg==} + '@sindresorhus/is@6.3.1': + resolution: {integrity: sha512-FX4MfcifwJyFOI2lPoX7PQxCqx8BG1HCho7WdiXwpEQx1Ycij0JxkfYtGK7yqNScrZGSlt6RE6sw8QYoH7eKnQ==} engines: {node: '>=16'} + '@sindresorhus/merge-streams@2.3.0': + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + '@sinonjs/commons@2.0.0': resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} @@ -3692,275 +4071,299 @@ packages: '@sinonjs/text-encoding@0.7.2': resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} - '@smithy/abort-controller@2.0.14': - resolution: {integrity: sha512-zXtteuYLWbSXnzI3O6xq3FYvigYZFW8mdytGibfarLL2lxHto9L3ILtGVnVGmFZa7SDh62l39EnU5hesLN87Fw==} - engines: {node: '>=14.0.0'} - '@smithy/abort-controller@2.2.0': resolution: {integrity: sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==} engines: {node: '>=14.0.0'} - '@smithy/chunked-blob-reader-native@2.0.0': - resolution: {integrity: sha512-HM8V2Rp1y8+1343tkZUKZllFhEQPNmpNdgFAncbTsxkZ18/gqjk23XXv3qGyXWp412f3o43ZZ1UZHVcHrpRnCQ==} + '@smithy/abort-controller@3.1.1': + resolution: {integrity: sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==} + engines: {node: '>=16.0.0'} - '@smithy/chunked-blob-reader@2.0.0': - resolution: {integrity: sha512-k+J4GHJsMSAIQPChGBrjEmGS+WbPonCXesoqP9fynIqjn7rdOThdH8FAeCmokP9mxTYKQAKoHCLPzNlm6gh7Wg==} + '@smithy/chunked-blob-reader-native@3.0.0': + resolution: {integrity: sha512-VDkpCYW+peSuM4zJip5WDfqvg2Mo/e8yxOv3VF1m11y7B8KKMKVFtmZWDe36Fvk8rGuWrPZHHXZ7rR7uM5yWyg==} - '@smithy/config-resolver@2.0.9': - resolution: {integrity: sha512-QBkGPLUqyPmis9Erz8v4q5lo/ErnF7+GD5WZHa6JZiXopUPfaaM+B21n8gzS5xCkIXZmnwzNQhObP9xQPu8oqQ==} - engines: {node: '>=14.0.0'} + '@smithy/chunked-blob-reader@3.0.0': + resolution: {integrity: sha512-sbnURCwjF0gSToGlsBiAmd1lRCmSn72nu9axfJu5lIx6RUEgHu6GwTMbqCdhQSi0Pumcm5vFxsi9XWXb2mTaoA==} - '@smithy/credential-provider-imds@2.0.11': - resolution: {integrity: sha512-uJJs8dnM5iXkn8a2GaKvlKMhcOJ+oJPYqY9gY3CM/EieCVObIDjxUtR/g8lU/k/A+OauA78GzScAfulmFjPOYA==} - engines: {node: '>=14.0.0'} + '@smithy/config-resolver@3.0.4': + resolution: {integrity: sha512-VwiOk7TwXoE7NlNguV/aPq1hFH72tqkHCw8eWXbr2xHspRyyv9DLpLXhq+Ieje+NwoqXrY0xyQjPXdOE6cGcHA==} + engines: {node: '>=16.0.0'} - '@smithy/eventstream-codec@2.0.8': - resolution: {integrity: sha512-onO4to8ujCKn4m5XagReT9Nc6FlNG5vveuvjp1H7AtaG7njdet1LOl6/jmUOkskF2C/w+9jNw3r9Ak+ghOvN0A==} + '@smithy/core@2.2.4': + resolution: {integrity: sha512-qdY3LpMOUyLM/gfjjMQZui+UTNS7kBRDWlvyIhVOql5dn2J3isk9qUTBtQ1CbDH8MTugHis1zu3h4rH+Qmmh4g==} + engines: {node: '>=16.0.0'} - '@smithy/eventstream-serde-browser@2.0.8': - resolution: {integrity: sha512-/RGlkKUnC0sd+xKBKH/2APSBRmVMZTeLOKZMhrZmrO+ONoU+DwyMr/RLJ6WnmBKN+2ebjffM4pcIJTKLNNDD8g==} - engines: {node: '>=14.0.0'} + '@smithy/credential-provider-imds@3.1.3': + resolution: {integrity: sha512-U1Yrv6hx/mRK6k8AncuI6jLUx9rn0VVSd9NPEX6pyYFBfkSkChOc/n4zUb8alHUVg83TbI4OdZVo1X0Zfj3ijA==} + engines: {node: '>=16.0.0'} - '@smithy/eventstream-serde-config-resolver@2.0.8': - resolution: {integrity: sha512-EyAEj258eMUv9zcMvBbqrInh2eHRYuiwQAjXDMxZFCyP+JePzQB6O++3wFwjQeRKMFFgZipNgnEXfReII4+NAw==} - engines: {node: '>=14.0.0'} + '@smithy/eventstream-codec@3.1.2': + resolution: {integrity: sha512-0mBcu49JWt4MXhrhRAlxASNy0IjDRFU+aWNDRal9OtUJvJNiwDuyKMUONSOjLjSCeGwZaE0wOErdqULer8r7yw==} - '@smithy/eventstream-serde-node@2.0.8': - resolution: {integrity: sha512-FMBatSUSKwh6aguKVJokXfJaV8nqsuCkCZHb9MP9zah0ZF+ohbTLeeed7DQGeTVBueVIVWEzIsShPxtxBv7MMQ==} - engines: {node: '>=14.0.0'} + '@smithy/eventstream-serde-browser@3.0.4': + resolution: {integrity: sha512-Eo4anLZX6ltGJTZ5yJMc80gZPYYwBn44g0h7oFq6et+TYr5dUsTpIcDbz2evsOKIZhZ7zBoFWHtBXQ4QQeb5xA==} + engines: {node: '>=16.0.0'} - '@smithy/eventstream-serde-universal@2.0.8': - resolution: {integrity: sha512-6InMXH8BUKoEDa6CAuxR4Gn8Gf2vBfVtjA9A6zDKZClYHT+ANUJS+2EtOBc5wECJJGk4KLn5ajQyrt9MBv5lcw==} - engines: {node: '>=14.0.0'} + '@smithy/eventstream-serde-config-resolver@3.0.3': + resolution: {integrity: sha512-NVTYjOuYpGfrN/VbRQgn31x73KDLfCXCsFdad8DiIc3IcdxL+dYA9zEQPyOP7Fy2QL8CPy2WE4WCUD+ZsLNfaQ==} + engines: {node: '>=16.0.0'} - '@smithy/fetch-http-handler@2.1.4': - resolution: {integrity: sha512-SL24M9W5ERByoXaVicRx+bj9GJVujDnPn+QO7GY7adhY0mPGa6DSF58pVKsgIh4r5Tx/k3SWCPlH4BxxSxA/fQ==} + '@smithy/eventstream-serde-node@3.0.4': + resolution: {integrity: sha512-mjlG0OzGAYuUpdUpflfb9zyLrBGgmQmrobNT8b42ZTsGv/J03+t24uhhtVEKG/b2jFtPIHF74Bq+VUtbzEKOKg==} + engines: {node: '>=16.0.0'} - '@smithy/hash-blob-browser@2.0.8': - resolution: {integrity: sha512-IgvRlBMfg/qLg321a59T1yTdEEbaizLrEVsU3DHj65DAO4lFRMF5f+l7vuV+je6m1G9wSD5GQXLturX8qlGb4g==} + '@smithy/eventstream-serde-universal@3.0.4': + resolution: {integrity: sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==} + engines: {node: '>=16.0.0'} - '@smithy/hash-node@2.0.8': - resolution: {integrity: sha512-yZL/nmxZzjZV5/QX5JWSgXlt0HxuMTwFO89CS++jOMMPiCMZngf6VYmtNdccs8IIIAMmfQeTzwu07XgUE/Zd3Q==} - engines: {node: '>=14.0.0'} + '@smithy/fetch-http-handler@3.2.0': + resolution: {integrity: sha512-vFvDxMrc6sO5Atec8PaISckMcAwsCrRhYxwUylg97bRT2KZoumOF7qk5+6EVUtuM1IG9AJV5aqXnHln9ZdXHpg==} - '@smithy/hash-stream-node@2.0.8': - resolution: {integrity: sha512-82zC6I9ZJycbEZH8TVyXyBx9c2ZIPQDgBvM0x5AFPUl/i1AxwKKX+lwYRnzgkF//cYhIIoJaCfJ9mjSMPRGvCQ==} - engines: {node: '>=14.0.0'} + '@smithy/hash-blob-browser@3.1.2': + resolution: {integrity: sha512-hAbfqN2UbISltakCC2TP0kx4LqXBttEv2MqSPE98gVuDFMf05lU+TpC41QtqGP3Ff5A3GwZMPfKnEy0VmEUpmg==} - '@smithy/invalid-dependency@2.0.8': - resolution: {integrity: sha512-88VOS7W3KzUz/bNRc+Sl/F/CDIasFspEE4G39YZRHIh9YmsXF7GUyVaAKURfMNulTie62ayk6BHC9O0nOBAVgQ==} + '@smithy/hash-node@3.0.3': + resolution: {integrity: sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==} + engines: {node: '>=16.0.0'} + + '@smithy/hash-stream-node@3.1.2': + resolution: {integrity: sha512-PBgDMeEdDzi6JxKwbfBtwQG9eT9cVwsf0dZzLXoJF4sHKHs5HEo/3lJWpn6jibfJwT34I1EBXpBnZE8AxAft6g==} + engines: {node: '>=16.0.0'} + + '@smithy/invalid-dependency@3.0.3': + resolution: {integrity: sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==} '@smithy/is-array-buffer@2.0.0': resolution: {integrity: sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==} engines: {node: '>=14.0.0'} - '@smithy/md5-js@2.0.8': - resolution: {integrity: sha512-1VVECXEiuJvjXv+mudiaUFKYwgDLOWz5MTTy8RzbrPiU3GiOb3/o5/urdkYpqmgoMfxdvxxOw/Adjv2dV2q2Yg==} + '@smithy/is-array-buffer@3.0.0': + resolution: {integrity: sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==} + engines: {node: '>=16.0.0'} - '@smithy/middleware-content-length@2.0.10': - resolution: {integrity: sha512-EGSbysyA4jH0p3xI6G0jdXoj9Iz9GUnAta6aEaHtXm3wVWtenRf80y2TeVvNkVSr5jwKOdSCjKIRI2l1A/oZLA==} - engines: {node: '>=14.0.0'} + '@smithy/md5-js@3.0.3': + resolution: {integrity: sha512-O/SAkGVwpWmelpj/8yDtsaVe6sINHLB1q8YE/+ZQbDxIw3SRLbTZuRaI10K12sVoENdnHqzPp5i3/H+BcZ3m3Q==} - '@smithy/middleware-endpoint@2.0.8': - resolution: {integrity: sha512-yOpogfG2d2V0cbJdAJ6GLAWkNOc9pVsL5hZUfXcxJu408N3CUCsXzIAFF6+70ZKSE+lCfG3GFErcSXv/UfUbjw==} - engines: {node: '>=14.0.0'} + '@smithy/middleware-content-length@3.0.3': + resolution: {integrity: sha512-Dbz2bzexReYIQDWMr+gZhpwBetNXzbhnEMhYKA6urqmojO14CsXjnsoPYO8UL/xxcawn8ZsuVU61ElkLSltIUQ==} + engines: {node: '>=16.0.0'} - '@smithy/middleware-retry@2.0.11': - resolution: {integrity: sha512-pknfokumZ+wvBERSuKAI2vVr+aK3ZgPiWRg6+0ZG4kKJogBRpPmDGWw+Jht0izS9ZaEbIobNzueIb4wD33JJVg==} - engines: {node: '>=14.0.0'} + '@smithy/middleware-endpoint@3.0.4': + resolution: {integrity: sha512-whUJMEPwl3ANIbXjBXZVdJNgfV2ZU8ayln7xUM47rXL2txuenI7jQ/VFFwCzy5lCmXScjp6zYtptW5Evud8e9g==} + engines: {node: '>=16.0.0'} - '@smithy/middleware-serde@2.0.8': - resolution: {integrity: sha512-Is0sm+LiNlgsc0QpstDzifugzL9ehno1wXp109GgBgpnKTK3j+KphiparBDI4hWTtH9/7OUsxuspNqai2yyhcg==} - engines: {node: '>=14.0.0'} + '@smithy/middleware-retry@3.0.7': + resolution: {integrity: sha512-f5q7Y09G+2h5ivkSx5CHvlAT4qRR3jBFEsfXyQ9nFNiWQlr8c48blnu5cmbTQ+p1xmIO14UXzKoF8d7Tm0Gsjw==} + engines: {node: '>=16.0.0'} - '@smithy/middleware-stack@2.0.1': - resolution: {integrity: sha512-UexsfY6/oQZRjTQL56s9AKtMcR60tBNibSgNYX1I2WXaUaXg97W9JCkFyth85TzBWKDBTyhLfenrukS/kyu54A==} - engines: {node: '>=14.0.0'} + '@smithy/middleware-serde@3.0.3': + resolution: {integrity: sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==} + engines: {node: '>=16.0.0'} - '@smithy/node-config-provider@2.0.11': - resolution: {integrity: sha512-CaR1dciSSGKttjhcefpytYjsfI/Yd5mqL8am4wfmyFCDxSiPsvnEWHl8UjM/RbcAjX0klt+CeIKPSHEc0wGvJA==} - engines: {node: '>=14.0.0'} + '@smithy/middleware-stack@3.0.3': + resolution: {integrity: sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==} + engines: {node: '>=16.0.0'} + + '@smithy/node-config-provider@3.1.3': + resolution: {integrity: sha512-rxdpAZczzholz6CYZxtqDu/aKTxATD5DAUDVj7HoEulq+pDSQVWzbg0btZDlxeFfa6bb2b5tUvgdX5+k8jUqcg==} + engines: {node: '>=16.0.0'} '@smithy/node-http-handler@2.5.0': resolution: {integrity: sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA==} engines: {node: '>=14.0.0'} - '@smithy/property-provider@2.0.9': - resolution: {integrity: sha512-25pPZ8f8DeRwYI5wbPRZaoMoR+3vrw8DwbA0TjP+GsdiB2KxScndr4HQehiJ5+WJ0giOTWhLz0bd+7Djv1qpUQ==} - engines: {node: '>=14.0.0'} + '@smithy/node-http-handler@3.1.1': + resolution: {integrity: sha512-L71NLyPeP450r2J/mfu1jMc//Z1YnqJt2eSNw7uhiItaONnBLDA68J5jgxq8+MBDsYnFwNAIc7dBG1ImiWBiwg==} + engines: {node: '>=16.0.0'} - '@smithy/protocol-http@3.0.10': - resolution: {integrity: sha512-6+tjNk7rXW7YTeGo9qwxXj/2BFpJTe37kTj3EnZCoX/nH+NP/WLA7O83fz8XhkGqsaAhLUPo/bB12vvd47nsmg==} - engines: {node: '>=14.0.0'} + '@smithy/property-provider@3.1.3': + resolution: {integrity: sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==} + engines: {node: '>=16.0.0'} '@smithy/protocol-http@3.3.0': resolution: {integrity: sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ==} engines: {node: '>=14.0.0'} - '@smithy/querystring-builder@2.0.14': - resolution: {integrity: sha512-lQ4pm9vTv9nIhl5jt6uVMPludr6syE2FyJmHsIJJuOD7QPIJnrf9HhUGf1iHh9KJ4CUv21tpOU3X6s0rB6uJ0g==} - engines: {node: '>=14.0.0'} + '@smithy/protocol-http@4.0.3': + resolution: {integrity: sha512-x5jmrCWwQlx+Zv4jAtc33ijJ+vqqYN+c/ZkrnpvEe/uDas7AT7A/4Rc2CdfxgWv4WFGmEqODIrrUToPN6DDkGw==} + engines: {node: '>=16.0.0'} '@smithy/querystring-builder@2.2.0': resolution: {integrity: sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A==} engines: {node: '>=14.0.0'} - '@smithy/querystring-parser@2.0.8': - resolution: {integrity: sha512-ArbanNuR7O/MmTd90ZqhDqGOPPDYmxx3huHxD+R3cuCnazcK/1tGQA+SnnR5307T7ZRb5WTpB6qBggERuibVSA==} - engines: {node: '>=14.0.0'} + '@smithy/querystring-builder@3.0.3': + resolution: {integrity: sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==} + engines: {node: '>=16.0.0'} - '@smithy/service-error-classification@2.0.1': - resolution: {integrity: sha512-QHa9+t+v4s0cMuDCcbjIJN67mNZ42/+fc3jKe8P6ZMPXZl5ksKk6a8vhZ/m494GZng5eFTc3OePv+NF9cG83yg==} - engines: {node: '>=14.0.0'} + '@smithy/querystring-parser@3.0.3': + resolution: {integrity: sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==} + engines: {node: '>=16.0.0'} - '@smithy/shared-ini-file-loader@2.0.10': - resolution: {integrity: sha512-jWASteSezRKohJ7GdA7pHDvmr7Q7tw3b5mu3xLHIkZy/ICftJ+O7aqNaF8wklhI7UNFoQ7flFRM3Rd0KA+1BbQ==} - engines: {node: '>=14.0.0'} + '@smithy/service-error-classification@3.0.3': + resolution: {integrity: sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==} + engines: {node: '>=16.0.0'} - '@smithy/signature-v4@2.0.5': - resolution: {integrity: sha512-ABIzXmUDXK4n2c9cXjQLELgH2RdtABpYKT+U131e2I6RbCypFZmxIHmIBufJzU2kdMCQ3+thBGDWorAITFW04A==} - engines: {node: '>=14.0.0'} + '@smithy/shared-ini-file-loader@3.1.3': + resolution: {integrity: sha512-Z8Y3+08vgoDgl4HENqNnnzSISAaGrF2RoKupoC47u2wiMp+Z8P/8mDh1CL8+8ujfi2U5naNvopSBmP/BUj8b5w==} + engines: {node: '>=16.0.0'} - '@smithy/smithy-client@2.1.5': - resolution: {integrity: sha512-7S865uKzsxApM8W8Q6zkij7tcUFgaG8PuADMFdMt1yL/ku3d0+s6Zwrg3N7iXCPM08Gu/mf0BIfTXIu/9i450Q==} - engines: {node: '>=14.0.0'} + '@smithy/signature-v4@3.1.2': + resolution: {integrity: sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==} + engines: {node: '>=16.0.0'} + + '@smithy/smithy-client@3.1.5': + resolution: {integrity: sha512-x9bL9Mx2CT2P1OiUlHM+ZNpbVU6TgT32f9CmTRzqIHA7M4vYrROCWEoC3o4xHNJASoGd4Opos3cXYPgh+/m4Ww==} + engines: {node: '>=16.0.0'} '@smithy/types@2.12.0': resolution: {integrity: sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==} engines: {node: '>=14.0.0'} - '@smithy/types@2.6.0': - resolution: {integrity: sha512-PgqxJq2IcdMF9iAasxcqZqqoOXBHufEfmbEUdN1pmJrJltT42b0Sc8UiYSWWzKkciIp9/mZDpzYi4qYG1qqg6g==} - engines: {node: '>=14.0.0'} + '@smithy/types@3.3.0': + resolution: {integrity: sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==} + engines: {node: '>=16.0.0'} - '@smithy/url-parser@2.0.8': - resolution: {integrity: sha512-wQw7j004ScCrBRJ+oNPXlLE9mtofxyadSZ9D8ov/rHkyurS7z1HTNuyaGRj6OvKsEk0SVQsuY0C9+EfM75XTkw==} + '@smithy/url-parser@3.0.3': + resolution: {integrity: sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==} - '@smithy/util-base64@2.0.0': - resolution: {integrity: sha512-Zb1E4xx+m5Lud8bbeYi5FkcMJMnn+1WUnJF3qD7rAdXpaL7UjkFQLdmW5fHadoKbdHpwH9vSR8EyTJFHJs++tA==} - engines: {node: '>=14.0.0'} + '@smithy/util-base64@3.0.0': + resolution: {integrity: sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==} + engines: {node: '>=16.0.0'} - '@smithy/util-body-length-browser@2.0.0': - resolution: {integrity: sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg==} + '@smithy/util-body-length-browser@3.0.0': + resolution: {integrity: sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==} - '@smithy/util-body-length-node@2.1.0': - resolution: {integrity: sha512-/li0/kj/y3fQ3vyzn36NTLGmUwAICb7Jbe/CsWCktW363gh1MOcpEcSO3mJ344Gv2dqz8YJCLQpb6hju/0qOWw==} - engines: {node: '>=14.0.0'} + '@smithy/util-body-length-node@3.0.0': + resolution: {integrity: sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==} + engines: {node: '>=16.0.0'} '@smithy/util-buffer-from@2.0.0': resolution: {integrity: sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==} engines: {node: '>=14.0.0'} - '@smithy/util-config-provider@2.0.0': - resolution: {integrity: sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==} - engines: {node: '>=14.0.0'} + '@smithy/util-buffer-from@3.0.0': + resolution: {integrity: sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==} + engines: {node: '>=16.0.0'} - '@smithy/util-defaults-mode-browser@2.0.9': - resolution: {integrity: sha512-JONLJVQWT8165XoSV36ERn3SVlZLJJ4D6IeGsCSePv65Uxa93pzSLE0UMSR9Jwm4zix7rst9AS8W5QIypZWP8Q==} + '@smithy/util-config-provider@3.0.0': + resolution: {integrity: sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==} + engines: {node: '>=16.0.0'} + + '@smithy/util-defaults-mode-browser@3.0.7': + resolution: {integrity: sha512-Q2txLyvQyGfmjsaDbVV7Sg8psefpFcrnlGapDzXGFRPFKRBeEg6OvFK8FljqjeHSaCZ6/UuzQExUPqBR/2qlDA==} engines: {node: '>= 10.0.0'} - '@smithy/util-defaults-mode-node@2.0.11': - resolution: {integrity: sha512-tmqjNsfj+bgZN6jXBe6efZnukzILA7BUytHkzqikuRLNtR+0VVchQHvawD0w6vManh76rO81ydhioe7i4oBzuA==} + '@smithy/util-defaults-mode-node@3.0.7': + resolution: {integrity: sha512-F4Qcj1fG6MGi2BSWCslfsMSwllws/WzYONBGtLybyY+halAcXdWhcew+mej8M5SKd5hqPYp4f7b+ABQEaeytgg==} engines: {node: '>= 10.0.0'} - '@smithy/util-hex-encoding@2.0.0': - resolution: {integrity: sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA==} - engines: {node: '>=14.0.0'} + '@smithy/util-endpoints@2.0.4': + resolution: {integrity: sha512-ZAtNf+vXAsgzgRutDDiklU09ZzZiiV/nATyqde4Um4priTmasDH+eLpp3tspL0hS2dEootyFMhu1Y6Y+tzpWBQ==} + engines: {node: '>=16.0.0'} - '@smithy/util-middleware@2.0.1': - resolution: {integrity: sha512-LnsBMi0Mg3gfz/TpNGLv2Jjcz2ra1OX5HR/4IaCepIYmtPQzqMWDdhX/XTW1LS8OZ0xbQuyQPcHkQ+2XkhWOVQ==} - engines: {node: '>=14.0.0'} + '@smithy/util-hex-encoding@3.0.0': + resolution: {integrity: sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==} + engines: {node: '>=16.0.0'} - '@smithy/util-retry@2.0.1': - resolution: {integrity: sha512-naj4X0IafJ9yJnVJ58QgSMkCNLjyQOnyrnKh/T0f+0UOUxJiT8vuFn/hS7B/pNqbo2STY7PyJ4J4f+5YqxwNtA==} - engines: {node: '>= 14.0.0'} + '@smithy/util-middleware@3.0.3': + resolution: {integrity: sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==} + engines: {node: '>=16.0.0'} - '@smithy/util-stream@2.0.11': - resolution: {integrity: sha512-2MeWfqSpZKdmEJ+tH8CJQSgzLWhH5cmdE24X7JB0hiamXrOmswWGGuPvyj/9sQCTclo57pNxLR2p7KrP8Ahiyg==} - engines: {node: '>=14.0.0'} + '@smithy/util-retry@3.0.3': + resolution: {integrity: sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==} + engines: {node: '>=16.0.0'} - '@smithy/util-uri-escape@2.0.0': - resolution: {integrity: sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==} - engines: {node: '>=14.0.0'} + '@smithy/util-stream@3.0.5': + resolution: {integrity: sha512-xC3L5PKMAT/Bh8fmHNXP9sdQ4+4aKVUU3EEJ2CF/lLk7R+wtMJM+v/1B4en7jO++Wa5spGzFDBCl0QxgbUc5Ug==} + engines: {node: '>=16.0.0'} '@smithy/util-uri-escape@2.2.0': resolution: {integrity: sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==} engines: {node: '>=14.0.0'} + '@smithy/util-uri-escape@3.0.0': + resolution: {integrity: sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==} + engines: {node: '>=16.0.0'} + '@smithy/util-utf8@2.0.0': resolution: {integrity: sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==} engines: {node: '>=14.0.0'} - '@smithy/util-waiter@2.0.8': - resolution: {integrity: sha512-t9yaoofNhdEhNlyDeV5al/JJEFJ62HIQBGktgCUE63MvKn6imnbkh1qISsYMyMYVLwhWCpZ3Xa3R1LA+SnWcng==} - engines: {node: '>=14.0.0'} + '@smithy/util-utf8@3.0.0': + resolution: {integrity: sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==} + engines: {node: '>=16.0.0'} + + '@smithy/util-waiter@3.1.2': + resolution: {integrity: sha512-4pP0EV3iTsexDx+8PPGAKCQpd/6hsQBaQhqWzU4hqKPHN5epPsxKbvUTIiYIHTxaKt6/kEaqPBpu/ufvfbrRzw==} + engines: {node: '>=16.0.0'} '@sqltools/formatter@1.2.5': resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==} - '@storybook/addon-actions@8.0.9': - resolution: {integrity: sha512-+I3VTvlKdj8puHeS2tyaOVv9syDiNLneVZbTfqN+UDOK2i42NwvZr8PVwjTzMlEj9eePJdCZgiipz55xwts5bw==} + '@storybook/addon-actions@8.1.11': + resolution: {integrity: sha512-jqYXgBgOVInStOCk//AA+dGkrfN8R7rDXA4lyu82zM59kvICtG9iqgmkSRDn0Z3zUkM+lIHZGoz0aLVQ8pxsgw==} - '@storybook/addon-backgrounds@8.0.9': - resolution: {integrity: sha512-pCDecACrVyxPaJKEWS0sHsRb8xw+IPCSxDM1TkjaAQ6zZ468A/dcUnqW+LVK8bSXgQwWzn23wqnqPFSy5yptuQ==} + '@storybook/addon-backgrounds@8.1.11': + resolution: {integrity: sha512-naGf1ovmsU2pSWb270yRO1IidnO+0YCZ5Tcb8I4rPhZ0vsdXNURYKS1LPSk1OZkvaUXdeB4Im9HhHfUBJOW9oQ==} - '@storybook/addon-controls@8.0.9': - resolution: {integrity: sha512-wWdmd62UP/sfPm8M7aJjEA+kEXTUIR/QsYi9PoYBhBZcXiikZ4kNan7oD7GfsnzGGKHrBVfwQhO+TqaENGYytA==} + '@storybook/addon-controls@8.1.11': + resolution: {integrity: sha512-q/Vt4meNVlFlBWIMCJhx6r+bqiiYocCta2RoUK5nyIZUiLzHncKHX6JnCU36EmJzRyah9zkwjfCb2G1r9cjnoQ==} - '@storybook/addon-docs@8.0.9': - resolution: {integrity: sha512-x7hX7UuzJtClu6XwU3SfpyFhuckVcgqgD6BU6Ihxl0zs+i4xp6iKVXYSnHFMRM1sgoeT8TjPxab35Ke8w8BVRw==} + '@storybook/addon-docs@8.1.11': + resolution: {integrity: sha512-69dv+CE4R5wFU7xnJmhuyEbLN2PEVDV3N/BbgJqeucIYPmm6zDV83Q66teCHKYtRln3BFUqPH5mxsjiHobxfJQ==} - '@storybook/addon-essentials@8.0.9': - resolution: {integrity: sha512-mwAgdfrOsTuTDcagvM7veBh+iayZIWmKOazzkhrIWbhYcrXOsweigD2UOVeHgAiAzJK49znr4FXTCKcE1hOWcw==} + '@storybook/addon-essentials@8.1.11': + resolution: {integrity: sha512-uRTpcIZQnflML8H+2onicUNIIssKfuviW8Lyrs/KFwSZ1rMcYzhwzCNbGlIbAv04tgHe5NqEyNhb+DVQcZQBzg==} - '@storybook/addon-highlight@8.0.9': - resolution: {integrity: sha512-vaRHGDbx7dpNpQECAHk5wczlZO3ntstprGlqnZt0o7ylz6xB5+pTQwTuIFty0hwKv+3TPcskzzifATUyEOEmyg==} + '@storybook/addon-highlight@8.1.11': + resolution: {integrity: sha512-Iu8FCAd4ETsB6QF4xDE/OLLZY3HOFopuLM5KE0f58jnccF5zAVGr1Rj/54p6TeK0PEou0tLRPFuZs+LPlEzrSw==} - '@storybook/addon-interactions@8.0.9': - resolution: {integrity: sha512-AMIdNcyM6DDAWvMitBJMqp1iPZND8AXB4QT4VZHGMKG2ngHNKktriEKpTfcRkfKPGTJs9T+71dWfm6/R4tticw==} + '@storybook/addon-interactions@8.1.11': + resolution: {integrity: sha512-nkc01z61mYM1kxf0ncBQLlFnnwW4RAVPfRSxK9BdbFN3AAvFiHCwVZdn71mi+C3L8oTqYR6o32e0RlXk+AjhHA==} - '@storybook/addon-links@8.0.9': - resolution: {integrity: sha512-FVt+AdW3JFSqbJzkKiqKsMRWqHXqEvCBqFs7lNfk3OW0w0jfv1iREtrxE0dVdJoUFQC9V/2Im/EpJ7UB3C2bNQ==} + '@storybook/addon-links@8.1.11': + resolution: {integrity: sha512-HlV2RQSrZyi+55W1B1a9eWNuJdNpWx0g3j7s2arNlNmbd6/kfWAp84axBstI1tL0nW4svut7bWlCsMSOIden+A==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta peerDependenciesMeta: react: optional: true - '@storybook/addon-mdx-gfm@8.0.9': - resolution: {integrity: sha512-AoEx+OGKANtVZgKyWKrQhGpMpDuc2S7PnOlNLUiDYzmj8ABAGPmEJmqeb/VHVgqLQSjhOW1fMsQ4fYsecvMxTQ==} + '@storybook/addon-mdx-gfm@8.1.11': + resolution: {integrity: sha512-0/4Xaisvmoi26iK1ezTOB9dN2b0JbgWKzO2PO6att2Jh7lplLCf1QeoE8Y4SgCh0brage+mA8mKI8NrT7d18pg==} - '@storybook/addon-measure@8.0.9': - resolution: {integrity: sha512-91svOOGEXmGG4USglwXLE3wtlUVgtbKJVxTKX7xRI+AC5JEEaKByVzP17/X8Qn/8HilUL7AfSQ0kCoqtPSJ5cA==} + '@storybook/addon-measure@8.1.11': + resolution: {integrity: sha512-LkQD3SiLWaWt53aLB3EnmhD9Im8EOO+HKSUE+XGnIJRUcHHRqHfvDkN9KX7T1DCWbfRE5WzMHF5o23b3UiAANw==} - '@storybook/addon-outline@8.0.9': - resolution: {integrity: sha512-fQ+jm356TgUnz81IxsC99/aOesbLw3N5OQRJpo/A6kqbLMzlq3ybVzuXYCKC3f0ArgQRNh4NoMeJBMRFMtaWRw==} + '@storybook/addon-outline@8.1.11': + resolution: {integrity: sha512-vco3RLVjkcS25dNtj1lxmjq4fC0Nq08KNLMS5cbNPVJWNTuSUi/2EthSTQQCdpfMV/p6u+D5uF20A9Pl0xJFXw==} - '@storybook/addon-storysource@8.0.9': - resolution: {integrity: sha512-5m3K2Rs4fQtKtqwrq4CDS1jK2wzWOlnxhE2ArX5XTWytb1am65CEPxfYTEQkvZH9oPGwX3cXytPCziynqysFMQ==} + '@storybook/addon-storysource@8.1.11': + resolution: {integrity: sha512-b2K3+ZzfANDTTeN1jnqNgAQ5ZIhnhIAv89gC/36cOhSK5NLyKmyVKLGQmR3fVqX3URpnz9xccst2JNXopvtccw==} - '@storybook/addon-toolbars@8.0.9': - resolution: {integrity: sha512-nNSBnnBOhQ+EJwkrIkK4ZBYPcozNmEH770CZ/6NK85SUJ6WEBZapE6ru33jIUokFGEvlOlNCeai0GUc++cQP8w==} + '@storybook/addon-toolbars@8.1.11': + resolution: {integrity: sha512-reIKB0+JTiP+GNzynlDcRf4xmv9+j/DQ94qiXl2ZG5+ufKilH8DiRZpVA/i0x+4+TxdGdOJr1/pOf8tAmhNEoQ==} - '@storybook/addon-viewport@8.0.9': - resolution: {integrity: sha512-Ao4+D56cO7biaw+iTlMU1FBec1idX0cmdosDeCFZin06MSawcPkeBlRBeruaSQYdLes8TBMdZPFgfuqI5yIk6g==} + '@storybook/addon-viewport@8.1.11': + resolution: {integrity: sha512-qk4IcGnAgiAUQxt8l5PIQ293Za+w6wxlJQIpxr7+QM8OVkADPzXY0MmQfYWU9EQplrxAC2MSx3/C1gZeq+MDOQ==} - '@storybook/blocks@8.0.9': - resolution: {integrity: sha512-F2zSrfSwzTFN7qW3zB80tG+EXtmfmCDC6Ird0F7tolszb6tOqJcAcBOwQbE2O0wI63sLu21qxzXgaKBMkiWvJg==} + '@storybook/blocks@8.1.11': + resolution: {integrity: sha512-eMed7PpL/hAVM6tBS7h70bEAyzbiSU9I/kye4jZ7DkCbAsrX6OKmC7pcHSDn712WTcf3vVqxy5jOKUmOXpc0eg==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta peerDependenciesMeta: react: optional: true react-dom: optional: true - '@storybook/builder-manager@8.0.9': - resolution: {integrity: sha512-/PxDwZIfMc/PSRZcasb6SIdGr3azIlenzx7dBF7Imt8i4jLHiAf1t00GvghlfJsvsrn4DNp95rbRbXTDyTj7tQ==} + '@storybook/builder-manager@8.1.11': + resolution: {integrity: sha512-U7bmed4Ayg+OlJ8HPmLeGxLTHzDY7rxmxM4aAs4YL01fufYfBcjkIP9kFhJm+GJOvGm+YJEUAPe5mbM1P/bn0Q==} - '@storybook/builder-vite@8.0.9': - resolution: {integrity: sha512-7hEQFZIIz7VvxdySDpPE96iMvZxQvRZcRdhaNGeE+8Y2pyc3DgYE4WY3sjr+LUoB0a6TYLpAIKqbXwtLz0R+PQ==} + '@storybook/builder-vite@8.1.11': + resolution: {integrity: sha512-hG4eoNMCPgjZ2Ai+zSmk69zjsyEihe75XbJXtYfGRqjMWtz2+SAUFO54fLc2BD5svcUiTeN+ukWcTrwApyPsKg==} peerDependencies: '@preact/preset-vite': '*' typescript: '>= 4.3.x' @@ -3974,48 +4377,53 @@ packages: vite-plugin-glimmerx: optional: true - '@storybook/channels@8.0.9': - resolution: {integrity: sha512-7Lcfyy5CsLWWGhMPO9WG4jZ/Alzp0AjepFhEreYHRPtQrfttp6qMAjE/g1aHgun0qHCYWxwqIG4NLR/hqDNrXQ==} + '@storybook/channels@8.1.11': + resolution: {integrity: sha512-fu5FTqo6duOqtJFa6gFzKbiSLJoia+8Tibn3xFfB6BeifWrH81hc+AZq0lTmHo5qax2G5t8ZN8JooHjMw6k2RA==} - '@storybook/cli@8.0.9': - resolution: {integrity: sha512-lilYTKn8F5YOePijqfRYFa5v2mHVIJxPCIgTn+OXAmAFbcizZ6P8P6niU4J/NXulgx68Ln1M7hYhFtTP25hVTw==} + '@storybook/cli@8.1.11': + resolution: {integrity: sha512-4U48w9C7mVEKrykcPcfHwJkRyCqJ28XipbElACbjIIkQEqaHaOVtP3GeKIrgkoOXe/HK3O4zKWRP2SqlVS0r4A==} hasBin: true - '@storybook/client-logger@8.0.9': - resolution: {integrity: sha512-LzV/RHkbf07sRc1Jc0ff36RlapKf9Ul7/+9VMvVbI3hshH1CpmrZK4t/tsIdpX/EVOdJ1Gg5cES06PnleOAIPA==} + '@storybook/client-logger@8.1.11': + resolution: {integrity: sha512-DVMh2usz3yYmlqCLCiCKy5fT8/UR9aTh+gSqwyNFkGZrIM4otC5A8eMXajXifzotQLT5SaOEnM3WzHwmpvMIEA==} - '@storybook/codemod@8.0.9': - resolution: {integrity: sha512-VBeGpSZSQpL6iyLLqceJSNGhdCqcNwv+xC/aWdDFOkmuE1YfbmNNwpa9QYv4ZFJ2QjUsm4iTWG60qK+9NXeSKA==} + '@storybook/codemod@8.1.11': + resolution: {integrity: sha512-/LCozjH1IQ1TOs9UQV59BE0X6UZ9q+C0NEUz7qmJZPrwAii3FkW4l7D/fwxblpMExaoxv0oE8NQfUz49U/5Ymg==} - '@storybook/components@8.0.9': - resolution: {integrity: sha512-JcwBGADzIJs0PSzqykrrD2KHzNG9wtexUOKuidt+FSv9szpUhe3qBAXIHpdfBRl7mOJ9TRZ5rt+mukEnfncdzA==} + '@storybook/components@8.1.11': + resolution: {integrity: sha512-iXKsNu7VmrLBtjMfPj7S4yJ6T13GU6joKcVcrcw8wfrQJGlPFp4YaURPBUEDxvCt1XWi5JkaqJBvb48kIrROEQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - '@storybook/core-common@8.0.9': - resolution: {integrity: sha512-Jmue+sfHFb4GTYBzyWYw1MygoJiQSfISIrKmNIzAmZ+oR9EOr+jpu/i/bH+uetZ2Hqg1AGhj1VB7OtJp9HQyWw==} + '@storybook/core-common@8.1.11': + resolution: {integrity: sha512-Ix0nplD4I4DrV2t9B+62jaw1baKES9UbR/Jz9LVKFF9nsua3ON0aVe73dOjMxFWBngpzBYWe+zYBTZ7aQtDH4Q==} + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true - '@storybook/core-events@8.0.9': - resolution: {integrity: sha512-DxSUx7wG9Qe3OFUBnv3OrYq48J8UWNo2DUR5/JecJCtp3n++L4fAEW3J0IF5FfxpQDMQSp1yTNjZ2PaWCMd2ag==} + '@storybook/core-events@8.1.11': + resolution: {integrity: sha512-vXaNe2KEW9BGlLrg0lzmf5cJ0xt+suPjWmEODH5JqBbrdZ67X6ApA2nb6WcxDQhykesWCuFN5gp1l+JuDOBi7A==} - '@storybook/core-server@8.0.9': - resolution: {integrity: sha512-BIe1T5YUBl0GYxEjRoTQsvXD2pyuzL8rPTUD41zlzSQM0R8U6Iant9SzRms4u0+rKUm2mGxxKuODlUo5ewqaGA==} + '@storybook/core-server@8.1.11': + resolution: {integrity: sha512-L6dzQTmR0np/kagNONvvlm6lSvF1FNc9js3vxsEEPnEypLbhx8bDZaHmuhmBpYUzKyUMpRVQTE/WgjHLuBBuxA==} - '@storybook/csf-plugin@8.0.9': - resolution: {integrity: sha512-pXaNCNi++kxKsqSWwvx215fPx8cNqvepLVxQ7B69qXLHj80DHn0Q3DFBO3sLXNiQMJ2JK4OYcTxMfuOiyzszKw==} + '@storybook/csf-plugin@8.1.11': + resolution: {integrity: sha512-hkA8gjFtSN/tabG0cuvmEqanMXtxPr3qTkp4UNSt1R6jBEgFHRG2y/KYLl367kDwOSFTT987ZgRfJJruU66Fvw==} - '@storybook/csf-tools@8.0.9': - resolution: {integrity: sha512-PiNMhL97giLytTdQwuhsZ92buVk4gy9H/8DtrDhUc45/1OmF95gogm6T2Yap729SIFwgpOcuq/U3aVo6d6swVQ==} + '@storybook/csf-tools@8.1.11': + resolution: {integrity: sha512-6qMWAg/dBwCVIHzANM9lSHoirwqSS+wWmv+NwAs0t9S94M75IttHYxD3IyzwaSYCC5llp0EQFvtXXAuSfFbibg==} - '@storybook/csf@0.1.6': - resolution: {integrity: sha512-JjWnBptVhBYJ14yq+cHs66BXjykRUWQ5TlD1RhPxMOtavynYyV/Q+QR98/N+XB+mcPtFMm5I2DvNkpj0/Dk8Mw==} + '@storybook/csf@0.1.9': + resolution: {integrity: sha512-JlZ6v/iFn+iKohKGpYXnMeNeTiiAMeFoDhYnPLIC8GnyyIWqEI9wJYrOK9i9rxlJ8NZAH/ojGC/u/xVC41qSgQ==} - '@storybook/docs-mdx@3.0.0': - resolution: {integrity: sha512-NmiGXl2HU33zpwTv1XORe9XG9H+dRUC1Jl11u92L4xr062pZtrShLmD4VKIsOQujxhhOrbxpwhNOt+6TdhyIdQ==} + '@storybook/docs-mdx@3.1.0-next.0': + resolution: {integrity: sha512-t4syFIeSyufieNovZbLruPt2DmRKpbwL4fERCZ1MifWDRIORCKLc4NCEHy+IqvIqd71/SJV2k4B51nF7vlJfmQ==} - '@storybook/docs-tools@8.0.9': - resolution: {integrity: sha512-OzogAeOmeHea/MxSPKRBWtOQVNSpoq+OOpimO9YRA5h5GBRJ2TUOGT44Gny6QT4ll5AvQA8fIiq9KezKcLekAg==} + '@storybook/docs-tools@8.1.11': + resolution: {integrity: sha512-mEXtR9rS7Y+OdKtT/QG6JBGYR1L41mcDhIqhnk7RmYl9qJstVAegrCKWR53sPKFdTVOHU7dmu6k+BD+TqHpyyw==} '@storybook/global@5.0.0': resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} @@ -4027,83 +4435,83 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - '@storybook/instrumenter@8.0.9': - resolution: {integrity: sha512-Gw74dgpTU/2p7FG0s7DuVdqCbJ2MEcSuRJjDo7HcXRYcvWp7I6Ly+C0v7N5VaoS+kbBVerAhLKIHZgG/LZf1og==} + '@storybook/instrumenter@8.1.11': + resolution: {integrity: sha512-r/U9hcqnodNMHuzRt1g56mWrVsDazR85Djz64M3KOwBhrTj5d46DF4/EE80w/5zR5JOrT7p8WmjJRowiVteOCQ==} - '@storybook/manager-api@8.0.9': - resolution: {integrity: sha512-99b3yKArDSvfabXL7QE3nA95e4DdW/5H/ZCcr6/E2qCQJayZ6G1v/WWamKXbiaTpkndulFmcb/+ZmnDXcweIIQ==} + '@storybook/manager-api@8.1.11': + resolution: {integrity: sha512-QSgwKfAw01K9YvvZj30iGBMgQ4YaCT3vojmttuqdH5ukyXkiO7pENLJj4Y+alwUeSi0g+SJeadCI3PXySBHOGg==} - '@storybook/manager@8.0.9': - resolution: {integrity: sha512-+NnRo+5JQFGNqveKrLtC0b+Z08Tae4m44iq292bPeZMpr9OkFsIkU0PBPsHTHPkrqC/zZXRNsCsTEgvu3p2OIA==} + '@storybook/manager@8.1.11': + resolution: {integrity: sha512-e02y9dmxowo7cTKYm9am7UO6NOHoHy6Xi7xZf/UA932qLwFZUtk5pnwIEFaZWI3OQsRUCGhP+FL5zizU7uVZeg==} - '@storybook/node-logger@8.0.9': - resolution: {integrity: sha512-5ajMdZFrYrjGLJOVDq7dlEQNFsgeLHymt4dCK9MulL/ciXykmXUZXE3Bye0wFy+I2qqDVvrvR8uzCvSFvm5MAQ==} + '@storybook/node-logger@8.1.11': + resolution: {integrity: sha512-wdzFo7B2naGhS52L3n1qBkt5BfvQjs8uax6B741yKRpiGgeAN8nz8+qelkD25MbSukxvbPgDot7WJvsMU/iCzg==} - '@storybook/preview-api@8.0.9': - resolution: {integrity: sha512-zHfX34bkAMzzmE7vbDzaqFwSW6ExiBD0HiO1L/IsHF55f0f7xV7IH8uJyFRrDTvAoW3ReSxZDMvvPpeydFPKGA==} + '@storybook/preview-api@8.1.11': + resolution: {integrity: sha512-8ZChmFV56GKppCJ0hnBd/kNTfGn2gWVq1242kuet13pbJtBpvOhyq4W01e/Yo14tAPXvgz8dSnMvWLbJx4QfhQ==} - '@storybook/preview@8.0.9': - resolution: {integrity: sha512-tFsR8xc8AYBZZrZw8enklFbSQt7ZAV+rv20BoxwDhd3q7fjXyK7O4moGPqUwBZ7rukTG13nPoISxr+VXAk/HYA==} + '@storybook/preview@8.1.11': + resolution: {integrity: sha512-K/9NZmjnL0D1BROkTNWNoPqgL2UaocALRSqCARmkBLgU2Rn/FuZgEclHkWlYo6pUrmLNK+bZ+XzpNMu12iTbpg==} - '@storybook/react-dom-shim@8.0.9': - resolution: {integrity: sha512-8011KlRuG3obr5pZZ7bcEyYYNWF3tR596YadoMd267NPoHKvwAbKL1L/DNgb6kiYjZDUf9QfaKSCWW31k0kcRQ==} + '@storybook/react-dom-shim@8.1.11': + resolution: {integrity: sha512-KVDSuipqkFjpGfldoRM5xR/N1/RNmbr+sVXqMmelr0zV2jGnexEZnoa7wRHk7IuXuivLWe8BxMxzvQWqjIa4GA==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - '@storybook/react-vite@8.0.9': - resolution: {integrity: sha512-FT5KeulUH6grfzOJOxJCxpv9+81UVDrT9UPcgiFhQT9rKtsgmltezThwbHknByZNw3WWnf+ieidMLEis9hd73A==} + '@storybook/react-vite@8.1.11': + resolution: {integrity: sha512-QqkE6QKsIDthXtps9+YSBQ39O4VvU7Uu3y6WSA3IPgKTtGnmIvhwXtapjf7WQ2cNb5KY1JksFxHXbDe0i5IL4g==} engines: {node: '>=18.0.0'} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta vite: ^4.0.0 || ^5.0.0 - '@storybook/react@8.0.9': - resolution: {integrity: sha512-NeQ6suZG3HKikwe3Tx9cAIaRx7uP8FKCmlVvIiBg4LTTI5orCt94PPakvuZukZcbkqvcCnEBkebAzwUpn8PiJw==} + '@storybook/react@8.1.11': + resolution: {integrity: sha512-t+EYXOkgwg3ropLGS9y8gGvX5/Okffu/6JYL3YWksrBGAZSqVV4NkxCnVJZepS717SyhR0tN741gv/SxxFPJMg==} engines: {node: '>=18.0.0'} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta typescript: '>= 4.2.x' peerDependenciesMeta: typescript: optional: true - '@storybook/router@8.0.9': - resolution: {integrity: sha512-aAOWxbM9J4mt+cp4o88T2PB29mgBBTOzU37/pUsTHYnKnR9XI4npXEXdN8Gv+ryqM0kj0AbBpz/llFlnR2MNNA==} + '@storybook/router@8.1.11': + resolution: {integrity: sha512-nU5lsBvy0L8wBYOkjagh29ztZicDATpZNYrHuavlhQ2jznmmHdJvXKYk+VrMAbthjQ6ZBqfeeMNPR1UlnqR5Rw==} - '@storybook/source-loader@8.0.9': - resolution: {integrity: sha512-FDnpxIGE5nIYT15pvYe6rz95TSBrdLcDll7lOHNyZisWt19MI3wZU3YkVsFNRBuFrebo+FjVU3wHyoV81ur1Qw==} + '@storybook/source-loader@8.1.11': + resolution: {integrity: sha512-4cfJ7aPjtniIdDGiFjdFpO47byHOl4RKYCJEHf9t+j0xHmlXe4B9aAinxuFfv3GKAXfLvSbbwGO0cDZQRj+brw==} - '@storybook/telemetry@8.0.9': - resolution: {integrity: sha512-AGGfcup06t+wxhBIkHd0iybieOh9PDVZQJ9oPct5JGB39+ni9wvs0WOD+MYlHbsjp8id7+aGkh6mYuYOvfck+Q==} + '@storybook/telemetry@8.1.11': + resolution: {integrity: sha512-Jqvm7HcZismKzPuebhyLECO6KjGiSk4ycbca1WUM/TUvifxCXqgoUPlHHQEEfaRdHS63/MSqtMNjLsQRLC/vNQ==} - '@storybook/test@8.0.9': - resolution: {integrity: sha512-bRd5tBJnPzR6UKbDXONWnFWtdkNOY99HMLDUWe5fTRo50GwkrpFBVqPflhdkruEeof0kAbBUbnoN2CIYgtnAFw==} + '@storybook/test@8.1.11': + resolution: {integrity: sha512-k+V3HemF2/I8fkRxRqM8uH8ULrpBSAAdBOtWSHWLvHguVcb2YA4g4kKo6tXBB9256QfyDW4ZiaAj0/9TMxmJPQ==} - '@storybook/theming@8.0.9': - resolution: {integrity: sha512-jgfDuYoiNMMirQiASN3Eg0hGDXsEtpdAcMxyShqYGwu9elxgD9yUnYC2nSckYsM74a3ZQ3JaViZ9ZFSe2FHmeQ==} + '@storybook/theming@8.1.11': + resolution: {integrity: sha512-Chn/opjO6Rl1isNobutYqAH2PjKNkj09YBw/8noomk6gElSa3JbUTyaG/+JCHA6OG/9kUsqoKDb5cZmAKNq/jA==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta peerDependenciesMeta: react: optional: true react-dom: optional: true - '@storybook/types@8.0.9': - resolution: {integrity: sha512-ew0EXzk9k4B557P1qIWYrnvUcgaE0WWA5qQS0AU8l+fRTp5nvl9O3SP/zNIB0SN1qDFO7dXr3idTNTyIikTcEQ==} + '@storybook/types@8.1.11': + resolution: {integrity: sha512-k9N5iRuY2+t7lVRL6xeu6diNsxO3YI3lS4Juv3RZ2K4QsE/b3yG5ElfJB8DjHDSHwRH4ORyrU71KkOCUVfvtnw==} - '@storybook/vue3-vite@8.0.9': - resolution: {integrity: sha512-IkzYsEyCo5HIvLWbJeGrBu/VIN4u+LvdIAz7vcFqVVXBtTUhy+9/8caLx8fdnM0FWgKcBRQs8HnjBB2V0lOFcg==} + '@storybook/vue3-vite@8.1.11': + resolution: {integrity: sha512-q0bqh8XEEunaTmp4YiDqM2+YZLwEIevTb5PnNe7G7f2qOiSCE1ncBDnBK717UlCd+iYr34NTztgV2/jIhz1i5w==} engines: {node: '>=18.0.0'} peerDependencies: vite: ^4.0.0 || ^5.0.0 - '@storybook/vue3@8.0.9': - resolution: {integrity: sha512-EqVdS62YbOCAE0wJrQKW0sHpM90be8N8Mvmj+HzB0QYhJNtFqP9ehwbcTfwEKtaVGudisHgGBOzNoSKDlxFaag==} + '@storybook/vue3@8.1.11': + resolution: {integrity: sha512-xJtvfLiCOY3UqwDMd0hZdsadPm1q8dwjfM1UN2Q2ssRWNfXzww1oi+Msj902wz9zFZMYVZypfTfgrdRgWmfEjA==} engines: {node: '>=18.0.0'} peerDependencies: vue: ^3.0.0 @@ -4131,8 +4539,8 @@ packages: cpu: [arm64] os: [darwin] - '@swc/core-darwin-arm64@1.4.17': - resolution: {integrity: sha512-HVl+W4LezoqHBAYg2JCqR+s9ife9yPfgWSj37iIawLWzOmuuJ7jVdIB7Ee2B75bEisSEKyxRlTl6Y1Oq3owBgw==} + '@swc/core-darwin-arm64@1.6.6': + resolution: {integrity: sha512-5DA8NUGECcbcK1YLKJwNDKqdtTYDVnkfDU1WvQSXq/rU+bjYCLtn5gCe8/yzL7ISXA6rwqPU1RDejhbNt4ARLQ==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] @@ -4143,8 +4551,8 @@ packages: cpu: [x64] os: [darwin] - '@swc/core-darwin-x64@1.4.17': - resolution: {integrity: sha512-WYRO9Fdzq4S/he8zjW5I95G1zcvyd9yyD3Tgi4/ic84P5XDlSMpBDpBLbr/dCPjmSg7aUXxNQqKqGkl6dQxYlA==} + '@swc/core-darwin-x64@1.6.6': + resolution: {integrity: sha512-2nbh/RHpweNRsJiYDFk1KcX7UtaKgzzTNUjwtvK5cp0wWrpbXmPvdlWOx3yzwoiSASDFx78242JHHXCIOlEdsw==} engines: {node: '>=10'} cpu: [x64] os: [darwin] @@ -4161,8 +4569,8 @@ packages: cpu: [arm] os: [linux] - '@swc/core-linux-arm-gnueabihf@1.4.17': - resolution: {integrity: sha512-cgbvpWOvtMH0XFjvwppUCR+Y+nf6QPaGu6AQ5hqCP+5Lv2zO5PG0RfasC4zBIjF53xgwEaaWmGP5/361P30X8Q==} + '@swc/core-linux-arm-gnueabihf@1.6.6': + resolution: {integrity: sha512-YgytuyUfR7b0z0SRHKV+ylr83HmgnROgeT7xryEkth6JGpAEHooCspQ4RrWTU8+WKJ7aXiZlGXPgybQ4TiS+TA==} engines: {node: '>=10'} cpu: [arm] os: [linux] @@ -4173,8 +4581,8 @@ packages: cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-gnu@1.4.17': - resolution: {integrity: sha512-l7zHgaIY24cF9dyQ/FOWbmZDsEj2a9gRFbmgx2u19e3FzOPuOnaopFj0fRYXXKCmtdx+anD750iBIYnTR+pq/Q==} + '@swc/core-linux-arm64-gnu@1.6.6': + resolution: {integrity: sha512-yGwx9fddzEE0iURqRVwKBQ4IwRHE6hNhl15WliHpi/PcYhzmYkUIpcbRXjr0dssubXAVPVnx6+jZVDSbutvnfg==} engines: {node: '>=10'} cpu: [arm64] os: [linux] @@ -4185,8 +4593,8 @@ packages: cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.4.17': - resolution: {integrity: sha512-qhH4gr9gAlVk8MBtzXbzTP3BJyqbAfUOATGkyUtohh85fPXQYuzVlbExix3FZXTwFHNidGHY8C+ocscI7uDaYw==} + '@swc/core-linux-arm64-musl@1.6.6': + resolution: {integrity: sha512-a6fMbqzSAsS5KCxFJyg1mD5kwN3ZFO8qQLyJ75R/htZP/eCt05jrhmOI7h2n+1HjiG332jLnZ9S8lkVE5O8Nqw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] @@ -4197,8 +4605,8 @@ packages: cpu: [x64] os: [linux] - '@swc/core-linux-x64-gnu@1.4.17': - resolution: {integrity: sha512-vRDFATL1oN5oZMImkwbgSHEkp8xG1ofEASBypze01W1Tqto8t+yo6gsp69wzCZBlxldsvPpvFZW55Jq0Rn+UnA==} + '@swc/core-linux-x64-gnu@1.6.6': + resolution: {integrity: sha512-hRGsUKNzzZle28YF0dYIpN0bt9PceR9LaVBq7x8+l9TAaDLFbgksSxcnU/ubTtsy+WsYSYGn+A83w3xWC0O8CQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] @@ -4209,8 +4617,8 @@ packages: cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.4.17': - resolution: {integrity: sha512-zQNPXAXn3nmPqv54JVEN8k2JMEcMTQ6veVuU0p5O+A7KscJq+AGle/7ZQXzpXSfUCXlLMX4wvd+rwfGhh3J4cw==} + '@swc/core-linux-x64-musl@1.6.6': + resolution: {integrity: sha512-NokIUtFxJDVv3LzGeEtYMTV3j2dnGKLac59luTeq36DQLZdJQawQIdTbzzWl2jE7lxxTZme+dhsVOH9LxE3ceg==} engines: {node: '>=10'} cpu: [x64] os: [linux] @@ -4221,8 +4629,8 @@ packages: cpu: [arm64] os: [win32] - '@swc/core-win32-arm64-msvc@1.4.17': - resolution: {integrity: sha512-z86n7EhOwyzxwm+DLE5NoLkxCTme2lq7QZlDjbQyfCxOt6isWz8rkW5QowTX8w9Rdmk34ncrjSLvnHOeLY17+w==} + '@swc/core-win32-arm64-msvc@1.6.6': + resolution: {integrity: sha512-lzYdI4qb4k1dFG26yv+9Jaq/bUMAhgs/2JsrLncGjLof86+uj74wKYCQnbzKAsq2hDtS5DqnHnl+//J+miZfGA==} engines: {node: '>=10'} cpu: [arm64] os: [win32] @@ -4233,8 +4641,8 @@ packages: cpu: [ia32] os: [win32] - '@swc/core-win32-ia32-msvc@1.4.17': - resolution: {integrity: sha512-JBwuSTJIgiJJX6wtr4wmXbfvOswHFj223AumUrK544QV69k60FJ9q2adPW9Csk+a8wm1hLxq4HKa2K334UHJ/g==} + '@swc/core-win32-ia32-msvc@1.6.6': + resolution: {integrity: sha512-bvl7FMaXIJQ76WZU0ER4+RyfKIMGb6S2MgRkBhJOOp0i7VFx4WLOnrmMzaeoPJaJSkityVKAftfNh7NBzTIydQ==} engines: {node: '>=10'} cpu: [ia32] os: [win32] @@ -4245,17 +4653,17 @@ packages: cpu: [x64] os: [win32] - '@swc/core-win32-x64-msvc@1.4.17': - resolution: {integrity: sha512-jFkOnGQamtVDBm3MF5Kq1lgW8vx4Rm1UvJWRUfg+0gx7Uc3Jp3QMFeMNw/rDNQYRDYPG3yunCC+2463ycd5+dg==} + '@swc/core-win32-x64-msvc@1.6.6': + resolution: {integrity: sha512-WAP0JoCTfgeYKgOeYJoJV4ZS0sQUmU3OwvXa2dYYtMLF7zsNqOiW4niU7QlThBHgUv/qNZm2p6ITEgh3w1cltw==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.4.17': - resolution: {integrity: sha512-tq+mdWvodMBNBBZbwFIMTVGYHe9N7zvEaycVVjfvAx20k1XozHbHhRv+9pEVFJjwRxLdXmtvFZd3QZHRAOpoNQ==} + '@swc/core@1.6.6': + resolution: {integrity: sha512-sHfmIUPUXNrQTwFMVCY5V5Ena2GTOeaWjS2GFUpjLhAgVfP90OP67DWow7+cYrfFtqBdILHuWnjkTcd0+uPKlg==} engines: {node: '>=10'} peerDependencies: - '@swc/helpers': ^0.5.0 + '@swc/helpers': '*' peerDependenciesMeta: '@swc/helpers': optional: true @@ -4269,8 +4677,8 @@ packages: peerDependencies: '@swc/core': '*' - '@swc/types@0.1.5': - resolution: {integrity: sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==} + '@swc/types@0.1.9': + resolution: {integrity: sha512-qKnCno++jzcJ4lM4NTfYifm1EFSCeIfKiAHAfkENZAV5Kl9PjJIyd2yeeVv6c/2CckuLyv2NmRC5pv6pm2WQBg==} '@swc/wasm@1.2.130': resolution: {integrity: sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==} @@ -4332,16 +4740,16 @@ packages: resolution: {integrity: sha512-EmCsnzdvawyk4b+4JKaLLuicHcJQRZtL1zSy9AWJLiiHTbDDseYgLxfaCEfLk8v2bUe7SBXwl3n3B7OjgvH11Q==} hasBin: true - '@testing-library/dom@9.3.3': - resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==} - engines: {node: '>=14'} + '@testing-library/dom@10.1.0': + resolution: {integrity: sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==} + engines: {node: '>=18'} '@testing-library/dom@9.3.4': resolution: {integrity: sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==} engines: {node: '>=14'} - '@testing-library/jest-dom@6.4.2': - resolution: {integrity: sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==} + '@testing-library/jest-dom@6.4.5': + resolution: {integrity: sha512-AguB9yvTXmCnySBP1lWjfNNUwpbElsaQ567lt2VdGqAdHtpieLgjmcVyv1q7PMIvLbgpDdkWV5Ydv3FEejyp2A==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} peerDependencies: '@jest/globals': '>= 28' @@ -4367,8 +4775,8 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' - '@testing-library/vue@8.0.3': - resolution: {integrity: sha512-wSsbNlZ69ZFQgVlHMtc/ZC/g9BHO7MhyDrd4nHyfEubtMr3kToN/w4/BsSBknGIF8w9UmPbsgbIuq/CbdBHzCA==} + '@testing-library/vue@8.1.0': + resolution: {integrity: sha512-ls4RiHO1ta4mxqqajWRh8158uFObVrrtAPoxk7cIp4HrnQUj/ScKzqz53HxYpG3X6Zb7H2v+0eTGLSoy8HQ2nA==} engines: {node: '>=14'} peerDependencies: '@vue/compiler-sfc': '>= 3' @@ -4384,8 +4792,8 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} - '@tsd/typescript@5.3.3': - resolution: {integrity: sha512-CQlfzol0ldaU+ftWuG52vH29uRoKboLinLy84wS8TQOu+m+tWoaUfk4svL4ij2V8M5284KymJBlHUusKj6k34w==} + '@tsd/typescript@5.4.5': + resolution: {integrity: sha512-saiCxzHRhUrRxQV2JhH580aQUZiKQUXI38FcAcikcfOomAil4G4lxT0RfrrKywoAYP/rqAdYXYmNRLppcd+hQQ==} engines: {node: '>=14.17'} '@twemoji/parser@15.0.0': @@ -4430,12 +4838,6 @@ packages: '@types/cacheable-request@6.0.3': resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} - '@types/chai-subset@1.3.5': - resolution: {integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==} - - '@types/chai@4.3.11': - resolution: {integrity: sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==} - '@types/color-convert@2.0.3': resolution: {integrity: sha512-2Q6wzrNiuEvYxVQqhh7sXM2mhIhvZR/Paq4FdsQkOMgWsCIkKvSGj8Le1/XalulrmgOzPMqNa0ix+ePY4hTrfg==} @@ -4466,6 +4868,9 @@ packages: '@types/detect-port@1.3.2': resolution: {integrity: sha512-xxgAGA2SAU4111QefXPSp5eGbDm/hW6zhvYl9IeEPZEry9F4d66QAHm5qpUXjb6IsevZV/7emAEx5MhP6O192g==} + '@types/diff@5.2.1': + resolution: {integrity: sha512-uxpcuwWJGhe2AR1g8hD9F5OYGCqjqWnBUQFD8gMZsDbv8oPHzxJF6iMO6n8Tk0AdzlxoaaoQhOYlIg/PukVU8g==} + '@types/disposable-email-domains@1.0.2': resolution: {integrity: sha512-SDKwyYTjk3y5aZBxxc38yRecpJPjsqn57STz1bNxYYlv4k11bBe7QB8w4llXDTmQXKT1mFvgGmJv+8Zdu3YmJw==} @@ -4529,8 +4934,8 @@ packages: '@types/http-errors@2.0.4': resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - '@types/http-link-header@1.0.5': - resolution: {integrity: sha512-AxhIKR8UbyoqCTNp9rRepkktHuUOw3DjfOfDCaO9kwI8AYzjhxyrvZq4+mRw/2daD3hYDknrtSeV6SsPwmc71w==} + '@types/http-link-header@1.0.7': + resolution: {integrity: sha512-snm5oLckop0K3cTDAiBnZDy6ncx9DJ3mCRDvs42C884MbVYPP74Tiq2hFsSDRTyjK6RyDYDIulPiW23ge+g5Lw==} '@types/istanbul-lib-coverage@2.0.4': resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} @@ -4547,8 +4952,8 @@ packages: '@types/js-yaml@4.0.9': resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} - '@types/jsdom@21.1.6': - resolution: {integrity: sha512-/7kkMsC+/kMs7gAYmmBR9P0vGTnOoLhQhyhQJSlXGI5bzTHp6xdo0TtKWQAsz6pmSAeVqKSbqeyP6hytqr9FDw==} + '@types/jsdom@21.1.7': + resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==} '@types/json-schema@7.0.12': resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} @@ -4559,8 +4964,8 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/jsonld@1.5.13': - resolution: {integrity: sha512-n7fUU6W4kSYK8VQlf/LsE9kddBHPKhODoVOjsZswmve+2qLwBy6naWxs/EiuSZN9NU0N06Ra01FR+j87C62T0A==} + '@types/jsonld@1.5.14': + resolution: {integrity: sha512-z4IRf5oRgjPTkazDDv94sjzI5iK3DrDEW7Y5Gk4VO4+ANymgtHtNaXWi93+BmiAoG3PB9QTv5DgSpKWGYVvysA==} '@types/jsrsasign@10.5.14': resolution: {integrity: sha512-lppSlfK6etu+cuKs40K4rg8As79PH6hzIB+v55zSqImbSH3SE6Fm8MBHCiI91cWlAP3Z4igtJK1VL3fSN09blQ==} @@ -4595,8 +5000,8 @@ packages: '@types/mdx@2.0.3': resolution: {integrity: sha512-IgHxcT3RC8LzFLhKwP3gbMPeaK7BM9eBH46OdapPA7yvuIUJ8H6zHZV53J8hGZcTSnt95jANt+rTBNUUc22ACQ==} - '@types/micromatch@4.0.7': - resolution: {integrity: sha512-C/FMQ8HJAZhTsDpl4wDKZdMeeW5USjgzOczUwTGbRc1ZopPgOhIEnxY2ZgUrsuyy4DwK1JVOJZKFakv3TbCKiA==} + '@types/micromatch@4.0.9': + resolution: {integrity: sha512-7V+8ncr22h4UoYRLnLXSpTxjQrNUXtWHGeMPRJt1nULXI57G9bIcpyrHlmrQ7QK24EyyuXvYcSSWAM8GA9nqCg==} '@types/mime-types@2.1.4': resolution: {integrity: sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==} @@ -4628,8 +5033,8 @@ packages: '@types/node@20.11.5': resolution: {integrity: sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==} - '@types/node@20.12.7': - resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} + '@types/node@20.14.9': + resolution: {integrity: sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==} '@types/node@20.9.1': resolution: {integrity: sha512-HhmzZh5LSJNS5O8jQKpJ/3ZcrrlG6L70hpGqMIAoM9YVD0YBRNWYsfwcXq8VnSjlNpCpgLzMXdiPo+dxcvSmiA==} @@ -4646,8 +5051,8 @@ packages: '@types/oauth2orize@1.11.5': resolution: {integrity: sha512-C6hrRoh9hCnqis39OpeUZSwgw+TIzcV0CsxwJMGfQjTx4I1r+CLmuEPzoDJr5NRTfc7OMwHNLkQwrGFLKrJjMQ==} - '@types/oauth@0.9.4': - resolution: {integrity: sha512-qk9orhti499fq5XxKCCEbd0OzdPZuancneyse3KtR+vgMiHRbh+mn8M4G6t64ob/Fg+GZGpa565MF/2dKWY32A==} + '@types/oauth@0.9.5': + resolution: {integrity: sha512-+oQ3C2Zx6ambINOcdIARF5Z3Tu3x//HipE889/fqo3sgpQZbe9c6ExdQFtN6qlhpR7p83lTZfPJt0tCAW29dog==} '@types/offscreencanvas@2019.3.0': resolution: {integrity: sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==} @@ -4658,8 +5063,8 @@ packages: '@types/pg-pool@2.0.4': resolution: {integrity: sha512-qZAvkv1K3QbmHHFYSNRYPkRjOWRLBYrL4B9c+wG0GSVGBw0NtJwPcgx/DSddeDJvRGMHCEQ4VMEVfuJ/0gZ3XQ==} - '@types/pg@8.11.5': - resolution: {integrity: sha512-2xMjVviMxneZHDHX5p5S6tsRRs7TpDHeeK7kTTMe/kAC/mRRNjWHjZg0rkiY+e17jXSZV3zJYDxXV8Cy72/Vuw==} + '@types/pg@8.11.6': + resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==} '@types/pg@8.6.1': resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} @@ -4766,6 +5171,9 @@ packages: '@types/unist@3.0.2': resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + '@types/uuid@9.0.8': resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} @@ -4815,8 +5223,8 @@ packages: typescript: optional: true - '@typescript-eslint/eslint-plugin@7.7.1': - resolution: {integrity: sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==} + '@typescript-eslint/eslint-plugin@7.15.0': + resolution: {integrity: sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -4846,8 +5254,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@7.7.1': - resolution: {integrity: sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==} + '@typescript-eslint/parser@7.15.0': + resolution: {integrity: sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -4864,8 +5272,8 @@ packages: resolution: {integrity: sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/scope-manager@7.7.1': - resolution: {integrity: sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==} + '@typescript-eslint/scope-manager@7.15.0': + resolution: {integrity: sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==} engines: {node: ^18.18.0 || >=20.0.0} '@typescript-eslint/type-utils@6.11.0': @@ -4888,8 +5296,8 @@ packages: typescript: optional: true - '@typescript-eslint/type-utils@7.7.1': - resolution: {integrity: sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==} + '@typescript-eslint/type-utils@7.15.0': + resolution: {integrity: sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -4906,8 +5314,8 @@ packages: resolution: {integrity: sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/types@7.7.1': - resolution: {integrity: sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==} + '@typescript-eslint/types@7.15.0': + resolution: {integrity: sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==} engines: {node: ^18.18.0 || >=20.0.0} '@typescript-eslint/typescript-estree@6.11.0': @@ -4928,8 +5336,8 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@7.7.1': - resolution: {integrity: sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==} + '@typescript-eslint/typescript-estree@7.15.0': + resolution: {integrity: sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' @@ -4949,8 +5357,8 @@ packages: peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/utils@7.7.1': - resolution: {integrity: sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==} + '@typescript-eslint/utils@7.15.0': + resolution: {integrity: sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -4963,87 +5371,78 @@ packages: resolution: {integrity: sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/visitor-keys@7.7.1': - resolution: {integrity: sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==} + '@typescript-eslint/visitor-keys@7.15.0': + resolution: {integrity: sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==} engines: {node: ^18.18.0 || >=20.0.0} '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - '@vitejs/plugin-vue@5.0.4': - resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==} + '@vitejs/plugin-vue@5.0.5': + resolution: {integrity: sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 vue: ^3.2.25 - '@vitest/coverage-v8@0.34.6': - resolution: {integrity: sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==} + '@vitest/coverage-v8@1.6.0': + resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==} peerDependencies: - vitest: '>=0.32.0 <1' - - '@vitest/expect@0.34.6': - resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==} - - '@vitest/expect@1.3.1': - resolution: {integrity: sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==} - - '@vitest/runner@0.34.6': - resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==} + vitest: 1.6.0 - '@vitest/snapshot@0.34.6': - resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==} + '@vitest/expect@1.6.0': + resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} - '@vitest/spy@0.34.6': - resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==} + '@vitest/runner@1.6.0': + resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} - '@vitest/spy@1.3.1': - resolution: {integrity: sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==} + '@vitest/snapshot@1.6.0': + resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} '@vitest/spy@1.6.0': resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} - '@vitest/utils@0.34.6': - resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==} - - '@vitest/utils@1.3.1': - resolution: {integrity: sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==} - '@vitest/utils@1.6.0': resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} '@volar/language-core@2.2.0': resolution: {integrity: sha512-a8WG9+4OdeNDW4ywABZIM6S6UN7em8uIlM/BZ2pWQUYrVmX+m8sj/X+QadvO+Li/t/LjAqbWJQtVgxdpEWLALQ==} + '@volar/language-core@2.4.0-alpha.11': + resolution: {integrity: sha512-DtftH0DtpksK1y+de/kLnu8CHcFQ7huKXi7cyxH9R0PbOOTSGXd31kijBeKNzyoXRp8dqGpu/7WhOlCWXQR62w==} + '@volar/source-map@2.2.0': resolution: {integrity: sha512-HQlPRlHOVqCCHK8wI76ZldHkEwKsjp7E6idUc36Ekni+KJDNrqgSqPvyHQixybXPHNU7CI9Uxd9/IkxO7LuNBw==} + '@volar/source-map@2.4.0-alpha.11': + resolution: {integrity: sha512-yyjmv8KUkTcxXzwme9qUMl6Szdji9JUQa8eadE4ib/spFXXZGq6QOX8cgSu5UQ0ooyBJFO1zdVH5otBJyZE3Ew==} + '@volar/typescript@2.2.0': resolution: {integrity: sha512-wC6l4zLiiCLxF+FGaHCbWlQYf4vMsnRxYhcI6WgvaNppOD6r1g+Ef1RKRJUApALWU46Yy/JDU/TbdV6w/X6Liw==} - '@vue/compiler-core@3.4.21': - resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==} + '@volar/typescript@2.4.0-alpha.11': + resolution: {integrity: sha512-N/v+wSddhtsNtfv2w0Bxj2QQWURN5budGzpyBTrlcXxz2dnvB0eAMqrEQbBi6rCOVHlRaXbh+wyTRdAcB/FHrg==} - '@vue/compiler-core@3.4.25': - resolution: {integrity: sha512-Y2pLLopaElgWnMNolgG8w3C5nNUVev80L7hdQ5iIKPtMJvhVpG0zhnBG/g3UajJmZdvW0fktyZTotEHD1Srhbg==} + '@vue/compiler-core@3.4.29': + resolution: {integrity: sha512-TFKiRkKKsRCKvg/jTSSKK7mYLJEQdUiUfykbG49rubC9SfDyvT2JrzTReopWlz2MxqeLyxh9UZhvxEIBgAhtrg==} - '@vue/compiler-core@3.4.26': - resolution: {integrity: sha512-N9Vil6Hvw7NaiyFUFBPXrAyETIGlQ8KcFMkyk6hW1Cl6NvoqvP+Y8p1Eqvx+UdqsnrnI9+HMUEJegzia3mhXmQ==} + '@vue/compiler-core@3.4.31': + resolution: {integrity: sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==} - '@vue/compiler-dom@3.4.21': - resolution: {integrity: sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==} + '@vue/compiler-dom@3.4.29': + resolution: {integrity: sha512-A6+iZ2fKIEGnfPJejdB7b1FlJzgiD+Y/sxxKwJWg1EbJu6ZPgzaPQQ51ESGNv0CP6jm6Z7/pO6Ia8Ze6IKrX7w==} - '@vue/compiler-dom@3.4.25': - resolution: {integrity: sha512-Ugz5DusW57+HjllAugLci19NsDK+VyjGvmbB2TXaTcSlQxwL++2PETHx/+Qv6qFwNLzSt7HKepPe4DcTE3pBWg==} + '@vue/compiler-dom@3.4.31': + resolution: {integrity: sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==} - '@vue/compiler-dom@3.4.26': - resolution: {integrity: sha512-4CWbR5vR9fMg23YqFOhr6t6WB1Fjt62d6xdFPyj8pxrYub7d+OgZaObMsoxaF9yBUHPMiPFK303v61PwAuGvZA==} + '@vue/compiler-sfc@3.4.31': + resolution: {integrity: sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==} - '@vue/compiler-sfc@3.4.26': - resolution: {integrity: sha512-It1dp+FAOCgluYSVYlDn5DtZBxk1NCiJJfu2mlQqa/b+k8GL6NG/3/zRbJnHdhV2VhxFghaDq5L4K+1dakW6cw==} + '@vue/compiler-ssr@3.4.29': + resolution: {integrity: sha512-rFbwCmxJ16tDp3N8XCx5xSQzjhidYjXllvEcqX/lopkoznlNPz3jyy0WGJCyhAaVQK677WWFt3YO/WUEkMMUFQ==} - '@vue/compiler-ssr@3.4.26': - resolution: {integrity: sha512-FNwLfk7LlEPRY/g+nw2VqiDKcnDTVdCfBREekF8X74cPLiWHUX6oldktf/Vx28yh4STNy7t+/yuLoMBBF7YDiQ==} + '@vue/compiler-ssr@3.4.31': + resolution: {integrity: sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==} '@vue/devtools-api@6.6.1': resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==} @@ -5056,28 +5455,38 @@ packages: typescript: optional: true - '@vue/reactivity@3.4.26': - resolution: {integrity: sha512-E/ynEAu/pw0yotJeLdvZEsp5Olmxt+9/WqzvKff0gE67tw73gmbx6tRkiagE/eH0UCubzSlGRebCbidB1CpqZQ==} + '@vue/language-core@2.0.24': + resolution: {integrity: sha512-997YD6Lq/66LXr3ZOLNxDCmyn13z9NP8LU1UZn9hGCDWhzlbXAIP0hOgL3w3x4RKEaWTaaRtsHP9DzHvmduruQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.4.31': + resolution: {integrity: sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==} - '@vue/runtime-core@3.4.26': - resolution: {integrity: sha512-AFJDLpZvhT4ujUgZSIL9pdNcO23qVFh7zWCsNdGQBw8ecLNxOOnPcK9wTTIYCmBJnuPHpukOwo62a2PPivihqw==} + '@vue/runtime-core@3.4.31': + resolution: {integrity: sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==} - '@vue/runtime-dom@3.4.26': - resolution: {integrity: sha512-UftYA2hUXR2UOZD/Fc3IndZuCOOJgFxJsWOxDkhfVcwLbsfh2CdXE2tG4jWxBZuDAs9J9PzRTUFt1PgydEtItw==} + '@vue/runtime-dom@3.4.31': + resolution: {integrity: sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==} - '@vue/server-renderer@3.4.26': - resolution: {integrity: sha512-xoGAqSjYDPGAeRWxeoYwqJFD/gw7mpgzOvSxEmjWaFO2rE6qpbD1PC172YRpvKhrihkyHJkNDADFXTfCyVGhKw==} + '@vue/server-renderer@3.4.29': + resolution: {integrity: sha512-HMLCmPI2j/k8PVkSBysrA2RxcxC5DgBiCdj7n7H2QtR8bQQPqKAe8qoaxLcInzouBmzwJ+J0x20ygN/B5mYBng==} peerDependencies: - vue: 3.4.26 + vue: 3.4.29 - '@vue/shared@3.4.21': - resolution: {integrity: sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==} + '@vue/server-renderer@3.4.31': + resolution: {integrity: sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==} + peerDependencies: + vue: 3.4.31 - '@vue/shared@3.4.25': - resolution: {integrity: sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA==} + '@vue/shared@3.4.29': + resolution: {integrity: sha512-hQ2gAQcBO/CDpC82DCrinJNgOHI2v+FA7BDW4lMSPeBpQ7sRe2OLHWe5cph1s7D8DUQAwRt18dBDfJJ220APEA==} - '@vue/shared@3.4.26': - resolution: {integrity: sha512-Fg4zwR0GNnjzodMt3KRy2AWGMKQXByl56+4HjN87soxLNU9P5xcJkstAlIeEF3cU6UYOzmJl1tV0dVPGIljCnQ==} + '@vue/shared@3.4.31': + resolution: {integrity: sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==} '@vue/test-utils@2.4.1': resolution: {integrity: sha512-VO8nragneNzUZUah6kOjiFmD/gwRjUauG9DROh6oaOeFwX1cZRUNHhdeogE8635cISigXFTtGLUQWx5KCb0xeg==} @@ -5151,8 +5560,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + acorn@8.12.0: + resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==} engines: {node: '>=0.4.0'} hasBin: true @@ -5205,12 +5614,26 @@ packages: ajv: optional: true + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + ajv@8.13.0: resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==} + ajv@8.16.0: + resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -5290,9 +5713,16 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} @@ -5368,6 +5798,9 @@ packages: async-mutex@0.5.0: resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + async@0.2.10: + resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==} + async@3.2.4: resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} @@ -5389,8 +5822,8 @@ packages: avvio@8.3.0: resolution: {integrity: sha512-VBVH0jubFr9LdFASy/vNtm5giTrnbVquWBhT0fyizuNK2rQ7e7ONU2plZQWUNqtE1EmxFEb+kbSkFRkstiaS9Q==} - aws-sdk-client-mock@3.0.1: - resolution: {integrity: sha512-9VAzJLl8mz99KP9HjOm/93d8vznRRUTpJooPBOunRdUAnVYopCe9xmMuu7eVemu8fQ+w6rP7o5bBK1kAFkB2KQ==} + aws-sdk-client-mock@4.0.1: + resolution: {integrity: sha512-yD2mmgy73Xce097G5hIpr1k7j50qzvJ49/+6osGZiCyk4m6cwhb+2x7kKFY1gEMwTzaS8+m8fXv9SB29SkRYyQ==} aws-sign2@0.7.0: resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} @@ -5426,18 +5859,18 @@ packages: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - babel-plugin-polyfill-corejs2@0.4.6: - resolution: {integrity: sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==} + babel-plugin-polyfill-corejs2@0.4.11: + resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.8.6: - resolution: {integrity: sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==} + babel-plugin-polyfill-corejs3@0.10.4: + resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.5.3: - resolution: {integrity: sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==} + babel-plugin-polyfill-regenerator@0.6.2: + resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -5510,10 +5943,6 @@ packages: bn.js@4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} - body-parser@1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - body-parser@1.20.2: resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -5538,6 +5967,10 @@ packages: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + broadcast-channel@7.0.0: resolution: {integrity: sha512-a2tW0Ia1pajcPBOGUF2jXlDnvE9d5/dg6BG9h60OmRUcZVr/veUrU8vEQFwwQIhwG3KVzYwSk3v2nRRGFgQDXQ==} @@ -5586,8 +6019,8 @@ packages: resolution: {integrity: sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==} engines: {node: '>=6.14.2'} - bullmq@5.7.8: - resolution: {integrity: sha512-F/Haeu6AVHkFrfeaU/kLOjhfrH6x3CaKAZlQQ+76fa8l3kfI9oaUHeFMW+1mYVz0NtYPF7PNTWFq4ylAHYcCgA==} + bullmq@5.8.3: + resolution: {integrity: sha512-RJgQu/vgSZqjOYrZ7F1UJsSAzveNx7FFpR3Tp/1TxOMXXN9TtZMSly5MT+vjzOhQX//3+YWNRbMWpC1mkqBc9w==} buraha@0.0.1: resolution: {integrity: sha512-G563A0mTbzknm2jDaNxfZuNKIdeArs8T+XQN6t+KbmgnOoevXSXhKDkyf8Md/36Jrx99ikwbCag37VGe3myExQ==} @@ -5624,6 +6057,10 @@ packages: resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} engines: {node: '>=14.16'} + cacheable-request@12.0.1: + resolution: {integrity: sha512-Yo9wGIQUaAfIbk+qY0X4cDQgCosecfBe3V9NSyeY4qPC2SAkbCS4Xj79VP8WOzitpJUZKc/wsRCYF5ariDIwkg==} + engines: {node: '>=18'} + cacheable-request@7.0.2: resolution: {integrity: sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==} engines: {node: '>=8'} @@ -5713,8 +6150,8 @@ packages: character-parser@2.2.0: resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} - chart.js@4.4.2: - resolution: {integrity: sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==} + chart.js@4.4.3: + resolution: {integrity: sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==} engines: {pnpm: '>=8'} chartjs-adapter-date-fns@3.0.0: @@ -5763,8 +6200,8 @@ packages: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} - chromatic@11.3.0: - resolution: {integrity: sha512-q1ZtJDJrjLGnz60ivpC16gmd7KFzcaA4eTb7gcytCqbaKqlHhCFr1xQmcUDsm14CK7JsqdkFU6S+JQdOd2ZNJg==} + chromatic@11.5.4: + resolution: {integrity: sha512-+J+CopeUSyGUIQJsU6X7CfvSmeVBs0j6LZ9AgF4+XTjI4pFmUiUXsTc00rH9x9W1jCppOaqDXv2kqJJXGDK3mA==} hasBin: true peerDependencies: '@chromatic-com/cypress': ^0.*.* || ^1.0.0 @@ -5799,10 +6236,6 @@ packages: engines: {node: '>=8.0.0', npm: '>=5.0.0'} hasBin: true - cli-spinners@2.7.0: - resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} - engines: {node: '>=6'} - cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} @@ -5982,8 +6415,8 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} - core-js-compat@3.33.3: - resolution: {integrity: sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow==} + core-js-compat@3.37.1: + resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==} core-js@3.29.1: resolution: {integrity: sha512-+jwgnhg6cQxKYIIjGtAHq2nwUOolo9eoFZ4sHfUH09BLXBgxnH4gA0zEd+t+BO2cNB8idaBtZFcFTRjQJRJmAw==} @@ -6037,9 +6470,9 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - crypto-random-string@2.0.0: - resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} - engines: {node: '>=8'} + crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} css-declaration-sorter@7.2.0: resolution: {integrity: sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==} @@ -6102,13 +6535,8 @@ packages: cwise-compiler@1.1.3: resolution: {integrity: sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ==} - cypress@13.7.3: - resolution: {integrity: sha512-uoecY6FTCAuIEqLUYkTrxamDBjMHTYak/1O7jtgwboHiTnS1NaMOoR08KcTrbRZFCBvYOiS4tEkQRmsV+xcrag==} - engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} - hasBin: true - - cypress@13.8.1: - resolution: {integrity: sha512-Uk6ovhRbTg6FmXjeZW/TkbRM07KPtvM5gah1BIMp4Y2s+i/NMxgaLw0+PbYTOdw1+egE0FP3mWRiGcRkjjmhzA==} + cypress@13.13.0: + resolution: {integrity: sha512-ou/MQUDq4tcDJI2FsPaod2FZpex4kpIK43JJlcBgWrX8WX7R/05ZxGTuxedOuZBfxjZxja+fbijZGyxiLP6CFA==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} hasBin: true @@ -6162,6 +6590,15 @@ packages: supports-color: optional: true + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} engines: {node: '>=0.10.0'} @@ -6235,10 +6672,6 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - del@6.1.1: - resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} - engines: {node: '>=10'} - delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -6278,6 +6711,9 @@ packages: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + detect-package-manager@2.0.1: resolution: {integrity: sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==} engines: {node: '>=12'} @@ -6300,6 +6736,10 @@ packages: resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} engines: {node: '>=0.3.1'} + diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + dijkstrajs@1.0.2: resolution: {integrity: sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==} @@ -6371,8 +6811,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - ejs@3.1.9: - resolution: {integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==} + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} engines: {node: '>=0.10.0'} hasBin: true @@ -6438,8 +6878,8 @@ packages: es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - es-module-lexer@0.9.3: - resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} es-set-tostringtag@2.0.1: resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} @@ -6476,11 +6916,16 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.20.2: - resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} hasBin: true + esbuild@0.22.0: + resolution: {integrity: sha512-zNYA6bFZsVnsU481FnGAQjLDW0Pl/8BGG7EvAp15RzUvGC+ME7hf1q7LvIfStEQBz/iEHuBJCYcOwPmNCf1Tlw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -6550,8 +6995,8 @@ packages: '@typescript-eslint/parser': optional: true - eslint-plugin-vue@9.25.0: - resolution: {integrity: sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==} + eslint-plugin-vue@9.26.0: + resolution: {integrity: sha512-eTvlxXgd4ijE1cdur850G6KalZqk65k1JKoOI2d1kT3hr8sPD07j1q98FRFdNnpxBELGPWxZmInxeHGF/GxtqQ==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 @@ -6563,20 +7008,27 @@ packages: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.0.1: + resolution: {integrity: sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint@8.53.0: - resolution: {integrity: sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true + eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint@9.6.0: + resolution: {integrity: sha512-ElQkdLMEEqQNM9Njff+2Y4q2afHk7JpkPvrd7Xh7xefwgQynqPxwf55J7di9+MEibWUGdNjFF9ITG9Pck5M84w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true + espree@10.1.0: + resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6590,6 +7042,10 @@ packages: resolution: {integrity: sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==} engines: {node: '>=0.10'} + esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -6652,6 +7108,10 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} + execa@9.2.0: + resolution: {integrity: sha512-vpOyYg7UAVKLAWWtRS2gAdgkT7oJbCn0me3gmUmxZih4kd3MF/oo8kNTBTIbkO3yuuF5uB4ZCZfn8BOolITYhg==} + engines: {node: ^18.19.0 || >=20.5.0} + executable@4.1.1: resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} engines: {node: '>=4'} @@ -6667,10 +7127,6 @@ packages: exponential-backoff@3.1.1: resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} - express@4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} - engines: {node: '>= 0.10.0'} - express@4.19.2: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} @@ -6744,11 +7200,8 @@ packages: resolution: {integrity: sha512-F4o8ZIMVx4YoxGfwrZys6wyjl40gF3Yv6AWWRy62ozFAyZBSS831/uyyCAqKYw3tR73g180ryG98yih6To1PUQ==} engines: {node: '>= 10'} - fastify@4.26.2: - resolution: {integrity: sha512-90pjTuPGrfVKtdpLeLzND5nyC4woXZN5VadiNQCicj/iJU4viNHKhsAnb7jmv1vu2IzkLXyBiCzdWuzeXgQ5Ug==} - - fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + fastify@4.28.1: + resolution: {integrity: sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ==} fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -6774,9 +7227,13 @@ packages: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} file-system-cache@2.3.0: resolution: {integrity: sha512-l4DMNdsIPsVnKrgEXbJwDJsA5mB8rGwHYERMgqQx/xAUtChPJMre1bXBzDEqqVbWv9AIbFezXMxeEkZDSrXUOQ==} @@ -6804,6 +7261,10 @@ packages: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + finalhandler@1.2.0: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} engines: {node: '>= 0.8'} @@ -6843,20 +7304,20 @@ packages: resolution: {integrity: sha512-MdYSsbdCaIRjzo5edthZtWmEZVMfr1qrtYZUHIdO3swCE+CoZA8S5l0s4jDsYlTa9ZiXv0pTgpzE7s4N8NeUOA==} engines: {node: '>=18'} - flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} - flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} flow-parser@0.202.0: resolution: {integrity: sha512-ZiXxSIXK3zPmY3zrzCofFonM2T+/3Jz5QZKJyPVtUERQEJUnYkXBQ+0H3FzyqiyJs+VXqb/UNU6/K6sziVYdxw==} engines: {node: '>=0.4.0'} - fluent-ffmpeg@2.1.2: - resolution: {integrity: sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==} - engines: {node: '>=0.8.0'} + fluent-ffmpeg@2.1.3: + resolution: {integrity: sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==} + engines: {node: '>=18'} follow-redirects@1.15.2: resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} @@ -6978,6 +7439,10 @@ packages: get-intrinsic@1.2.1: resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-npm-tarball-url@2.0.3: resolution: {integrity: sha512-R/PW6RqyaBQNWYaSyfrh54/qtcnOp22FHCCiRhSSZj0FP3KQWCsxxt0DzIdVTbwTqe9CtQfvl/FPD4UIPt4pqw==} engines: {node: '>=12.17'} @@ -7005,6 +7470,10 @@ packages: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} @@ -7056,12 +7525,19 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true + glob@10.4.2: + resolution: {integrity: sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==} + engines: {node: '>=16 || 14 >=14.18'} + hasBin: true + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported global-dirs@3.0.1: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} @@ -7071,14 +7547,18 @@ packages: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - globals@13.19.0: - resolution: {integrity: sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==} - engines: {node: '>=8'} - globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.7.0: + resolution: {integrity: sha512-ivatRXWwKC6ImcdKO7dOwXuXR5XFrdwo45qFwD7D0qOkEPzzJdLXC3BHceBdyrPOD3p1suPaWi4Y4NMm2D++AQ==} + engines: {node: '>=18'} + globalthis@1.0.3: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} engines: {node: '>= 0.4'} @@ -7087,6 +7567,10 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + globby@14.0.1: + resolution: {integrity: sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==} + engines: {node: '>=18'} + google-protobuf@3.21.2: resolution: {integrity: sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==} @@ -7101,8 +7585,8 @@ packages: resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} engines: {node: '>=14.16'} - got@14.2.1: - resolution: {integrity: sha512-KOaPMremmsvx6l9BLC04LYE6ZFW4x7e4HkTe3LwBmtuYYQwpeS4XKqzhubTIkaQ1Nr+eXxeori0zuwupXMovBQ==} + got@14.4.1: + resolution: {integrity: sha512-IvDJbJBUeexX74xNQuMIVgCRRuNOm5wuK+OC3Dc2pnSoh1AOmgc7JVj7WC+cJ4u0aPcO9KZ2frTXcqK4W/5qTQ==} engines: {node: '>=20'} graceful-fs@4.2.11: @@ -7260,6 +7744,10 @@ packages: resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} engines: {node: '>= 14'} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + http-signature@1.2.0: resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} engines: {node: '>=0.8', npm: '>=1.3.7'} @@ -7292,6 +7780,10 @@ packages: resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==} engines: {node: '>= 14'} + https-proxy-agent@7.0.4: + resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} + engines: {node: '>= 14'} + human-signals@1.1.1: resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} engines: {node: '>=8.12.0'} @@ -7308,6 +7800,10 @@ packages: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} + human-signals@7.0.0: + resolution: {integrity: sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==} + engines: {node: '>=18.18.0'} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -7347,8 +7843,8 @@ packages: import-in-the-middle@1.4.2: resolution: {integrity: sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==} - import-in-the-middle@1.7.4: - resolution: {integrity: sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==} + import-in-the-middle@1.8.1: + resolution: {integrity: sha512-yhRwoHtiLGvmSozNOALgjRPFI6uYsds60EoMqqnXyyv+JOIW/BrrLejuTGBt+bq0T5tLzOHrN0T7xYTm4Qt/ng==} import-lazy@4.0.0: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} @@ -7398,6 +7894,9 @@ packages: intersection-observer@0.12.2: resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==} + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + ioredis@5.4.1: resolution: {integrity: sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==} engines: {node: '>=12.22.0'} @@ -7405,13 +7904,13 @@ packages: iota-array@1.0.0: resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==} - ip-address@7.1.0: - resolution: {integrity: sha512-V9pWC/VJf2lsXqP7IWJ+pe3P1/HCYGBMZrrnT62niLGjAfCbeiwXMUxaeHvnVlz19O27pvXP4azs+Pj/A0x+SQ==} - engines: {node: '>= 10'} + ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} - ip-cidr@3.1.0: - resolution: {integrity: sha512-HUCn4snshEX1P8cja/IyU3qk8FVDW8T5zZcegDFbu4w7NojmAhk5NcOgj3M8+0fmumo1afJTPDtJlzsxLdOjtg==} - engines: {node: '>=10.0.0'} + ip-cidr@4.0.1: + resolution: {integrity: sha512-V5Nce94SVJ7NtyT/UKUeTM7sY3V7TEk48hURhtBgTiGduOa5t6p9Hd+zBOGvr4Gu7iWPxFVYNl017p0akQA84w==} + engines: {node: '>=16.14.0'} ip-regex@4.3.0: resolution: {integrity: sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==} @@ -7553,10 +8052,6 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-path-cwd@2.2.0: - resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} - engines: {node: '>=6'} - is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} @@ -7605,12 +8100,16 @@ packages: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} - is-svg@5.0.0: - resolution: {integrity: sha512-sRl7J0oX9yUNamSdc8cwgzh9KBLnQXNzGmW0RVHwg/jEYjGNYHC6UvnYD8+hAeut9WwxRvhG9biK7g/wDGxcMw==} + is-svg@5.0.1: + resolution: {integrity: sha512-mLYxDsfisQWdS4+gSblAwhATDoNMS/tx8G7BKA+aBIf7F0m1iUwMvuKAo6mW4WMleQAEE50I1Zqef9yMMfHk3w==} engines: {node: '>=14.16'} is-symbol@1.0.4: @@ -7628,6 +8127,10 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + is-unicode-supported@2.0.0: + resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} + engines: {node: '>=18'} + is-weakmap@2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} @@ -7684,6 +8187,10 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} + istanbul-lib-source-maps@5.0.4: + resolution: {integrity: sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==} + engines: {node: '>=10'} + istanbul-reports@3.1.6: resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} engines: {node: '>=8'} @@ -7696,6 +8203,10 @@ packages: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} + jackspeak@3.4.0: + resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} + engines: {node: '>=14'} + jake@10.8.5: resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==} engines: {node: '>=10'} @@ -7856,6 +8367,9 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.0: + resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} + js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -7883,8 +8397,8 @@ packages: '@babel/preset-env': optional: true - jsdom@24.0.0: - resolution: {integrity: sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==} + jsdom@24.1.0: + resolution: {integrity: sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==} engines: {node: '>=18'} peerDependencies: canvas: ^2.11.2 @@ -7966,9 +8480,6 @@ packages: jsrsasign@11.1.0: resolution: {integrity: sha512-Ov74K9GihaK9/9WncTe1mPmvrO7Py665TUfUKvraXBpu+xcTWitrtuOwcjf4KMU9maPaYn0OuaWy0HOzy/GBXg==} - jssha@3.3.1: - resolution: {integrity: sha512-VCMZj12FCFMQYcFLPRm/0lOBbLi8uM2BhXPTqw3U4YAfs4AZfiApOoBLoN8cQE60Z50m1MYMTQVCfgF/KaCVhQ==} - jstransformer@1.0.0: resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} @@ -8045,8 +8556,8 @@ packages: enquirer: optional: true - local-pkg@0.4.3: - resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} locate-path@3.0.0: @@ -8073,9 +8584,6 @@ packages: lodash.isarguments@3.1.0: resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} - lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} @@ -8157,9 +8665,8 @@ packages: magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} - magic-string@0.30.7: - resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} - engines: {node: '>=12'} + magicast@0.3.4: + resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==} mailcheck@1.1.1: resolution: {integrity: sha512-3WjL8+ZDouZwKlyJBMp/4LeziLFXgleOdsYu87piGcMLqhBzCsy2QFdbtAwv757TFC/rtqd738fgJw1tFQCSgA==} @@ -8252,8 +8759,8 @@ packages: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} - meilisearch@0.38.0: - resolution: {integrity: sha512-bHaq8nYxSKw9/Qslq1Zes5g9tHgFkxy/I9o8942wv2PqlNOT0CzptIkh/x98N52GikoSZOXSQkgt6oMjtf5uZw==} + meilisearch@0.41.0: + resolution: {integrity: sha512-5KcGLxEXD7E+uNO7R68rCbGSHgCqeM3Q3RFFLSsN7ZrIgr8HPDXVAIlP4LHggAZfk0FkSzo8VSXifHCwa2k80g==} memoizerific@1.11.3: resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} @@ -8367,8 +8874,8 @@ packages: micromark@4.0.0: resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} engines: {node: '>=8.6'} mime-db@1.52.0: @@ -8480,6 +8987,10 @@ packages: resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + minizlib@1.3.3: resolution: {integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==} @@ -8541,13 +9052,13 @@ packages: msgpackr@1.10.1: resolution: {integrity: sha512-r5VRLv9qouXuLiIBrLpl2d5ZvPt8svdQTl5/vMvE4nzDMyEX4sgW5yWhuBBj5UmgwOTWj8CIdSXn5sAfsHAWIQ==} - msw-storybook-addon@2.0.1: - resolution: {integrity: sha512-pZ3JDQ9HkGQ3XDMIHvMcDSI4Vbp/LHmwHwiZu+pHLzimtI1vhAo1swjFEDAEJuBcozljYvREEC4sS7rQHPNtWg==} + msw-storybook-addon@2.0.2: + resolution: {integrity: sha512-sdw++X+AoUbaG2ku493ViVqCA/LfqnybXsKXyPUrF3ZS/x8BqGBnkBLmT/0SHCC5zIO3Vfm5zlclAxnhqOOikQ==} peerDependencies: msw: ^2.0.0 - msw@2.2.14: - resolution: {integrity: sha512-64i8rNCa1xzDK8ZYsTrVMli05D687jty8+Th+PU5VTbJ2/4P7fkQFVyDQ6ZFT5FrNR8z2BHhbY47fKNvfHrumA==} + msw@2.3.1: + resolution: {integrity: sha512-ocgvBCLn/5l3jpl1lssIb3cniuACJLoOfZu01e3n5dbJrpA5PeeWn28jCLgQDNt6d7QT8tF2fYRzm9JoEHtiig==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -8701,8 +9212,8 @@ packages: node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} - nodemailer@6.9.13: - resolution: {integrity: sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA==} + nodemailer@6.9.14: + resolution: {integrity: sha512-Dobp/ebDKBvz91sbtRKhcznLThrKxKt97GI2FAlAyy+fk19j73Uz3sBXolVtmcXjaorivqsbbbjDY+Jkt4/bQA==} engines: {node: '>=6.0.0'} nodemon@3.0.2: @@ -8710,8 +9221,8 @@ packages: engines: {node: '>=10'} hasBin: true - nodemon@3.1.0: - resolution: {integrity: sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==} + nodemon@3.1.4: + resolution: {integrity: sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==} engines: {node: '>=10'} hasBin: true @@ -8757,6 +9268,10 @@ packages: resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} engines: {node: '>=14.16'} + normalize-url@8.0.1: + resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} + engines: {node: '>=14.16'} + npm-run-path@2.0.2: resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} engines: {node: '>=4'} @@ -8769,6 +9284,10 @@ packages: resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + npmlog@5.0.1: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} @@ -8780,8 +9299,8 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nwsapi@2.2.9: - resolution: {integrity: sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==} + nwsapi@2.2.10: + resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==} oauth-sign@0.9.0: resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} @@ -8894,8 +9413,8 @@ packages: ospath@1.2.2: resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==} - otpauth@9.2.3: - resolution: {integrity: sha512-oAG55Ch4MBL5Jdg+RXfKiRCZ2lCwa/UIQKsmSfYbGGLSI4dErY1HPZv0JGPPESIYGyDO3s9iJqM4HU/1IppMoQ==} + otpauth@9.3.1: + resolution: {integrity: sha512-E6d2tMxPofHNk4sRFp+kqW7vQ+WJGO9VLI2N/W00DnI+ThskU12Qa10kyNSGklrzhN5c+wRUsN4GijVgCU2N9w==} outvariant@1.4.2: resolution: {integrity: sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==} @@ -8924,9 +9443,9 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} - p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} p-locate@3.0.0: resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} @@ -8956,6 +9475,9 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} @@ -8970,6 +9492,10 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + parse-srcset@1.0.2: resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==} @@ -9030,6 +9556,10 @@ packages: resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} engines: {node: '>=16 || 14 >=14.17'} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} @@ -9046,6 +9576,10 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + path-type@5.0.0: + resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} + engines: {node: '>=12'} + pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -9087,9 +9621,6 @@ packages: peerDependencies: pg: '>=8.0' - pg-protocol@1.6.0: - resolution: {integrity: sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==} - pg-protocol@1.6.1: resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==} @@ -9101,8 +9632,8 @@ packages: resolution: {integrity: sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==} engines: {node: '>=10'} - pg@8.11.5: - resolution: {integrity: sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==} + pg@8.12.0: + resolution: {integrity: sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==} engines: {node: '>= 8.0.0'} peerDependencies: pg-native: '>=3.0.1' @@ -9113,8 +9644,8 @@ packages: pgpass@1.0.5: resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} - photoswipe@5.4.3: - resolution: {integrity: sha512-9UC6oJBK4oXFZ5HcdlcvGkfEHsVrmE4csUdCQhEjHYb3PvPLO3PG7UhnPuOgjxwmhq5s17Un5NUdum01LgBDng==} + photoswipe@5.4.4: + resolution: {integrity: sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA==} engines: {node: '>= 0.12.0'} picocolors@1.0.0: @@ -9136,14 +9667,14 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - pino-abstract-transport@1.1.0: - resolution: {integrity: sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==} + pino-abstract-transport@1.2.0: + resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} - pino-std-serializers@6.1.0: - resolution: {integrity: sha512-KO0m2f1HkrPe9S0ldjx7za9BJjeHqBku5Ch8JyxETxT8dEFGz1PwgrHaOQupVYitpzbFSYm7nnljxD8dik2c+g==} + pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} - pino@8.17.0: - resolution: {integrity: sha512-ey+Mku+PVPhvxglLXMg1l1zQMwSHuNrKC3MD40EDZbkckJmmuY7DYZLIOwwjZ8ix/Nvhe9dZt5H99cgkot9bAw==} + pino@9.2.0: + resolution: {integrity: sha512-g3/hpwfujK5a4oVbaefoJxezLzsDgLcNJeITvC6yrfwYeT9la+edCK42j5QpEQSQCZgTKapXvnQIdgZwvRaZug==} hasBin: true pirates@4.0.5: @@ -9411,8 +9942,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.2.5: - resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + prettier@3.3.2: + resolution: {integrity: sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==} engines: {node: '>=14'} hasBin: true @@ -9432,6 +9963,10 @@ packages: resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} engines: {node: '>= 0.8'} + pretty-ms@9.0.0: + resolution: {integrity: sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==} + engines: {node: '>=18'} + private-ip@2.3.3: resolution: {integrity: sha512-5zyFfekIVUOTVbL92hc8LJOtE/gyGHeREHkJ2yTyByP8Q2YZVoBqLg3EfYLeF0oVvGqtaEX2t2Qovja0/gStXw==} @@ -9517,12 +10052,15 @@ packages: pug-attrs@3.0.0: resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} - pug-code-gen@3.0.2: - resolution: {integrity: sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==} + pug-code-gen@3.0.3: + resolution: {integrity: sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==} pug-error@2.0.0: resolution: {integrity: sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==} + pug-error@2.1.0: + resolution: {integrity: sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==} + pug-filters@4.0.0: resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==} @@ -9547,8 +10085,8 @@ packages: pug-walk@2.0.0: resolution: {integrity: sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==} - pug@3.0.2: - resolution: {integrity: sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==} + pug@3.0.3: + resolution: {integrity: sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==} pump@2.0.1: resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} @@ -9631,10 +10169,6 @@ packages: ratelimiter@3.4.1: resolution: {integrity: sha512-5FJbRW/Jkkdk29ksedAfWFkQkhbUrMx3QJGwMKAypeIiQf4yrLW+gtPKZiaWt4zPrtw1uGufOjGO7UGM6VllsQ==} - raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} - raw-body@2.5.2: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} @@ -9643,8 +10177,8 @@ packages: resolution: {integrity: sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==} engines: {node: '>=12'} - re2@1.21.2: - resolution: {integrity: sha512-f8jqI0vCbwDhzY66Fgx1V2RoNDdmAupKkqRqR/AEF+2/MZNRbtEOjax6oHSht95MU40vx6+2ITsJr/9esukckg==} + re2@1.21.3: + resolution: {integrity: sha512-GI+KoGkHT4kxTaX+9p0FgNB1XUnCndO9slG5qqeEoZ7kbf6Dk6ohQVpmwKVeSp7LPLn+g6Q3BaCopz4oHuBDuQ==} react-colorful@5.6.1: resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} @@ -9684,6 +10218,36 @@ packages: react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + react-remove-scroll-bar@2.3.6: + resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.5.7: + resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.1: + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -9725,10 +10289,6 @@ packages: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} - recast@0.23.4: - resolution: {integrity: sha512-qtEDqIZGVcSZCHniWwZWbRy79Dc6Wp3kT/UmDA2RJKBPg7+7k51aQBZirHmUGn5uvHf2rg8DkjizrN26k61ATw==} - engines: {node: '>= 4'} - recast@0.23.6: resolution: {integrity: sha512-9FHoNjX1yjuesMwuthAmPKabxYQdOgihFYmT5ebXfYGBcnqXZf3WOVz+5foEZ8Y83P4ZY6yQD5GMmtV+pgCCAQ==} engines: {node: '>= 4'} @@ -9852,9 +10412,6 @@ packages: resolution: {integrity: sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==} engines: {node: '>=10'} - resolve@1.19.0: - resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} - resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -9887,6 +10444,7 @@ packages: rimraf@2.6.3: resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true rimraf@2.7.1: @@ -9897,14 +10455,17 @@ packages: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true - rollup@4.17.2: - resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} + rollup@4.18.0: + resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true rrweb-cssom@0.6.0: resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} + rrweb-cssom@0.7.1: + resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} + rss-parser@3.13.0: resolution: {integrity: sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==} @@ -9940,8 +10501,8 @@ packages: sanitize-html@2.13.0: resolution: {integrity: sha512-Xff91Z+4Mz5QiNSLdLWwjgBDm5b1RU6xBT0+12rapjiaR7SwfRdjw8f+6Rir2MXKLrDicRFHdb51hGOAxmsUIA==} - sass@1.76.0: - resolution: {integrity: sha512-nc3LeqvF2FNW5xGF1zxZifdW3ffIz5aBb7I7tSvOoNu7z1RQ6pFt9MBuiPtjgaI62YWrM/txjWlOCFiGtf2xpw==} + sass@1.77.6: + resolution: {integrity: sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==} engines: {node: '>=14.0.0'} hasBin: true @@ -10015,8 +10576,8 @@ packages: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} - sharp@0.33.3: - resolution: {integrity: sha512-vHUeXJU1UvlO/BNwTpT0x/r53WkLUVxrmb5JTgW92fdFCFk0ispLMAeu/jPO2vjkXM1fYUi3K7/qcLF47pwM1A==} + sharp@0.33.4: + resolution: {integrity: sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==} engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@1.2.0: @@ -10035,8 +10596,8 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shiki@1.4.0: - resolution: {integrity: sha512-5WIn0OL8PWm7JhnTwRWXniy6eEDY234mRrERVlFa646V2ErQqwIFd2UML7e0Pq9eqSKLoMa3Ke+xbsF+DAuy+Q==} + shiki@1.10.0: + resolution: {integrity: sha512-YD2sXQ+TMD/F9BimV9Jn0wj35pqOvywvOG/3PB6hGHyGKlM7TJ9tyJ02jOb2kF8F0HfJwKNYrh3sW7jEcuRlXA==} shimmer@1.2.1: resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} @@ -10054,8 +10615,8 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-oauth2@5.0.0: - resolution: {integrity: sha512-8291lo/z5ZdpmiOFzOs1kF3cxn22bMj5FFH+DNUppLJrpoIlM1QnFiE7KpshHu3J3i21TVcx4yW+gXYjdCKDLQ==} + simple-oauth2@5.0.1: + resolution: {integrity: sha512-JcmGdzvbHKU3GegF3BK6zNi46DqFTxPMjwYddu2bgYqZuy7Gtm8U8wdedkVE4lI4LEqXocmPBLAvC4BIiiBc5w==} simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -10155,6 +10716,10 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + slice-ansi@3.0.0: resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} engines: {node: '>=8'} @@ -10175,8 +10740,8 @@ packages: resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} - sonic-boom@3.7.0: - resolution: {integrity: sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==} + sonic-boom@4.0.1: + resolution: {integrity: sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==} sort-keys-length@1.0.1: resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} @@ -10236,8 +10801,8 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - sprintf-js@1.1.2: - resolution: {integrity: sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==} + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} sshpk@1.17.0: resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} @@ -10258,8 +10823,8 @@ packages: standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} - start-server-and-test@2.0.3: - resolution: {integrity: sha512-QsVObjfjFZKJE6CS6bSKNwWZCKBG6975/jKRPPGFfFh+yOQglSeGXiNWjzgQNXdphcBI9nXbyso9tPfX4YAUhg==} + start-server-and-test@2.0.4: + resolution: {integrity: sha512-CKNeBTcP0hVqIlNismHMudb9q3lLdAjcVPO13/7gfI66fcJpeIb/o4NzQd1JK/CD+lfWVqr10ZH9Y14+OwlJuw==} engines: {node: '>=16'} hasBin: true @@ -10296,8 +10861,8 @@ packages: react-dom: optional: true - storybook@8.0.9: - resolution: {integrity: sha512-/Mvij0Br5bUwJpCvqAUZMEDIWmdRxEyllvVj8Ukw5lIWJePxfpSsz4px5jg9+R6B9tO8sQSqjg4HJvQ/pZk8Tg==} + storybook@8.1.11: + resolution: {integrity: sha512-3KjIhF8lczXhKKHyHbOqV30dvuRYJSxc0d1as/C8kybuwE7cLaydhWGma7VBv5bTSPv0rDzucx7KcO+achArPg==} hasBin: true stream-browserify@3.0.0: @@ -10395,6 +10960,10 @@ packages: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -10407,8 +10976,8 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@1.3.0: - resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + strip-literal@2.1.0: + resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} strip-outer@2.0.0: resolution: {integrity: sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg==} @@ -10459,8 +11028,8 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - systeminformation@5.22.7: - resolution: {integrity: sha512-AWxlP05KeHbpGdgvZkcudJpsmChc2Y5Eo/GvxG/iUA/Aws5LZKHAMSeAo+V+nD+nxWZaxrwpWcnx4SH3oxNL3A==} + systeminformation@5.22.11: + resolution: {integrity: sha512-aLws5yi4KCHTb0BVvbodQY5bY8eW4asMRDTxTW46hqw9lGjACX6TlLdJrkdoHYRB0qs+MekqEq1zG7WDnWE8Ug==} engines: {node: '>=8.0.0'} os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true @@ -10490,20 +11059,20 @@ packages: telejson@7.2.0: resolution: {integrity: sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ==} - temp-dir@2.0.0: - resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} - engines: {node: '>=8'} + temp-dir@3.0.0: + resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} + engines: {node: '>=14.16'} temp@0.8.4: resolution: {integrity: sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==} engines: {node: '>=6.0.0'} - tempy@1.0.1: - resolution: {integrity: sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==} - engines: {node: '>=10'} + tempy@3.1.0: + resolution: {integrity: sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==} + engines: {node: '>=14.16'} - terser@5.30.3: - resolution: {integrity: sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==} + terser@5.31.1: + resolution: {integrity: sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==} engines: {node: '>=10'} hasBin: true @@ -10524,14 +11093,14 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - thread-stream@2.3.0: - resolution: {integrity: sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==} + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} - three@0.164.1: - resolution: {integrity: sha512-iC/hUBbl1vzFny7f5GtqzVXYjMJKaTPxiCxXfrvVdBi1Sf+jhd1CAkitiFwC7mIBFCo3MrDLJG97yisoaWig0w==} + three@0.165.0: + resolution: {integrity: sha512-cc96IlVYGydeceu0e5xq70H8/yoVT/tXBxV/W8A/U6uOq7DXc4/s1Mkmnu6SqoYGhSRWWYFOhVwvq6V0VtbplA==} - throttle-debounce@5.0.0: - resolution: {integrity: sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==} + throttle-debounce@5.0.2: + resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} engines: {node: '>=12.22'} throttleit@1.0.0: @@ -10546,9 +11115,6 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tiny-invariant@1.3.1: - resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} - tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -10562,8 +11128,8 @@ packages: tinycolor2@1.6.0: resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} - tinypool@0.7.0: - resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} engines: {node: '>=14.0.0'} tinyspy@2.2.0: @@ -10588,10 +11154,6 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - toad-cache@3.3.0: - resolution: {integrity: sha512-3oDzcogWGHZdkwrHyvJVpPjA7oNzY6ENOV3PsWJY9XYPZ6INo94Yd47s5may1U+nleBPwDhrRiTPMIvKaa3MQg==} - engines: {node: '>=12'} - toad-cache@3.7.0: resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} engines: {node: '>=12'} @@ -10618,8 +11180,8 @@ packages: resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} engines: {node: '>=0.8'} - tough-cookie@4.1.3: - resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} tr46@0.0.3: @@ -10666,8 +11228,8 @@ packages: ts-map@1.0.3: resolution: {integrity: sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==} - tsc-alias@1.8.8: - resolution: {integrity: sha512-OYUOd2wl0H858NvABWr/BoSKNERw3N9GTi3rHPK8Iv4O1UyUXIrTTOAZNHsjlVpXFOhpJBVARI1s+rzwLivN3Q==} + tsc-alias@1.8.10: + resolution: {integrity: sha512-Ibv4KAWfFkFdKJxnWfVtdOmB0Zi1RJVxcbPGiCDsFpCQSsmpWyuzHG3rQyI5YkobWwxFPEyQfu1hdo4qLG2zPw==} hasBin: true tsconfig-paths@3.15.0: @@ -10677,8 +11239,8 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} - tsd@0.30.7: - resolution: {integrity: sha512-oTiJ28D6B/KXoU3ww/Eji+xqHJojiuPVMwA12g4KYX1O72N93Nb6P3P3h2OAhhf92Xl8NIhb/xFmBZd5zw/xUw==} + tsd@0.31.1: + resolution: {integrity: sha512-sSL84A0SFwx2xGMWrxlGaarKFSQszWjJS2vgNDDLwatytzg2aq6ShlwHsBYxRNmjzXISODwMva5ZOdAg/4AoOA==} engines: {node: '>=14.16'} hasBin: true @@ -10688,6 +11250,9 @@ packages: tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + tsx@4.4.0: resolution: {integrity: sha512-4fwcEjRUxW20ciSaMB8zkpGwCPxuRGnadDuj/pBk5S9uT29zvWz15PK36GrKJo45mSJomDxVejZ73c6lr3811Q==} engines: {node: '>=18.0.0'} @@ -10707,10 +11272,6 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - type-fest@0.16.0: - resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} - engines: {node: '>=10'} - type-fest@0.18.1: resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} engines: {node: '>=10'} @@ -10731,10 +11292,18 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} + type-fest@4.20.1: + resolution: {integrity: sha512-R6wDsVsoS9xYOpy8vgeBlqpdOyzJ12HNfQhC/aAKWM3YoCV9TtunJzh/QpkMgeDhkoynDcw5f1y+qF9yc/HHyg==} + engines: {node: '>=16'} + type-fest@4.9.0: resolution: {integrity: sha512-KS/6lh/ynPGiHD/LnAobrEFq3Ad4pBzOlJ1wAnJx9N4EYoqFhMfLIBjUT2UEx4wg5ZE+cC1ob6DCSpppVo+rtg==} engines: {node: '>=16'} @@ -10829,8 +11398,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.5.2: - resolution: {integrity: sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==} + typescript@5.5.3: + resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} engines: {node: '>=14.17'} hasBin: true @@ -10882,6 +11451,10 @@ packages: resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} engines: {node: '>=4'} + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + unified@11.0.4: resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} @@ -10896,9 +11469,9 @@ packages: resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - unique-string@2.0.0: - resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} - engines: {node: '>=8'} + unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} unist-util-is@6.0.0: resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} @@ -10950,6 +11523,26 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + use-callback-ref@1.3.2: + resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.2: + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + utf-8-validate@6.0.3: resolution: {integrity: sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==} engines: {node: '>=6.14.2'} @@ -10964,6 +11557,10 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + uuid@3.4.0: resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. @@ -10977,8 +11574,8 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true - v-code-diff@1.11.0: - resolution: {integrity: sha512-lBlO+FXw3I3qFKbnlorXZ4sb5cFnrdxlc6lj3Y1CWrbn2LC7PoVbGlwH0W+nvAVX1rdJhhc15rKIQdHyMkXe/w==} + v-code-diff@1.12.0: + resolution: {integrity: sha512-vvdCBG02mIIiW6Gx6jF119hzxELt+6TlJIwchglR1JYzboHePNxIkVBjR/aoAOVlsGa+5Vtb77cd/N84nrXWPA==} peerDependencies: '@vue/composition-api': ^1.4.9 vue: ^2.6.0 || >=3.0.0 @@ -10993,10 +11590,6 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - validator@13.9.0: - resolution: {integrity: sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==} - engines: {node: '>= 0.10'} - vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -11011,16 +11604,16 @@ packages: vfile@6.0.1: resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} - vite-node@0.34.6: - resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} - engines: {node: '>=v14.18.0'} + vite-node@1.6.0: + resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true vite-plugin-turbosnap@1.0.3: resolution: {integrity: sha512-p4D8CFVhZS412SyQX125qxyzOgIFouwOcvjZWk6bQbNPR1wtaEzFT6jZxAjf1dejlGqa6fqHcuCvQea6EWUkUA==} - vite@5.2.11: - resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} + vite@5.3.2: + resolution: {integrity: sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -11053,22 +11646,22 @@ packages: peerDependencies: vitest: '>=0.16.0' - vitest@0.34.6: - resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==} - engines: {node: '>=v14.18.0'} + vitest@1.6.0: + resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@vitest/browser': '*' - '@vitest/ui': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.6.0 + '@vitest/ui': 1.6.0 happy-dom: '*' jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true + '@types/node': + optional: true '@vitest/browser': optional: true '@vitest/ui': @@ -11077,12 +11670,6 @@ packages: optional: true jsdom: optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true void-elements@3.1.0: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} @@ -11109,6 +11696,9 @@ packages: resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} hasBin: true + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + vue-component-meta@2.0.16: resolution: {integrity: sha512-IyIMClUMYcKxAL34GqdPbR4V45MUeHXqQiZlHxeYMV5Qcqp4M+CEmtGpF//XBSS138heDkYkceHAtJQjLUB1Lw==} peerDependencies: @@ -11123,8 +11713,8 @@ packages: vue-component-type-helpers@2.0.16: resolution: {integrity: sha512-qisL/iAfdO++7w+SsfYQJVPj6QKvxp4i1MMxvsNO41z/8zu3KuAw9LkhKUfP/kcOWGDxESp+pQObWppXusejCA==} - vue-component-type-helpers@2.0.21: - resolution: {integrity: sha512-3NaicyZ7N4B6cft4bfb7dOnPbE9CjLcx+6wZWAg5zwszfO4qXRh+U52dN5r5ZZfc6iMaxKCEcoH9CmxxoFZHLg==} + vue-component-type-helpers@2.0.24: + resolution: {integrity: sha512-Jr5N8QVYEcbQuMN1LRgvg61758G8HTnzUlQsAFOxx6Y6X8kmhJ7C+jOvWsQruYxi3uHhhS6BghyRlyiwO99DBg==} vue-demi@0.14.7: resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} @@ -11142,8 +11732,8 @@ packages: peerDependencies: vue: '>=2' - vue-eslint-parser@9.4.2: - resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==} + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' @@ -11162,14 +11752,14 @@ packages: vue-template-compiler@2.7.14: resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==} - vue-tsc@2.0.16: - resolution: {integrity: sha512-/gHAWJa216PeEhfxtAToIbxdWgw01wuQzo48ZUqMYVEyNqDp+OYV9xMO5HaPS2P3Ls0+EsjguMZLY4cGobX4Ew==} + vue-tsc@2.0.24: + resolution: {integrity: sha512-1qi4P8L7yS78A7OJ7CDDxUIZPD6nVxoQEgX3DkRZNi1HI1qOfzOJwQlNpmwkogSVD6S/XcanbW9sktzpSxz6rA==} hasBin: true peerDependencies: - typescript: '*' + typescript: '>=5.0.0' - vue@3.4.26: - resolution: {integrity: sha512-bUIq/p+VB+0xrJubaemrfhk1/FiW9iX+pDV+62I/XJ6EkspAO9/DXEjbDFoe8pIfOZBqfk45i9BMc41ptP/uRg==} + vue@3.4.31: + resolution: {integrity: sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -11310,8 +11900,8 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - ws@8.17.0: - resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==} + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -11403,10 +11993,9 @@ packages: resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} engines: {node: '>=12.20'} - z-schema@5.0.5: - resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} - engines: {node: '>=8.0.0'} - hasBin: true + yoctocolors@2.0.2: + resolution: {integrity: sha512-Ct97huExsu7cWeEjmrXlofevF8CvzUglJ4iGUet5B8xn1oumtAZBpHU4GzYuoE6PVqcZ5hghtBrSlhwHuR1Jmw==} + engines: {node: '>=18'} zip-stream@6.0.1: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} @@ -11442,458 +12031,510 @@ snapshots: dependencies: default-browser-id: 3.0.0 - '@aws-crypto/crc32@3.0.0': - dependencies: - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.413.0 - tslib: 1.14.1 - - '@aws-crypto/crc32c@3.0.0': + '@aws-crypto/crc32@5.2.0': dependencies: - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.413.0 - tslib: 1.14.1 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.598.0 + tslib: 2.6.2 - '@aws-crypto/ie11-detection@3.0.0': + '@aws-crypto/crc32c@5.2.0': dependencies: - tslib: 1.14.1 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.598.0 + tslib: 2.6.2 - '@aws-crypto/sha1-browser@3.0.0': + '@aws-crypto/sha1-browser@5.2.0': dependencies: - '@aws-crypto/ie11-detection': 3.0.0 - '@aws-crypto/supports-web-crypto': 3.0.0 - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.413.0 + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.598.0 '@aws-sdk/util-locate-window': 3.208.0 - '@aws-sdk/util-utf8-browser': 3.259.0 - tslib: 1.14.1 + '@smithy/util-utf8': 2.0.0 + tslib: 2.6.2 - '@aws-crypto/sha256-browser@3.0.0': + '@aws-crypto/sha256-browser@5.2.0': dependencies: - '@aws-crypto/ie11-detection': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-crypto/supports-web-crypto': 3.0.0 - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.413.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.598.0 '@aws-sdk/util-locate-window': 3.208.0 - '@aws-sdk/util-utf8-browser': 3.259.0 - tslib: 1.14.1 + '@smithy/util-utf8': 2.0.0 + tslib: 2.6.2 - '@aws-crypto/sha256-js@3.0.0': + '@aws-crypto/sha256-js@5.2.0': dependencies: - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.413.0 - tslib: 1.14.1 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.598.0 + tslib: 2.6.2 - '@aws-crypto/supports-web-crypto@3.0.0': + '@aws-crypto/supports-web-crypto@5.2.0': dependencies: - tslib: 1.14.1 + tslib: 2.6.2 - '@aws-crypto/util@3.0.0': + '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.413.0 - '@aws-sdk/util-utf8-browser': 3.259.0 - tslib: 1.14.1 - - '@aws-sdk/client-s3@3.412.0': - dependencies: - '@aws-crypto/sha1-browser': 3.0.0 - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.410.0 - '@aws-sdk/credential-provider-node': 3.410.0 - '@aws-sdk/middleware-bucket-endpoint': 3.410.0 - '@aws-sdk/middleware-expect-continue': 3.410.0 - '@aws-sdk/middleware-flexible-checksums': 3.410.0 - '@aws-sdk/middleware-host-header': 3.410.0 - '@aws-sdk/middleware-location-constraint': 3.410.0 - '@aws-sdk/middleware-logger': 3.410.0 - '@aws-sdk/middleware-recursion-detection': 3.410.0 - '@aws-sdk/middleware-sdk-s3': 3.410.0 - '@aws-sdk/middleware-signing': 3.410.0 - '@aws-sdk/middleware-ssec': 3.410.0 - '@aws-sdk/middleware-user-agent': 3.410.0 - '@aws-sdk/signature-v4-multi-region': 3.412.0 - '@aws-sdk/types': 3.410.0 - '@aws-sdk/util-endpoints': 3.410.0 - '@aws-sdk/util-user-agent-browser': 3.410.0 - '@aws-sdk/util-user-agent-node': 3.410.0 - '@aws-sdk/xml-builder': 3.310.0 - '@smithy/config-resolver': 2.0.9 - '@smithy/eventstream-serde-browser': 2.0.8 - '@smithy/eventstream-serde-config-resolver': 2.0.8 - '@smithy/eventstream-serde-node': 2.0.8 - '@smithy/fetch-http-handler': 2.1.4 - '@smithy/hash-blob-browser': 2.0.8 - '@smithy/hash-node': 2.0.8 - '@smithy/hash-stream-node': 2.0.8 - '@smithy/invalid-dependency': 2.0.8 - '@smithy/md5-js': 2.0.8 - '@smithy/middleware-content-length': 2.0.10 - '@smithy/middleware-endpoint': 2.0.8 - '@smithy/middleware-retry': 2.0.11 - '@smithy/middleware-serde': 2.0.8 - '@smithy/middleware-stack': 2.0.1 - '@smithy/node-config-provider': 2.0.11 - '@smithy/node-http-handler': 2.5.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/smithy-client': 2.1.5 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.8 - '@smithy/util-base64': 2.0.0 - '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.1.0 - '@smithy/util-defaults-mode-browser': 2.0.9 - '@smithy/util-defaults-mode-node': 2.0.11 - '@smithy/util-retry': 2.0.1 - '@smithy/util-stream': 2.0.11 + '@aws-sdk/types': 3.598.0 '@smithy/util-utf8': 2.0.0 - '@smithy/util-waiter': 2.0.8 - fast-xml-parser: 4.2.5 + tslib: 2.6.2 + + '@aws-sdk/client-s3@3.600.0': + dependencies: + '@aws-crypto/sha1-browser': 5.2.0 + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sso-oidc': 3.600.0(@aws-sdk/client-sts@3.600.0) + '@aws-sdk/client-sts': 3.600.0 + '@aws-sdk/core': 3.598.0 + '@aws-sdk/credential-provider-node': 3.600.0(@aws-sdk/client-sso-oidc@3.600.0)(@aws-sdk/client-sts@3.600.0) + '@aws-sdk/middleware-bucket-endpoint': 3.598.0 + '@aws-sdk/middleware-expect-continue': 3.598.0 + '@aws-sdk/middleware-flexible-checksums': 3.598.0 + '@aws-sdk/middleware-host-header': 3.598.0 + '@aws-sdk/middleware-location-constraint': 3.598.0 + '@aws-sdk/middleware-logger': 3.598.0 + '@aws-sdk/middleware-recursion-detection': 3.598.0 + '@aws-sdk/middleware-sdk-s3': 3.598.0 + '@aws-sdk/middleware-signing': 3.598.0 + '@aws-sdk/middleware-ssec': 3.598.0 + '@aws-sdk/middleware-user-agent': 3.598.0 + '@aws-sdk/region-config-resolver': 3.598.0 + '@aws-sdk/signature-v4-multi-region': 3.598.0 + '@aws-sdk/types': 3.598.0 + '@aws-sdk/util-endpoints': 3.598.0 + '@aws-sdk/util-user-agent-browser': 3.598.0 + '@aws-sdk/util-user-agent-node': 3.598.0 + '@aws-sdk/xml-builder': 3.598.0 + '@smithy/config-resolver': 3.0.4 + '@smithy/core': 2.2.4 + '@smithy/eventstream-serde-browser': 3.0.4 + '@smithy/eventstream-serde-config-resolver': 3.0.3 + '@smithy/eventstream-serde-node': 3.0.4 + '@smithy/fetch-http-handler': 3.2.0 + '@smithy/hash-blob-browser': 3.1.2 + '@smithy/hash-node': 3.0.3 + '@smithy/hash-stream-node': 3.1.2 + '@smithy/invalid-dependency': 3.0.3 + '@smithy/md5-js': 3.0.3 + '@smithy/middleware-content-length': 3.0.3 + '@smithy/middleware-endpoint': 3.0.4 + '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.3 + '@smithy/node-http-handler': 3.1.1 + '@smithy/protocol-http': 4.0.3 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.7 + '@smithy/util-defaults-mode-node': 3.0.7 + '@smithy/util-endpoints': 2.0.4 + '@smithy/util-retry': 3.0.3 + '@smithy/util-stream': 3.0.5 + '@smithy/util-utf8': 3.0.0 + '@smithy/util-waiter': 3.1.2 tslib: 2.6.2 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.410.0': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/middleware-host-header': 3.410.0 - '@aws-sdk/middleware-logger': 3.410.0 - '@aws-sdk/middleware-recursion-detection': 3.410.0 - '@aws-sdk/middleware-user-agent': 3.410.0 - '@aws-sdk/types': 3.410.0 - '@aws-sdk/util-endpoints': 3.410.0 - '@aws-sdk/util-user-agent-browser': 3.410.0 - '@aws-sdk/util-user-agent-node': 3.410.0 - '@smithy/config-resolver': 2.0.9 - '@smithy/fetch-http-handler': 2.1.4 - '@smithy/hash-node': 2.0.8 - '@smithy/invalid-dependency': 2.0.8 - '@smithy/middleware-content-length': 2.0.10 - '@smithy/middleware-endpoint': 2.0.8 - '@smithy/middleware-retry': 2.0.11 - '@smithy/middleware-serde': 2.0.8 - '@smithy/middleware-stack': 2.0.1 - '@smithy/node-config-provider': 2.0.11 - '@smithy/node-http-handler': 2.5.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/smithy-client': 2.1.5 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.8 - '@smithy/util-base64': 2.0.0 - '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.1.0 - '@smithy/util-defaults-mode-browser': 2.0.9 - '@smithy/util-defaults-mode-node': 2.0.11 - '@smithy/util-retry': 2.0.1 - '@smithy/util-utf8': 2.0.0 + '@aws-sdk/client-sso-oidc@3.600.0(@aws-sdk/client-sts@3.600.0)': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sts': 3.600.0 + '@aws-sdk/core': 3.598.0 + '@aws-sdk/credential-provider-node': 3.600.0(@aws-sdk/client-sso-oidc@3.600.0)(@aws-sdk/client-sts@3.600.0) + '@aws-sdk/middleware-host-header': 3.598.0 + '@aws-sdk/middleware-logger': 3.598.0 + '@aws-sdk/middleware-recursion-detection': 3.598.0 + '@aws-sdk/middleware-user-agent': 3.598.0 + '@aws-sdk/region-config-resolver': 3.598.0 + '@aws-sdk/types': 3.598.0 + '@aws-sdk/util-endpoints': 3.598.0 + '@aws-sdk/util-user-agent-browser': 3.598.0 + '@aws-sdk/util-user-agent-node': 3.598.0 + '@smithy/config-resolver': 3.0.4 + '@smithy/core': 2.2.4 + '@smithy/fetch-http-handler': 3.2.0 + '@smithy/hash-node': 3.0.3 + '@smithy/invalid-dependency': 3.0.3 + '@smithy/middleware-content-length': 3.0.3 + '@smithy/middleware-endpoint': 3.0.4 + '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.3 + '@smithy/node-http-handler': 3.1.1 + '@smithy/protocol-http': 4.0.3 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.7 + '@smithy/util-defaults-mode-node': 3.0.7 + '@smithy/util-endpoints': 2.0.4 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/client-sts' - aws-crt - '@aws-sdk/client-sts@3.410.0': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/credential-provider-node': 3.410.0 - '@aws-sdk/middleware-host-header': 3.410.0 - '@aws-sdk/middleware-logger': 3.410.0 - '@aws-sdk/middleware-recursion-detection': 3.410.0 - '@aws-sdk/middleware-sdk-sts': 3.410.0 - '@aws-sdk/middleware-signing': 3.410.0 - '@aws-sdk/middleware-user-agent': 3.410.0 - '@aws-sdk/types': 3.410.0 - '@aws-sdk/util-endpoints': 3.410.0 - '@aws-sdk/util-user-agent-browser': 3.410.0 - '@aws-sdk/util-user-agent-node': 3.410.0 - '@smithy/config-resolver': 2.0.9 - '@smithy/fetch-http-handler': 2.1.4 - '@smithy/hash-node': 2.0.8 - '@smithy/invalid-dependency': 2.0.8 - '@smithy/middleware-content-length': 2.0.10 - '@smithy/middleware-endpoint': 2.0.8 - '@smithy/middleware-retry': 2.0.11 - '@smithy/middleware-serde': 2.0.8 - '@smithy/middleware-stack': 2.0.1 - '@smithy/node-config-provider': 2.0.11 - '@smithy/node-http-handler': 2.5.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/smithy-client': 2.1.5 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.8 - '@smithy/util-base64': 2.0.0 - '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.1.0 - '@smithy/util-defaults-mode-browser': 2.0.9 - '@smithy/util-defaults-mode-node': 2.0.11 - '@smithy/util-retry': 2.0.1 - '@smithy/util-utf8': 2.0.0 - fast-xml-parser: 4.2.5 + '@aws-sdk/client-sso@3.598.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.598.0 + '@aws-sdk/middleware-host-header': 3.598.0 + '@aws-sdk/middleware-logger': 3.598.0 + '@aws-sdk/middleware-recursion-detection': 3.598.0 + '@aws-sdk/middleware-user-agent': 3.598.0 + '@aws-sdk/region-config-resolver': 3.598.0 + '@aws-sdk/types': 3.598.0 + '@aws-sdk/util-endpoints': 3.598.0 + '@aws-sdk/util-user-agent-browser': 3.598.0 + '@aws-sdk/util-user-agent-node': 3.598.0 + '@smithy/config-resolver': 3.0.4 + '@smithy/core': 2.2.4 + '@smithy/fetch-http-handler': 3.2.0 + '@smithy/hash-node': 3.0.3 + '@smithy/invalid-dependency': 3.0.3 + '@smithy/middleware-content-length': 3.0.3 + '@smithy/middleware-endpoint': 3.0.4 + '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.3 + '@smithy/node-http-handler': 3.1.1 + '@smithy/protocol-http': 4.0.3 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.7 + '@smithy/util-defaults-mode-node': 3.0.7 + '@smithy/util-endpoints': 2.0.4 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-sts@3.600.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sso-oidc': 3.600.0(@aws-sdk/client-sts@3.600.0) + '@aws-sdk/core': 3.598.0 + '@aws-sdk/credential-provider-node': 3.600.0(@aws-sdk/client-sso-oidc@3.600.0)(@aws-sdk/client-sts@3.600.0) + '@aws-sdk/middleware-host-header': 3.598.0 + '@aws-sdk/middleware-logger': 3.598.0 + '@aws-sdk/middleware-recursion-detection': 3.598.0 + '@aws-sdk/middleware-user-agent': 3.598.0 + '@aws-sdk/region-config-resolver': 3.598.0 + '@aws-sdk/types': 3.598.0 + '@aws-sdk/util-endpoints': 3.598.0 + '@aws-sdk/util-user-agent-browser': 3.598.0 + '@aws-sdk/util-user-agent-node': 3.598.0 + '@smithy/config-resolver': 3.0.4 + '@smithy/core': 2.2.4 + '@smithy/fetch-http-handler': 3.2.0 + '@smithy/hash-node': 3.0.3 + '@smithy/invalid-dependency': 3.0.3 + '@smithy/middleware-content-length': 3.0.3 + '@smithy/middleware-endpoint': 3.0.4 + '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.3 + '@smithy/node-http-handler': 3.1.1 + '@smithy/protocol-http': 4.0.3 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.7 + '@smithy/util-defaults-mode-node': 3.0.7 + '@smithy/util-endpoints': 2.0.4 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-env@3.410.0': + '@aws-sdk/core@3.598.0': + dependencies: + '@smithy/core': 2.2.4 + '@smithy/protocol-http': 4.0.3 + '@smithy/signature-v4': 3.1.2 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 + fast-xml-parser: 4.2.5 + tslib: 2.6.2 + + '@aws-sdk/credential-provider-env@3.598.0': + dependencies: + '@aws-sdk/types': 3.598.0 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 + tslib: 2.6.2 + + '@aws-sdk/credential-provider-http@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/property-provider': 2.0.9 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/fetch-http-handler': 3.2.0 + '@smithy/node-http-handler': 3.1.1 + '@smithy/property-provider': 3.1.3 + '@smithy/protocol-http': 4.0.3 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 + '@smithy/util-stream': 3.0.5 tslib: 2.6.2 - '@aws-sdk/credential-provider-ini@3.410.0': - dependencies: - '@aws-sdk/credential-provider-env': 3.410.0 - '@aws-sdk/credential-provider-process': 3.410.0 - '@aws-sdk/credential-provider-sso': 3.410.0 - '@aws-sdk/credential-provider-web-identity': 3.410.0 - '@aws-sdk/types': 3.410.0 - '@smithy/credential-provider-imds': 2.0.11 - '@smithy/property-provider': 2.0.9 - '@smithy/shared-ini-file-loader': 2.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/credential-provider-ini@3.598.0(@aws-sdk/client-sso-oidc@3.600.0)(@aws-sdk/client-sts@3.600.0)': + dependencies: + '@aws-sdk/client-sts': 3.600.0 + '@aws-sdk/credential-provider-env': 3.598.0 + '@aws-sdk/credential-provider-http': 3.598.0 + '@aws-sdk/credential-provider-process': 3.598.0 + '@aws-sdk/credential-provider-sso': 3.598.0(@aws-sdk/client-sso-oidc@3.600.0) + '@aws-sdk/credential-provider-web-identity': 3.598.0(@aws-sdk/client-sts@3.600.0) + '@aws-sdk/types': 3.598.0 + '@smithy/credential-provider-imds': 3.1.3 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-node@3.410.0': - dependencies: - '@aws-sdk/credential-provider-env': 3.410.0 - '@aws-sdk/credential-provider-ini': 3.410.0 - '@aws-sdk/credential-provider-process': 3.410.0 - '@aws-sdk/credential-provider-sso': 3.410.0 - '@aws-sdk/credential-provider-web-identity': 3.410.0 - '@aws-sdk/types': 3.410.0 - '@smithy/credential-provider-imds': 2.0.11 - '@smithy/property-provider': 2.0.9 - '@smithy/shared-ini-file-loader': 2.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/credential-provider-node@3.600.0(@aws-sdk/client-sso-oidc@3.600.0)(@aws-sdk/client-sts@3.600.0)': + dependencies: + '@aws-sdk/credential-provider-env': 3.598.0 + '@aws-sdk/credential-provider-http': 3.598.0 + '@aws-sdk/credential-provider-ini': 3.598.0(@aws-sdk/client-sso-oidc@3.600.0)(@aws-sdk/client-sts@3.600.0) + '@aws-sdk/credential-provider-process': 3.598.0 + '@aws-sdk/credential-provider-sso': 3.598.0(@aws-sdk/client-sso-oidc@3.600.0) + '@aws-sdk/credential-provider-web-identity': 3.598.0(@aws-sdk/client-sts@3.600.0) + '@aws-sdk/types': 3.598.0 + '@smithy/credential-provider-imds': 3.1.3 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - '@aws-sdk/client-sts' - aws-crt - '@aws-sdk/credential-provider-process@3.410.0': + '@aws-sdk/credential-provider-process@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/property-provider': 2.0.9 - '@smithy/shared-ini-file-loader': 2.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/credential-provider-sso@3.410.0': + '@aws-sdk/credential-provider-sso@3.598.0(@aws-sdk/client-sso-oidc@3.600.0)': dependencies: - '@aws-sdk/client-sso': 3.410.0 - '@aws-sdk/token-providers': 3.410.0 - '@aws-sdk/types': 3.410.0 - '@smithy/property-provider': 2.0.9 - '@smithy/shared-ini-file-loader': 2.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/client-sso': 3.598.0 + '@aws-sdk/token-providers': 3.598.0(@aws-sdk/client-sso-oidc@3.600.0) + '@aws-sdk/types': 3.598.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-web-identity@3.410.0': + '@aws-sdk/credential-provider-web-identity@3.598.0(@aws-sdk/client-sts@3.600.0)': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/property-provider': 2.0.9 - '@smithy/types': 2.6.0 + '@aws-sdk/client-sts': 3.600.0 + '@aws-sdk/types': 3.598.0 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/lib-storage@3.412.0(@aws-sdk/client-s3@3.412.0)': + '@aws-sdk/lib-storage@3.600.0(@aws-sdk/client-s3@3.600.0)': dependencies: - '@aws-sdk/client-s3': 3.412.0 - '@smithy/abort-controller': 2.0.14 - '@smithy/middleware-endpoint': 2.0.8 - '@smithy/smithy-client': 2.1.5 + '@aws-sdk/client-s3': 3.600.0 + '@smithy/abort-controller': 3.1.1 + '@smithy/middleware-endpoint': 3.0.4 + '@smithy/smithy-client': 3.1.5 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: 2.6.2 - '@aws-sdk/middleware-bucket-endpoint@3.410.0': + '@aws-sdk/middleware-bucket-endpoint@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@aws-sdk/util-arn-parser': 3.310.0 - '@smithy/node-config-provider': 2.0.11 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 - '@smithy/util-config-provider': 2.0.0 + '@aws-sdk/types': 3.598.0 + '@aws-sdk/util-arn-parser': 3.568.0 + '@smithy/node-config-provider': 3.1.3 + '@smithy/protocol-http': 4.0.3 + '@smithy/types': 3.3.0 + '@smithy/util-config-provider': 3.0.0 tslib: 2.6.2 - '@aws-sdk/middleware-expect-continue@3.410.0': + '@aws-sdk/middleware-expect-continue@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/protocol-http': 4.0.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/middleware-flexible-checksums@3.410.0': + '@aws-sdk/middleware-flexible-checksums@3.598.0': dependencies: - '@aws-crypto/crc32': 3.0.0 - '@aws-crypto/crc32c': 3.0.0 - '@aws-sdk/types': 3.410.0 - '@smithy/is-array-buffer': 2.0.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 - '@smithy/util-utf8': 2.0.0 + '@aws-crypto/crc32': 5.2.0 + '@aws-crypto/crc32c': 5.2.0 + '@aws-sdk/types': 3.598.0 + '@smithy/is-array-buffer': 3.0.0 + '@smithy/protocol-http': 4.0.3 + '@smithy/types': 3.3.0 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 - '@aws-sdk/middleware-host-header@3.410.0': + '@aws-sdk/middleware-host-header@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/protocol-http': 4.0.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/middleware-location-constraint@3.410.0': + '@aws-sdk/middleware-location-constraint@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/middleware-logger@3.410.0': + '@aws-sdk/middleware-logger@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/middleware-recursion-detection@3.410.0': + '@aws-sdk/middleware-recursion-detection@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/protocol-http': 4.0.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/middleware-sdk-s3@3.410.0': + '@aws-sdk/middleware-sdk-s3@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@aws-sdk/util-arn-parser': 3.310.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@aws-sdk/util-arn-parser': 3.568.0 + '@smithy/node-config-provider': 3.1.3 + '@smithy/protocol-http': 4.0.3 + '@smithy/signature-v4': 3.1.2 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 + '@smithy/util-config-provider': 3.0.0 tslib: 2.6.2 - '@aws-sdk/middleware-sdk-sts@3.410.0': + '@aws-sdk/middleware-signing@3.598.0': dependencies: - '@aws-sdk/middleware-signing': 3.410.0 - '@aws-sdk/types': 3.410.0 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/property-provider': 3.1.3 + '@smithy/protocol-http': 4.0.3 + '@smithy/signature-v4': 3.1.2 + '@smithy/types': 3.3.0 + '@smithy/util-middleware': 3.0.3 tslib: 2.6.2 - '@aws-sdk/middleware-signing@3.410.0': + '@aws-sdk/middleware-ssec@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/property-provider': 2.0.9 - '@smithy/protocol-http': 3.0.10 - '@smithy/signature-v4': 2.0.5 - '@smithy/types': 2.6.0 - '@smithy/util-middleware': 2.0.1 + '@aws-sdk/types': 3.598.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/middleware-ssec@3.410.0': + '@aws-sdk/middleware-user-agent@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@aws-sdk/util-endpoints': 3.598.0 + '@smithy/protocol-http': 4.0.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/middleware-user-agent@3.410.0': + '@aws-sdk/region-config-resolver@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@aws-sdk/util-endpoints': 3.410.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/node-config-provider': 3.1.3 + '@smithy/types': 3.3.0 + '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.3 tslib: 2.6.2 - '@aws-sdk/signature-v4-multi-region@3.412.0': + '@aws-sdk/signature-v4-multi-region@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/protocol-http': 3.0.10 - '@smithy/signature-v4': 2.0.5 - '@smithy/types': 2.6.0 - tslib: 2.6.2 - - '@aws-sdk/token-providers@3.410.0': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/middleware-host-header': 3.410.0 - '@aws-sdk/middleware-logger': 3.410.0 - '@aws-sdk/middleware-recursion-detection': 3.410.0 - '@aws-sdk/middleware-user-agent': 3.410.0 - '@aws-sdk/types': 3.410.0 - '@aws-sdk/util-endpoints': 3.410.0 - '@aws-sdk/util-user-agent-browser': 3.410.0 - '@aws-sdk/util-user-agent-node': 3.410.0 - '@smithy/config-resolver': 2.0.9 - '@smithy/fetch-http-handler': 2.1.4 - '@smithy/hash-node': 2.0.8 - '@smithy/invalid-dependency': 2.0.8 - '@smithy/middleware-content-length': 2.0.10 - '@smithy/middleware-endpoint': 2.0.8 - '@smithy/middleware-retry': 2.0.11 - '@smithy/middleware-serde': 2.0.8 - '@smithy/middleware-stack': 2.0.1 - '@smithy/node-config-provider': 2.0.11 - '@smithy/node-http-handler': 2.5.0 - '@smithy/property-provider': 2.0.9 - '@smithy/protocol-http': 3.0.10 - '@smithy/shared-ini-file-loader': 2.0.10 - '@smithy/smithy-client': 2.1.5 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.8 - '@smithy/util-base64': 2.0.0 - '@smithy/util-body-length-browser': 2.0.0 - '@smithy/util-body-length-node': 2.1.0 - '@smithy/util-defaults-mode-browser': 2.0.9 - '@smithy/util-defaults-mode-node': 2.0.11 - '@smithy/util-retry': 2.0.1 - '@smithy/util-utf8': 2.0.0 + '@aws-sdk/middleware-sdk-s3': 3.598.0 + '@aws-sdk/types': 3.598.0 + '@smithy/protocol-http': 4.0.3 + '@smithy/signature-v4': 3.1.2 + '@smithy/types': 3.3.0 tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - '@aws-sdk/types@3.410.0': + '@aws-sdk/token-providers@3.598.0(@aws-sdk/client-sso-oidc@3.600.0)': dependencies: - '@smithy/types': 2.6.0 + '@aws-sdk/client-sso-oidc': 3.600.0(@aws-sdk/client-sts@3.600.0) + '@aws-sdk/types': 3.598.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/types@3.413.0': + '@aws-sdk/types@3.598.0': dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/util-arn-parser@3.310.0': + '@aws-sdk/util-arn-parser@3.568.0': dependencies: tslib: 2.6.2 - '@aws-sdk/util-endpoints@3.410.0': + '@aws-sdk/util-endpoints@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 + '@aws-sdk/types': 3.598.0 + '@smithy/types': 3.3.0 + '@smithy/util-endpoints': 2.0.4 tslib: 2.6.2 '@aws-sdk/util-locate-window@3.208.0': dependencies: tslib: 2.6.2 - '@aws-sdk/util-user-agent-browser@3.410.0': + '@aws-sdk/util-user-agent-browser@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/types': 3.3.0 bowser: 2.11.0 tslib: 2.6.2 - '@aws-sdk/util-user-agent-node@3.410.0': + '@aws-sdk/util-user-agent-node@3.598.0': dependencies: - '@aws-sdk/types': 3.410.0 - '@smithy/node-config-provider': 2.0.11 - '@smithy/types': 2.6.0 + '@aws-sdk/types': 3.598.0 + '@smithy/node-config-provider': 3.1.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@aws-sdk/util-utf8-browser@3.259.0': - dependencies: - tslib: 2.6.2 - - '@aws-sdk/xml-builder@3.310.0': + '@aws-sdk/xml-builder@3.598.0': dependencies: + '@smithy/types': 3.3.0 tslib: 2.6.2 '@babel/code-frame@7.23.5': @@ -11901,8 +12542,15 @@ snapshots: '@babel/highlight': 7.23.4 chalk: 2.4.2 + '@babel/code-frame@7.24.7': + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.0 + '@babel/compat-data@7.23.5': {} + '@babel/compat-data@7.24.7': {} + '@babel/core@7.23.5': dependencies: '@ampproject/remapping': 2.2.1 @@ -11916,27 +12564,27 @@ snapshots: '@babel/traverse': 7.23.5 '@babel/types': 7.23.5 convert-source-map: 2.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/core@7.24.0': + '@babel/core@7.24.7': dependencies: '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) - '@babel/helpers': 7.24.0 - '@babel/parser': 7.24.0 - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.0 - '@babel/types': 7.24.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helpers': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 convert-source-map: 2.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -11950,20 +12598,23 @@ snapshots: '@jridgewell/trace-mapping': 0.3.18 jsesc: 2.5.2 - '@babel/generator@7.23.6': + '@babel/generator@7.24.7': dependencies: - '@babel/types': 7.24.0 - '@jridgewell/gen-mapping': 0.3.2 - '@jridgewell/trace-mapping': 0.3.18 + '@babel/types': 7.24.7 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 - '@babel/helper-annotate-as-pure@7.22.5': + '@babel/helper-annotate-as-pure@7.24.7': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.24.7 - '@babel/helper-builder-binary-assignment-operator-visitor@7.22.15': + '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': dependencies: - '@babel/types': 7.24.0 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color '@babel/helper-compilation-targets@7.22.15': dependencies: @@ -11973,40 +12624,42 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-compilation-targets@7.23.6': + '@babel/helper-compilation-targets@7.24.7': dependencies: - '@babel/compat-data': 7.23.5 - '@babel/helper-validator-option': 7.23.5 + '@babel/compat-data': 7.24.7 + '@babel/helper-validator-option': 7.24.7 browserslist: 4.23.0 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.23.5(@babel/core@7.24.0)': - dependencies: - '@babel/core': 7.24.0 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-member-expression-to-functions': 7.23.0 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0) - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-create-class-features-plugin@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.7 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 semver: 6.3.1 + transitivePeerDependencies: + - supports-color - '@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.0)': + '@babel/helper-create-regexp-features-plugin@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 regexpu-core: 5.3.2 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.4.3(@babel/core@7.24.0)': + '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 - debug: 4.3.4(supports-color@8.1.1) + '@babel/core': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + debug: 4.3.5(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -12014,23 +12667,46 @@ snapshots: '@babel/helper-environment-visitor@7.22.20': {} + '@babel/helper-environment-visitor@7.24.7': + dependencies: + '@babel/types': 7.24.7 + '@babel/helper-function-name@7.23.0': dependencies: - '@babel/template': 7.24.0 - '@babel/types': 7.24.0 + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + + '@babel/helper-function-name@7.24.7': + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 '@babel/helper-hoist-variables@7.22.5': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.24.7 - '@babel/helper-member-expression-to-functions@7.23.0': + '@babel/helper-hoist-variables@7.24.7': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.24.7 + + '@babel/helper-member-expression-to-functions@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color '@babel/helper-module-imports@7.22.15': dependencies: '@babel/types': 7.23.5 + '@babel/helper-module-imports@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.23.3(@babel/core@7.23.5)': dependencies: '@babel/core': 7.23.5 @@ -12040,58 +12716,89 @@ snapshots: '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 - '@babel/helper-module-transforms@7.23.3(@babel/core@7.24.0)': + '@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.20 + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/helper-optimise-call-expression@7.22.5': + '@babel/helper-optimise-call-expression@7.24.7': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.24.7 '@babel/helper-plugin-utils@7.22.5': {} - '@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.0)': - dependencies: - '@babel/core': 7.24.0 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-wrap-function': 7.22.20 + '@babel/helper-plugin-utils@7.24.7': {} - '@babel/helper-replace-supers@7.22.20(@babel/core@7.24.0)': + '@babel/helper-remap-async-to-generator@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-member-expression-to-functions': 7.23.0 - '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-wrap-function': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/helper-simple-access@7.22.5': + '@babel/helper-replace-supers@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.7 + '@babel/helper-optimise-call-expression': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.22.5': dependencies: '@babel/types': 7.23.5 - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': + '@babel/helper-simple-access@7.24.7': dependencies: - '@babel/types': 7.24.0 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color '@babel/helper-split-export-declaration@7.22.6': dependencies: '@babel/types': 7.23.5 + '@babel/helper-split-export-declaration@7.24.7': + dependencies: + '@babel/types': 7.24.7 + '@babel/helper-string-parser@7.23.4': {} + '@babel/helper-string-parser@7.24.7': {} + '@babel/helper-validator-identifier@7.22.20': {} + '@babel/helper-validator-identifier@7.24.7': {} + '@babel/helper-validator-option@7.23.5': {} - '@babel/helper-wrap-function@7.22.20': + '@babel/helper-validator-option@7.24.7': {} + + '@babel/helper-wrap-function@7.24.7': dependencies: - '@babel/helper-function-name': 7.23.0 - '@babel/template': 7.24.0 - '@babel/types': 7.24.0 + '@babel/helper-function-name': 7.24.7 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color '@babel/helpers@7.23.5': dependencies: @@ -12101,13 +12808,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helpers@7.24.0': + '@babel/helpers@7.24.7': dependencies: - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.0 - '@babel/types': 7.24.0 - transitivePeerDependencies: - - supports-color + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 '@babel/highlight@7.23.4': dependencies: @@ -12115,48 +12819,63 @@ snapshots: chalk: 2.4.2 js-tokens: 4.0.0 + '@babel/highlight@7.24.7': + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.0 + '@babel/parser@7.23.9': dependencies: '@babel/types': 7.23.5 - '@babel/parser@7.24.0': + '@babel/parser@7.24.5': dependencies: '@babel/types': 7.24.0 - '@babel/parser@7.24.5': + '@babel/parser@7.24.7': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.24.7 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-transform-optional-chaining': 7.24.7(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.0)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.5)': dependencies: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.0)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.5)': @@ -12169,49 +12888,49 @@ snapshots: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.0)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.0)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-flow@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-flow@7.23.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.5)': dependencies: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.0)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.5)': @@ -12219,9 +12938,9 @@ snapshots: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.5)': @@ -12229,9 +12948,9 @@ snapshots: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.5)': @@ -12239,9 +12958,9 @@ snapshots: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.0)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.5)': @@ -12249,9 +12968,9 @@ snapshots: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.5)': @@ -12259,9 +12978,9 @@ snapshots: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.0)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.5)': @@ -12269,9 +12988,9 @@ snapshots: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.5)': @@ -12279,9 +12998,9 @@ snapshots: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.5)': @@ -12289,24 +13008,24 @@ snapshots: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.0)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.5)': dependencies: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.0)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.5)': @@ -12314,435 +13033,471 @@ snapshots: '@babel/core': 7.23.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.0)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-async-generator-functions@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-async-generator-functions@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.0) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-block-scoping@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-class-properties@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-classes@7.23.5(@babel/core@7.24.0)': + '@babel/plugin-transform-classes@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0) - '@babel/helper-split-export-declaration': 7.22.6 + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + '@babel/helper-split-export-declaration': 7.24.7 globals: 11.12.0 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/template': 7.24.0 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/template': 7.24.7 - '@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-destructuring@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-transform-flow-strip-types@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-flow-strip-types@7.23.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.24.7) - '@babel/plugin-transform-for-of@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-for-of@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-function-name@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-function-name@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-transform-literals@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-literals@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.7) - '@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-modules-commonjs@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-simple-access': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-modules-systemjs@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-modules-systemjs@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-identifier': 7.22.20 + '@babel/core': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.0)': + '@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-new-target@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-new-target@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.7) - '@babel/plugin-transform-object-rest-spread@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/compat-data': 7.23.5 - '@babel/core': 7.24.0 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-object-super@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-object-super@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-optional-chaining@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-parameters@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-parameters@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-private-methods@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.24.0)': + '@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 regenerator-transform: 0.15.2 - '@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.24.0)': - dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-shorthand-properties@7.23.3(@babel/core@7.24.0)': - dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-spread@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-spread@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.24.0)': - dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-typescript@7.23.5(@babel/core@7.24.0)': + '@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-typeof-symbol@7.24.7(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.24.0)': + '@babel/plugin-transform-typescript@7.23.5(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 - - '@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.24.0)': - dependencies: - '@babel/core': 7.24.0 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0) - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color - '@babel/preset-env@7.23.5(@babel/core@7.24.0)': - dependencies: - '@babel/compat-data': 7.23.5 - '@babel/core': 7.24.0 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.0) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.0) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.0) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-import-assertions': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.0) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.0) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.0) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.0) - '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-async-generator-functions': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-classes': 7.23.5(@babel/core@7.24.0) - '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-dotall-regex': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-duplicate-keys': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-dynamic-import': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-exponentiation-operator': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-for-of': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-json-strings': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-logical-assignment-operators': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-modules-amd': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-modules-systemjs': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-modules-umd': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.24.0) - '@babel/plugin-transform-new-target': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-numeric-separator': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-object-rest-spread': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-optional-catch-binding': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-regenerator': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-reserved-words': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-typeof-symbol': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-unicode-escapes': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-unicode-property-regex': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-unicode-sets-regex': 7.23.3(@babel/core@7.24.0) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.0) - babel-plugin-polyfill-corejs2: 0.4.6(@babel/core@7.24.0) - babel-plugin-polyfill-corejs3: 0.8.6(@babel/core@7.24.0) - babel-plugin-polyfill-regenerator: 0.5.3(@babel/core@7.24.0) - core-js-compat: 3.33.3 + '@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-transform-unicode-sets-regex@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/preset-env@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/compat-data': 7.24.7 + '@babel/core': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-validator-option': 7.24.7 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.7) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.7) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.7) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.7) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.7) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.7) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.7) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.7) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.7) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.7) + '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-async-generator-functions': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-block-scoping': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-class-properties': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-classes': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-destructuring': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-function-name': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-literals': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-modules-commonjs': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-modules-systemjs': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-optional-chaining': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-typeof-symbol': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-unicode-sets-regex': 7.24.7(@babel/core@7.24.7) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.7) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.7) + babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.7) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.7) + core-js-compat: 3.37.1 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-flow@7.23.3(@babel/core@7.24.0)': + '@babel/preset-flow@7.23.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-transform-flow-strip-types': 7.23.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-validator-option': 7.24.7 + '@babel/plugin-transform-flow-strip-types': 7.23.3(@babel/core@7.24.7) - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.0)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/types': 7.24.0 + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/types': 7.24.7 esutils: 2.0.3 - '@babel/preset-typescript@7.23.3(@babel/core@7.24.0)': + '@babel/preset-typescript@7.23.3(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-typescript': 7.23.5(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-validator-option': 7.24.7 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.7) + '@babel/plugin-transform-modules-commonjs': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-typescript': 7.23.5(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color - '@babel/register@7.22.15(@babel/core@7.24.0)': + '@babel/register@7.22.15(@babel/core@7.24.7)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 clone-deep: 4.0.1 find-cache-dir: 2.1.0 make-dir: 2.1.0 @@ -12763,9 +13518,15 @@ snapshots: '@babel/template@7.24.0': dependencies: - '@babel/code-frame': 7.23.5 - '@babel/parser': 7.24.0 - '@babel/types': 7.24.0 + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + + '@babel/template@7.24.7': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 '@babel/traverse@7.23.5': dependencies: @@ -12777,22 +13538,22 @@ snapshots: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.23.9 '@babel/types': 7.23.5 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/traverse@7.24.0': - dependencies: - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.24.0 - '@babel/types': 7.24.0 - debug: 4.3.4(supports-color@8.1.1) + '@babel/traverse@7.24.7': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + debug: 4.3.5(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -12809,26 +13570,32 @@ snapshots: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 + '@babel/types@7.24.7': + dependencies: + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + '@base2/pretty-print-object@1.0.1': {} '@bcoe/v8-coverage@0.2.3': {} - '@bull-board/api@5.17.0(@bull-board/ui@5.17.0)': + '@bull-board/api@5.20.5(@bull-board/ui@5.20.5)': dependencies: - '@bull-board/ui': 5.17.0 + '@bull-board/ui': 5.20.5 redis-info: 3.1.0 - '@bull-board/fastify@5.17.0': + '@bull-board/fastify@5.20.5': dependencies: - '@bull-board/api': 5.17.0(@bull-board/ui@5.17.0) - '@bull-board/ui': 5.17.0 + '@bull-board/api': 5.20.5(@bull-board/ui@5.20.5) + '@bull-board/ui': 5.20.5 '@fastify/static': 6.12.0 '@fastify/view': 8.2.0 - ejs: 3.1.9 + ejs: 3.1.10 - '@bull-board/ui@5.17.0': + '@bull-board/ui@5.20.5': dependencies: - '@bull-board/api': 5.17.0(@bull-board/ui@5.17.0) + '@bull-board/api': 5.20.5(@bull-board/ui@5.20.5) '@bundled-es-modules/cookie@2.0.0': dependencies: @@ -12926,7 +13693,7 @@ snapshots: performance-now: 2.1.0 qs: 6.10.4 safe-buffer: 5.2.1 - tough-cookie: 4.1.3 + tough-cookie: 4.1.4 tunnel-agent: 0.6.0 uuid: 8.3.2 @@ -12966,7 +13733,10 @@ snapshots: '@esbuild/aix-ppc64@0.19.11': optional: true - '@esbuild/aix-ppc64@0.20.2': + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.22.0': optional: true '@esbuild/android-arm64@0.18.20': @@ -12975,7 +13745,10 @@ snapshots: '@esbuild/android-arm64@0.19.11': optional: true - '@esbuild/android-arm64@0.20.2': + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.22.0': optional: true '@esbuild/android-arm@0.18.20': @@ -12984,7 +13757,10 @@ snapshots: '@esbuild/android-arm@0.19.11': optional: true - '@esbuild/android-arm@0.20.2': + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.22.0': optional: true '@esbuild/android-x64@0.18.20': @@ -12993,7 +13769,10 @@ snapshots: '@esbuild/android-x64@0.19.11': optional: true - '@esbuild/android-x64@0.20.2': + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.22.0': optional: true '@esbuild/darwin-arm64@0.18.20': @@ -13002,7 +13781,10 @@ snapshots: '@esbuild/darwin-arm64@0.19.11': optional: true - '@esbuild/darwin-arm64@0.20.2': + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.22.0': optional: true '@esbuild/darwin-x64@0.18.20': @@ -13011,7 +13793,10 @@ snapshots: '@esbuild/darwin-x64@0.19.11': optional: true - '@esbuild/darwin-x64@0.20.2': + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.22.0': optional: true '@esbuild/freebsd-arm64@0.18.20': @@ -13020,7 +13805,10 @@ snapshots: '@esbuild/freebsd-arm64@0.19.11': optional: true - '@esbuild/freebsd-arm64@0.20.2': + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.22.0': optional: true '@esbuild/freebsd-x64@0.18.20': @@ -13029,7 +13817,10 @@ snapshots: '@esbuild/freebsd-x64@0.19.11': optional: true - '@esbuild/freebsd-x64@0.20.2': + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.22.0': optional: true '@esbuild/linux-arm64@0.18.20': @@ -13038,7 +13829,10 @@ snapshots: '@esbuild/linux-arm64@0.19.11': optional: true - '@esbuild/linux-arm64@0.20.2': + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.22.0': optional: true '@esbuild/linux-arm@0.18.20': @@ -13047,7 +13841,10 @@ snapshots: '@esbuild/linux-arm@0.19.11': optional: true - '@esbuild/linux-arm@0.20.2': + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.22.0': optional: true '@esbuild/linux-ia32@0.18.20': @@ -13056,7 +13853,10 @@ snapshots: '@esbuild/linux-ia32@0.19.11': optional: true - '@esbuild/linux-ia32@0.20.2': + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.22.0': optional: true '@esbuild/linux-loong64@0.18.20': @@ -13065,7 +13865,10 @@ snapshots: '@esbuild/linux-loong64@0.19.11': optional: true - '@esbuild/linux-loong64@0.20.2': + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.22.0': optional: true '@esbuild/linux-mips64el@0.18.20': @@ -13074,7 +13877,10 @@ snapshots: '@esbuild/linux-mips64el@0.19.11': optional: true - '@esbuild/linux-mips64el@0.20.2': + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.22.0': optional: true '@esbuild/linux-ppc64@0.18.20': @@ -13083,7 +13889,10 @@ snapshots: '@esbuild/linux-ppc64@0.19.11': optional: true - '@esbuild/linux-ppc64@0.20.2': + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.22.0': optional: true '@esbuild/linux-riscv64@0.18.20': @@ -13092,7 +13901,10 @@ snapshots: '@esbuild/linux-riscv64@0.19.11': optional: true - '@esbuild/linux-riscv64@0.20.2': + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.22.0': optional: true '@esbuild/linux-s390x@0.18.20': @@ -13101,7 +13913,10 @@ snapshots: '@esbuild/linux-s390x@0.19.11': optional: true - '@esbuild/linux-s390x@0.20.2': + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.22.0': optional: true '@esbuild/linux-x64@0.18.20': @@ -13110,7 +13925,10 @@ snapshots: '@esbuild/linux-x64@0.19.11': optional: true - '@esbuild/linux-x64@0.20.2': + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.22.0': optional: true '@esbuild/netbsd-x64@0.18.20': @@ -13119,7 +13937,13 @@ snapshots: '@esbuild/netbsd-x64@0.19.11': optional: true - '@esbuild/netbsd-x64@0.20.2': + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.22.0': + optional: true + + '@esbuild/openbsd-arm64@0.22.0': optional: true '@esbuild/openbsd-x64@0.18.20': @@ -13128,7 +13952,10 @@ snapshots: '@esbuild/openbsd-x64@0.19.11': optional: true - '@esbuild/openbsd-x64@0.20.2': + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.22.0': optional: true '@esbuild/sunos-x64@0.18.20': @@ -13137,7 +13964,10 @@ snapshots: '@esbuild/sunos-x64@0.19.11': optional: true - '@esbuild/sunos-x64@0.20.2': + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.22.0': optional: true '@esbuild/win32-arm64@0.18.20': @@ -13146,7 +13976,10 @@ snapshots: '@esbuild/win32-arm64@0.19.11': optional: true - '@esbuild/win32-arm64@0.20.2': + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.22.0': optional: true '@esbuild/win32-ia32@0.18.20': @@ -13155,7 +13988,10 @@ snapshots: '@esbuild/win32-ia32@0.19.11': optional: true - '@esbuild/win32-ia32@0.20.2': + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.22.0': optional: true '@esbuild/win32-x64@0.18.20': @@ -13164,30 +14000,38 @@ snapshots: '@esbuild/win32-x64@0.19.11': optional: true - '@esbuild/win32-x64@0.20.2': + '@esbuild/win32-x64@0.21.5': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.53.0)': - dependencies: - eslint: 8.53.0 - eslint-visitor-keys: 3.4.3 + '@esbuild/win32-x64@0.22.0': + optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@9.6.0)': dependencies: - eslint: 8.57.0 + eslint: 9.6.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.10.0': {} '@eslint-community/regexpp@4.6.2': {} - '@eslint/eslintrc@2.1.4': + '@eslint/compat@1.1.0': {} + + '@eslint/config-array@0.17.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.5(supports-color@8.1.1) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) - espree: 9.6.1 - globals: 13.19.0 - ignore: 5.2.4 + debug: 4.3.5(supports-color@8.1.1) + espree: 10.1.0 + globals: 14.0.0 + ignore: 5.3.1 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -13195,9 +14039,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.53.0': {} + '@eslint/js@9.6.0': {} - '@eslint/js@8.57.0': {} + '@eslint/object-schema@2.1.4': {} '@fal-works/esbuild-plugin-global-externals@2.1.2': {} @@ -13210,8 +14054,8 @@ snapshots: '@fastify/ajv-compiler@3.5.0': dependencies: - ajv: 8.13.0 - ajv-formats: 2.1.1(ajv@8.13.0) + ajv: 8.16.0 + ajv-formats: 2.1.1(ajv@8.16.0) fast-uri: 2.2.0 '@fastify/busboy@2.1.0': {} @@ -13246,12 +14090,12 @@ snapshots: '@fastify/reply-from': 9.0.1 fast-querystring: 1.1.2 fastify-plugin: 4.5.0 - ws: 8.17.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) + ws: 8.17.1(bufferutil@4.0.7)(utf-8-validate@6.0.3) transitivePeerDependencies: - bufferutil - utf-8-validate - '@fastify/multipart@8.2.0': + '@fastify/multipart@8.3.0': dependencies: '@fastify/busboy': 2.1.0 '@fastify/deepmerge': 1.3.0 @@ -13287,14 +14131,14 @@ snapshots: glob: 8.1.0 p-limit: 3.1.0 - '@fastify/static@7.0.3': + '@fastify/static@7.0.4': dependencies: '@fastify/accept-negotiator': 1.0.0 '@fastify/send': 2.0.1 content-disposition: 0.5.4 fastify-plugin: 4.5.0 fastq: 1.17.1 - glob: 10.3.12 + glob: 10.4.2 '@fastify/view@8.2.0': dependencies: @@ -13310,13 +14154,11 @@ snapshots: '@hapi/boom@10.0.1': dependencies: - '@hapi/hoek': 11.0.2 + '@hapi/hoek': 11.0.4 '@hapi/bourne@3.0.0': {} - '@hapi/hoek@10.0.1': {} - - '@hapi/hoek@11.0.2': {} + '@hapi/hoek@11.0.4': {} '@hapi/hoek@9.3.0': {} @@ -13328,40 +14170,22 @@ snapshots: dependencies: '@hapi/boom': 10.0.1 '@hapi/bourne': 3.0.0 - '@hapi/hoek': 11.0.2 + '@hapi/hoek': 11.0.4 '@hexagon/base64@1.1.27': {} - '@humanwhocodes/config-array@0.11.13': - dependencies: - '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4(supports-color@8.1.1) - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@humanwhocodes/config-array@0.11.14': - dependencies: - '@humanwhocodes/object-schema': 2.0.2 - debug: 4.3.4(supports-color@8.1.1) - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - '@humanwhocodes/module-importer@1.0.1': {} '@humanwhocodes/momoa@2.0.4': {} - '@humanwhocodes/object-schema@2.0.1': {} + '@humanwhocodes/retry@0.3.0': {} - '@humanwhocodes/object-schema@2.0.2': {} - - '@img/sharp-darwin-arm64@0.33.3': + '@img/sharp-darwin-arm64@0.33.4': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.0.2 optional: true - '@img/sharp-darwin-x64@0.33.3': + '@img/sharp-darwin-x64@0.33.4': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.0.2 optional: true @@ -13390,45 +14214,45 @@ snapshots: '@img/sharp-libvips-linuxmusl-x64@1.0.2': optional: true - '@img/sharp-linux-arm64@0.33.3': + '@img/sharp-linux-arm64@0.33.4': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.0.2 optional: true - '@img/sharp-linux-arm@0.33.3': + '@img/sharp-linux-arm@0.33.4': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.0.2 optional: true - '@img/sharp-linux-s390x@0.33.3': + '@img/sharp-linux-s390x@0.33.4': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.0.2 optional: true - '@img/sharp-linux-x64@0.33.3': + '@img/sharp-linux-x64@0.33.4': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.0.2 optional: true - '@img/sharp-linuxmusl-arm64@0.33.3': + '@img/sharp-linuxmusl-arm64@0.33.4': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 optional: true - '@img/sharp-linuxmusl-x64@0.33.3': + '@img/sharp-linuxmusl-x64@0.33.4': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.0.2 optional: true - '@img/sharp-wasm32@0.33.3': + '@img/sharp-wasm32@0.33.4': dependencies: '@emnapi/runtime': 1.1.1 optional: true - '@img/sharp-win32-ia32@0.33.3': + '@img/sharp-win32-ia32@0.33.4': optional: true - '@img/sharp-win32-x64@0.33.3': + '@img/sharp-win32-x64@0.33.4': optional: true '@inquirer/confirm@3.1.6': @@ -13441,7 +14265,7 @@ snapshots: '@inquirer/figures': 1.0.1 '@inquirer/type': 1.3.1 '@types/mute-stream': 0.0.4 - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/wrap-ansi': 3.0.0 ansi-escapes: 4.3.2 chalk: 4.1.2 @@ -13464,7 +14288,7 @@ snapshots: '@intlify/message-compiler@9.13.1': dependencies: '@intlify/shared': 9.13.1 - source-map-js: 1.0.2 + source-map-js: 1.2.0 '@intlify/shared@9.13.1': {} @@ -13492,7 +14316,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 20.12.7 + '@types/node': 20.14.9 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -13505,14 +14329,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.7 + '@types/node': 20.14.9 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.7.1 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.12.7) + jest-config: 29.7.0(@types/node@20.14.9) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -13524,7 +14348,7 @@ snapshots: jest-util: 29.7.0 jest-validate: 29.7.0 jest-watcher: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.7 pretty-format: 29.7.0 slash: 3.0.0 strip-ansi: 6.0.1 @@ -13541,7 +14365,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.7 + '@types/node': 20.14.9 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -13559,7 +14383,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.12.7 + '@types/node': 20.14.9 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -13581,7 +14405,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.18 - '@types/node': 20.12.7 + '@types/node': 20.14.9 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -13639,7 +14463,7 @@ snapshots: jest-haste-map: 29.7.0 jest-regex-util: 29.6.3 jest-util: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.7 pirates: 4.0.5 slash: 3.0.0 write-file-atomic: 4.0.2 @@ -13651,19 +14475,19 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/yargs': 17.0.19 chalk: 4.1.2 - '@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.3.1(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1))': dependencies: glob: 7.2.3 glob-promise: 4.2.2(glob@7.2.3) magic-string: 0.27.0 - react-docgen-typescript: 2.2.2(typescript@5.5.2) - vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) + react-docgen-typescript: 2.2.2(typescript@5.5.3) + vite: 5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1) optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 '@jridgewell/gen-mapping@0.3.2': dependencies: @@ -13671,14 +14495,22 @@ snapshots: '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/resolve-uri@3.1.0': {} '@jridgewell/set-array@1.1.2': {} + '@jridgewell/set-array@1.2.1': {} + '@jridgewell/source-map@0.3.5': dependencies: - '@jridgewell/gen-mapping': 0.3.2 - '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/sourcemap-codec@1.4.14': {} @@ -13689,6 +14521,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jsdevtools/ono@7.1.3': {} '@kurkle/color@0.3.2': {} @@ -13727,23 +14564,23 @@ snapshots: '@types/react': 18.0.28 react: 18.3.1 - '@microsoft/api-extractor-model@7.28.14(@types/node@20.12.7)': + '@microsoft/api-extractor-model@7.29.2(@types/node@20.14.9)': dependencies: - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 4.1.0(@types/node@20.12.7) + '@microsoft/tsdoc': 0.15.0 + '@microsoft/tsdoc-config': 0.17.0 + '@rushstack/node-core-library': 5.4.1(@types/node@20.14.9) transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.43.1(@types/node@20.12.7)': + '@microsoft/api-extractor@7.47.0(@types/node@20.14.9)': dependencies: - '@microsoft/api-extractor-model': 7.28.14(@types/node@20.12.7) - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 4.1.0(@types/node@20.12.7) + '@microsoft/api-extractor-model': 7.29.2(@types/node@20.14.9) + '@microsoft/tsdoc': 0.15.0 + '@microsoft/tsdoc-config': 0.17.0 + '@rushstack/node-core-library': 5.4.1(@types/node@20.14.9) '@rushstack/rig-package': 0.5.2 - '@rushstack/terminal': 0.10.1(@types/node@20.12.7) - '@rushstack/ts-command-line': 4.19.2(@types/node@20.12.7) + '@rushstack/terminal': 0.13.0(@types/node@20.14.9) + '@rushstack/ts-command-line': 4.22.0(@types/node@20.14.9) lodash: 4.17.21 minimatch: 3.0.8 resolve: 1.22.8 @@ -13753,43 +14590,31 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@microsoft/tsdoc-config@0.16.2': + '@microsoft/tsdoc-config@0.17.0': dependencies: - '@microsoft/tsdoc': 0.14.2 - ajv: 6.12.6 + '@microsoft/tsdoc': 0.15.0 + ajv: 8.12.0 jju: 1.4.0 - resolve: 1.19.0 + resolve: 1.22.8 - '@microsoft/tsdoc@0.14.2': {} + '@microsoft/tsdoc@0.15.0': {} '@misskey-dev/browser-image-resizer@2024.1.0': {} - '@misskey-dev/eslint-plugin@1.0.0(@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint@8.53.0)(typescript@5.3.3))(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint@8.53.0))(eslint@8.53.0)': - dependencies: - '@typescript-eslint/eslint-plugin': 6.11.0(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint@8.53.0)(typescript@5.3.3) - '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.3.3) - eslint: 8.53.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint@8.53.0) - - '@misskey-dev/eslint-plugin@1.0.0(@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3))(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0))(eslint@8.57.0)': - dependencies: - '@typescript-eslint/eslint-plugin': 7.1.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3) - '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3) - eslint: 8.57.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0) - - '@misskey-dev/eslint-plugin@1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0))(eslint@8.57.0)': + '@misskey-dev/eslint-plugin@2.0.2(@eslint/compat@1.1.0)(@typescript-eslint/eslint-plugin@7.15.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3))(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0))(eslint@9.6.0)(globals@15.7.0)': dependencies: - '@typescript-eslint/eslint-plugin': 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2) - '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.5.2) - eslint: 8.57.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0) + '@eslint/compat': 1.1.0 + '@typescript-eslint/eslint-plugin': 7.15.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/parser': 7.15.0(eslint@9.6.0)(typescript@5.5.3) + eslint: 9.6.0 + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0) + globals: 15.7.0 '@misskey-dev/sharp-read-bmp@1.2.0': dependencies: decode-bmp: 0.2.1 decode-ico: 0.4.1 - sharp: 0.33.3 + sharp: 0.33.4 '@misskey-dev/summaly@5.1.0': dependencies: @@ -13833,7 +14658,7 @@ snapshots: '@mswjs/cookies@1.1.0': {} - '@mswjs/interceptors@0.26.15': + '@mswjs/interceptors@0.29.1': dependencies: '@open-draft/deferred-promise': 2.2.0 '@open-draft/logger': 0.3.0 @@ -13842,44 +14667,44 @@ snapshots: outvariant: 1.4.2 strict-event-emitter: 0.5.1 - '@napi-rs/canvas-android-arm64@0.1.52': + '@napi-rs/canvas-android-arm64@0.1.53': optional: true - '@napi-rs/canvas-darwin-arm64@0.1.52': + '@napi-rs/canvas-darwin-arm64@0.1.53': optional: true - '@napi-rs/canvas-darwin-x64@0.1.52': + '@napi-rs/canvas-darwin-x64@0.1.53': optional: true - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.52': + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.53': optional: true - '@napi-rs/canvas-linux-arm64-gnu@0.1.52': + '@napi-rs/canvas-linux-arm64-gnu@0.1.53': optional: true - '@napi-rs/canvas-linux-arm64-musl@0.1.52': + '@napi-rs/canvas-linux-arm64-musl@0.1.53': optional: true - '@napi-rs/canvas-linux-x64-gnu@0.1.52': + '@napi-rs/canvas-linux-x64-gnu@0.1.53': optional: true - '@napi-rs/canvas-linux-x64-musl@0.1.52': + '@napi-rs/canvas-linux-x64-musl@0.1.53': optional: true - '@napi-rs/canvas-win32-x64-msvc@0.1.52': + '@napi-rs/canvas-win32-x64-msvc@0.1.53': optional: true - '@napi-rs/canvas@0.1.52': + '@napi-rs/canvas@0.1.53': optionalDependencies: - '@napi-rs/canvas-android-arm64': 0.1.52 - '@napi-rs/canvas-darwin-arm64': 0.1.52 - '@napi-rs/canvas-darwin-x64': 0.1.52 - '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.52 - '@napi-rs/canvas-linux-arm64-gnu': 0.1.52 - '@napi-rs/canvas-linux-arm64-musl': 0.1.52 - '@napi-rs/canvas-linux-x64-gnu': 0.1.52 - '@napi-rs/canvas-linux-x64-musl': 0.1.52 - '@napi-rs/canvas-win32-x64-msvc': 0.1.52 + '@napi-rs/canvas-android-arm64': 0.1.53 + '@napi-rs/canvas-darwin-arm64': 0.1.53 + '@napi-rs/canvas-darwin-x64': 0.1.53 + '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.53 + '@napi-rs/canvas-linux-arm64-gnu': 0.1.53 + '@napi-rs/canvas-linux-arm64-musl': 0.1.53 + '@napi-rs/canvas-linux-x64-gnu': 0.1.53 + '@napi-rs/canvas-linux-x64-musl': 0.1.53 + '@napi-rs/canvas-win32-x64-msvc': 0.1.53 '@ndelangen/get-tarball@3.0.7': dependencies: @@ -13887,49 +14712,51 @@ snapshots: pump: 3.0.0 tar-fs: 2.1.1 - '@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1)': + '@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1)': dependencies: iterare: 1.2.1 reflect-metadata: 0.2.2 rxjs: 7.8.1 - tslib: 2.6.2 + tslib: 2.6.3 uid: 2.0.2 - '@nestjs/core@10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.8)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1)': + '@nestjs/core@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1)': dependencies: - '@nestjs/common': 10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/common': 10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nuxtjs/opencollective': 0.3.2(encoding@0.1.13) fast-safe-stringify: 2.1.1 iterare: 1.2.1 path-to-regexp: 3.2.0 reflect-metadata: 0.2.2 rxjs: 7.8.1 - tslib: 2.6.2 + tslib: 2.6.3 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.8) + '@nestjs/platform-express': 10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10) transitivePeerDependencies: - encoding - '@nestjs/platform-express@10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.8)': + '@nestjs/platform-express@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10)': dependencies: - '@nestjs/common': 10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1) - '@nestjs/core': 10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.8)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/common': 10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) body-parser: 1.20.2 cors: 2.8.5 express: 4.19.2 multer: 1.4.4-lts.1 - tslib: 2.6.2 + tslib: 2.6.3 transitivePeerDependencies: - supports-color - '@nestjs/testing@10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.8)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.8))': + '@nestjs/testing@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10))': dependencies: - '@nestjs/common': 10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1) - '@nestjs/core': 10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.8)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) - tslib: 2.6.2 + '@nestjs/common': 10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) + tslib: 2.6.3 optionalDependencies: - '@nestjs/platform-express': 10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.8) + '@nestjs/platform-express': 10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10) + + '@noble/hashes@1.4.0': {} '@nodelib/fs.scandir@2.1.5': dependencies: @@ -13941,7 +14768,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 + fastq: 1.17.1 '@npmcli/agent@2.2.0': dependencies: @@ -13990,153 +14817,167 @@ snapshots: '@open-draft/until@2.1.0': {} - '@opentelemetry/api-logs@0.51.1': + '@opentelemetry/api-logs@0.52.1': dependencies: - '@opentelemetry/api': 1.8.0 + '@opentelemetry/api': 1.9.0 - '@opentelemetry/api@1.8.0': {} + '@opentelemetry/api@1.9.0': {} - '@opentelemetry/context-async-hooks@1.24.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/context-async-hooks@1.25.1(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 + '@opentelemetry/api': 1.9.0 - '@opentelemetry/core@1.24.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/core@1.24.1(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 + '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.24.1 - '@opentelemetry/instrumentation-connect@0.36.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.25.1 + + '@opentelemetry/instrumentation-connect@0.37.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 '@types/connect': 3.4.36 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-express@0.39.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-express@0.40.1(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-fastify@0.36.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-fastify@0.37.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-graphql@0.40.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-graphql@0.41.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-hapi@0.38.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-hapi@0.39.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-http@0.51.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-http@0.52.1(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 semver: 7.6.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-ioredis@0.40.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-ioredis@0.41.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) '@opentelemetry/redis-common': 0.36.2 - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-koa@0.40.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-koa@0.41.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 '@types/koa': 2.14.0 '@types/koa__router': 12.0.3 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mongodb@0.43.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-mongodb@0.45.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/sdk-metrics': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 1.24.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mongoose@0.38.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-mongoose@0.39.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mysql2@0.38.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-mysql2@0.39.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 - '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.8.0) + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mysql@0.38.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-mysql@0.39.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 '@types/mysql': 2.15.22 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-nestjs-core@0.37.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-nestjs-core@0.38.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-pg@0.41.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-pg@0.42.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 - '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.8.0) + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0) '@types/pg': 8.6.1 '@types/pg-pool': 2.0.4 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.43.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation-redis-4@0.40.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/redis-common': 0.36.2 + '@opentelemetry/semantic-conventions': 1.25.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation@0.43.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 '@types/shimmer': 1.0.5 import-in-the-middle: 1.4.2 require-in-the-middle: 7.3.0 @@ -14146,12 +14987,12 @@ snapshots: - supports-color optional: true - '@opentelemetry/instrumentation@0.51.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/api-logs': 0.51.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.52.1 '@types/shimmer': 1.0.5 - import-in-the-middle: 1.7.4 + import-in-the-middle: 1.8.1 require-in-the-middle: 7.3.0 semver: 7.6.0 shimmer: 1.2.1 @@ -14160,32 +15001,40 @@ snapshots: '@opentelemetry/redis-common@0.36.2': {} - '@opentelemetry/resources@1.24.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/resources@1.24.1(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.24.1 - '@opentelemetry/sdk-metrics@1.24.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + + '@opentelemetry/sdk-metrics@1.24.1(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.9.0) lodash.merge: 4.6.2 - '@opentelemetry/sdk-trace-base@1.24.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 '@opentelemetry/semantic-conventions@1.24.1': {} - '@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/semantic-conventions@1.25.1': {} + + '@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) '@peculiar/asn1-android@2.3.10': dependencies: @@ -14230,35 +15079,149 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@prisma/instrumentation@5.14.0': + '@prisma/instrumentation@5.16.0': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/sdk-trace-base': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@radix-ui/react-compose-refs@1.0.1(@types/react@18.0.28)(react@18.3.1)': + '@radix-ui/primitive@1.1.0': {} + + '@radix-ui/react-compose-refs@1.1.0(@types/react@18.0.28)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 react: 18.3.1 optionalDependencies: '@types/react': 18.0.28 - '@radix-ui/react-slot@1.0.2(@types/react@18.0.28)(react@18.3.1)': + '@radix-ui/react-context@1.1.0(@types/react@18.0.28)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.4 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.0.28)(react@18.3.1) react: 18.3.1 optionalDependencies: '@types/react': 18.0.28 - '@readme/better-ajv-errors@1.6.0(ajv@8.13.0)': + '@radix-ui/react-dialog@1.1.1(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.0.28)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.0.28)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.0.28)(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.0.28)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.28)(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.7(@types/react@18.0.28)(react@18.3.1) + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-dismissable-layer@1.1.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.28)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.28)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.0.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-focus-guards@1.1.0(@types/react@18.0.28)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-focus-scope@1.1.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.28)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-id@1.1.0(@types/react@18.0.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.0.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-portal@1.1.1(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.0.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-presence@1.1.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.28)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.0.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-primitive@2.0.0(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-slot': 1.1.0(@types/react@18.0.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-slot@1.1.0(@types/react@18.0.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.0.28)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.0.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.0.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.0.28 + + '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.0.28)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.0.28 + + '@readme/better-ajv-errors@1.6.0(ajv@8.16.0)': dependencies: '@babel/code-frame': 7.23.5 '@babel/runtime': 7.23.4 '@humanwhocodes/momoa': 2.0.4 - ajv: 8.13.0 + ajv: 8.16.0 chalk: 4.1.2 json-to-ast: 2.1.0 jsonpointer: 5.0.1 @@ -14276,181 +15239,186 @@ snapshots: '@apidevtools/openapi-schemas': 2.1.0 '@apidevtools/swagger-methods': 3.0.2 '@jsdevtools/ono': 7.1.3 - '@readme/better-ajv-errors': 1.6.0(ajv@8.13.0) + '@readme/better-ajv-errors': 1.6.0(ajv@8.16.0) '@readme/json-schema-ref-parser': 1.2.0 - ajv: 8.13.0 - ajv-draft-04: 1.0.0(ajv@8.13.0) + ajv: 8.16.0 + ajv-draft-04: 1.0.0(ajv@8.16.0) call-me-maybe: 1.0.2 openapi-types: 12.1.3 - '@rollup/plugin-json@6.1.0(rollup@4.17.2)': + '@rollup/plugin-json@6.1.0(rollup@4.18.0)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.17.2) + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) optionalDependencies: - rollup: 4.17.2 + rollup: 4.18.0 - '@rollup/plugin-replace@5.0.5(rollup@4.17.2)': + '@rollup/plugin-replace@5.0.7(rollup@4.18.0)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.17.2) - magic-string: 0.30.7 + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + magic-string: 0.30.10 optionalDependencies: - rollup: 4.17.2 + rollup: 4.18.0 - '@rollup/pluginutils@5.1.0(rollup@4.17.2)': + '@rollup/pluginutils@5.1.0(rollup@4.18.0)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 4.17.2 + rollup: 4.18.0 - '@rollup/rollup-android-arm-eabi@4.17.2': + '@rollup/rollup-android-arm-eabi@4.18.0': optional: true - '@rollup/rollup-android-arm64@4.17.2': + '@rollup/rollup-android-arm64@4.18.0': optional: true - '@rollup/rollup-darwin-arm64@4.17.2': + '@rollup/rollup-darwin-arm64@4.18.0': optional: true - '@rollup/rollup-darwin-x64@4.17.2': + '@rollup/rollup-darwin-x64@4.18.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.17.2': + '@rollup/rollup-linux-arm-musleabihf@4.18.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.17.2': + '@rollup/rollup-linux-arm64-gnu@4.18.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.17.2': + '@rollup/rollup-linux-arm64-musl@4.18.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.17.2': + '@rollup/rollup-linux-riscv64-gnu@4.18.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.17.2': + '@rollup/rollup-linux-s390x-gnu@4.18.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.17.2': + '@rollup/rollup-linux-x64-gnu@4.18.0': optional: true - '@rollup/rollup-linux-x64-musl@4.17.2': + '@rollup/rollup-linux-x64-musl@4.18.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.17.2': + '@rollup/rollup-win32-arm64-msvc@4.18.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.17.2': + '@rollup/rollup-win32-ia32-msvc@4.18.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.17.2': + '@rollup/rollup-win32-x64-msvc@4.18.0': optional: true - '@rushstack/node-core-library@4.1.0(@types/node@20.12.7)': + '@rushstack/node-core-library@5.4.1(@types/node@20.14.9)': dependencies: + ajv: 8.13.0 + ajv-draft-04: 1.0.0(ajv@8.13.0) + ajv-formats: 3.0.1(ajv@8.13.0) fs-extra: 7.0.1 import-lazy: 4.0.0 jju: 1.4.0 resolve: 1.22.8 semver: 7.5.4 - z-schema: 5.0.5 optionalDependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@rushstack/rig-package@0.5.2': dependencies: resolve: 1.22.8 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.10.1(@types/node@20.12.7)': + '@rushstack/terminal@0.13.0(@types/node@20.14.9)': dependencies: - '@rushstack/node-core-library': 4.1.0(@types/node@20.12.7) + '@rushstack/node-core-library': 5.4.1(@types/node@20.14.9) supports-color: 8.1.1 optionalDependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 - '@rushstack/ts-command-line@4.19.2(@types/node@20.12.7)': + '@rushstack/ts-command-line@4.22.0(@types/node@20.14.9)': dependencies: - '@rushstack/terminal': 0.10.1(@types/node@20.12.7) + '@rushstack/terminal': 0.13.0(@types/node@20.14.9) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.1 transitivePeerDependencies: - '@types/node' - '@sentry/core@8.5.0': - dependencies: - '@sentry/types': 8.5.0 - '@sentry/utils': 8.5.0 - - '@sentry/node@8.5.0': - dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/context-async-hooks': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-connect': 0.36.0(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-express': 0.39.0(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-fastify': 0.36.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-graphql': 0.40.0(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-hapi': 0.38.0(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-http': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-ioredis': 0.40.0(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-koa': 0.40.0(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-mongodb': 0.43.0(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-mongoose': 0.38.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-mysql': 0.38.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-mysql2': 0.38.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-nestjs-core': 0.37.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-pg': 0.41.0(@opentelemetry/api@1.8.0) - '@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/sdk-trace-base': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 - '@prisma/instrumentation': 5.14.0 - '@sentry/core': 8.5.0 - '@sentry/opentelemetry': 8.5.0(@opentelemetry/api@1.8.0)(@opentelemetry/core@1.24.1(@opentelemetry/api@1.8.0))(@opentelemetry/instrumentation@0.51.1(@opentelemetry/api@1.8.0))(@opentelemetry/sdk-trace-base@1.24.1(@opentelemetry/api@1.8.0))(@opentelemetry/semantic-conventions@1.24.1) - '@sentry/types': 8.5.0 - '@sentry/utils': 8.5.0 + '@sec-ant/readable-stream@0.4.1': {} + + '@sentry/core@8.13.0': + dependencies: + '@sentry/types': 8.13.0 + '@sentry/utils': 8.13.0 + + '@sentry/node@8.13.0': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/context-async-hooks': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-connect': 0.37.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-express': 0.40.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-fastify': 0.37.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-graphql': 0.41.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-hapi': 0.39.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-http': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-ioredis': 0.41.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-koa': 0.41.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongodb': 0.45.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongoose': 0.39.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql': 0.39.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql2': 0.39.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-nestjs-core': 0.38.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-pg': 0.42.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-redis-4': 0.40.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + '@prisma/instrumentation': 5.16.0 + '@sentry/core': 8.13.0 + '@sentry/opentelemetry': 8.13.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1) + '@sentry/types': 8.13.0 + '@sentry/utils': 8.13.0 optionalDependencies: opentelemetry-instrumentation-fetch-node: 1.2.0 transitivePeerDependencies: - supports-color - '@sentry/opentelemetry@8.5.0(@opentelemetry/api@1.8.0)(@opentelemetry/core@1.24.1(@opentelemetry/api@1.8.0))(@opentelemetry/instrumentation@0.51.1(@opentelemetry/api@1.8.0))(@opentelemetry/sdk-trace-base@1.24.1(@opentelemetry/api@1.8.0))(@opentelemetry/semantic-conventions@1.24.1)': + '@sentry/opentelemetry@8.13.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1)': dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/sdk-trace-base': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 - '@sentry/core': 8.5.0 - '@sentry/types': 8.5.0 - '@sentry/utils': 8.5.0 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + '@sentry/core': 8.13.0 + '@sentry/types': 8.13.0 + '@sentry/utils': 8.13.0 - '@sentry/profiling-node@8.5.0': + '@sentry/profiling-node@8.13.0': dependencies: - '@sentry/core': 8.5.0 - '@sentry/node': 8.5.0 - '@sentry/types': 8.5.0 - '@sentry/utils': 8.5.0 + '@sentry/core': 8.13.0 + '@sentry/node': 8.13.0 + '@sentry/types': 8.13.0 + '@sentry/utils': 8.13.0 detect-libc: 2.0.3 node-abi: 3.62.0 transitivePeerDependencies: - supports-color - '@sentry/types@8.5.0': {} + '@sentry/types@8.13.0': {} - '@sentry/utils@8.5.0': + '@sentry/utils@8.13.0': dependencies: - '@sentry/types': 8.5.0 + '@sentry/types': 8.13.0 - '@shikijs/core@1.4.0': {} + '@shikijs/core@1.10.0': {} '@sideway/address@4.1.4': dependencies: @@ -14482,7 +15450,11 @@ snapshots: '@sindresorhus/is@5.3.0': {} - '@sindresorhus/is@6.1.0': {} + '@sindresorhus/is@6.3.1': {} + + '@sindresorhus/merge-streams@2.3.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} '@sinonjs/commons@2.0.0': dependencies: @@ -14508,154 +15480,172 @@ snapshots: '@sinonjs/text-encoding@0.7.2': {} - '@smithy/abort-controller@2.0.14': + '@smithy/abort-controller@2.2.0': dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 2.12.0 tslib: 2.6.2 - '@smithy/abort-controller@2.2.0': + '@smithy/abort-controller@3.1.1': dependencies: - '@smithy/types': 2.12.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/chunked-blob-reader-native@2.0.0': + '@smithy/chunked-blob-reader-native@3.0.0': dependencies: - '@smithy/util-base64': 2.0.0 + '@smithy/util-base64': 3.0.0 tslib: 2.6.2 - '@smithy/chunked-blob-reader@2.0.0': + '@smithy/chunked-blob-reader@3.0.0': dependencies: tslib: 2.6.2 - '@smithy/config-resolver@2.0.9': + '@smithy/config-resolver@3.0.4': dependencies: - '@smithy/node-config-provider': 2.0.11 - '@smithy/types': 2.6.0 - '@smithy/util-config-provider': 2.0.0 - '@smithy/util-middleware': 2.0.1 + '@smithy/node-config-provider': 3.1.3 + '@smithy/types': 3.3.0 + '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.3 tslib: 2.6.2 - '@smithy/credential-provider-imds@2.0.11': + '@smithy/core@2.2.4': dependencies: - '@smithy/node-config-provider': 2.0.11 - '@smithy/property-provider': 2.0.9 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.8 + '@smithy/middleware-endpoint': 3.0.4 + '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-serde': 3.0.3 + '@smithy/protocol-http': 4.0.3 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 + '@smithy/util-middleware': 3.0.3 tslib: 2.6.2 - '@smithy/eventstream-codec@2.0.8': + '@smithy/credential-provider-imds@3.1.3': dependencies: - '@aws-crypto/crc32': 3.0.0 - '@smithy/types': 2.6.0 - '@smithy/util-hex-encoding': 2.0.0 + '@smithy/node-config-provider': 3.1.3 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 tslib: 2.6.2 - '@smithy/eventstream-serde-browser@2.0.8': + '@smithy/eventstream-codec@3.1.2': dependencies: - '@smithy/eventstream-serde-universal': 2.0.8 - '@smithy/types': 2.6.0 + '@aws-crypto/crc32': 5.2.0 + '@smithy/types': 3.3.0 + '@smithy/util-hex-encoding': 3.0.0 tslib: 2.6.2 - '@smithy/eventstream-serde-config-resolver@2.0.8': + '@smithy/eventstream-serde-browser@3.0.4': dependencies: - '@smithy/types': 2.6.0 + '@smithy/eventstream-serde-universal': 3.0.4 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/eventstream-serde-node@2.0.8': + '@smithy/eventstream-serde-config-resolver@3.0.3': dependencies: - '@smithy/eventstream-serde-universal': 2.0.8 - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/eventstream-serde-universal@2.0.8': + '@smithy/eventstream-serde-node@3.0.4': dependencies: - '@smithy/eventstream-codec': 2.0.8 - '@smithy/types': 2.6.0 + '@smithy/eventstream-serde-universal': 3.0.4 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/fetch-http-handler@2.1.4': + '@smithy/eventstream-serde-universal@3.0.4': dependencies: - '@smithy/protocol-http': 3.0.10 - '@smithy/querystring-builder': 2.0.14 - '@smithy/types': 2.6.0 - '@smithy/util-base64': 2.0.0 + '@smithy/eventstream-codec': 3.1.2 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/hash-blob-browser@2.0.8': + '@smithy/fetch-http-handler@3.2.0': dependencies: - '@smithy/chunked-blob-reader': 2.0.0 - '@smithy/chunked-blob-reader-native': 2.0.0 - '@smithy/types': 2.6.0 + '@smithy/protocol-http': 4.0.3 + '@smithy/querystring-builder': 3.0.3 + '@smithy/types': 3.3.0 + '@smithy/util-base64': 3.0.0 tslib: 2.6.2 - '@smithy/hash-node@2.0.8': + '@smithy/hash-blob-browser@3.1.2': dependencies: - '@smithy/types': 2.6.0 - '@smithy/util-buffer-from': 2.0.0 - '@smithy/util-utf8': 2.0.0 + '@smithy/chunked-blob-reader': 3.0.0 + '@smithy/chunked-blob-reader-native': 3.0.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/hash-stream-node@2.0.8': + '@smithy/hash-node@3.0.3': dependencies: - '@smithy/types': 2.6.0 - '@smithy/util-utf8': 2.0.0 + '@smithy/types': 3.3.0 + '@smithy/util-buffer-from': 3.0.0 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 - '@smithy/invalid-dependency@2.0.8': + '@smithy/hash-stream-node@3.1.2': dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.2 + + '@smithy/invalid-dependency@3.0.3': + dependencies: + '@smithy/types': 3.3.0 tslib: 2.6.2 '@smithy/is-array-buffer@2.0.0': dependencies: tslib: 2.6.2 - '@smithy/md5-js@2.0.8': + '@smithy/is-array-buffer@3.0.0': dependencies: - '@smithy/types': 2.6.0 - '@smithy/util-utf8': 2.0.0 tslib: 2.6.2 - '@smithy/middleware-content-length@2.0.10': + '@smithy/md5-js@3.0.3': dependencies: - '@smithy/protocol-http': 3.0.10 - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 - '@smithy/middleware-endpoint@2.0.8': + '@smithy/middleware-content-length@3.0.3': dependencies: - '@smithy/middleware-serde': 2.0.8 - '@smithy/types': 2.6.0 - '@smithy/url-parser': 2.0.8 - '@smithy/util-middleware': 2.0.1 + '@smithy/protocol-http': 4.0.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/middleware-retry@2.0.11': + '@smithy/middleware-endpoint@3.0.4': dependencies: - '@smithy/node-config-provider': 2.0.11 - '@smithy/protocol-http': 3.0.10 - '@smithy/service-error-classification': 2.0.1 - '@smithy/types': 2.6.0 - '@smithy/util-middleware': 2.0.1 - '@smithy/util-retry': 2.0.1 + '@smithy/middleware-serde': 3.0.3 + '@smithy/node-config-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.3 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-middleware': 3.0.3 tslib: 2.6.2 - uuid: 8.3.2 - '@smithy/middleware-serde@2.0.8': + '@smithy/middleware-retry@3.0.7': dependencies: - '@smithy/types': 2.6.0 + '@smithy/node-config-provider': 3.1.3 + '@smithy/protocol-http': 4.0.3 + '@smithy/service-error-classification': 3.0.3 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 tslib: 2.6.2 + uuid: 9.0.1 - '@smithy/middleware-stack@2.0.1': + '@smithy/middleware-serde@3.0.3': dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/node-config-provider@2.0.11': + '@smithy/middleware-stack@3.0.3': dependencies: - '@smithy/property-provider': 2.0.9 - '@smithy/shared-ini-file-loader': 2.0.10 - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 + tslib: 2.6.2 + + '@smithy/node-config-provider@3.1.3': + dependencies: + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 '@smithy/node-http-handler@2.5.0': @@ -14666,14 +15656,17 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.6.2 - '@smithy/property-provider@2.0.9': + '@smithy/node-http-handler@3.1.1': dependencies: - '@smithy/types': 2.6.0 + '@smithy/abort-controller': 3.1.1 + '@smithy/protocol-http': 4.0.3 + '@smithy/querystring-builder': 3.0.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/protocol-http@3.0.10': + '@smithy/property-provider@3.1.3': dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 '@smithy/protocol-http@3.3.0': @@ -14681,10 +15674,9 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.6.2 - '@smithy/querystring-builder@2.0.14': + '@smithy/protocol-http@4.0.3': dependencies: - '@smithy/types': 2.6.0 - '@smithy/util-uri-escape': 2.0.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 '@smithy/querystring-builder@2.2.0': @@ -14693,62 +15685,70 @@ snapshots: '@smithy/util-uri-escape': 2.2.0 tslib: 2.6.2 - '@smithy/querystring-parser@2.0.8': + '@smithy/querystring-builder@3.0.3': dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 + '@smithy/util-uri-escape': 3.0.0 tslib: 2.6.2 - '@smithy/service-error-classification@2.0.1': + '@smithy/querystring-parser@3.0.3': dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 + tslib: 2.6.2 - '@smithy/shared-ini-file-loader@2.0.10': + '@smithy/service-error-classification@3.0.3': dependencies: - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 + + '@smithy/shared-ini-file-loader@3.1.3': + dependencies: + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/signature-v4@2.0.5': + '@smithy/signature-v4@3.1.2': dependencies: - '@smithy/eventstream-codec': 2.0.8 - '@smithy/is-array-buffer': 2.0.0 - '@smithy/types': 2.6.0 - '@smithy/util-hex-encoding': 2.0.0 - '@smithy/util-middleware': 2.0.1 - '@smithy/util-uri-escape': 2.0.0 - '@smithy/util-utf8': 2.0.0 + '@smithy/is-array-buffer': 3.0.0 + '@smithy/types': 3.3.0 + '@smithy/util-hex-encoding': 3.0.0 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-uri-escape': 3.0.0 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 - '@smithy/smithy-client@2.1.5': + '@smithy/smithy-client@3.1.5': dependencies: - '@smithy/middleware-stack': 2.0.1 - '@smithy/types': 2.6.0 - '@smithy/util-stream': 2.0.11 + '@smithy/middleware-endpoint': 3.0.4 + '@smithy/middleware-stack': 3.0.3 + '@smithy/protocol-http': 4.0.3 + '@smithy/types': 3.3.0 + '@smithy/util-stream': 3.0.5 tslib: 2.6.2 '@smithy/types@2.12.0': dependencies: tslib: 2.6.2 - '@smithy/types@2.6.0': + '@smithy/types@3.3.0': dependencies: tslib: 2.6.2 - '@smithy/url-parser@2.0.8': + '@smithy/url-parser@3.0.3': dependencies: - '@smithy/querystring-parser': 2.0.8 - '@smithy/types': 2.6.0 + '@smithy/querystring-parser': 3.0.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/util-base64@2.0.0': + '@smithy/util-base64@3.0.0': dependencies: - '@smithy/util-buffer-from': 2.0.0 + '@smithy/util-buffer-from': 3.0.0 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 - '@smithy/util-body-length-browser@2.0.0': + '@smithy/util-body-length-browser@3.0.0': dependencies: tslib: 2.6.2 - '@smithy/util-body-length-node@2.1.0': + '@smithy/util-body-length-node@3.0.0': dependencies: tslib: 2.6.2 @@ -14757,117 +15757,136 @@ snapshots: '@smithy/is-array-buffer': 2.0.0 tslib: 2.6.2 - '@smithy/util-config-provider@2.0.0': + '@smithy/util-buffer-from@3.0.0': dependencies: + '@smithy/is-array-buffer': 3.0.0 tslib: 2.6.2 - '@smithy/util-defaults-mode-browser@2.0.9': + '@smithy/util-config-provider@3.0.0': dependencies: - '@smithy/property-provider': 2.0.9 - '@smithy/smithy-client': 2.1.5 - '@smithy/types': 2.6.0 + tslib: 2.6.2 + + '@smithy/util-defaults-mode-browser@3.0.7': + dependencies: + '@smithy/property-provider': 3.1.3 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 bowser: 2.11.0 tslib: 2.6.2 - '@smithy/util-defaults-mode-node@2.0.11': + '@smithy/util-defaults-mode-node@3.0.7': dependencies: - '@smithy/config-resolver': 2.0.9 - '@smithy/credential-provider-imds': 2.0.11 - '@smithy/node-config-provider': 2.0.11 - '@smithy/property-provider': 2.0.9 - '@smithy/smithy-client': 2.1.5 - '@smithy/types': 2.6.0 + '@smithy/config-resolver': 3.0.4 + '@smithy/credential-provider-imds': 3.1.3 + '@smithy/node-config-provider': 3.1.3 + '@smithy/property-provider': 3.1.3 + '@smithy/smithy-client': 3.1.5 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/util-hex-encoding@2.0.0': + '@smithy/util-endpoints@2.0.4': dependencies: + '@smithy/node-config-provider': 3.1.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/util-middleware@2.0.1': + '@smithy/util-hex-encoding@3.0.0': dependencies: - '@smithy/types': 2.6.0 tslib: 2.6.2 - '@smithy/util-retry@2.0.1': + '@smithy/util-middleware@3.0.3': dependencies: - '@smithy/service-error-classification': 2.0.1 - '@smithy/types': 2.6.0 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/util-stream@2.0.11': + '@smithy/util-retry@3.0.3': dependencies: - '@smithy/fetch-http-handler': 2.1.4 - '@smithy/node-http-handler': 2.5.0 - '@smithy/types': 2.6.0 - '@smithy/util-base64': 2.0.0 - '@smithy/util-buffer-from': 2.0.0 - '@smithy/util-hex-encoding': 2.0.0 - '@smithy/util-utf8': 2.0.0 + '@smithy/service-error-classification': 3.0.3 + '@smithy/types': 3.3.0 tslib: 2.6.2 - '@smithy/util-uri-escape@2.0.0': + '@smithy/util-stream@3.0.5': dependencies: + '@smithy/fetch-http-handler': 3.2.0 + '@smithy/node-http-handler': 3.1.1 + '@smithy/types': 3.3.0 + '@smithy/util-base64': 3.0.0 + '@smithy/util-buffer-from': 3.0.0 + '@smithy/util-hex-encoding': 3.0.0 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.2 '@smithy/util-uri-escape@2.2.0': dependencies: tslib: 2.6.2 + '@smithy/util-uri-escape@3.0.0': + dependencies: + tslib: 2.6.2 + '@smithy/util-utf8@2.0.0': dependencies: '@smithy/util-buffer-from': 2.0.0 tslib: 2.6.2 - '@smithy/util-waiter@2.0.8': + '@smithy/util-utf8@3.0.0': + dependencies: + '@smithy/util-buffer-from': 3.0.0 + tslib: 2.6.2 + + '@smithy/util-waiter@3.1.2': dependencies: - '@smithy/abort-controller': 2.0.14 - '@smithy/types': 2.6.0 + '@smithy/abort-controller': 3.1.1 + '@smithy/types': 3.3.0 tslib: 2.6.2 '@sqltools/formatter@1.2.5': {} - '@storybook/addon-actions@8.0.9': + '@storybook/addon-actions@8.1.11': dependencies: - '@storybook/core-events': 8.0.9 + '@storybook/core-events': 8.1.11 '@storybook/global': 5.0.0 '@types/uuid': 9.0.8 dequal: 2.0.3 polished: 4.2.2 uuid: 9.0.1 - '@storybook/addon-backgrounds@8.0.9': + '@storybook/addon-backgrounds@8.1.11': dependencies: '@storybook/global': 5.0.0 memoizerific: 1.11.3 ts-dedent: 2.2.0 - '@storybook/addon-controls@8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@storybook/addon-controls@8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@storybook/blocks': 8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/blocks': 8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + dequal: 2.0.3 lodash: 4.17.21 ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' + - '@types/react-dom' - encoding + - prettier - react - react-dom - supports-color - '@storybook/addon-docs@8.0.9(encoding@0.1.13)': + '@storybook/addon-docs@8.1.11(encoding@0.1.13)(prettier@3.3.2)': dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 '@mdx-js/react': 3.0.1(@types/react@18.0.28)(react@18.3.1) - '@storybook/blocks': 8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/client-logger': 8.0.9 - '@storybook/components': 8.0.9(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/csf-plugin': 8.0.9 - '@storybook/csf-tools': 8.0.9 + '@storybook/blocks': 8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/client-logger': 8.1.11 + '@storybook/components': 8.1.11(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/csf-plugin': 8.1.11 + '@storybook/csf-tools': 8.1.11 '@storybook/global': 5.0.0 - '@storybook/node-logger': 8.0.9 - '@storybook/preview-api': 8.0.9 - '@storybook/react-dom-shim': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/theming': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/types': 8.0.9 + '@storybook/node-logger': 8.1.11 + '@storybook/preview-api': 8.1.11 + '@storybook/react-dom-shim': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/theming': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/types': 8.1.11 '@types/react': 18.0.28 fs-extra: 11.1.1 react: 18.3.1 @@ -14876,42 +15895,46 @@ snapshots: rehype-slug: 6.0.0 ts-dedent: 2.2.0 transitivePeerDependencies: + - '@types/react-dom' - encoding + - prettier - supports-color - '@storybook/addon-essentials@8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@storybook/addon-actions': 8.0.9 - '@storybook/addon-backgrounds': 8.0.9 - '@storybook/addon-controls': 8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/addon-docs': 8.0.9(encoding@0.1.13) - '@storybook/addon-highlight': 8.0.9 - '@storybook/addon-measure': 8.0.9 - '@storybook/addon-outline': 8.0.9 - '@storybook/addon-toolbars': 8.0.9 - '@storybook/addon-viewport': 8.0.9 - '@storybook/core-common': 8.0.9(encoding@0.1.13) - '@storybook/manager-api': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/node-logger': 8.0.9 - '@storybook/preview-api': 8.0.9 + '@storybook/addon-essentials@8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@storybook/addon-actions': 8.1.11 + '@storybook/addon-backgrounds': 8.1.11 + '@storybook/addon-controls': 8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/addon-docs': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/addon-highlight': 8.1.11 + '@storybook/addon-measure': 8.1.11 + '@storybook/addon-outline': 8.1.11 + '@storybook/addon-toolbars': 8.1.11 + '@storybook/addon-viewport': 8.1.11 + '@storybook/core-common': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/manager-api': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/node-logger': 8.1.11 + '@storybook/preview-api': 8.1.11 ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' + - '@types/react-dom' - encoding + - prettier - react - react-dom - supports-color - '@storybook/addon-highlight@8.0.9': + '@storybook/addon-highlight@8.1.11': dependencies: '@storybook/global': 5.0.0 - '@storybook/addon-interactions@8.0.9(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.12.7))(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3))': + '@storybook/addon-interactions@8.1.11(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.14.9))(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1))': dependencies: '@storybook/global': 5.0.0 - '@storybook/instrumenter': 8.0.9 - '@storybook/test': 8.0.9(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.12.7))(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3)) - '@storybook/types': 8.0.9 + '@storybook/instrumenter': 8.1.11 + '@storybook/test': 8.1.11(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.14.9))(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1)) + '@storybook/types': 8.1.11 polished: 4.2.2 ts-dedent: 2.2.0 transitivePeerDependencies: @@ -14921,58 +15944,58 @@ snapshots: - jest - vitest - '@storybook/addon-links@8.0.9(react@18.3.1)': + '@storybook/addon-links@8.1.11(react@18.3.1)': dependencies: - '@storybook/csf': 0.1.6 + '@storybook/csf': 0.1.9 '@storybook/global': 5.0.0 ts-dedent: 2.2.0 optionalDependencies: react: 18.3.1 - '@storybook/addon-mdx-gfm@8.0.9': + '@storybook/addon-mdx-gfm@8.1.11': dependencies: - '@storybook/node-logger': 8.0.9 + '@storybook/node-logger': 8.1.11 remark-gfm: 4.0.0 ts-dedent: 2.2.0 transitivePeerDependencies: - supports-color - '@storybook/addon-measure@8.0.9': + '@storybook/addon-measure@8.1.11': dependencies: '@storybook/global': 5.0.0 - tiny-invariant: 1.3.1 + tiny-invariant: 1.3.3 - '@storybook/addon-outline@8.0.9': + '@storybook/addon-outline@8.1.11': dependencies: '@storybook/global': 5.0.0 ts-dedent: 2.2.0 - '@storybook/addon-storysource@8.0.9': + '@storybook/addon-storysource@8.1.11': dependencies: - '@storybook/source-loader': 8.0.9 + '@storybook/source-loader': 8.1.11 estraverse: 5.3.0 - tiny-invariant: 1.3.1 + tiny-invariant: 1.3.3 - '@storybook/addon-toolbars@8.0.9': {} + '@storybook/addon-toolbars@8.1.11': {} - '@storybook/addon-viewport@8.0.9': + '@storybook/addon-viewport@8.1.11': dependencies: memoizerific: 1.11.3 - '@storybook/blocks@8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@storybook/blocks@8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@storybook/channels': 8.0.9 - '@storybook/client-logger': 8.0.9 - '@storybook/components': 8.0.9(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/core-events': 8.0.9 - '@storybook/csf': 0.1.6 - '@storybook/docs-tools': 8.0.9(encoding@0.1.13) + '@storybook/channels': 8.1.11 + '@storybook/client-logger': 8.1.11 + '@storybook/components': 8.1.11(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/core-events': 8.1.11 + '@storybook/csf': 0.1.9 + '@storybook/docs-tools': 8.1.11(encoding@0.1.13)(prettier@3.3.2) '@storybook/global': 5.0.0 '@storybook/icons': 1.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/manager-api': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/preview-api': 8.0.9 - '@storybook/theming': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/types': 8.0.9 + '@storybook/manager-api': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/preview-api': 8.1.11 + '@storybook/theming': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/types': 8.1.11 '@types/lodash': 4.14.191 color-convert: 2.0.1 dequal: 2.0.3 @@ -14990,20 +16013,22 @@ snapshots: react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - '@types/react' + - '@types/react-dom' - encoding + - prettier - supports-color - '@storybook/builder-manager@8.0.9(encoding@0.1.13)': + '@storybook/builder-manager@8.1.11(encoding@0.1.13)(prettier@3.3.2)': dependencies: '@fal-works/esbuild-plugin-global-externals': 2.1.2 - '@storybook/core-common': 8.0.9(encoding@0.1.13) - '@storybook/manager': 8.0.9 - '@storybook/node-logger': 8.0.9 + '@storybook/core-common': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/manager': 8.1.11 + '@storybook/node-logger': 8.1.11 '@types/ejs': 3.1.2 - '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.20.2) + '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.19.11) browser-assert: 1.2.1 - ejs: 3.1.9 - esbuild: 0.20.2 + ejs: 3.1.10 + esbuild: 0.19.11 esbuild-plugin-alias: 0.2.1 express: 4.19.2 fs-extra: 11.1.1 @@ -15011,55 +16036,57 @@ snapshots: util: 0.12.5 transitivePeerDependencies: - encoding + - prettier - supports-color - '@storybook/builder-vite@8.0.9(encoding@0.1.13)(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))': - dependencies: - '@storybook/channels': 8.0.9 - '@storybook/client-logger': 8.0.9 - '@storybook/core-common': 8.0.9(encoding@0.1.13) - '@storybook/core-events': 8.0.9 - '@storybook/csf-plugin': 8.0.9 - '@storybook/node-logger': 8.0.9 - '@storybook/preview': 8.0.9 - '@storybook/preview-api': 8.0.9 - '@storybook/types': 8.0.9 + '@storybook/builder-vite@8.1.11(encoding@0.1.13)(prettier@3.3.2)(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1))': + dependencies: + '@storybook/channels': 8.1.11 + '@storybook/client-logger': 8.1.11 + '@storybook/core-common': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/core-events': 8.1.11 + '@storybook/csf-plugin': 8.1.11 + '@storybook/node-logger': 8.1.11 + '@storybook/preview': 8.1.11 + '@storybook/preview-api': 8.1.11 + '@storybook/types': 8.1.11 '@types/find-cache-dir': 3.2.1 browser-assert: 1.2.1 - es-module-lexer: 0.9.3 - express: 4.18.2 + es-module-lexer: 1.5.4 + express: 4.19.2 find-cache-dir: 3.3.2 fs-extra: 11.1.1 - magic-string: 0.30.7 + magic-string: 0.30.10 ts-dedent: 2.2.0 - vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) + vite: 5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1) optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 transitivePeerDependencies: - encoding + - prettier - supports-color - '@storybook/channels@8.0.9': + '@storybook/channels@8.1.11': dependencies: - '@storybook/client-logger': 8.0.9 - '@storybook/core-events': 8.0.9 + '@storybook/client-logger': 8.1.11 + '@storybook/core-events': 8.1.11 '@storybook/global': 5.0.0 telejson: 7.2.0 - tiny-invariant: 1.3.1 + tiny-invariant: 1.3.3 - '@storybook/cli@8.0.9(@babel/preset-env@7.23.5(@babel/core@7.24.0))(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)': + '@storybook/cli@8.1.11(@babel/preset-env@7.24.7(@babel/core@7.24.7))(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)': dependencies: - '@babel/core': 7.24.0 - '@babel/types': 7.24.0 + '@babel/core': 7.24.7 + '@babel/types': 7.24.7 '@ndelangen/get-tarball': 3.0.7 - '@storybook/codemod': 8.0.9 - '@storybook/core-common': 8.0.9(encoding@0.1.13) - '@storybook/core-events': 8.0.9 - '@storybook/core-server': 8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3) - '@storybook/csf-tools': 8.0.9 - '@storybook/node-logger': 8.0.9 - '@storybook/telemetry': 8.0.9(encoding@0.1.13) - '@storybook/types': 8.0.9 + '@storybook/codemod': 8.1.11 + '@storybook/core-common': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/core-events': 8.1.11 + '@storybook/core-server': 8.1.11(bufferutil@4.0.7)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3) + '@storybook/csf-tools': 8.1.11 + '@storybook/node-logger': 8.1.11 + '@storybook/telemetry': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/types': 8.1.11 '@types/semver': 7.5.8 '@yarnpkg/fslib': 2.10.3 '@yarnpkg/libzip': 2.3.0 @@ -15073,17 +16100,17 @@ snapshots: fs-extra: 11.1.1 get-npm-tarball-url: 2.0.3 giget: 1.1.2 - globby: 11.1.0 - jscodeshift: 0.15.1(@babel/preset-env@7.23.5(@babel/core@7.24.0)) + globby: 14.0.1 + jscodeshift: 0.15.1(@babel/preset-env@7.24.7(@babel/core@7.24.7)) leven: 3.1.0 ora: 5.4.1 - prettier: 3.2.5 + prettier: 3.3.2 prompts: 2.4.2 read-pkg-up: 7.0.1 semver: 7.6.0 strip-json-comments: 3.1.1 - tempy: 1.0.1 - tiny-invariant: 1.3.1 + tempy: 3.1.0 + tiny-invariant: 1.3.3 ts-dedent: 2.2.0 transitivePeerDependencies: - '@babel/preset-env' @@ -15094,104 +16121,112 @@ snapshots: - supports-color - utf-8-validate - '@storybook/client-logger@8.0.9': + '@storybook/client-logger@8.1.11': dependencies: '@storybook/global': 5.0.0 - '@storybook/codemod@8.0.9': + '@storybook/codemod@8.1.11': dependencies: - '@babel/core': 7.24.0 - '@babel/preset-env': 7.23.5(@babel/core@7.24.0) - '@babel/types': 7.24.0 - '@storybook/csf': 0.1.6 - '@storybook/csf-tools': 8.0.9 - '@storybook/node-logger': 8.0.9 - '@storybook/types': 8.0.9 + '@babel/core': 7.24.7 + '@babel/preset-env': 7.24.7(@babel/core@7.24.7) + '@babel/types': 7.24.7 + '@storybook/csf': 0.1.9 + '@storybook/csf-tools': 8.1.11 + '@storybook/node-logger': 8.1.11 + '@storybook/types': 8.1.11 '@types/cross-spawn': 6.0.2 cross-spawn: 7.0.3 - globby: 11.1.0 - jscodeshift: 0.15.1(@babel/preset-env@7.23.5(@babel/core@7.24.0)) + globby: 14.0.1 + jscodeshift: 0.15.1(@babel/preset-env@7.24.7(@babel/core@7.24.7)) lodash: 4.17.21 - prettier: 3.2.5 + prettier: 3.3.2 recast: 0.23.6 - tiny-invariant: 1.3.1 + tiny-invariant: 1.3.3 transitivePeerDependencies: - supports-color - '@storybook/components@8.0.9(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@storybook/components@8.1.11(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-slot': 1.0.2(@types/react@18.0.28)(react@18.3.1) - '@storybook/client-logger': 8.0.9 - '@storybook/csf': 0.1.6 + '@radix-ui/react-dialog': 1.1.1(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.0.28)(react@18.3.1) + '@storybook/client-logger': 8.1.11 + '@storybook/csf': 0.1.9 '@storybook/global': 5.0.0 '@storybook/icons': 1.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/theming': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/types': 8.0.9 + '@storybook/theming': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/types': 8.1.11 memoizerific: 1.11.3 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) util-deprecate: 1.0.2 transitivePeerDependencies: - '@types/react' + - '@types/react-dom' - '@storybook/core-common@8.0.9(encoding@0.1.13)': + '@storybook/core-common@8.1.11(encoding@0.1.13)(prettier@3.3.2)': dependencies: - '@storybook/core-events': 8.0.9 - '@storybook/csf-tools': 8.0.9 - '@storybook/node-logger': 8.0.9 - '@storybook/types': 8.0.9 + '@storybook/core-events': 8.1.11 + '@storybook/csf-tools': 8.1.11 + '@storybook/node-logger': 8.1.11 + '@storybook/types': 8.1.11 '@yarnpkg/fslib': 2.10.3 '@yarnpkg/libzip': 2.3.0 chalk: 4.1.2 cross-spawn: 7.0.3 - esbuild: 0.20.2 - esbuild-register: 3.5.0(esbuild@0.20.2) + esbuild: 0.19.11 + esbuild-register: 3.5.0(esbuild@0.19.11) execa: 5.1.1 file-system-cache: 2.3.0 find-cache-dir: 3.3.2 find-up: 5.0.0 fs-extra: 11.1.1 - glob: 10.3.12 + glob: 10.4.2 handlebars: 4.7.7 lazy-universal-dotenv: 4.0.0 node-fetch: 2.7.0(encoding@0.1.13) picomatch: 2.3.1 pkg-dir: 5.0.0 + prettier-fallback: prettier@3.3.2 pretty-hrtime: 1.0.3 resolve-from: 5.0.0 semver: 7.6.0 - tempy: 1.0.1 - tiny-invariant: 1.3.1 + tempy: 3.1.0 + tiny-invariant: 1.3.3 ts-dedent: 2.2.0 util: 0.12.5 + optionalDependencies: + prettier: 3.3.2 transitivePeerDependencies: - encoding - supports-color - '@storybook/core-events@8.0.9': + '@storybook/core-events@8.1.11': dependencies: + '@storybook/csf': 0.1.9 ts-dedent: 2.2.0 - '@storybook/core-server@8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)': + '@storybook/core-server@8.1.11(bufferutil@4.0.7)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)': dependencies: '@aw-web-design/x-default-browser': 1.4.126 - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 + '@babel/parser': 7.24.7 '@discoveryjs/json-ext': 0.5.7 - '@storybook/builder-manager': 8.0.9(encoding@0.1.13) - '@storybook/channels': 8.0.9 - '@storybook/core-common': 8.0.9(encoding@0.1.13) - '@storybook/core-events': 8.0.9 - '@storybook/csf': 0.1.6 - '@storybook/csf-tools': 8.0.9 - '@storybook/docs-mdx': 3.0.0 + '@storybook/builder-manager': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/channels': 8.1.11 + '@storybook/core-common': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/core-events': 8.1.11 + '@storybook/csf': 0.1.9 + '@storybook/csf-tools': 8.1.11 + '@storybook/docs-mdx': 3.1.0-next.0 '@storybook/global': 5.0.0 - '@storybook/manager': 8.0.9 - '@storybook/manager-api': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/node-logger': 8.0.9 - '@storybook/preview-api': 8.0.9 - '@storybook/telemetry': 8.0.9(encoding@0.1.13) - '@storybook/types': 8.0.9 + '@storybook/manager': 8.1.11 + '@storybook/manager-api': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/node-logger': 8.1.11 + '@storybook/preview-api': 8.1.11 + '@storybook/telemetry': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/types': 8.1.11 '@types/detect-port': 1.3.2 + '@types/diff': 5.2.1 '@types/node': 18.17.15 '@types/pretty-hrtime': 1.0.1 '@types/semver': 7.5.8 @@ -15200,10 +16235,10 @@ snapshots: cli-table3: 0.6.3 compression: 1.7.4 detect-port: 1.5.1 - express: 4.18.2 + diff: 5.2.0 + express: 4.19.2 fs-extra: 11.1.1 - globby: 11.1.0 - ip: 2.0.1 + globby: 14.0.1 lodash: 4.17.21 open: 8.4.2 pretty-hrtime: 1.0.3 @@ -15211,59 +16246,61 @@ snapshots: read-pkg-up: 7.0.1 semver: 7.6.0 telejson: 7.2.0 - tiny-invariant: 1.3.1 + tiny-invariant: 1.3.3 ts-dedent: 2.2.0 util: 0.12.5 util-deprecate: 1.0.2 watchpack: 2.4.0 - ws: 8.17.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) + ws: 8.17.1(bufferutil@4.0.7)(utf-8-validate@6.0.3) transitivePeerDependencies: - bufferutil - encoding + - prettier - react - react-dom - supports-color - utf-8-validate - '@storybook/csf-plugin@8.0.9': + '@storybook/csf-plugin@8.1.11': dependencies: - '@storybook/csf-tools': 8.0.9 + '@storybook/csf-tools': 8.1.11 unplugin: 1.4.0 transitivePeerDependencies: - supports-color - '@storybook/csf-tools@8.0.9': + '@storybook/csf-tools@8.1.11': dependencies: - '@babel/generator': 7.23.6 - '@babel/parser': 7.24.0 - '@babel/traverse': 7.24.0 - '@babel/types': 7.24.0 - '@storybook/csf': 0.1.6 - '@storybook/types': 8.0.9 + '@babel/generator': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + '@storybook/csf': 0.1.9 + '@storybook/types': 8.1.11 fs-extra: 11.1.1 recast: 0.23.6 ts-dedent: 2.2.0 transitivePeerDependencies: - supports-color - '@storybook/csf@0.1.6': + '@storybook/csf@0.1.9': dependencies: type-fest: 2.19.0 - '@storybook/docs-mdx@3.0.0': {} + '@storybook/docs-mdx@3.1.0-next.0': {} - '@storybook/docs-tools@8.0.9(encoding@0.1.13)': + '@storybook/docs-tools@8.1.11(encoding@0.1.13)(prettier@3.3.2)': dependencies: - '@storybook/core-common': 8.0.9(encoding@0.1.13) - '@storybook/core-events': 8.0.9 - '@storybook/preview-api': 8.0.9 - '@storybook/types': 8.0.9 + '@storybook/core-common': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/core-events': 8.1.11 + '@storybook/preview-api': 8.1.11 + '@storybook/types': 8.1.11 '@types/doctrine': 0.0.3 assert: 2.1.0 doctrine: 3.0.0 lodash: 4.17.21 transitivePeerDependencies: - encoding + - prettier - supports-color '@storybook/global@5.0.0': {} @@ -15273,27 +16310,27 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/instrumenter@8.0.9': + '@storybook/instrumenter@8.1.11': dependencies: - '@storybook/channels': 8.0.9 - '@storybook/client-logger': 8.0.9 - '@storybook/core-events': 8.0.9 + '@storybook/channels': 8.1.11 + '@storybook/client-logger': 8.1.11 + '@storybook/core-events': 8.1.11 '@storybook/global': 5.0.0 - '@storybook/preview-api': 8.0.9 + '@storybook/preview-api': 8.1.11 '@vitest/utils': 1.6.0 util: 0.12.5 - '@storybook/manager-api@8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@storybook/manager-api@8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@storybook/channels': 8.0.9 - '@storybook/client-logger': 8.0.9 - '@storybook/core-events': 8.0.9 - '@storybook/csf': 0.1.6 + '@storybook/channels': 8.1.11 + '@storybook/client-logger': 8.1.11 + '@storybook/core-events': 8.1.11 + '@storybook/csf': 0.1.9 '@storybook/global': 5.0.0 '@storybook/icons': 1.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/router': 8.0.9 - '@storybook/theming': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/types': 8.0.9 + '@storybook/router': 8.1.11 + '@storybook/theming': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/types': 8.1.11 dequal: 2.0.3 lodash: 4.17.21 memoizerific: 1.11.3 @@ -15304,65 +16341,67 @@ snapshots: - react - react-dom - '@storybook/manager@8.0.9': {} + '@storybook/manager@8.1.11': {} - '@storybook/node-logger@8.0.9': {} + '@storybook/node-logger@8.1.11': {} - '@storybook/preview-api@8.0.9': + '@storybook/preview-api@8.1.11': dependencies: - '@storybook/channels': 8.0.9 - '@storybook/client-logger': 8.0.9 - '@storybook/core-events': 8.0.9 - '@storybook/csf': 0.1.6 + '@storybook/channels': 8.1.11 + '@storybook/client-logger': 8.1.11 + '@storybook/core-events': 8.1.11 + '@storybook/csf': 0.1.9 '@storybook/global': 5.0.0 - '@storybook/types': 8.0.9 + '@storybook/types': 8.1.11 '@types/qs': 6.9.7 dequal: 2.0.3 lodash: 4.17.21 memoizerific: 1.11.3 qs: 6.11.1 - tiny-invariant: 1.3.1 + tiny-invariant: 1.3.3 ts-dedent: 2.2.0 util-deprecate: 1.0.2 - '@storybook/preview@8.0.9': {} + '@storybook/preview@8.1.11': {} - '@storybook/react-dom-shim@8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@storybook/react-dom-shim@8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/react-vite@8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.17.2)(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))': + '@storybook/react-vite@8.1.11(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.18.0)(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1))': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) - '@rollup/pluginutils': 5.1.0(rollup@4.17.2) - '@storybook/builder-vite': 8.0.9(encoding@0.1.13)(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) - '@storybook/node-logger': 8.0.9 - '@storybook/react': 8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.2) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.1(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1)) + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + '@storybook/builder-vite': 8.1.11(encoding@0.1.13)(prettier@3.3.2)(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1)) + '@storybook/node-logger': 8.1.11 + '@storybook/react': 8.1.11(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.3) + '@storybook/types': 8.1.11 find-up: 5.0.0 - magic-string: 0.30.7 + magic-string: 0.30.10 react: 18.3.1 react-docgen: 7.0.1 react-dom: 18.3.1(react@18.3.1) resolve: 1.22.8 tsconfig-paths: 4.2.0 - vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) + vite: 5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1) transitivePeerDependencies: - '@preact/preset-vite' - encoding + - prettier - rollup - supports-color - typescript - vite-plugin-glimmerx - '@storybook/react@8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.2)': + '@storybook/react@8.1.11(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.3)': dependencies: - '@storybook/client-logger': 8.0.9 - '@storybook/docs-tools': 8.0.9(encoding@0.1.13) + '@storybook/client-logger': 8.1.11 + '@storybook/docs-tools': 8.1.11(encoding@0.1.13)(prettier@3.3.2) '@storybook/global': 5.0.0 - '@storybook/preview-api': 8.0.9 - '@storybook/react-dom-shim': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/types': 8.0.9 + '@storybook/preview-api': 8.1.11 + '@storybook/react-dom-shim': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/types': 8.1.11 '@types/escodegen': 0.0.6 '@types/estree': 0.0.51 '@types/node': 18.17.15 @@ -15381,30 +16420,31 @@ snapshots: type-fest: 2.19.0 util-deprecate: 1.0.2 optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 transitivePeerDependencies: - encoding + - prettier - supports-color - '@storybook/router@8.0.9': + '@storybook/router@8.1.11': dependencies: - '@storybook/client-logger': 8.0.9 + '@storybook/client-logger': 8.1.11 memoizerific: 1.11.3 qs: 6.11.1 - '@storybook/source-loader@8.0.9': + '@storybook/source-loader@8.1.11': dependencies: - '@storybook/csf': 0.1.6 - '@storybook/types': 8.0.9 + '@storybook/csf': 0.1.9 + '@storybook/types': 8.1.11 estraverse: 5.3.0 lodash: 4.17.21 - prettier: 3.2.5 + prettier: 3.3.2 - '@storybook/telemetry@8.0.9(encoding@0.1.13)': + '@storybook/telemetry@8.1.11(encoding@0.1.13)(prettier@3.3.2)': dependencies: - '@storybook/client-logger': 8.0.9 - '@storybook/core-common': 8.0.9(encoding@0.1.13) - '@storybook/csf-tools': 8.0.9 + '@storybook/client-logger': 8.1.11 + '@storybook/core-common': 8.1.11(encoding@0.1.13)(prettier@3.3.2) + '@storybook/csf-tools': 8.1.11 chalk: 4.1.2 detect-package-manager: 2.0.1 fetch-retry: 5.0.4 @@ -15412,18 +16452,19 @@ snapshots: read-pkg-up: 7.0.1 transitivePeerDependencies: - encoding + - prettier - supports-color - '@storybook/test@8.0.9(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.12.7))(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3))': + '@storybook/test@8.1.11(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.14.9))(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1))': dependencies: - '@storybook/client-logger': 8.0.9 - '@storybook/core-events': 8.0.9 - '@storybook/instrumenter': 8.0.9 - '@storybook/preview-api': 8.0.9 - '@testing-library/dom': 9.3.4 - '@testing-library/jest-dom': 6.4.2(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.12.7))(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3)) - '@testing-library/user-event': 14.5.2(@testing-library/dom@9.3.4) - '@vitest/expect': 1.3.1 + '@storybook/client-logger': 8.1.11 + '@storybook/core-events': 8.1.11 + '@storybook/instrumenter': 8.1.11 + '@storybook/preview-api': 8.1.11 + '@testing-library/dom': 10.1.0 + '@testing-library/jest-dom': 6.4.5(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.14.9))(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1)) + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.1.0) + '@vitest/expect': 1.6.0 '@vitest/spy': 1.6.0 util: 0.12.5 transitivePeerDependencies: @@ -15433,37 +16474,39 @@ snapshots: - jest - vitest - '@storybook/theming@8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@storybook/theming@8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.3.1) - '@storybook/client-logger': 8.0.9 + '@storybook/client-logger': 8.1.11 '@storybook/global': 5.0.0 memoizerific: 1.11.3 optionalDependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/types@8.0.9': + '@storybook/types@8.1.11': dependencies: - '@storybook/channels': 8.0.9 + '@storybook/channels': 8.1.11 '@types/express': 4.17.17 file-system-cache: 2.3.0 - '@storybook/vue3-vite@8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.5.2))': + '@storybook/vue3-vite@8.1.11(bufferutil@4.0.7)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1))(vue@3.4.31(typescript@5.5.3))': dependencies: - '@storybook/builder-vite': 8.0.9(encoding@0.1.13)(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) - '@storybook/core-server': 8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3) - '@storybook/vue3': 8.0.9(encoding@0.1.13)(vue@3.4.26(typescript@5.5.2)) + '@storybook/builder-vite': 8.1.11(encoding@0.1.13)(prettier@3.3.2)(typescript@5.5.3)(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1)) + '@storybook/core-server': 8.1.11(bufferutil@4.0.7)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3) + '@storybook/types': 8.1.11 + '@storybook/vue3': 8.1.11(encoding@0.1.13)(prettier@3.3.2)(vue@3.4.31(typescript@5.5.3)) find-package-json: 1.2.0 - magic-string: 0.30.7 - typescript: 5.5.2 - vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) - vue-component-meta: 2.0.16(typescript@5.5.2) - vue-docgen-api: 4.75.1(vue@3.4.26(typescript@5.5.2)) + magic-string: 0.30.10 + typescript: 5.5.3 + vite: 5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1) + vue-component-meta: 2.0.16(typescript@5.5.3) + vue-docgen-api: 4.75.1(vue@3.4.31(typescript@5.5.3)) transitivePeerDependencies: - '@preact/preset-vite' - bufferutil - encoding + - prettier - react - react-dom - supports-color @@ -15471,26 +16514,27 @@ snapshots: - vite-plugin-glimmerx - vue - '@storybook/vue3@8.0.9(encoding@0.1.13)(vue@3.4.26(typescript@5.5.2))': + '@storybook/vue3@8.1.11(encoding@0.1.13)(prettier@3.3.2)(vue@3.4.31(typescript@5.5.3))': dependencies: - '@storybook/docs-tools': 8.0.9(encoding@0.1.13) + '@storybook/docs-tools': 8.1.11(encoding@0.1.13)(prettier@3.3.2) '@storybook/global': 5.0.0 - '@storybook/preview-api': 8.0.9 - '@storybook/types': 8.0.9 - '@vue/compiler-core': 3.4.21 + '@storybook/preview-api': 8.1.11 + '@storybook/types': 8.1.11 + '@vue/compiler-core': 3.4.29 lodash: 4.17.21 ts-dedent: 2.2.0 type-fest: 2.19.0 - vue: 3.4.26(typescript@5.5.2) - vue-component-type-helpers: 2.0.21 + vue: 3.4.31(typescript@5.5.3) + vue-component-type-helpers: 2.0.24 transitivePeerDependencies: - encoding + - prettier - supports-color - '@swc/cli@0.3.12(@swc/core@1.4.17)(chokidar@3.5.3)': + '@swc/cli@0.3.12(@swc/core@1.6.6)(chokidar@3.5.3)': dependencies: '@mole-inc/bin-wrapper': 8.0.1 - '@swc/core': 1.4.17 + '@swc/core': 1.6.6 '@swc/counter': 0.1.3 commander: 8.3.0 fast-glob: 3.3.2 @@ -15510,13 +16554,13 @@ snapshots: '@swc/core-darwin-arm64@1.3.56': optional: true - '@swc/core-darwin-arm64@1.4.17': + '@swc/core-darwin-arm64@1.6.6': optional: true '@swc/core-darwin-x64@1.3.56': optional: true - '@swc/core-darwin-x64@1.4.17': + '@swc/core-darwin-x64@1.6.6': optional: true '@swc/core-freebsd-x64@1.3.11': @@ -15527,77 +16571,79 @@ snapshots: '@swc/core-linux-arm-gnueabihf@1.3.56': optional: true - '@swc/core-linux-arm-gnueabihf@1.4.17': + '@swc/core-linux-arm-gnueabihf@1.6.6': optional: true '@swc/core-linux-arm64-gnu@1.3.56': optional: true - '@swc/core-linux-arm64-gnu@1.4.17': + '@swc/core-linux-arm64-gnu@1.6.6': optional: true '@swc/core-linux-arm64-musl@1.3.56': optional: true - '@swc/core-linux-arm64-musl@1.4.17': + '@swc/core-linux-arm64-musl@1.6.6': optional: true '@swc/core-linux-x64-gnu@1.3.56': optional: true - '@swc/core-linux-x64-gnu@1.4.17': + '@swc/core-linux-x64-gnu@1.6.6': optional: true '@swc/core-linux-x64-musl@1.3.56': optional: true - '@swc/core-linux-x64-musl@1.4.17': + '@swc/core-linux-x64-musl@1.6.6': optional: true '@swc/core-win32-arm64-msvc@1.3.56': optional: true - '@swc/core-win32-arm64-msvc@1.4.17': + '@swc/core-win32-arm64-msvc@1.6.6': optional: true '@swc/core-win32-ia32-msvc@1.3.56': optional: true - '@swc/core-win32-ia32-msvc@1.4.17': + '@swc/core-win32-ia32-msvc@1.6.6': optional: true '@swc/core-win32-x64-msvc@1.3.56': optional: true - '@swc/core-win32-x64-msvc@1.4.17': + '@swc/core-win32-x64-msvc@1.6.6': optional: true - '@swc/core@1.4.17': + '@swc/core@1.6.6': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.5 + '@swc/types': 0.1.9 optionalDependencies: - '@swc/core-darwin-arm64': 1.4.17 - '@swc/core-darwin-x64': 1.4.17 - '@swc/core-linux-arm-gnueabihf': 1.4.17 - '@swc/core-linux-arm64-gnu': 1.4.17 - '@swc/core-linux-arm64-musl': 1.4.17 - '@swc/core-linux-x64-gnu': 1.4.17 - '@swc/core-linux-x64-musl': 1.4.17 - '@swc/core-win32-arm64-msvc': 1.4.17 - '@swc/core-win32-ia32-msvc': 1.4.17 - '@swc/core-win32-x64-msvc': 1.4.17 + '@swc/core-darwin-arm64': 1.6.6 + '@swc/core-darwin-x64': 1.6.6 + '@swc/core-linux-arm-gnueabihf': 1.6.6 + '@swc/core-linux-arm64-gnu': 1.6.6 + '@swc/core-linux-arm64-musl': 1.6.6 + '@swc/core-linux-x64-gnu': 1.6.6 + '@swc/core-linux-x64-musl': 1.6.6 + '@swc/core-win32-arm64-msvc': 1.6.6 + '@swc/core-win32-ia32-msvc': 1.6.6 + '@swc/core-win32-x64-msvc': 1.6.6 '@swc/counter@0.1.3': {} - '@swc/jest@0.2.36(@swc/core@1.4.17)': + '@swc/jest@0.2.36(@swc/core@1.6.6)': dependencies: '@jest/create-cache-key-function': 29.7.0 - '@swc/core': 1.4.17 + '@swc/core': 1.6.6 '@swc/counter': 0.1.3 jsonc-parser: 3.2.0 - '@swc/types@0.1.5': {} + '@swc/types@0.1.9': + dependencies: + '@swc/counter': 0.1.3 '@swc/wasm@1.2.130': optional: true @@ -15701,12 +16747,12 @@ snapshots: - encoding - seedrandom - '@testing-library/dom@9.3.3': + '@testing-library/dom@10.1.0': dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.24.7 '@babel/runtime': 7.23.4 '@types/aria-query': 5.0.1 - aria-query: 5.1.3 + aria-query: 5.3.0 chalk: 4.1.2 dom-accessibility-api: 0.5.16 lz-string: 1.5.0 @@ -15723,7 +16769,7 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.4.2(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.12.7))(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3))': + '@testing-library/jest-dom@6.4.5(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.14.9))(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1))': dependencies: '@adobe/css-tools': 4.3.3 '@babel/runtime': 7.23.4 @@ -15736,21 +16782,21 @@ snapshots: optionalDependencies: '@jest/globals': 29.7.0 '@types/jest': 29.5.12 - jest: 29.7.0(@types/node@20.12.7) - vitest: 0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3) + jest: 29.7.0(@types/node@20.14.9) + vitest: 1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1) - '@testing-library/user-event@14.5.2(@testing-library/dom@9.3.4)': + '@testing-library/user-event@14.5.2(@testing-library/dom@10.1.0)': dependencies: - '@testing-library/dom': 9.3.4 + '@testing-library/dom': 10.1.0 - '@testing-library/vue@8.0.3(@vue/compiler-sfc@3.4.26)(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.5.2)))(vue@3.4.26(typescript@5.5.2))': + '@testing-library/vue@8.1.0(@vue/compiler-sfc@3.4.31)(@vue/server-renderer@3.4.29(vue@3.4.31(typescript@5.5.3)))(vue@3.4.31(typescript@5.5.3))': dependencies: '@babel/runtime': 7.23.4 - '@testing-library/dom': 9.3.3 - '@vue/test-utils': 2.4.1(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.5.2)))(vue@3.4.26(typescript@5.5.2)) - vue: 3.4.26(typescript@5.5.2) + '@testing-library/dom': 9.3.4 + '@vue/test-utils': 2.4.1(@vue/server-renderer@3.4.29(vue@3.4.31(typescript@5.5.3)))(vue@3.4.31(typescript@5.5.3)) + vue: 3.4.31(typescript@5.5.3) optionalDependencies: - '@vue/compiler-sfc': 3.4.26 + '@vue/compiler-sfc': 3.4.31 transitivePeerDependencies: - '@vue/server-renderer' @@ -15758,7 +16804,7 @@ snapshots: '@trysound/sax@0.2.0': {} - '@tsd/typescript@5.3.3': {} + '@tsd/typescript@5.4.5': {} '@twemoji/parser@15.0.0': {} @@ -15766,7 +16812,7 @@ snapshots: '@types/accepts@1.3.7': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/archiver@6.0.2': dependencies: @@ -15778,31 +16824,31 @@ snapshots: '@types/babel__core@7.20.0': dependencies: - '@babel/parser': 7.24.0 - '@babel/types': 7.24.0 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.20.0 '@types/babel__generator@7.6.4': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.24.7 '@types/babel__template@7.4.1': dependencies: - '@babel/parser': 7.24.0 - '@babel/types': 7.24.0 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 '@types/babel__traverse@7.20.0': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.24.7 '@types/bcryptjs@2.4.6': {} '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.35 - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/braces@3.0.1': {} @@ -15810,15 +16856,9 @@ snapshots: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/responselike': 1.0.0 - '@types/chai-subset@1.3.5': - dependencies: - '@types/chai': 4.3.11 - - '@types/chai@4.3.11': {} - '@types/color-convert@2.0.3': dependencies: '@types/color-name': 1.1.1 @@ -15827,11 +16867,11 @@ snapshots: '@types/connect@3.4.35': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/connect@3.4.36': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/content-disposition@0.5.8': {} @@ -15839,14 +16879,14 @@ snapshots: '@types/cookies@0.9.0': dependencies: - '@types/connect': 3.4.35 + '@types/connect': 3.4.36 '@types/express': 4.17.17 '@types/keygrip': 1.0.6 - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/cross-spawn@6.0.2': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/debug@4.1.12': dependencies: @@ -15854,6 +16894,8 @@ snapshots: '@types/detect-port@1.3.2': {} + '@types/diff@5.2.1': {} + '@types/disposable-email-domains@1.0.2': {} '@types/doctrine@0.0.3': {} @@ -15871,7 +16913,7 @@ snapshots: '@types/eslint@7.29.0': dependencies: '@types/estree': 1.0.5 - '@types/json-schema': 7.0.12 + '@types/json-schema': 7.0.15 '@types/estree@0.0.51': {} @@ -15879,7 +16921,7 @@ snapshots: '@types/express-serve-static-core@4.17.33': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 @@ -15894,16 +16936,16 @@ snapshots: '@types/fluent-ffmpeg@2.1.24': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/glob@7.2.0': dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/graceful-fs@4.1.6': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/hast@3.0.4': dependencies: @@ -15917,9 +16959,9 @@ snapshots: '@types/http-errors@2.0.4': {} - '@types/http-link-header@1.0.5': + '@types/http-link-header@1.0.7': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/istanbul-lib-coverage@2.0.4': {} @@ -15938,9 +16980,9 @@ snapshots: '@types/js-yaml@4.0.9': {} - '@types/jsdom@21.1.6': + '@types/jsdom@21.1.7': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/tough-cookie': 4.0.2 parse5: 7.1.2 @@ -15950,7 +16992,7 @@ snapshots: '@types/json5@0.0.29': {} - '@types/jsonld@1.5.13': {} + '@types/jsonld@1.5.14': {} '@types/jsrsasign@10.5.14': {} @@ -15958,7 +17000,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/koa-compose@3.2.8': dependencies: @@ -15973,7 +17015,7 @@ snapshots: '@types/http-errors': 2.0.4 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.8 - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/koa__router@12.0.3': dependencies: @@ -15991,7 +17033,7 @@ snapshots: '@types/mdx@2.0.3': {} - '@types/micromatch@4.0.7': + '@types/micromatch@4.0.9': dependencies: '@types/braces': 3.0.1 @@ -16007,15 +17049,15 @@ snapshots: '@types/mute-stream@0.0.4': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/mysql@2.15.22': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/node-fetch@2.6.4': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 form-data: 3.0.1 '@types/node@18.17.15': {} @@ -16024,7 +17066,7 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@20.12.7': + '@types/node@20.14.9': dependencies: undici-types: 5.26.5 @@ -16034,7 +17076,7 @@ snapshots: '@types/nodemailer@6.4.15': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/normalize-package-data@2.4.1': {} @@ -16045,11 +17087,11 @@ snapshots: '@types/oauth2orize@1.11.5': dependencies: '@types/express': 4.17.17 - '@types/node': 20.12.7 + '@types/node': 20.14.9 - '@types/oauth@0.9.4': + '@types/oauth@0.9.5': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/offscreencanvas@2019.3.0': {} @@ -16057,17 +17099,17 @@ snapshots: '@types/pg-pool@2.0.4': dependencies: - '@types/pg': 8.11.5 + '@types/pg': 8.11.6 - '@types/pg@8.11.5': + '@types/pg@8.11.6': dependencies: - '@types/node': 20.12.7 - pg-protocol: 1.6.0 + '@types/node': 20.14.9 + pg-protocol: 1.6.1 pg-types: 4.0.1 '@types/pg@8.6.1': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 pg-protocol: 1.6.1 pg-types: 2.2.0 @@ -16081,7 +17123,7 @@ snapshots: '@types/qrcode@1.5.5': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/qs@6.9.7': {} @@ -16099,7 +17141,7 @@ snapshots: '@types/readdir-glob@1.1.1': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/rename@1.0.7': {} @@ -16107,7 +17149,7 @@ snapshots: '@types/responselike@1.0.0': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/sanitize-html@2.11.0': dependencies: @@ -16124,7 +17166,7 @@ snapshots: '@types/serve-static@1.15.1': dependencies: '@types/mime': 3.0.1 - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/serviceworker@0.0.67': {} @@ -16156,15 +17198,17 @@ snapshots: '@types/unist@3.0.2': {} + '@types/uuid@10.0.0': {} + '@types/uuid@9.0.8': {} '@types/vary@1.1.3': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/web-push@3.6.3': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/webgl-ext@0.0.30': {} @@ -16172,7 +17216,7 @@ snapshots: '@types/ws@8.5.10': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 '@types/yargs-parser@21.0.0': {} @@ -16182,19 +17226,19 @@ snapshots: '@types/yauzl@2.10.0': dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 optional: true - '@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint@8.53.0)(typescript@5.3.3)': + '@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0(eslint@9.6.0)(typescript@5.3.3))(eslint@9.6.0)(typescript@5.3.3)': dependencies: '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.11.0(eslint@9.6.0)(typescript@5.3.3) '@typescript-eslint/scope-manager': 6.11.0 - '@typescript-eslint/type-utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3) + '@typescript-eslint/type-utils': 6.11.0(eslint@9.6.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.11.0(eslint@9.6.0)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.11.0 - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.53.0 + debug: 4.3.4(supports-color@5.5.0) + eslint: 9.6.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 @@ -16205,16 +17249,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3)': + '@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0(eslint@9.6.0)(typescript@5.3.3))(eslint@9.6.0)(typescript@5.3.3)': dependencies: '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/parser': 7.1.0(eslint@9.6.0)(typescript@5.3.3) '@typescript-eslint/scope-manager': 7.1.0 - '@typescript-eslint/type-utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3) - '@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/type-utils': 7.1.0(eslint@9.6.0)(typescript@5.3.3) + '@typescript-eslint/utils': 7.1.0(eslint@9.6.0)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 7.1.0 - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + debug: 4.3.4(supports-color@5.5.0) + eslint: 9.6.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 @@ -16225,62 +17269,60 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)': + '@typescript-eslint/eslint-plugin@7.15.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0)(typescript@5.5.3)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.5.2) - '@typescript-eslint/scope-manager': 7.7.1 - '@typescript-eslint/type-utils': 7.7.1(eslint@8.57.0)(typescript@5.5.2) - '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.5.2) - '@typescript-eslint/visitor-keys': 7.7.1 - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + '@typescript-eslint/parser': 7.15.0(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/scope-manager': 7.15.0 + '@typescript-eslint/type-utils': 7.15.0(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/utils': 7.15.0(eslint@9.6.0)(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 7.15.0 + eslint: 9.6.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 - semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.5.2) + ts-api-utils: 1.3.0(typescript@5.5.3) optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3)': + '@typescript-eslint/parser@6.11.0(eslint@9.6.0)(typescript@5.3.3)': dependencies: '@typescript-eslint/scope-manager': 6.11.0 '@typescript-eslint/types': 6.11.0 '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.11.0 - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.53.0 + debug: 4.3.4(supports-color@5.5.0) + eslint: 9.6.0 optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3)': + '@typescript-eslint/parser@7.1.0(eslint@9.6.0)(typescript@5.3.3)': dependencies: '@typescript-eslint/scope-manager': 7.1.0 '@typescript-eslint/types': 7.1.0 '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 7.1.0 - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + debug: 4.3.4(supports-color@5.5.0) + eslint: 9.6.0 optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2)': + '@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3)': dependencies: - '@typescript-eslint/scope-manager': 7.7.1 - '@typescript-eslint/types': 7.7.1 - '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.2) - '@typescript-eslint/visitor-keys': 7.7.1 - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + '@typescript-eslint/scope-manager': 7.15.0 + '@typescript-eslint/types': 7.15.0 + '@typescript-eslint/typescript-estree': 7.15.0(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 7.15.0 + debug: 4.3.5(supports-color@8.1.1) + eslint: 9.6.0 optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -16294,44 +17336,44 @@ snapshots: '@typescript-eslint/types': 7.1.0 '@typescript-eslint/visitor-keys': 7.1.0 - '@typescript-eslint/scope-manager@7.7.1': + '@typescript-eslint/scope-manager@7.15.0': dependencies: - '@typescript-eslint/types': 7.7.1 - '@typescript-eslint/visitor-keys': 7.7.1 + '@typescript-eslint/types': 7.15.0 + '@typescript-eslint/visitor-keys': 7.15.0 - '@typescript-eslint/type-utils@6.11.0(eslint@8.53.0)(typescript@5.3.3)': + '@typescript-eslint/type-utils@6.11.0(eslint@9.6.0)(typescript@5.3.3)': dependencies: '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3) - '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3) - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.53.0 + '@typescript-eslint/utils': 6.11.0(eslint@9.6.0)(typescript@5.3.3) + debug: 4.3.5(supports-color@8.1.1) + eslint: 9.6.0 ts-api-utils: 1.0.1(typescript@5.3.3) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@7.1.0(eslint@8.57.0)(typescript@5.3.3)': + '@typescript-eslint/type-utils@7.1.0(eslint@9.6.0)(typescript@5.3.3)': dependencies: '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3) - '@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3) - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + '@typescript-eslint/utils': 7.1.0(eslint@9.6.0)(typescript@5.3.3) + debug: 4.3.4(supports-color@5.5.0) + eslint: 9.6.0 ts-api-utils: 1.0.1(typescript@5.3.3) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@7.7.1(eslint@8.57.0)(typescript@5.5.2)': + '@typescript-eslint/type-utils@7.15.0(eslint@9.6.0)(typescript@5.5.3)': dependencies: - '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.2) - '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.5.2) - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.5.2) + '@typescript-eslint/typescript-estree': 7.15.0(typescript@5.5.3) + '@typescript-eslint/utils': 7.15.0(eslint@9.6.0)(typescript@5.5.3) + debug: 4.3.5(supports-color@8.1.1) + eslint: 9.6.0 + ts-api-utils: 1.3.0(typescript@5.5.3) optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 transitivePeerDependencies: - supports-color @@ -16339,13 +17381,13 @@ snapshots: '@typescript-eslint/types@7.1.0': {} - '@typescript-eslint/types@7.7.1': {} + '@typescript-eslint/types@7.15.0': {} '@typescript-eslint/typescript-estree@6.11.0(typescript@5.3.3)': dependencies: '@typescript-eslint/types': 6.11.0 '@typescript-eslint/visitor-keys': 6.11.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 @@ -16359,7 +17401,7 @@ snapshots: dependencies: '@typescript-eslint/types': 7.1.0 '@typescript-eslint/visitor-keys': 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -16370,59 +17412,56 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@7.7.1(typescript@5.5.2)': + '@typescript-eslint/typescript-estree@7.15.0(typescript@5.5.3)': dependencies: - '@typescript-eslint/types': 7.7.1 - '@typescript-eslint/visitor-keys': 7.7.1 - debug: 4.3.4(supports-color@8.1.1) + '@typescript-eslint/types': 7.15.0 + '@typescript-eslint/visitor-keys': 7.15.0 + debug: 4.3.5(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.4 semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.5.2) + ts-api-utils: 1.3.0(typescript@5.5.3) optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@6.11.0(eslint@8.53.0)(typescript@5.3.3)': + '@typescript-eslint/utils@6.11.0(eslint@9.6.0)(typescript@5.3.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.6.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 6.11.0 '@typescript-eslint/types': 6.11.0 '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3) - eslint: 8.53.0 + eslint: 9.6.0 semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@7.1.0(eslint@8.57.0)(typescript@5.3.3)': + '@typescript-eslint/utils@7.1.0(eslint@9.6.0)(typescript@5.3.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.6.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 7.1.0 '@typescript-eslint/types': 7.1.0 '@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3) - eslint: 8.57.0 + eslint: 9.6.0 semver: 7.6.0 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@7.7.1(eslint@8.57.0)(typescript@5.5.2)': + '@typescript-eslint/utils@7.15.0(eslint@9.6.0)(typescript@5.5.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 7.7.1 - '@typescript-eslint/types': 7.7.1 - '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.2) - eslint: 8.57.0 - semver: 7.6.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.6.0) + '@typescript-eslint/scope-manager': 7.15.0 + '@typescript-eslint/types': 7.15.0 + '@typescript-eslint/typescript-estree': 7.15.0(typescript@5.5.3) + eslint: 9.6.0 transitivePeerDependencies: - supports-color - typescript @@ -16437,83 +17476,58 @@ snapshots: '@typescript-eslint/types': 7.1.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@7.7.1': + '@typescript-eslint/visitor-keys@7.15.0': dependencies: - '@typescript-eslint/types': 7.7.1 + '@typescript-eslint/types': 7.15.0 eslint-visitor-keys: 3.4.3 '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-vue@5.0.4(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.5.2))': + '@vitejs/plugin-vue@5.0.5(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1))(vue@3.4.31(typescript@5.5.3))': dependencies: - vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) - vue: 3.4.26(typescript@5.5.2) + vite: 5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1) + vue: 3.4.31(typescript@5.5.3) - '@vitest/coverage-v8@0.34.6(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3))': + '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1))': dependencies: '@ampproject/remapping': 2.2.1 '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.4(supports-color@5.5.0) istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 + istanbul-lib-source-maps: 5.0.4 istanbul-reports: 3.1.6 - magic-string: 0.30.7 + magic-string: 0.30.10 + magicast: 0.3.4 picocolors: 1.0.0 std-env: 3.7.0 + strip-literal: 2.1.0 test-exclude: 6.0.0 - v8-to-istanbul: 9.2.0 - vitest: 0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3) + vitest: 1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1) transitivePeerDependencies: - supports-color - '@vitest/expect@0.34.6': - dependencies: - '@vitest/spy': 0.34.6 - '@vitest/utils': 0.34.6 - chai: 4.3.10 - - '@vitest/expect@1.3.1': - dependencies: - '@vitest/spy': 1.3.1 - '@vitest/utils': 1.3.1 - chai: 4.3.10 - - '@vitest/runner@0.34.6': - dependencies: - '@vitest/utils': 0.34.6 - p-limit: 4.0.0 - pathe: 1.1.2 - - '@vitest/snapshot@0.34.6': + '@vitest/expect@1.6.0': dependencies: - magic-string: 0.30.7 - pathe: 1.1.2 - pretty-format: 29.7.0 - - '@vitest/spy@0.34.6': - dependencies: - tinyspy: 2.2.0 - - '@vitest/spy@1.3.1': - dependencies: - tinyspy: 2.2.0 + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + chai: 4.3.10 - '@vitest/spy@1.6.0': + '@vitest/runner@1.6.0': dependencies: - tinyspy: 2.2.0 + '@vitest/utils': 1.6.0 + p-limit: 5.0.0 + pathe: 1.1.2 - '@vitest/utils@0.34.6': + '@vitest/snapshot@1.6.0': dependencies: - diff-sequences: 29.6.3 - loupe: 2.3.7 + magic-string: 0.30.10 + pathe: 1.1.2 pretty-format: 29.7.0 - '@vitest/utils@1.3.1': + '@vitest/spy@1.6.0': dependencies: - diff-sequences: 29.6.3 - estree-walker: 3.0.3 - loupe: 2.3.7 - pretty-format: 29.7.0 + tinyspy: 2.2.0 '@vitest/utils@1.6.0': dependencies: @@ -16526,125 +17540,149 @@ snapshots: dependencies: '@volar/source-map': 2.2.0 + '@volar/language-core@2.4.0-alpha.11': + dependencies: + '@volar/source-map': 2.4.0-alpha.11 + '@volar/source-map@2.2.0': dependencies: muggle-string: 0.4.1 + '@volar/source-map@2.4.0-alpha.11': {} + '@volar/typescript@2.2.0': dependencies: '@volar/language-core': 2.2.0 path-browserify: 1.0.1 - '@vue/compiler-core@3.4.21': + '@volar/typescript@2.4.0-alpha.11': dependencies: - '@babel/parser': 7.24.0 - '@vue/shared': 3.4.21 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.0.2 + '@volar/language-core': 2.4.0-alpha.11 + path-browserify: 1.0.1 + vscode-uri: 3.0.8 - '@vue/compiler-core@3.4.25': + '@vue/compiler-core@3.4.29': dependencies: - '@babel/parser': 7.24.5 - '@vue/shared': 3.4.25 + '@babel/parser': 7.24.7 + '@vue/shared': 3.4.29 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.0 - '@vue/compiler-core@3.4.26': + '@vue/compiler-core@3.4.31': dependencies: - '@babel/parser': 7.24.5 - '@vue/shared': 3.4.26 + '@babel/parser': 7.24.7 + '@vue/shared': 3.4.31 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.0 - '@vue/compiler-dom@3.4.21': + '@vue/compiler-dom@3.4.29': dependencies: - '@vue/compiler-core': 3.4.21 - '@vue/shared': 3.4.21 + '@vue/compiler-core': 3.4.29 + '@vue/shared': 3.4.29 - '@vue/compiler-dom@3.4.25': + '@vue/compiler-dom@3.4.31': dependencies: - '@vue/compiler-core': 3.4.25 - '@vue/shared': 3.4.25 + '@vue/compiler-core': 3.4.31 + '@vue/shared': 3.4.31 - '@vue/compiler-dom@3.4.26': + '@vue/compiler-sfc@3.4.31': dependencies: - '@vue/compiler-core': 3.4.26 - '@vue/shared': 3.4.26 - - '@vue/compiler-sfc@3.4.26': - dependencies: - '@babel/parser': 7.24.5 - '@vue/compiler-core': 3.4.26 - '@vue/compiler-dom': 3.4.26 - '@vue/compiler-ssr': 3.4.26 - '@vue/shared': 3.4.26 + '@babel/parser': 7.24.7 + '@vue/compiler-core': 3.4.31 + '@vue/compiler-dom': 3.4.31 + '@vue/compiler-ssr': 3.4.31 + '@vue/shared': 3.4.31 estree-walker: 2.0.2 magic-string: 0.30.10 postcss: 8.4.38 source-map-js: 1.2.0 - '@vue/compiler-ssr@3.4.26': + '@vue/compiler-ssr@3.4.29': + dependencies: + '@vue/compiler-dom': 3.4.29 + '@vue/shared': 3.4.29 + optional: true + + '@vue/compiler-ssr@3.4.31': dependencies: - '@vue/compiler-dom': 3.4.26 - '@vue/shared': 3.4.26 + '@vue/compiler-dom': 3.4.31 + '@vue/shared': 3.4.31 '@vue/devtools-api@6.6.1': {} - '@vue/language-core@2.0.16(typescript@5.5.2)': + '@vue/language-core@2.0.16(typescript@5.5.3)': dependencies: '@volar/language-core': 2.2.0 - '@vue/compiler-dom': 3.4.25 - '@vue/shared': 3.4.25 + '@vue/compiler-dom': 3.4.29 + '@vue/shared': 3.4.29 + computeds: 0.0.1 + minimatch: 9.0.4 + path-browserify: 1.0.1 + vue-template-compiler: 2.7.14 + optionalDependencies: + typescript: 5.5.3 + + '@vue/language-core@2.0.24(typescript@5.5.3)': + dependencies: + '@volar/language-core': 2.4.0-alpha.11 + '@vue/compiler-dom': 3.4.29 + '@vue/shared': 3.4.29 computeds: 0.0.1 minimatch: 9.0.4 + muggle-string: 0.4.1 path-browserify: 1.0.1 vue-template-compiler: 2.7.14 optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 - '@vue/reactivity@3.4.26': + '@vue/reactivity@3.4.31': dependencies: - '@vue/shared': 3.4.26 + '@vue/shared': 3.4.31 - '@vue/runtime-core@3.4.26': + '@vue/runtime-core@3.4.31': dependencies: - '@vue/reactivity': 3.4.26 - '@vue/shared': 3.4.26 + '@vue/reactivity': 3.4.31 + '@vue/shared': 3.4.31 - '@vue/runtime-dom@3.4.26': + '@vue/runtime-dom@3.4.31': dependencies: - '@vue/runtime-core': 3.4.26 - '@vue/shared': 3.4.26 + '@vue/reactivity': 3.4.31 + '@vue/runtime-core': 3.4.31 + '@vue/shared': 3.4.31 csstype: 3.1.3 - '@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.5.2))': + '@vue/server-renderer@3.4.29(vue@3.4.31(typescript@5.5.3))': dependencies: - '@vue/compiler-ssr': 3.4.26 - '@vue/shared': 3.4.26 - vue: 3.4.26(typescript@5.5.2) + '@vue/compiler-ssr': 3.4.29 + '@vue/shared': 3.4.29 + vue: 3.4.31(typescript@5.5.3) + optional: true - '@vue/shared@3.4.21': {} + '@vue/server-renderer@3.4.31(vue@3.4.31(typescript@5.5.3))': + dependencies: + '@vue/compiler-ssr': 3.4.31 + '@vue/shared': 3.4.31 + vue: 3.4.31(typescript@5.5.3) - '@vue/shared@3.4.25': {} + '@vue/shared@3.4.29': {} - '@vue/shared@3.4.26': {} + '@vue/shared@3.4.31': {} - '@vue/test-utils@2.4.1(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.5.2)))(vue@3.4.26(typescript@5.5.2))': + '@vue/test-utils@2.4.1(@vue/server-renderer@3.4.29(vue@3.4.31(typescript@5.5.3)))(vue@3.4.31(typescript@5.5.3))': dependencies: js-beautify: 1.14.9 - vue: 3.4.26(typescript@5.5.2) + vue: 3.4.31(typescript@5.5.3) vue-component-type-helpers: 1.8.4 optionalDependencies: - '@vue/server-renderer': 3.4.26(vue@3.4.26(typescript@5.5.2)) + '@vue/server-renderer': 3.4.29(vue@3.4.31(typescript@5.5.3)) '@webgpu/types@0.1.30': {} - '@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.20.2)': + '@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.19.11)': dependencies: - esbuild: 0.20.2 + esbuild: 0.19.11 tslib: 2.6.2 '@yarnpkg/fslib@2.10.3': @@ -16672,22 +17710,22 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-import-assertions@1.9.0(acorn@8.11.3): + acorn-import-assertions@1.9.0(acorn@8.12.0): dependencies: - acorn: 8.11.3 + acorn: 8.12.0 optional: true - acorn-import-attributes@1.9.5(acorn@8.11.3): + acorn-import-attributes@1.9.5(acorn@8.12.0): dependencies: - acorn: 8.11.3 + acorn: 8.12.0 acorn-jsx@5.3.2(acorn@7.4.1): dependencies: acorn: 7.4.1 - acorn-jsx@5.3.2(acorn@8.11.3): + acorn-jsx@5.3.2(acorn@8.12.0): dependencies: - acorn: 8.11.3 + acorn: 8.12.0 acorn-walk@7.2.0: {} @@ -16695,7 +17733,7 @@ snapshots: acorn@7.4.1: {} - acorn@8.11.3: {} + acorn@8.12.0: {} address@1.2.2: {} @@ -16709,13 +17747,13 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) transitivePeerDependencies: - supports-color agent-base@7.1.0: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -16738,7 +17776,15 @@ snapshots: optionalDependencies: ajv: 8.13.0 - ajv-formats@2.1.1(ajv@8.13.0): + ajv-draft-04@1.0.0(ajv@8.16.0): + optionalDependencies: + ajv: 8.16.0 + + ajv-formats@2.1.1(ajv@8.16.0): + optionalDependencies: + ajv: 8.16.0 + + ajv-formats@3.0.1(ajv@8.13.0): optionalDependencies: ajv: 8.13.0 @@ -16749,6 +17795,13 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@8.12.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + ajv@8.13.0: dependencies: fast-deep-equal: 3.1.3 @@ -16756,6 +17809,13 @@ snapshots: require-from-string: 2.0.2 uri-js: 4.4.1 + ajv@8.16.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + ansi-colors@4.1.3: {} ansi-escapes@4.3.2: @@ -16798,7 +17858,7 @@ snapshots: archiver-utils@5.0.2: dependencies: - glob: 10.3.12 + glob: 10.4.2 graceful-fs: 4.2.11 is-stream: 2.0.1 lazystream: 1.0.1 @@ -16832,10 +17892,18 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.4: + dependencies: + tslib: 2.6.2 + aria-query@5.1.3: dependencies: deep-equal: 2.2.0 + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + array-buffer-byte-length@1.0.0: dependencies: call-bind: 1.0.2 @@ -16931,6 +17999,8 @@ snapshots: dependencies: tslib: 2.6.2 + async@0.2.10: {} + async@3.2.4: {} asynckit@0.4.0: {} @@ -16945,12 +18015,12 @@ snapshots: dependencies: '@fastify/error': 3.4.0 archy: 1.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) fastq: 1.17.1 transitivePeerDependencies: - supports-color - aws-sdk-client-mock@3.0.1: + aws-sdk-client-mock@4.0.1: dependencies: '@types/sinon': 10.0.13 sinon: 16.1.3 @@ -16962,13 +18032,13 @@ snapshots: axios@0.24.0: dependencies: - follow-redirects: 1.15.2(debug@4.3.4) + follow-redirects: 1.15.2(debug@4.3.5) transitivePeerDependencies: - debug - axios@1.6.2(debug@4.3.4): + axios@1.6.2(debug@4.3.5): dependencies: - follow-redirects: 1.15.2(debug@4.3.4) + follow-redirects: 1.15.2(debug@4.3.5) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -16976,9 +18046,9 @@ snapshots: b4a@1.6.4: {} - babel-core@7.0.0-bridge.0(@babel/core@7.24.0): + babel-core@7.0.0-bridge.0(@babel/core@7.24.7): dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.7 babel-jest@29.7.0(@babel/core@7.23.5): dependencies: @@ -17006,31 +18076,31 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: '@babel/template': 7.24.0 - '@babel/types': 7.24.0 + '@babel/types': 7.24.7 '@types/babel__core': 7.20.0 '@types/babel__traverse': 7.20.0 - babel-plugin-polyfill-corejs2@0.4.6(@babel/core@7.24.0): + babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.24.7): dependencies: - '@babel/compat-data': 7.23.5 - '@babel/core': 7.24.0 - '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.24.0) + '@babel/compat-data': 7.24.7 + '@babel/core': 7.24.7 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.8.6(@babel/core@7.24.0): + babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.7): dependencies: - '@babel/core': 7.24.0 - '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.24.0) - core-js-compat: 3.33.3 + '@babel/core': 7.24.7 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) + core-js-compat: 3.37.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.5.3(@babel/core@7.24.0): + babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.24.7): dependencies: - '@babel/core': 7.24.0 - '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.24.0) + '@babel/core': 7.24.7 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) transitivePeerDependencies: - supports-color @@ -17058,7 +18128,7 @@ snapshots: babel-walk@3.0.0-canary-5: dependencies: - '@babel/types': 7.23.5 + '@babel/types': 7.24.0 bail@2.0.2: {} @@ -17110,23 +18180,6 @@ snapshots: bn.js@4.12.0: {} - body-parser@1.20.1: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.1 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - body-parser@1.20.2: dependencies: bytes: 3.1.2 @@ -17165,6 +18218,10 @@ snapshots: dependencies: fill-range: 7.0.1 + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + broadcast-channel@7.0.0: dependencies: '@babel/runtime': 7.23.4 @@ -17224,7 +18281,7 @@ snapshots: node-gyp-build: 4.6.0 optional: true - bullmq@5.7.8: + bullmq@5.8.3: dependencies: cron-parser: 4.8.1 ioredis: 5.4.1 @@ -17252,7 +18309,7 @@ snapshots: dependencies: '@npmcli/fs': 3.1.0 fs-minipass: 3.0.2 - glob: 10.3.12 + glob: 10.4.2 lru-cache: 10.2.2 minipass: 7.0.4 minipass-collect: 1.0.2 @@ -17277,6 +18334,16 @@ snapshots: normalize-url: 8.0.0 responselike: 3.0.0 + cacheable-request@12.0.1: + dependencies: + '@types/http-cache-semantics': 4.0.4 + get-stream: 9.0.1 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.0.1 + responselike: 3.0.0 + cacheable-request@7.0.2: dependencies: clone-response: 1.0.3 @@ -17371,26 +18438,26 @@ snapshots: dependencies: is-regex: 1.1.4 - chart.js@4.4.2: + chart.js@4.4.3: dependencies: '@kurkle/color': 0.3.2 - chartjs-adapter-date-fns@3.0.0(chart.js@4.4.2)(date-fns@2.30.0): + chartjs-adapter-date-fns@3.0.0(chart.js@4.4.3)(date-fns@2.30.0): dependencies: - chart.js: 4.4.2 + chart.js: 4.4.3 date-fns: 2.30.0 - chartjs-chart-matrix@2.0.1(chart.js@4.4.2): + chartjs-chart-matrix@2.0.1(chart.js@4.4.3): dependencies: - chart.js: 4.4.2 + chart.js: 4.4.3 - chartjs-plugin-gradient@0.6.1(chart.js@4.4.2): + chartjs-plugin-gradient@0.6.1(chart.js@4.4.3): dependencies: - chart.js: 4.4.2 + chart.js: 4.4.3 - chartjs-plugin-zoom@2.0.1(chart.js@4.4.2): + chartjs-plugin-zoom@2.0.1(chart.js@4.4.3): dependencies: - chart.js: 4.4.2 + chart.js: 4.4.3 hammerjs: 2.0.8 check-error@1.0.3: @@ -17434,7 +18501,7 @@ snapshots: chownr@2.0.0: {} - chromatic@11.3.0: {} + chromatic@11.5.4: {} ci-info@3.7.1: {} @@ -17459,8 +18526,6 @@ snapshots: parse5-htmlparser2-tree-adapter: 6.0.1 yargs: 16.2.0 - cli-spinners@2.7.0: {} - cli-spinners@2.9.2: {} cli-table3@0.6.3: @@ -17612,8 +18677,8 @@ snapshots: constantinople@4.0.1: dependencies: - '@babel/parser': 7.23.9 - '@babel/types': 7.23.5 + '@babel/parser': 7.24.5 + '@babel/types': 7.24.0 content-disposition@0.5.4: dependencies: @@ -17631,7 +18696,7 @@ snapshots: cookie@0.6.0: {} - core-js-compat@3.33.3: + core-js-compat@3.37.1: dependencies: browserslist: 4.23.0 @@ -17653,13 +18718,13 @@ snapshots: crc-32: 1.2.2 readable-stream: 4.3.0 - create-jest@29.7.0(@types/node@20.12.7): + create-jest@29.7.0(@types/node@20.14.9): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.12.7) + jest-config: 29.7.0(@types/node@20.14.9) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -17705,7 +18770,9 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - crypto-random-string@2.0.0: {} + crypto-random-string@4.0.0: + dependencies: + type-fest: 1.4.0 css-declaration-sorter@7.2.0(postcss@8.4.38): dependencies: @@ -17793,52 +18860,7 @@ snapshots: dependencies: uniq: 1.0.1 - cypress@13.7.3: - dependencies: - '@cypress/request': 3.0.0 - '@cypress/xvfb': 1.2.4(supports-color@8.1.1) - '@types/sinonjs__fake-timers': 8.1.1 - '@types/sizzle': 2.3.3 - arch: 2.2.0 - blob-util: 2.0.2 - bluebird: 3.7.2 - buffer: 5.7.1 - cachedir: 2.3.0 - chalk: 4.1.2 - check-more-types: 2.24.0 - cli-cursor: 3.1.0 - cli-table3: 0.6.3 - commander: 6.2.1 - common-tags: 1.8.2 - dayjs: 1.11.10 - debug: 4.3.4(supports-color@8.1.1) - enquirer: 2.3.6 - eventemitter2: 6.4.7 - execa: 4.1.0 - executable: 4.1.1 - extract-zip: 2.0.1(supports-color@8.1.1) - figures: 3.2.0 - fs-extra: 9.1.0 - getos: 3.2.1 - is-ci: 3.0.1 - is-installed-globally: 0.4.0 - lazy-ass: 1.6.0 - listr2: 3.14.0(enquirer@2.3.6) - lodash: 4.17.21 - log-symbols: 4.1.0 - minimist: 1.2.8 - ospath: 1.2.2 - pretty-bytes: 5.6.0 - process: 0.11.10 - proxy-from-env: 1.0.0 - request-progress: 3.0.0 - semver: 7.6.0 - supports-color: 8.1.1 - tmp: 0.2.3 - untildify: 4.0.0 - yauzl: 2.10.0 - - cypress@13.8.1: + cypress@13.13.0: dependencies: '@cypress/request': 3.0.0 '@cypress/xvfb': 1.2.4(supports-color@8.1.1) @@ -17856,7 +18878,7 @@ snapshots: commander: 6.2.1 common-tags: 1.8.2 dayjs: 1.11.10 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) enquirer: 2.3.6 eventemitter2: 6.4.7 execa: 4.1.0 @@ -17920,7 +18942,7 @@ snapshots: optionalDependencies: supports-color: 5.5.0 - debug@4.3.4(supports-color@8.1.1): + debug@4.3.5(supports-color@8.1.1): dependencies: ms: 2.1.2 optionalDependencies: @@ -18013,17 +19035,6 @@ snapshots: defu@6.1.4: {} - del@6.1.1: - dependencies: - globby: 11.1.0 - graceful-fs: 4.2.11 - is-glob: 4.0.3 - is-path-cwd: 2.2.0 - is-path-inside: 3.0.3 - p-map: 4.0.0 - rimraf: 3.0.2 - slash: 3.0.0 - delayed-stream@1.0.0: {} delegates@1.0.0: @@ -18046,6 +19057,8 @@ snapshots: detect-newline@3.1.0: {} + detect-node-es@1.1.0: {} + detect-package-manager@2.0.1: dependencies: execa: 5.1.1 @@ -18053,7 +19066,7 @@ snapshots: detect-port@1.5.1: dependencies: address: 1.2.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -18067,6 +19080,8 @@ snapshots: diff@5.1.0: {} + diff@5.2.0: {} + dijkstrajs@1.0.2: {} dir-glob@3.0.1: @@ -18140,7 +19155,7 @@ snapshots: ee-first@1.1.1: {} - ejs@3.1.9: + ejs@3.1.10: dependencies: jake: 10.8.5 @@ -18239,7 +19254,7 @@ snapshots: isarray: 2.0.5 stop-iteration-iterator: 1.0.0 - es-module-lexer@0.9.3: {} + es-module-lexer@1.5.4: {} es-set-tostringtag@2.0.1: dependencies: @@ -18267,10 +19282,10 @@ snapshots: esbuild-plugin-alias@0.2.1: {} - esbuild-register@3.5.0(esbuild@0.20.2): + esbuild-register@3.5.0(esbuild@0.19.11): dependencies: - debug: 4.3.4(supports-color@8.1.1) - esbuild: 0.20.2 + debug: 4.3.5(supports-color@8.1.1) + esbuild: 0.19.11 transitivePeerDependencies: - supports-color @@ -18325,31 +19340,58 @@ snapshots: '@esbuild/win32-ia32': 0.19.11 '@esbuild/win32-x64': 0.19.11 - esbuild@0.20.2: + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.22.0: optionalDependencies: - '@esbuild/aix-ppc64': 0.20.2 - '@esbuild/android-arm': 0.20.2 - '@esbuild/android-arm64': 0.20.2 - '@esbuild/android-x64': 0.20.2 - '@esbuild/darwin-arm64': 0.20.2 - '@esbuild/darwin-x64': 0.20.2 - '@esbuild/freebsd-arm64': 0.20.2 - '@esbuild/freebsd-x64': 0.20.2 - '@esbuild/linux-arm': 0.20.2 - '@esbuild/linux-arm64': 0.20.2 - '@esbuild/linux-ia32': 0.20.2 - '@esbuild/linux-loong64': 0.20.2 - '@esbuild/linux-mips64el': 0.20.2 - '@esbuild/linux-ppc64': 0.20.2 - '@esbuild/linux-riscv64': 0.20.2 - '@esbuild/linux-s390x': 0.20.2 - '@esbuild/linux-x64': 0.20.2 - '@esbuild/netbsd-x64': 0.20.2 - '@esbuild/openbsd-x64': 0.20.2 - '@esbuild/sunos-x64': 0.20.2 - '@esbuild/win32-arm64': 0.20.2 - '@esbuild/win32-ia32': 0.20.2 - '@esbuild/win32-x64': 0.20.2 + '@esbuild/aix-ppc64': 0.22.0 + '@esbuild/android-arm': 0.22.0 + '@esbuild/android-arm64': 0.22.0 + '@esbuild/android-x64': 0.22.0 + '@esbuild/darwin-arm64': 0.22.0 + '@esbuild/darwin-x64': 0.22.0 + '@esbuild/freebsd-arm64': 0.22.0 + '@esbuild/freebsd-x64': 0.22.0 + '@esbuild/linux-arm': 0.22.0 + '@esbuild/linux-arm64': 0.22.0 + '@esbuild/linux-ia32': 0.22.0 + '@esbuild/linux-loong64': 0.22.0 + '@esbuild/linux-mips64el': 0.22.0 + '@esbuild/linux-ppc64': 0.22.0 + '@esbuild/linux-riscv64': 0.22.0 + '@esbuild/linux-s390x': 0.22.0 + '@esbuild/linux-x64': 0.22.0 + '@esbuild/netbsd-x64': 0.22.0 + '@esbuild/openbsd-arm64': 0.22.0 + '@esbuild/openbsd-x64': 0.22.0 + '@esbuild/sunos-x64': 0.22.0 + '@esbuild/win32-arm64': 0.22.0 + '@esbuild/win32-ia32': 0.22.0 + '@esbuild/win32-x64': 0.22.0 escalade@3.1.1: {} @@ -18392,91 +19434,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.53.0): - dependencies: - debug: 3.2.7(supports-color@8.1.1) - optionalDependencies: - '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.3.3) - eslint: 8.53.0 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.8.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): - dependencies: - debug: 3.2.7(supports-color@8.1.1) - optionalDependencies: - '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3) - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.8.0(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): - dependencies: - debug: 3.2.7(supports-color@8.1.1) - optionalDependencies: - '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.5.2) - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint@8.53.0): + eslint-module-utils@2.8.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@9.6.0): dependencies: - array-includes: 3.1.7 - array.prototype.findlastindex: 1.2.3 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 debug: 3.2.7(supports-color@8.1.1) - doctrine: 2.1.0 - eslint: 8.53.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.11.0(eslint@8.53.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.53.0) - hasown: 2.0.0 - is-core-module: 2.13.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.7 - object.groupby: 1.0.1 - object.values: 1.1.7 - semver: 6.3.1 - tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.11.0(eslint@8.53.0)(typescript@5.3.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0): - dependencies: - array-includes: 3.1.7 - array.prototype.findlastindex: 1.2.3 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7(supports-color@8.1.1) - doctrine: 2.1.0 - eslint: 8.57.0 + '@typescript-eslint/parser': 7.15.0(eslint@9.6.0)(typescript@5.5.3) + eslint: 9.6.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) - hasown: 2.0.0 - is-core-module: 2.13.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.7 - object.groupby: 1.0.1 - object.values: 1.1.7 - semver: 6.3.1 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3) transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint@9.6.0): dependencies: array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 @@ -18484,9 +19452,9 @@ snapshots: array.prototype.flatmap: 1.3.2 debug: 3.2.7(supports-color@8.1.1) doctrine: 2.1.0 - eslint: 8.57.0 + eslint: 9.6.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.15.0(eslint@9.6.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@9.6.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -18497,110 +19465,70 @@ snapshots: semver: 6.3.1 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.5.2) + '@typescript-eslint/parser': 7.15.0(eslint@9.6.0)(typescript@5.5.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-vue@9.25.0(eslint@8.57.0): + eslint-plugin-vue@9.26.0(eslint@9.6.0): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - eslint: 8.57.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.6.0) + eslint: 9.6.0 globals: 13.24.0 natural-compare: 1.4.0 nth-check: 2.1.1 - postcss-selector-parser: 6.0.15 + postcss-selector-parser: 6.0.16 semver: 7.6.0 - vue-eslint-parser: 9.4.2(eslint@8.57.0) + vue-eslint-parser: 9.4.3(eslint@9.6.0) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color eslint-rule-docs@1.1.235: {} - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint@8.53.0: - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) - '@eslint-community/regexpp': 4.6.2 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.53.0 - '@humanwhocodes/config-array': 0.11.13 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.4.2 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.19.0 - graphemer: 1.4.0 - ignore: 5.2.4 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.3 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - eslint@8.57.0: + eslint-scope@7.2.2: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@eslint-community/regexpp': 4.6.2 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.0 - '@humanwhocodes/config-array': 0.11.14 + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-scope@8.0.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.0.0: {} + + eslint@9.6.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.6.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/config-array': 0.17.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.6.0 '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.0 '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) - doctrine: 3.0.0 + debug: 4.3.5(supports-color@8.1.1) escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.4.2 + eslint-scope: 8.0.1 + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 + esquery: 1.5.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 + file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.19.0 - graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.1 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 @@ -18612,10 +19540,16 @@ snapshots: transitivePeerDependencies: - supports-color + espree@10.1.0: + dependencies: + acorn: 8.12.0 + acorn-jsx: 5.3.2(acorn@8.12.0) + eslint-visitor-keys: 4.0.0 + espree@9.6.1: dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) + acorn: 8.12.0 + acorn-jsx: 5.3.2(acorn@8.12.0) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} @@ -18624,6 +19558,10 @@ snapshots: dependencies: estraverse: 5.3.0 + esquery@1.5.0: + dependencies: + estraverse: 5.3.0 + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 @@ -18718,6 +19656,21 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 + execa@9.2.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.3 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 7.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 5.3.0 + pretty-ms: 9.0.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.0.2 + executable@4.1.1: dependencies: pify: 2.3.0 @@ -18734,42 +19687,6 @@ snapshots: exponential-backoff@3.1.1: {} - express@4.18.2: - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.1 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.5.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.2.0 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: 2.0.7 - qs: 6.11.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - express@4.19.2: dependencies: accepts: 1.3.8 @@ -18819,7 +19736,7 @@ snapshots: extract-zip@2.0.1(supports-color@8.1.1): dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -18843,15 +19760,15 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.7 fast-json-stable-stringify@2.1.0: {} fast-json-stringify@5.8.0: dependencies: '@fastify/deepmerge': 1.3.0 - ajv: 8.13.0 - ajv-formats: 2.1.1(ajv@8.13.0) + ajv: 8.16.0 + ajv-formats: 2.1.1(ajv@8.16.0) fast-deep-equal: 3.1.3 fast-uri: 2.2.0 rfdc: 1.3.0 @@ -18880,7 +19797,7 @@ snapshots: raw-body: 2.5.2 secure-json-parse: 2.7.0 - fastify@4.26.2: + fastify@4.28.1: dependencies: '@fastify/ajv-compiler': 3.5.0 '@fastify/error': 3.4.0 @@ -18891,20 +19808,16 @@ snapshots: fast-json-stringify: 5.8.0 find-my-way: 8.2.0 light-my-request: 5.11.0 - pino: 8.17.0 + pino: 9.2.0 process-warning: 3.0.0 proxy-addr: 2.0.7 rfdc: 1.3.0 secure-json-parse: 2.7.0 semver: 7.6.0 - toad-cache: 3.3.0 + toad-cache: 3.7.0 transitivePeerDependencies: - supports-color - fastq@1.15.0: - dependencies: - reusify: 1.0.4 - fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -18932,9 +19845,13 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - file-entry-cache@6.0.1: + figures@6.1.0: + dependencies: + is-unicode-supported: 2.0.0 + + file-entry-cache@8.0.0: dependencies: - flat-cache: 3.0.4 + flat-cache: 4.0.1 file-system-cache@2.3.0: dependencies: @@ -18969,6 +19886,10 @@ snapshots: dependencies: to-regex-range: 5.0.1 + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + finalhandler@1.2.0: dependencies: debug: 2.6.9 @@ -19028,23 +19949,23 @@ snapshots: ps-list: 8.1.1 taskkill: 5.0.0 - flat-cache@3.0.4: + flat-cache@4.0.1: dependencies: - flatted: 3.2.7 - rimraf: 3.0.2 + flatted: 3.3.1 + keyv: 4.5.4 - flatted@3.2.7: {} + flatted@3.3.1: {} flow-parser@0.202.0: {} - fluent-ffmpeg@2.1.2: + fluent-ffmpeg@2.1.3: dependencies: - async: 3.2.4 + async: 0.2.10 which: 1.3.1 - follow-redirects@1.15.2(debug@4.3.4): + follow-redirects@1.15.2(debug@4.3.5): optionalDependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) for-each@0.3.3: dependencies: @@ -19171,6 +20092,8 @@ snapshots: has-proto: 1.0.1 has-symbols: 1.0.3 + get-nonce@1.0.1: {} + get-npm-tarball-url@2.0.3: {} get-package-type@0.1.0: {} @@ -19199,6 +20122,11 @@ snapshots: get-stream@8.0.1: {} + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + get-symbol-description@1.0.0: dependencies: call-bind: 1.0.2 @@ -19265,6 +20193,15 @@ snapshots: minipass: 7.0.4 path-scurry: 1.10.2 + glob@10.4.2: + dependencies: + foreground-child: 3.1.1 + jackspeak: 3.4.0 + minimatch: 9.0.4 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -19288,14 +20225,14 @@ snapshots: globals@11.12.0: {} - globals@13.19.0: - dependencies: - type-fest: 0.20.2 - globals@13.24.0: dependencies: type-fest: 0.20.2 + globals@14.0.0: {} + + globals@15.7.0: {} + globalthis@1.0.3: dependencies: define-properties: 1.2.0 @@ -19309,6 +20246,15 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + globby@14.0.1: + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.2 + ignore: 5.3.1 + path-type: 5.0.0 + slash: 5.1.0 + unicorn-magic: 0.1.0 + google-protobuf@3.21.2: optional: true @@ -19344,12 +20290,12 @@ snapshots: p-cancelable: 3.0.0 responselike: 3.0.0 - got@14.2.1: + got@14.4.1: dependencies: - '@sindresorhus/is': 6.1.0 + '@sindresorhus/is': 6.3.1 '@szmarczak/http-timer': 5.0.1 cacheable-lookup: 7.0.0 - cacheable-request: 10.2.14 + cacheable-request: 12.0.1 decompress-response: 6.0.0 form-data-encoder: 4.0.2 get-stream: 8.0.1 @@ -19357,6 +20303,7 @@ snapshots: lowercase-keys: 3.0.0 p-cancelable: 4.0.1 responselike: 3.0.0 + type-fest: 4.20.1 graceful-fs@4.2.11: {} @@ -19499,7 +20446,14 @@ snapshots: http-proxy-agent@7.0.0: dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -19538,14 +20492,21 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.2: dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.4: + dependencies: + agent-base: 7.1.0 + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -19557,6 +20518,8 @@ snapshots: human-signals@5.0.0: {} + human-signals@7.0.0: {} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -19588,16 +20551,16 @@ snapshots: import-in-the-middle@1.4.2: dependencies: - acorn: 8.11.3 - acorn-import-assertions: 1.9.0(acorn@8.11.3) + acorn: 8.12.0 + acorn-import-assertions: 1.9.0(acorn@8.12.0) cjs-module-lexer: 1.2.2 module-details-from-path: 1.0.3 optional: true - import-in-the-middle@1.7.4: + import-in-the-middle@1.8.1: dependencies: - acorn: 8.11.3 - acorn-import-attributes: 1.9.5(acorn@8.11.3) + acorn: 8.12.0 + acorn-import-attributes: 1.9.5(acorn@8.12.0) cjs-module-lexer: 1.2.2 module-details-from-path: 1.0.3 @@ -19637,11 +20600,15 @@ snapshots: intersection-observer@0.12.2: {} + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + ioredis@5.4.1: dependencies: '@ioredis/commands': 1.2.0 cluster-key-slot: 1.1.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -19653,15 +20620,14 @@ snapshots: iota-array@1.0.0: {} - ip-address@7.1.0: + ip-address@9.0.5: dependencies: jsbn: 1.1.0 - sprintf-js: 1.1.2 + sprintf-js: 1.1.3 - ip-cidr@3.1.0: + ip-cidr@4.0.1: dependencies: - ip-address: 7.1.0 - jsbn: 1.1.0 + ip-address: 9.0.5 ip-regex@4.3.0: {} @@ -19776,8 +20742,6 @@ snapshots: is-number@7.0.0: {} - is-path-cwd@2.2.0: {} - is-path-inside@3.0.3: {} is-plain-obj@1.1.0: {} @@ -19811,11 +20775,13 @@ snapshots: is-stream@3.0.0: {} + is-stream@4.0.1: {} + is-string@1.0.7: dependencies: has-tostringtag: 1.0.0 - is-svg@5.0.0: + is-svg@5.0.1: dependencies: fast-xml-parser: 4.2.5 @@ -19835,6 +20801,8 @@ snapshots: is-unicode-supported@0.1.0: {} + is-unicode-supported@2.0.0: {} + is-weakmap@2.0.1: {} is-weakref@1.0.2: @@ -19868,8 +20836,8 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.24.0 - '@babel/parser': 7.24.0 + '@babel/core': 7.24.7 + '@babel/parser': 7.24.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -19878,8 +20846,8 @@ snapshots: istanbul-lib-instrument@6.0.0: dependencies: - '@babel/core': 7.24.0 - '@babel/parser': 7.24.0 + '@babel/core': 7.24.7 + '@babel/parser': 7.24.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.0 @@ -19894,12 +20862,20 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color + istanbul-lib-source-maps@5.0.4: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.3.5(supports-color@8.1.1) + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + istanbul-reports@3.1.6: dependencies: html-escaper: 2.0.2 @@ -19913,6 +20889,12 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jackspeak@3.4.0: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jake@10.8.5: dependencies: async: 3.2.4 @@ -19932,7 +20914,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.7 + '@types/node': 20.14.9 chalk: 4.1.2 co: 4.6.0 dedent: 1.3.0 @@ -19952,16 +20934,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.12.7): + jest-cli@29.7.0(@types/node@20.14.9): dependencies: '@jest/core': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.12.7) + create-jest: 29.7.0(@types/node@20.14.9) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.12.7) + jest-config: 29.7.0(@types/node@20.14.9) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -19971,7 +20953,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.12.7): + jest-config@29.7.0(@types/node@20.14.9): dependencies: '@babel/core': 7.23.5 '@jest/test-sequencer': 29.7.0 @@ -19990,13 +20972,13 @@ snapshots: jest-runner: 29.7.0 jest-util: 29.7.0 jest-validate: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.7 parse-json: 5.2.0 pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -20025,7 +21007,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.7 + '@types/node': 20.14.9 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -20042,14 +21024,14 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.6 - '@types/node': 20.12.7 + '@types/node': 20.14.9 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 jest-regex-util: 29.6.3 jest-util: 29.7.0 jest-worker: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.7 walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 @@ -20073,7 +21055,7 @@ snapshots: '@types/stack-utils': 2.0.1 chalk: 4.1.2 graceful-fs: 4.2.11 - micromatch: 4.0.5 + micromatch: 4.0.7 pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.6 @@ -20081,7 +21063,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.12.7 + '@types/node': 20.14.9 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -20116,7 +21098,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.7 + '@types/node': 20.14.9 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -20144,7 +21126,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.7 + '@types/node': 20.14.9 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -20190,7 +21172,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.12.7 + '@types/node': 20.14.9 chalk: 4.1.2 ci-info: 3.7.1 graceful-fs: 4.2.11 @@ -20209,7 +21191,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.7 + '@types/node': 20.14.9 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -20223,17 +21205,17 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.12.7): + jest@29.7.0(@types/node@20.14.9): dependencies: '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.12.7) + jest-cli: 29.7.0(@types/node@20.14.9) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -20263,6 +21245,8 @@ snapshots: js-tokens@4.0.0: {} + js-tokens@9.0.0: {} + js-yaml@3.14.1: dependencies: argparse: 1.0.10 @@ -20278,55 +21262,55 @@ snapshots: jschardet@3.0.0: {} - jscodeshift@0.15.1(@babel/preset-env@7.23.5(@babel/core@7.24.0)): - dependencies: - '@babel/core': 7.24.0 - '@babel/parser': 7.24.0 - '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.24.0) - '@babel/preset-flow': 7.23.3(@babel/core@7.24.0) - '@babel/preset-typescript': 7.23.3(@babel/core@7.24.0) - '@babel/register': 7.22.15(@babel/core@7.24.0) - babel-core: 7.0.0-bridge.0(@babel/core@7.24.0) + jscodeshift@0.15.1(@babel/preset-env@7.24.7(@babel/core@7.24.7)): + dependencies: + '@babel/core': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/plugin-transform-class-properties': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-modules-commonjs': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-optional-chaining': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.24.7) + '@babel/preset-flow': 7.23.3(@babel/core@7.24.7) + '@babel/preset-typescript': 7.23.3(@babel/core@7.24.7) + '@babel/register': 7.22.15(@babel/core@7.24.7) + babel-core: 7.0.0-bridge.0(@babel/core@7.24.7) chalk: 4.1.2 flow-parser: 0.202.0 graceful-fs: 4.2.11 - micromatch: 4.0.5 + micromatch: 4.0.7 neo-async: 2.6.2 node-dir: 0.1.17 - recast: 0.23.4 + recast: 0.23.6 temp: 0.8.4 write-file-atomic: 2.4.3 optionalDependencies: - '@babel/preset-env': 7.23.5(@babel/core@7.24.0) + '@babel/preset-env': 7.24.7(@babel/core@7.24.7) transitivePeerDependencies: - supports-color - jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3): + jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3): dependencies: cssstyle: 4.0.1 data-urls: 5.0.0 decimal.js: 10.4.3 form-data: 4.0.0 html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.0 - https-proxy-agent: 7.0.2 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.4 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.9 + nwsapi: 2.2.10 parse5: 7.1.2 - rrweb-cssom: 0.6.0 + rrweb-cssom: 0.7.1 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 4.1.3 + tough-cookie: 4.1.4 w3c-xmlserializer: 5.0.0 webidl-conversions: 7.0.0 whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.0.0 - ws: 8.17.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) + ws: 8.17.1(bufferutil@4.0.7)(utf-8-validate@6.0.3) xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil @@ -20407,8 +21391,6 @@ snapshots: jsrsasign@11.1.0: {} - jssha@3.3.1: {} - jstransformer@1.0.0: dependencies: is-promise: 2.2.2 @@ -20487,7 +21469,10 @@ snapshots: optionalDependencies: enquirer: 2.3.6 - local-pkg@0.4.3: {} + local-pkg@0.5.0: + dependencies: + mlly: 1.5.0 + pkg-types: 1.0.3 locate-path@3.0.0: dependencies: @@ -20510,8 +21495,6 @@ snapshots: lodash.isarguments@3.1.0: {} - lodash.isequal@4.5.0: {} - lodash.memoize@4.1.2: {} lodash.merge@4.6.2: {} @@ -20583,9 +21566,11 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - magic-string@0.30.7: + magicast@0.3.4: dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 + '@babel/parser': 7.24.5 + '@babel/types': 7.24.0 + source-map-js: 1.2.0 mailcheck@1.1.1: {} @@ -20745,7 +21730,7 @@ snapshots: media-typer@0.3.0: {} - meilisearch@0.38.0(encoding@0.1.13): + meilisearch@0.41.0(encoding@0.1.13): dependencies: cross-fetch: 3.1.6(encoding@0.1.13) transitivePeerDependencies: @@ -20958,7 +21943,7 @@ snapshots: micromark@4.0.0: dependencies: '@types/debug': 4.1.12 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) decode-named-character-reference: 1.0.2 devlop: 1.1.0 micromark-core-commonmark: 2.0.0 @@ -20977,9 +21962,9 @@ snapshots: transitivePeerDependencies: - supports-color - micromatch@4.0.5: + micromatch@4.0.7: dependencies: - braces: 3.0.2 + braces: 3.0.3 picomatch: 2.3.1 mime-db@1.52.0: {} @@ -21076,6 +22061,8 @@ snapshots: minipass@7.0.4: {} + minipass@7.1.2: {} + minizlib@1.3.3: dependencies: minipass: 2.9.0 @@ -21098,7 +22085,7 @@ snapshots: mlly@1.5.0: dependencies: - acorn: 8.11.3 + acorn: 8.12.0 pathe: 1.1.2 pkg-types: 1.0.3 ufo: 1.3.2 @@ -21137,18 +22124,18 @@ snapshots: optionalDependencies: msgpackr-extract: 3.0.2 - msw-storybook-addon@2.0.1(msw@2.2.14(typescript@5.5.2)): + msw-storybook-addon@2.0.2(msw@2.3.1(typescript@5.5.3)): dependencies: is-node-process: 1.2.0 - msw: 2.2.14(typescript@5.5.2) + msw: 2.3.1(typescript@5.5.3) - msw@2.2.14(typescript@5.5.2): + msw@2.3.1(typescript@5.5.3): dependencies: '@bundled-es-modules/cookie': 2.0.0 '@bundled-es-modules/statuses': 1.0.1 '@inquirer/confirm': 3.1.6 '@mswjs/cookies': 1.1.0 - '@mswjs/interceptors': 0.26.15 + '@mswjs/interceptors': 0.29.1 '@open-draft/until': 2.1.0 '@types/cookie': 0.6.0 '@types/statuses': 2.0.4 @@ -21162,7 +22149,7 @@ snapshots: type-fest: 4.9.0 yargs: 17.7.2 optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 muggle-string@0.4.1: {} @@ -21294,7 +22281,7 @@ snapshots: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.1 - glob: 10.3.12 + glob: 10.4.2 graceful-fs: 4.2.11 make-fetch-happen: 13.0.0 nopt: 7.2.0 @@ -21309,7 +22296,7 @@ snapshots: node-releases@2.0.14: {} - nodemailer@6.9.13: {} + nodemailer@6.9.14: {} nodemon@3.0.2: dependencies: @@ -21324,14 +22311,14 @@ snapshots: touch: 3.1.0 undefsafe: 2.0.5 - nodemon@3.1.0: + nodemon@3.1.4: dependencies: chokidar: 3.5.3 debug: 4.3.4(supports-color@5.5.0) ignore-by-default: 1.0.1 minimatch: 3.1.2 pstree.remy: 1.1.8 - semver: 7.5.4 + semver: 7.6.0 simple-update-notifier: 2.0.0 supports-color: 5.5.0 touch: 3.1.0 @@ -21376,6 +22363,8 @@ snapshots: normalize-url@8.0.0: {} + normalize-url@8.0.1: {} + npm-run-path@2.0.2: dependencies: path-key: 2.0.1 @@ -21388,6 +22377,10 @@ snapshots: dependencies: path-key: 4.0.0 + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + npmlog@5.0.1: dependencies: are-we-there-yet: 2.0.0 @@ -21405,7 +22398,7 @@ snapshots: dependencies: boolbase: 1.0.0 - nwsapi@2.2.9: {} + nwsapi@2.2.10: {} oauth-sign@0.9.0: {} @@ -21505,9 +22498,9 @@ snapshots: opentelemetry-instrumentation-fetch-node@1.2.0: dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.43.0(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.43.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color optional: true @@ -21526,7 +22519,7 @@ snapshots: bl: 4.1.0 chalk: 4.1.2 cli-cursor: 3.1.0 - cli-spinners: 2.7.0 + cli-spinners: 2.9.2 is-interactive: 1.0.0 is-unicode-supported: 0.1.0 log-symbols: 4.1.0 @@ -21541,9 +22534,9 @@ snapshots: ospath@1.2.2: {} - otpauth@9.2.3: + otpauth@9.3.1: dependencies: - jssha: 3.3.1 + '@noble/hashes': 1.4.0 outvariant@1.4.2: {} @@ -21563,7 +22556,7 @@ snapshots: dependencies: yocto-queue: 0.1.0 - p-limit@4.0.0: + p-limit@5.0.0: dependencies: yocto-queue: 1.0.0 @@ -21594,6 +22587,8 @@ snapshots: p-try@2.2.0: {} + package-json-from-dist@1.0.0: {} + pako@0.2.9: {} parent-module@1.0.1: @@ -21611,6 +22606,8 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse-ms@4.0.0: {} + parse-srcset@1.0.2: {} parse5-htmlparser2-tree-adapter@6.0.1: @@ -21658,6 +22655,11 @@ snapshots: lru-cache: 10.2.2 minipass: 7.0.4 + path-scurry@1.11.1: + dependencies: + lru-cache: 10.2.2 + minipass: 7.1.2 + path-to-regexp@0.1.7: {} path-to-regexp@1.8.0: @@ -21670,6 +22672,8 @@ snapshots: path-type@4.0.0: {} + path-type@5.0.0: {} + pathe@1.1.2: {} pathval@1.1.1: {} @@ -21699,11 +22703,9 @@ snapshots: pg-numeric@1.0.2: {} - pg-pool@3.6.2(pg@8.11.5): + pg-pool@3.6.2(pg@8.12.0): dependencies: - pg: 8.11.5 - - pg-protocol@1.6.0: {} + pg: 8.12.0 pg-protocol@1.6.1: {} @@ -21725,10 +22727,10 @@ snapshots: postgres-interval: 3.0.0 postgres-range: 1.1.3 - pg@8.11.5: + pg@8.12.0: dependencies: pg-connection-string: 2.6.4 - pg-pool: 3.6.2(pg@8.11.5) + pg-pool: 3.6.2(pg@8.12.0) pg-protocol: 1.6.1 pg-types: 2.2.0 pgpass: 1.0.5 @@ -21739,7 +22741,7 @@ snapshots: dependencies: split2: 4.1.0 - photoswipe@5.4.3: {} + photoswipe@5.4.4: {} picocolors@1.0.0: {} @@ -21753,26 +22755,26 @@ snapshots: pify@4.0.1: {} - pino-abstract-transport@1.1.0: + pino-abstract-transport@1.2.0: dependencies: readable-stream: 4.3.0 split2: 4.1.0 - pino-std-serializers@6.1.0: {} + pino-std-serializers@7.0.0: {} - pino@8.17.0: + pino@9.2.0: dependencies: atomic-sleep: 1.0.0 fast-redact: 3.1.2 on-exit-leak-free: 2.1.0 - pino-abstract-transport: 1.1.0 - pino-std-serializers: 6.1.0 - process-warning: 2.2.0 + pino-abstract-transport: 1.2.0 + pino-std-serializers: 7.0.0 + process-warning: 3.0.0 quick-format-unescaped: 4.0.4 real-require: 0.2.0 safe-stable-stringify: 2.4.2 - sonic-boom: 3.7.0 - thread-stream: 2.3.0 + sonic-boom: 4.0.1 + thread-stream: 3.1.0 pirates@4.0.5: {} @@ -22007,7 +23009,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier@3.2.5: {} + prettier@3.3.2: {} pretty-bytes@5.6.0: {} @@ -22025,6 +23027,10 @@ snapshots: pretty-hrtime@1.0.3: {} + pretty-ms@9.0.0: + dependencies: + parse-ms: 4.0.0 + private-ip@2.3.3: dependencies: ip-regex: 4.3.0 @@ -22110,19 +23116,21 @@ snapshots: js-stringify: 1.0.2 pug-runtime: 3.0.1 - pug-code-gen@3.0.2: + pug-code-gen@3.0.3: dependencies: constantinople: 4.0.1 doctypes: 1.1.0 js-stringify: 1.0.2 pug-attrs: 3.0.0 - pug-error: 2.0.0 + pug-error: 2.1.0 pug-runtime: 3.0.1 void-elements: 3.1.0 with: 7.0.2 pug-error@2.0.0: {} + pug-error@2.1.0: {} + pug-filters@4.0.0: dependencies: constantinople: 4.0.1 @@ -22160,9 +23168,9 @@ snapshots: pug-walk@2.0.0: {} - pug@3.0.2: + pug@3.0.3: dependencies: - pug-code-gen: 3.0.2 + pug-code-gen: 3.0.3 pug-filters: 4.0.0 pug-lexer: 5.0.1 pug-linker: 4.0.0 @@ -22242,13 +23250,6 @@ snapshots: ratelimiter@3.4.1: {} - raw-body@2.5.1: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - raw-body@2.5.2: dependencies: bytes: 3.1.2 @@ -22260,7 +23261,7 @@ snapshots: dependencies: setimmediate: 1.0.5 - re2@1.21.2: + re2@1.21.3: dependencies: install-artifact-from-github: 1.3.5 nan: 2.20.0 @@ -22273,15 +23274,15 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-docgen-typescript@2.2.2(typescript@5.5.2): + react-docgen-typescript@2.2.2(typescript@5.5.3): dependencies: - typescript: 5.5.2 + typescript: 5.5.3 react-docgen@7.0.1: dependencies: - '@babel/core': 7.24.0 - '@babel/traverse': 7.24.0 - '@babel/types': 7.24.0 + '@babel/core': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 '@types/babel__core': 7.20.0 '@types/babel__traverse': 7.20.0 '@types/doctrine': 0.0.9 @@ -22314,6 +23315,34 @@ snapshots: react-is@18.2.0: {} + react-remove-scroll-bar@2.3.6(@types/react@18.0.28)(react@18.3.1): + dependencies: + react: 18.3.1 + react-style-singleton: 2.2.1(@types/react@18.0.28)(react@18.3.1) + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.0.28 + + react-remove-scroll@2.5.7(@types/react@18.0.28)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.6(@types/react@18.0.28)(react@18.3.1) + react-style-singleton: 2.2.1(@types/react@18.0.28)(react@18.3.1) + tslib: 2.6.2 + use-callback-ref: 1.3.2(@types/react@18.0.28)(react@18.3.1) + use-sidecar: 1.1.2(@types/react@18.0.28)(react@18.3.1) + optionalDependencies: + '@types/react': 18.0.28 + + react-style-singleton@2.2.1(@types/react@18.0.28)(react@18.3.1): + dependencies: + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.3.1 + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.0.28 + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -22375,14 +23404,6 @@ snapshots: real-require@0.2.0: {} - recast@0.23.4: - dependencies: - assert: 2.1.0 - ast-types: 0.16.1 - esprima: 4.0.1 - source-map: 0.6.1 - tslib: 2.6.2 - recast@0.23.6: dependencies: ast-types: 0.16.1 @@ -22527,7 +23548,7 @@ snapshots: require-in-the-middle@7.3.0: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) module-details-from-path: 1.0.3 resolve: 1.22.8 transitivePeerDependencies: @@ -22551,11 +23572,6 @@ snapshots: resolve.exports@2.0.0: {} - resolve@1.19.0: - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - resolve@1.22.8: dependencies: is-core-module: 2.13.1 @@ -22595,31 +23611,34 @@ snapshots: rimraf@3.0.2: dependencies: glob: 7.2.3 + optional: true - rollup@4.17.2: + rollup@4.18.0: dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.17.2 - '@rollup/rollup-android-arm64': 4.17.2 - '@rollup/rollup-darwin-arm64': 4.17.2 - '@rollup/rollup-darwin-x64': 4.17.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.17.2 - '@rollup/rollup-linux-arm-musleabihf': 4.17.2 - '@rollup/rollup-linux-arm64-gnu': 4.17.2 - '@rollup/rollup-linux-arm64-musl': 4.17.2 - '@rollup/rollup-linux-powerpc64le-gnu': 4.17.2 - '@rollup/rollup-linux-riscv64-gnu': 4.17.2 - '@rollup/rollup-linux-s390x-gnu': 4.17.2 - '@rollup/rollup-linux-x64-gnu': 4.17.2 - '@rollup/rollup-linux-x64-musl': 4.17.2 - '@rollup/rollup-win32-arm64-msvc': 4.17.2 - '@rollup/rollup-win32-ia32-msvc': 4.17.2 - '@rollup/rollup-win32-x64-msvc': 4.17.2 + '@rollup/rollup-android-arm-eabi': 4.18.0 + '@rollup/rollup-android-arm64': 4.18.0 + '@rollup/rollup-darwin-arm64': 4.18.0 + '@rollup/rollup-darwin-x64': 4.18.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.18.0 + '@rollup/rollup-linux-arm-musleabihf': 4.18.0 + '@rollup/rollup-linux-arm64-gnu': 4.18.0 + '@rollup/rollup-linux-arm64-musl': 4.18.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0 + '@rollup/rollup-linux-riscv64-gnu': 4.18.0 + '@rollup/rollup-linux-s390x-gnu': 4.18.0 + '@rollup/rollup-linux-x64-gnu': 4.18.0 + '@rollup/rollup-linux-x64-musl': 4.18.0 + '@rollup/rollup-win32-arm64-msvc': 4.18.0 + '@rollup/rollup-win32-ia32-msvc': 4.18.0 + '@rollup/rollup-win32-x64-msvc': 4.18.0 fsevents: 2.3.3 rrweb-cssom@0.6.0: {} + rrweb-cssom@0.7.1: {} + rss-parser@3.13.0: dependencies: entities: 2.2.0 @@ -22667,7 +23686,7 @@ snapshots: parse-srcset: 1.0.2 postcss: 8.4.38 - sass@1.76.0: + sass@1.77.6: dependencies: chokidar: 3.5.3 immutable: 4.2.2 @@ -22749,14 +23768,14 @@ snapshots: dependencies: kind-of: 6.0.3 - sharp@0.33.3: + sharp@0.33.4: dependencies: color: 4.2.3 detect-libc: 2.0.3 semver: 7.6.0 optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.3 - '@img/sharp-darwin-x64': 0.33.3 + '@img/sharp-darwin-arm64': 0.33.4 + '@img/sharp-darwin-x64': 0.33.4 '@img/sharp-libvips-darwin-arm64': 1.0.2 '@img/sharp-libvips-darwin-x64': 1.0.2 '@img/sharp-libvips-linux-arm': 1.0.2 @@ -22765,15 +23784,15 @@ snapshots: '@img/sharp-libvips-linux-x64': 1.0.2 '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 '@img/sharp-libvips-linuxmusl-x64': 1.0.2 - '@img/sharp-linux-arm': 0.33.3 - '@img/sharp-linux-arm64': 0.33.3 - '@img/sharp-linux-s390x': 0.33.3 - '@img/sharp-linux-x64': 0.33.3 - '@img/sharp-linuxmusl-arm64': 0.33.3 - '@img/sharp-linuxmusl-x64': 0.33.3 - '@img/sharp-wasm32': 0.33.3 - '@img/sharp-win32-ia32': 0.33.3 - '@img/sharp-win32-x64': 0.33.3 + '@img/sharp-linux-arm': 0.33.4 + '@img/sharp-linux-arm64': 0.33.4 + '@img/sharp-linux-s390x': 0.33.4 + '@img/sharp-linux-x64': 0.33.4 + '@img/sharp-linuxmusl-arm64': 0.33.4 + '@img/sharp-linuxmusl-x64': 0.33.4 + '@img/sharp-wasm32': 0.33.4 + '@img/sharp-win32-ia32': 0.33.4 + '@img/sharp-win32-x64': 0.33.4 shebang-command@1.2.0: dependencies: @@ -22787,9 +23806,9 @@ snapshots: shebang-regex@3.0.0: {} - shiki@1.4.0: + shiki@1.10.0: dependencies: - '@shikijs/core': 1.4.0 + '@shikijs/core': 1.10.0 shimmer@1.2.1: {} @@ -22805,11 +23824,11 @@ snapshots: signal-exit@4.1.0: {} - simple-oauth2@5.0.0: + simple-oauth2@5.0.1: dependencies: - '@hapi/hoek': 10.0.1 + '@hapi/hoek': 11.0.4 '@hapi/wreck': 18.0.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) joi: 17.11.0 transitivePeerDependencies: - supports-color @@ -22890,6 +23909,8 @@ snapshots: slash@3.0.0: {} + slash@5.1.0: {} + slice-ansi@3.0.0: dependencies: ansi-styles: 4.3.0 @@ -22907,7 +23928,7 @@ snapshots: socks-proxy-agent@8.0.2: dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) socks: 2.7.1 transitivePeerDependencies: - supports-color @@ -22917,7 +23938,7 @@ snapshots: ip: 2.0.1 smart-buffer: 4.2.0 - sonic-boom@3.7.0: + sonic-boom@4.0.1: dependencies: atomic-sleep: 1.0.0 @@ -22973,7 +23994,7 @@ snapshots: sprintf-js@1.0.3: {} - sprintf-js@1.1.2: {} + sprintf-js@1.1.3: {} sshpk@1.17.0: dependencies: @@ -22999,16 +24020,16 @@ snapshots: standard-as-callback@2.1.0: {} - start-server-and-test@2.0.3: + start-server-and-test@2.0.4: dependencies: arg: 5.0.2 bluebird: 3.7.2 check-more-types: 2.24.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.5(supports-color@8.1.1) execa: 5.1.1 lazy-ass: 1.6.0 ps-tree: 1.2.0 - wait-on: 7.2.0(debug@4.3.4) + wait-on: 7.2.0(debug@4.3.5) transitivePeerDependencies: - supports-color @@ -23022,22 +24043,22 @@ snapshots: store2@2.14.2: {} - storybook-addon-misskey-theme@https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/components@8.0.9(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/core-events@8.0.9)(@storybook/manager-api@8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/preview-api@8.0.9)(@storybook/theming@8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/types@8.0.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + storybook-addon-misskey-theme@https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/components@8.1.11(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/core-events@8.1.11)(@storybook/manager-api@8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/preview-api@8.1.11)(@storybook/theming@8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@storybook/types@8.1.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@storybook/blocks': 8.0.9(@types/react@18.0.28)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/components': 8.0.9(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/core-events': 8.0.9 - '@storybook/manager-api': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/preview-api': 8.0.9 - '@storybook/theming': 8.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/types': 8.0.9 + '@storybook/blocks': 8.1.11(@types/react@18.0.28)(encoding@0.1.13)(prettier@3.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/components': 8.1.11(@types/react@18.0.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/core-events': 8.1.11 + '@storybook/manager-api': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/preview-api': 8.1.11 + '@storybook/theming': 8.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/types': 8.1.11 optionalDependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - storybook@8.0.9(@babel/preset-env@7.23.5(@babel/core@7.24.0))(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3): + storybook@8.1.11(@babel/preset-env@7.24.7(@babel/core@7.24.7))(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3): dependencies: - '@storybook/cli': 8.0.9(@babel/preset-env@7.23.5(@babel/core@7.24.0))(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3) + '@storybook/cli': 8.1.11(@babel/preset-env@7.24.7(@babel/core@7.24.7))(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3) transitivePeerDependencies: - '@babel/preset-env' - bufferutil @@ -23146,6 +24167,8 @@ snapshots: strip-final-newline@3.0.0: {} + strip-final-newline@4.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -23156,9 +24179,9 @@ snapshots: strip-json-comments@3.1.1: {} - strip-literal@1.3.0: + strip-literal@2.1.0: dependencies: - acorn: 8.11.3 + js-tokens: 9.0.0 strip-outer@2.0.0: {} @@ -23208,7 +24231,7 @@ snapshots: symbol-tree@3.2.4: {} - systeminformation@5.22.7: {} + systeminformation@5.22.11: {} tar-fs@2.1.1: dependencies: @@ -23259,24 +24282,23 @@ snapshots: dependencies: memoizerific: 1.11.3 - temp-dir@2.0.0: {} + temp-dir@3.0.0: {} temp@0.8.4: dependencies: rimraf: 2.6.3 - tempy@1.0.1: + tempy@3.1.0: dependencies: - del: 6.1.1 - is-stream: 2.0.1 - temp-dir: 2.0.0 - type-fest: 0.16.0 - unique-string: 2.0.0 + is-stream: 3.0.0 + temp-dir: 3.0.0 + type-fest: 2.19.0 + unique-string: 3.0.0 - terser@5.30.3: + terser@5.31.1: dependencies: '@jridgewell/source-map': 0.3.5 - acorn: 8.11.3 + acorn: 8.12.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -23298,13 +24320,13 @@ snapshots: dependencies: any-promise: 1.3.0 - thread-stream@2.3.0: + thread-stream@3.1.0: dependencies: real-require: 0.2.0 - three@0.164.1: {} + three@0.165.0: {} - throttle-debounce@5.0.0: {} + throttle-debounce@5.0.2: {} throttleit@1.0.0: {} @@ -23317,8 +24339,6 @@ snapshots: through@2.3.8: {} - tiny-invariant@1.3.1: {} - tiny-invariant@1.3.3: {} tiny-lru@10.0.1: {} @@ -23327,7 +24347,7 @@ snapshots: tinycolor2@1.6.0: {} - tinypool@0.7.0: {} + tinypool@0.8.4: {} tinyspy@2.2.0: {} @@ -23343,8 +24363,6 @@ snapshots: dependencies: is-number: 7.0.0 - toad-cache@3.3.0: {} - toad-cache@3.7.0: {} tocbot@4.21.1: {} @@ -23367,7 +24385,7 @@ snapshots: psl: 1.9.0 punycode: 2.3.1 - tough-cookie@4.1.3: + tough-cookie@4.1.4: dependencies: psl: 1.9.0 punycode: 2.3.1 @@ -23394,9 +24412,9 @@ snapshots: dependencies: typescript: 5.3.3 - ts-api-utils@1.3.0(typescript@5.5.2): + ts-api-utils@1.3.0(typescript@5.5.3): dependencies: - typescript: 5.5.2 + typescript: 5.5.3 ts-case-convert@2.0.2: {} @@ -23404,7 +24422,7 @@ snapshots: ts-map@1.0.3: {} - tsc-alias@1.8.8: + tsc-alias@1.8.10: dependencies: chokidar: 3.5.3 commander: 9.5.0 @@ -23426,9 +24444,9 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tsd@0.30.7: + tsd@0.31.1: dependencies: - '@tsd/typescript': 5.3.3 + '@tsd/typescript': 5.4.5 eslint-formatter-pretty: 4.1.0 globby: 11.1.0 jest-diff: 29.7.0 @@ -23440,6 +24458,8 @@ snapshots: tslib@2.6.2: {} + tslib@2.6.3: {} + tsx@4.4.0: dependencies: esbuild: 0.18.20 @@ -23459,8 +24479,6 @@ snapshots: type-detect@4.0.8: {} - type-fest@0.16.0: {} - type-fest@0.18.1: {} type-fest@0.20.2: {} @@ -23471,8 +24489,12 @@ snapshots: type-fest@0.8.1: {} + type-fest@1.4.0: {} + type-fest@2.19.0: {} + type-fest@4.20.1: {} + type-fest@4.9.0: {} type-is@1.6.18: @@ -23509,7 +24531,7 @@ snapshots: typedarray@0.0.6: {} - typeorm@0.3.20(ioredis@5.4.1)(pg@8.11.5): + typeorm@0.3.20(ioredis@5.4.1)(pg@8.12.0): dependencies: '@sqltools/formatter': 1.2.5 app-root-path: 3.1.0 @@ -23517,7 +24539,7 @@ snapshots: chalk: 4.1.2 cli-highlight: 2.1.11 dayjs: 1.11.10 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) dotenv: 16.0.3 glob: 10.3.10 mkdirp: 2.1.6 @@ -23528,7 +24550,7 @@ snapshots: yargs: 17.7.2 optionalDependencies: ioredis: 5.4.1 - pg: 8.11.5 + pg: 8.12.0 transitivePeerDependencies: - supports-color @@ -23536,7 +24558,7 @@ snapshots: typescript@5.4.2: {} - typescript@5.5.2: {} + typescript@5.5.3: {} ufo@1.3.2: {} @@ -23577,6 +24599,8 @@ snapshots: unicode-property-aliases-ecmascript@2.1.0: {} + unicorn-magic@0.1.0: {} + unified@11.0.4: dependencies: '@types/unist': 3.0.2 @@ -23597,9 +24621,9 @@ snapshots: dependencies: imurmurhash: 0.1.4 - unique-string@2.0.0: + unique-string@3.0.0: dependencies: - crypto-random-string: 2.0.0 + crypto-random-string: 4.0.0 unist-util-is@6.0.0: dependencies: @@ -23632,7 +24656,7 @@ snapshots: unplugin@1.4.0: dependencies: - acorn: 8.11.3 + acorn: 8.12.0 chokidar: 3.5.3 webpack-sources: 3.2.3 webpack-virtual-modules: 0.5.0 @@ -23660,6 +24684,21 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 + use-callback-ref@1.3.2(@types/react@18.0.28)(react@18.3.1): + dependencies: + react: 18.3.1 + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.0.28 + + use-sidecar@1.1.2(@types/react@18.0.28)(react@18.3.1): + dependencies: + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.0.28 + utf-8-validate@6.0.3: dependencies: node-gyp-build: 4.6.0 @@ -23677,20 +24716,22 @@ snapshots: utils-merge@1.0.1: {} + uuid@10.0.0: {} + uuid@3.4.0: {} uuid@8.3.2: {} uuid@9.0.1: {} - v-code-diff@1.11.0(vue@3.4.26(typescript@5.5.2)): + v-code-diff@1.12.0(vue@3.4.31(typescript@5.5.3)): dependencies: diff: 5.1.0 diff-match-patch: 1.0.5 highlight.js: 11.9.0 - vue: 3.4.26(typescript@5.5.2) - vue-demi: 0.14.7(vue@3.4.26(typescript@5.5.2)) - vue-i18n: 9.13.1(vue@3.4.26(typescript@5.5.2)) + vue: 3.4.31(typescript@5.5.3) + vue-demi: 0.14.7(vue@3.4.31(typescript@5.5.3)) + vue-i18n: 9.13.1(vue@3.4.31(typescript@5.5.3)) v8-to-istanbul@9.2.0: dependencies: @@ -23703,8 +24744,6 @@ snapshots: spdx-correct: 3.1.1 spdx-expression-parse: 3.0.1 - validator@13.9.0: {} - vary@1.1.2: {} verror@1.10.0: @@ -23724,14 +24763,13 @@ snapshots: unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 - vite-node@0.34.6(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3): + vite-node@1.6.0(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1): dependencies: cac: 6.7.14 - debug: 4.3.4(supports-color@8.1.1) - mlly: 1.5.0 + debug: 4.3.5(supports-color@8.1.1) pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) + vite: 5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1) transitivePeerDependencies: - '@types/node' - less @@ -23744,53 +24782,50 @@ snapshots: vite-plugin-turbosnap@1.0.3: {} - vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3): + vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1): dependencies: - esbuild: 0.20.2 + esbuild: 0.21.5 postcss: 8.4.38 - rollup: 4.17.2 + rollup: 4.18.0 optionalDependencies: - '@types/node': 20.12.7 + '@types/node': 20.14.9 fsevents: 2.3.3 - sass: 1.76.0 - terser: 5.30.3 + sass: 1.77.6 + terser: 5.31.1 - vitest-fetch-mock@0.2.2(encoding@0.1.13)(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3)): + vitest-fetch-mock@0.2.2(encoding@0.1.13)(vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1)): dependencies: cross-fetch: 3.1.6(encoding@0.1.13) - vitest: 0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3) + vitest: 1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1) transitivePeerDependencies: - encoding - vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3): - dependencies: - '@types/chai': 4.3.11 - '@types/chai-subset': 1.3.5 - '@types/node': 20.12.7 - '@vitest/expect': 0.34.6 - '@vitest/runner': 0.34.6 - '@vitest/snapshot': 0.34.6 - '@vitest/spy': 0.34.6 - '@vitest/utils': 0.34.6 - acorn: 8.11.3 + vitest@1.6.0(@types/node@20.14.9)(happy-dom@10.0.3)(jsdom@24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.77.6)(terser@5.31.1): + dependencies: + '@vitest/expect': 1.6.0 + '@vitest/runner': 1.6.0 + '@vitest/snapshot': 1.6.0 + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 acorn-walk: 8.3.2 - cac: 6.7.14 chai: 4.3.10 - debug: 4.3.4(supports-color@8.1.1) - local-pkg: 0.4.3 - magic-string: 0.30.7 + debug: 4.3.4(supports-color@5.5.0) + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.10 pathe: 1.1.2 picocolors: 1.0.0 std-env: 3.7.0 - strip-literal: 1.3.0 + strip-literal: 2.1.0 tinybench: 2.6.0 - tinypool: 0.7.0 - vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) - vite-node: 0.34.6(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) + tinypool: 0.8.4 + vite: 5.3.2(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1) + vite-node: 1.6.0(@types/node@20.14.9)(sass@1.77.6)(terser@5.31.1) why-is-node-running: 2.2.2 optionalDependencies: + '@types/node': 20.14.9 happy-dom: 10.0.3 - jsdom: 24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) + jsdom: 24.1.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) transitivePeerDependencies: - less - lightningcss @@ -23823,98 +24858,100 @@ snapshots: dependencies: vscode-languageserver-protocol: 3.17.5 - vue-component-meta@2.0.16(typescript@5.5.2): + vscode-uri@3.0.8: {} + + vue-component-meta@2.0.16(typescript@5.5.3): dependencies: '@volar/typescript': 2.2.0 - '@vue/language-core': 2.0.16(typescript@5.5.2) + '@vue/language-core': 2.0.16(typescript@5.5.3) path-browserify: 1.0.1 vue-component-type-helpers: 2.0.16 optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 vue-component-type-helpers@1.8.4: {} vue-component-type-helpers@2.0.16: {} - vue-component-type-helpers@2.0.21: {} + vue-component-type-helpers@2.0.24: {} - vue-demi@0.14.7(vue@3.4.26(typescript@5.5.2)): + vue-demi@0.14.7(vue@3.4.31(typescript@5.5.3)): dependencies: - vue: 3.4.26(typescript@5.5.2) + vue: 3.4.31(typescript@5.5.3) - vue-docgen-api@4.75.1(vue@3.4.26(typescript@5.5.2)): + vue-docgen-api@4.75.1(vue@3.4.31(typescript@5.5.3)): dependencies: - '@babel/parser': 7.24.0 - '@babel/types': 7.24.0 - '@vue/compiler-dom': 3.4.21 - '@vue/compiler-sfc': 3.4.26 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + '@vue/compiler-dom': 3.4.29 + '@vue/compiler-sfc': 3.4.31 ast-types: 0.16.1 hash-sum: 2.0.0 lru-cache: 8.0.4 - pug: 3.0.2 - recast: 0.23.4 + pug: 3.0.3 + recast: 0.23.6 ts-map: 1.0.3 - vue: 3.4.26(typescript@5.5.2) - vue-inbrowser-compiler-independent-utils: 4.71.1(vue@3.4.26(typescript@5.5.2)) + vue: 3.4.31(typescript@5.5.3) + vue-inbrowser-compiler-independent-utils: 4.71.1(vue@3.4.31(typescript@5.5.3)) - vue-eslint-parser@9.4.2(eslint@8.57.0): + vue-eslint-parser@9.4.3(eslint@9.6.0): dependencies: - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + debug: 4.3.4(supports-color@5.5.0) + eslint: 9.6.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 esquery: 1.4.2 lodash: 4.17.21 - semver: 7.5.4 + semver: 7.6.0 transitivePeerDependencies: - supports-color - vue-i18n@9.13.1(vue@3.4.26(typescript@5.5.2)): + vue-i18n@9.13.1(vue@3.4.31(typescript@5.5.3)): dependencies: '@intlify/core-base': 9.13.1 '@intlify/shared': 9.13.1 '@vue/devtools-api': 6.6.1 - vue: 3.4.26(typescript@5.5.2) + vue: 3.4.31(typescript@5.5.3) - vue-inbrowser-compiler-independent-utils@4.71.1(vue@3.4.26(typescript@5.5.2)): + vue-inbrowser-compiler-independent-utils@4.71.1(vue@3.4.31(typescript@5.5.3)): dependencies: - vue: 3.4.26(typescript@5.5.2) + vue: 3.4.31(typescript@5.5.3) vue-template-compiler@2.7.14: dependencies: de-indent: 1.0.2 he: 1.2.0 - vue-tsc@2.0.16(typescript@5.5.2): + vue-tsc@2.0.24(typescript@5.5.3): dependencies: - '@volar/typescript': 2.2.0 - '@vue/language-core': 2.0.16(typescript@5.5.2) + '@volar/typescript': 2.4.0-alpha.11 + '@vue/language-core': 2.0.24(typescript@5.5.3) semver: 7.6.0 - typescript: 5.5.2 + typescript: 5.5.3 - vue@3.4.26(typescript@5.5.2): + vue@3.4.31(typescript@5.5.3): dependencies: - '@vue/compiler-dom': 3.4.26 - '@vue/compiler-sfc': 3.4.26 - '@vue/runtime-dom': 3.4.26 - '@vue/server-renderer': 3.4.26(vue@3.4.26(typescript@5.5.2)) - '@vue/shared': 3.4.26 + '@vue/compiler-dom': 3.4.31 + '@vue/compiler-sfc': 3.4.31 + '@vue/runtime-dom': 3.4.31 + '@vue/server-renderer': 3.4.31(vue@3.4.31(typescript@5.5.3)) + '@vue/shared': 3.4.31 optionalDependencies: - typescript: 5.5.2 + typescript: 5.5.3 - vuedraggable@4.1.0(vue@3.4.26(typescript@5.5.2)): + vuedraggable@4.1.0(vue@3.4.31(typescript@5.5.3)): dependencies: sortablejs: 1.14.0 - vue: 3.4.26(typescript@5.5.2) + vue: 3.4.31(typescript@5.5.3) w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 - wait-on@7.2.0(debug@4.3.4): + wait-on@7.2.0(debug@4.3.5): dependencies: - axios: 1.6.2(debug@4.3.4) + axios: 1.6.2(debug@4.3.5) joi: 17.11.0 lodash: 4.17.21 minimist: 1.2.8 @@ -24026,8 +25063,8 @@ snapshots: with@7.0.2: dependencies: - '@babel/parser': 7.23.9 - '@babel/types': 7.23.5 + '@babel/parser': 7.24.5 + '@babel/types': 7.24.0 assert-never: 1.2.1 babel-walk: 3.0.0-canary-5 @@ -24064,7 +25101,7 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 - ws@8.17.0(bufferutil@4.0.7)(utf-8-validate@6.0.3): + ws@8.17.1(bufferutil@4.0.7)(utf-8-validate@6.0.3): optionalDependencies: bufferutil: 4.0.7 utf-8-validate: 6.0.3 @@ -24152,13 +25189,7 @@ snapshots: yocto-queue@1.0.0: {} - z-schema@5.0.5: - dependencies: - lodash.get: 4.4.2 - lodash.isequal: 4.5.0 - validator: 13.9.0 - optionalDependencies: - commander: 9.5.0 + yoctocolors@2.0.2: {} zip-stream@6.0.1: dependencies: diff --git a/scripts/changelog-checker/.eslintrc.cjs b/scripts/changelog-checker/.eslintrc.cjs deleted file mode 100644 index 6acf8b3e6e10..000000000000 --- a/scripts/changelog-checker/.eslintrc.cjs +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - extends: [ - '../../packages/shared/.eslintrc.js', - ], -}; diff --git a/scripts/changelog-checker/eslint.config.js b/scripts/changelog-checker/eslint.config.js new file mode 100644 index 000000000000..813e96981ace --- /dev/null +++ b/scripts/changelog-checker/eslint.config.js @@ -0,0 +1,17 @@ +import tsParser from '@typescript-eslint/parser'; +import sharedConfig from '../../packages/shared/eslint.config.js'; + +export default [ + ...sharedConfig, + { + files: ['src/**/*.ts', 'src/**/*.tsx'], + languageOptions: { + parserOptions: { + parser: tsParser, + project: ['./tsconfig.json'], + sourceType: 'module', + tsconfigRootDir: import.meta.dirname, + }, + }, + }, +]; From eafae79869204e6de4a3fd4835eda3eb23b53974 Mon Sep 17 00:00:00 2001 From: Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> Date: Tue, 2 Jul 2024 14:29:44 +0900 Subject: [PATCH 069/268] test(backend): goodbye, Lenna (#14111) --- .../src/models/json-schema/drive-file.ts | 2 +- .../api/endpoints/admin/drive/show-file.ts | 2 +- packages/backend/test/e2e/drive.ts | 6 +++--- packages/backend/test/e2e/endpoints.ts | 2 +- packages/backend/test/e2e/note.ts | 4 ++-- packages/backend/test/e2e/user-notes.ts | 4 ++-- packages/backend/test/resources/192.jpg | Bin 0 -> 5131 bytes packages/backend/test/resources/192.png | Bin 0 -> 26568 bytes packages/backend/test/resources/Lenna.jpg | Bin 25360 -> 0 bytes packages/backend/test/resources/Lenna.png | Bin 473831 -> 0 bytes packages/backend/test/unit/FileInfoService.ts | 10 +++++----- packages/backend/test/utils.ts | 2 +- packages/misskey-js/src/autogen/types.ts | 4 ++-- 13 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 packages/backend/test/resources/192.jpg create mode 100644 packages/backend/test/resources/192.png delete mode 100644 packages/backend/test/resources/Lenna.jpg delete mode 100644 packages/backend/test/resources/Lenna.png diff --git a/packages/backend/src/models/json-schema/drive-file.ts b/packages/backend/src/models/json-schema/drive-file.ts index ca88cc0e3975..5ee1561c50c4 100644 --- a/packages/backend/src/models/json-schema/drive-file.ts +++ b/packages/backend/src/models/json-schema/drive-file.ts @@ -20,7 +20,7 @@ export const packedDriveFileSchema = { name: { type: 'string', optional: false, nullable: false, - example: 'lenna.jpg', + example: '192.jpg', }, type: { type: 'string', diff --git a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts index 459d8880fad3..a7136d8c8cc8 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts @@ -61,7 +61,7 @@ export const meta = { name: { type: 'string', optional: false, nullable: false, - example: 'lenna.jpg', + example: '192.jpg', }, type: { type: 'string', diff --git a/packages/backend/test/e2e/drive.ts b/packages/backend/test/e2e/drive.ts index 828c5200ef0d..43a73163ebab 100644 --- a/packages/backend/test/e2e/drive.ts +++ b/packages/backend/test/e2e/drive.ts @@ -23,7 +23,7 @@ describe('Drive', () => { const marker = Math.random().toString(); - const url = 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg'; + const url = 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/192.jpg'; const catcher = makeStreamCatcher( alice, @@ -41,14 +41,14 @@ describe('Drive', () => { const file = await catcher; assert.strictEqual(res.status, 204); - assert.strictEqual(file.name, 'Lenna.jpg'); + assert.strictEqual(file.name, '192.jpg'); assert.strictEqual(file.type, 'image/jpeg'); }); test('ローカルからアップロードできる', async () => { // APIレスポンスを直接使用するので utils.js uploadFile が通過することで成功とする - const res = await uploadFile(alice, { path: 'Lenna.jpg', name: 'テスト画像' }); + const res = await uploadFile(alice, { path: '192.jpg', name: 'テスト画像' }); assert.strictEqual(res.body?.name, 'テスト画像.jpg'); assert.strictEqual(res.body.type, 'image/jpeg'); diff --git a/packages/backend/test/e2e/endpoints.ts b/packages/backend/test/e2e/endpoints.ts index de5e8ba95e34..d5583ea8bbcb 100644 --- a/packages/backend/test/e2e/endpoints.ts +++ b/packages/backend/test/e2e/endpoints.ts @@ -584,7 +584,7 @@ describe('Endpoints', () => { assert.strictEqual(res.status, 200); assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true); - assert.strictEqual(res.body!.name, 'Lenna.jpg'); + assert.strictEqual(res.body!.name, '192.jpg'); }); test('ファイルに名前を付けられる', async () => { diff --git a/packages/backend/test/e2e/note.ts b/packages/backend/test/e2e/note.ts index bda31d964074..7ce9f47bc308 100644 --- a/packages/backend/test/e2e/note.ts +++ b/packages/backend/test/e2e/note.ts @@ -41,7 +41,7 @@ describe('Note', () => { }); test('ファイルを添付できる', async () => { - const file = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg'); + const file = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/192.jpg'); const res = await api('notes/create', { fileIds: [file.id], @@ -53,7 +53,7 @@ describe('Note', () => { }, 1000 * 10); test('他人のファイルで怒られる', async () => { - const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg'); + const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/192.jpg'); const res = await api('notes/create', { text: 'test', diff --git a/packages/backend/test/e2e/user-notes.ts b/packages/backend/test/e2e/user-notes.ts index 331e053935f8..cc07c5ae71ac 100644 --- a/packages/backend/test/e2e/user-notes.ts +++ b/packages/backend/test/e2e/user-notes.ts @@ -17,8 +17,8 @@ describe('users/notes', () => { beforeAll(async () => { alice = await signup({ username: 'alice' }); - const jpg = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg'); - const png = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.png'); + const jpg = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/192.jpg'); + const png = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/192.png'); jpgNote = await post(alice, { fileIds: [jpg.id], }); diff --git a/packages/backend/test/resources/192.jpg b/packages/backend/test/resources/192.jpg new file mode 100644 index 0000000000000000000000000000000000000000..76374628e0acf2e3b85152d55c11c9a763027810 GIT binary patch literal 5131 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 LNkvXXu0mjfqyVNd literal 0 HcmV?d00001 diff --git a/packages/backend/test/resources/Lenna.jpg b/packages/backend/test/resources/Lenna.jpg deleted file mode 100644 index 6b5b32281c1ffd5893d23392169cc368d72e0823..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25360 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 z 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

Q*ie`|Cj&2i?YTA`Sqeun>bF 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 z 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ڵ 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 B { describe('IMAGE', () => { test('Generic JPEG', async () => { - const path = `${resources}/Lenna.jpg`; + const path = `${resources}/192.jpg`; const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any; delete info.warnings; delete info.blurhash; delete info.sensitive; delete info.porn; assert.deepStrictEqual(info, { - size: 25360, - md5: '091b3f259662aa31e2ffef4519951168', + size: 5131, + md5: '8c9ed0677dd2b8f9f7472c3af247e5e3', type: { mime: 'image/jpeg', ext: 'jpg', }, - width: 512, - height: 512, + width: 192, + height: 192, orientation: undefined, }); }); diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts index aad4ab37c93c..bf14d05ecaec 100644 --- a/packages/backend/test/utils.ts +++ b/packages/backend/test/utils.ts @@ -297,7 +297,7 @@ export const uploadFile = async (user?: UserToken, { path, name, blob }: UploadO body: misskey.entities.DriveFile | null }> => { const absPath = path == null - ? new URL('resources/Lenna.jpg', import.meta.url) + ? new URL('resources/192.jpg', import.meta.url) : isAbsolute(path.toString()) ? new URL(path) : new URL(path, new URL('resources/', import.meta.url)); diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 72aca4dee298..b59f8dcbe364 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -4299,7 +4299,7 @@ export type components = { id: string; /** Format: date-time */ createdAt: string; - /** @example lenna.jpg */ + /** @example 192.jpg */ name: string; /** @example image/jpeg */ type: string; @@ -6799,7 +6799,7 @@ export type operations = { * @example 15eca7fba0480996e2245f5185bf39f2 */ md5: string; - /** @example lenna.jpg */ + /** @example 192.jpg */ name: string; /** @example image/jpeg */ type: string; From de1fe7cc5a22fed6c677a6b35365c667eece8ab8 Mon Sep 17 00:00:00 2001 From: woxtu Date: Tue, 2 Jul 2024 14:47:07 +0900 Subject: [PATCH 070/268] Use built-in API (#14095) --- packages/backend/test/e2e/move.ts | 7 +- packages/backend/test/e2e/renote-mute.ts | 9 +- packages/backend/test/e2e/timelines.ts | 93 ++++++++++--------- packages/backend/test/unit/RoleService.ts | 8 +- .../backend/test/unit/SystemWebhookService.ts | 17 ++-- packages/backend/test/utils.ts | 8 -- 6 files changed, 69 insertions(+), 73 deletions(-) diff --git a/packages/backend/test/e2e/move.ts b/packages/backend/test/e2e/move.ts index 74cf61a7857a..35240cd3c844 100644 --- a/packages/backend/test/e2e/move.ts +++ b/packages/backend/test/e2e/move.ts @@ -7,12 +7,13 @@ import { INestApplicationContext } from '@nestjs/common'; process.env.NODE_ENV = 'test'; +import { setTimeout } from 'node:timers/promises'; import * as assert from 'assert'; import { loadConfig } from '@/config.js'; import { MiRepository, MiUser, UsersRepository, miRepository } from '@/models/_.js'; import { secureRndstr } from '@/misc/secure-rndstr.js'; import { jobQueue } from '@/boot/common.js'; -import { api, initTestDb, signup, sleep, successfulApiCall, uploadFile } from '../utils.js'; +import { api, initTestDb, signup, successfulApiCall, uploadFile } from '../utils.js'; import type * as misskey from 'misskey-js'; describe('Account Move', () => { @@ -271,7 +272,7 @@ describe('Account Move', () => { assert.strictEqual(move.status, 200); - await sleep(1000 * 3); // wait for jobs to finish + await setTimeout(1000 * 3); // wait for jobs to finish // Unfollow delayed? const aliceFollowings = await api('users/following', { @@ -330,7 +331,7 @@ describe('Account Move', () => { }); test('Unfollowed after 10 sec (24 hours in production).', async () => { - await sleep(1000 * 8); + await setTimeout(1000 * 8); const following = await api('users/following', { userId: alice.id, diff --git a/packages/backend/test/e2e/renote-mute.ts b/packages/backend/test/e2e/renote-mute.ts index 1abbb4f04494..f6895c43d89c 100644 --- a/packages/backend/test/e2e/renote-mute.ts +++ b/packages/backend/test/e2e/renote-mute.ts @@ -6,7 +6,8 @@ process.env.NODE_ENV = 'test'; import * as assert from 'assert'; -import { api, post, signup, sleep, waitFire } from '../utils.js'; +import { setTimeout } from 'node:timers/promises'; +import { api, post, signup, waitFire } from '../utils.js'; import type * as misskey from 'misskey-js'; describe('Renote Mute', () => { @@ -35,7 +36,7 @@ describe('Renote Mute', () => { const carolNote = await post(carol, { text: 'hi' }); // redisに追加されるのを待つ - await sleep(100); + await setTimeout(100); const res = await api('notes/local-timeline', {}, alice); @@ -52,7 +53,7 @@ describe('Renote Mute', () => { const carolNote = await post(carol, { text: 'hi' }); // redisに追加されるのを待つ - await sleep(100); + await setTimeout(100); const res = await api('notes/local-timeline', {}, alice); @@ -69,7 +70,7 @@ describe('Renote Mute', () => { const bobRenote = await post(bob, { renoteId: carolNote.id }); // redisに追加されるのを待つ - await sleep(100); + await setTimeout(100); const res = await api('notes/local-timeline', {}, alice); diff --git a/packages/backend/test/e2e/timelines.ts b/packages/backend/test/e2e/timelines.ts index f6cc2bac2874..fccc052d99d8 100644 --- a/packages/backend/test/e2e/timelines.ts +++ b/packages/backend/test/e2e/timelines.ts @@ -7,16 +7,17 @@ // pnpm jest -- e2e/timelines.ts import * as assert from 'assert'; +import { setTimeout } from 'node:timers/promises'; import { Redis } from 'ioredis'; import { loadConfig } from '@/config.js'; -import { api, post, randomString, sendEnvUpdateRequest, signup, sleep, uploadUrl } from '../utils.js'; +import { api, post, randomString, sendEnvUpdateRequest, signup, uploadUrl } from '../utils.js'; function genHost() { return randomString() + '.example.com'; } function waitForPushToTl() { - return sleep(500); + return setTimeout(500); } let redisForTimelines: Redis; @@ -44,7 +45,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi' }); const carolNote = await post(carol, { text: 'hi' }); @@ -60,7 +61,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'followers' }); const carolNote = await post(carol, { text: 'hi' }); @@ -77,7 +78,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id }); @@ -94,7 +95,7 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); await api('following/update', { userId: bob.id, withReplies: true }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id }); @@ -111,7 +112,7 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); await api('following/update', { userId: bob.id, withReplies: true }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id, visibility: 'specified', visibleUserIds: [carolNote.id] }); @@ -128,7 +129,7 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); await api('following/update', { userId: bob.id, withReplies: true }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi', visibility: 'followers' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id }); @@ -147,7 +148,7 @@ describe('Timelines', () => { await api('following/create', { userId: carol.id }, alice); await api('following/create', { userId: carol.id }, bob); await api('following/update', { userId: bob.id, withReplies: true }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi', visibility: 'followers' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id }); @@ -166,7 +167,7 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); await api('following/create', { userId: carol.id }, alice); await api('following/update', { userId: bob.id, withReplies: true }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id, visibility: 'specified', visibleUserIds: [carolNote.id] }); @@ -182,7 +183,7 @@ describe('Timelines', () => { const [alice, bob] = await Promise.all([signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote1 = await post(bob, { text: 'hi' }); const bobNote2 = await post(bob, { text: 'hi', replyId: bobNote1.id }); @@ -198,7 +199,7 @@ describe('Timelines', () => { const [alice, bob] = await Promise.all([signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const aliceNote = await post(alice, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id }); @@ -228,7 +229,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { renoteId: carolNote.id }); @@ -244,7 +245,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { renoteId: carolNote.id }); @@ -262,7 +263,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', renoteId: carolNote.id }); @@ -280,7 +281,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'specified', visibleUserIds: [carol.id] }); await waitForPushToTl(); @@ -295,7 +296,7 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); await api('mute/create', { userId: carol.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', renoteId: carolNote.id }); @@ -313,7 +314,7 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); await api('following/update', { userId: bob.id, withReplies: true }, alice); await api('mute/create', { userId: carol.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id }); @@ -359,7 +360,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const [bobFile, carolFile] = await Promise.all([ uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png'), uploadUrl(carol, 'https://raw.githubusercontent.com/misskey-dev/assets/main/public/icon.png'), @@ -384,7 +385,7 @@ describe('Timelines', () => { const channel = await api('channels/create', { name: 'channel' }, bob).then(x => x.body); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', channelId: channel.id }); await waitForPushToTl(); @@ -411,7 +412,7 @@ describe('Timelines', () => { const [alice, bob] = await Promise.all([signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'specified', visibleUserIds: [alice.id] }); await waitForPushToTl(); @@ -438,7 +439,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'specified', visibleUserIds: [carol.id] }); await waitForPushToTl(); @@ -566,7 +567,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('following/create', { userId: carol.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi', visibility: 'home' }); const bobNote = await post(bob, { text: 'hi' }); @@ -582,7 +583,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('mute/create', { userId: carol.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi' }); @@ -599,7 +600,7 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); await api('mute/create', { userId: carol.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', renoteId: carolNote.id }); @@ -617,7 +618,7 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); await api('following/update', { userId: bob.id, withReplies: true }, alice); await api('mute/create', { userId: carol.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id }); @@ -633,7 +634,7 @@ describe('Timelines', () => { const [alice, bob] = await Promise.all([signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const aliceNote = await post(alice, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id }); @@ -703,7 +704,7 @@ describe('Timelines', () => { const [alice, bob] = await Promise.all([signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'home' }); await waitForPushToTl(); @@ -717,7 +718,7 @@ describe('Timelines', () => { const [alice, bob] = await Promise.all([signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const aliceNote = await post(alice, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id }); @@ -820,7 +821,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi' }); await waitForPushToTl(); @@ -835,7 +836,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'home' }); await waitForPushToTl(); @@ -850,7 +851,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'followers' }); await waitForPushToTl(); @@ -865,7 +866,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id }); @@ -881,7 +882,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote1 = await post(bob, { text: 'hi' }); const bobNote2 = await post(bob, { text: 'hi', replyId: bobNote1.id }); @@ -899,7 +900,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); await api('users/lists/update-membership', { listId: list.id, userId: bob.id, withReplies: false }, alice); - await sleep(1000); + await setTimeout(1000); const aliceNote = await post(alice, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id }); @@ -916,7 +917,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); await api('users/lists/update-membership', { listId: list.id, userId: bob.id, withReplies: false }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id }); @@ -933,7 +934,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); await api('users/lists/update-membership', { listId: list.id, userId: bob.id, withReplies: true }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', replyId: carolNote.id }); @@ -950,7 +951,7 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'home' }); await waitForPushToTl(); @@ -966,7 +967,7 @@ describe('Timelines', () => { await api('following/create', { userId: bob.id }, alice); const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'followers' }); await waitForPushToTl(); @@ -982,7 +983,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: alice.id }, alice); - await sleep(1000); + await setTimeout(1000); const aliceNote = await post(alice, { text: 'hi', visibility: 'followers' }); await waitForPushToTl(); @@ -999,7 +1000,7 @@ describe('Timelines', () => { const channel = await api('channels/create', { name: 'channel' }, bob).then(x => x.body); const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', channelId: channel.id }); await waitForPushToTl(); @@ -1031,7 +1032,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'specified', visibleUserIds: [alice.id] }); await waitForPushToTl(); @@ -1048,7 +1049,7 @@ describe('Timelines', () => { const list = await api('users/lists/create', { name: 'list' }, alice).then(res => res.body); await api('users/lists/push', { listId: list.id, userId: bob.id }, alice); await api('users/lists/push', { listId: list.id, userId: carol.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'specified', visibleUserIds: [carol.id] }); await waitForPushToTl(); @@ -1088,7 +1089,7 @@ describe('Timelines', () => { const [alice, bob] = await Promise.all([signup(), signup()]); await api('following/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote = await post(bob, { text: 'hi', visibility: 'followers' }); await waitForPushToTl(); @@ -1228,7 +1229,7 @@ describe('Timelines', () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); await api('mute/create', { userId: carol.id }, alice); - await sleep(1000); + await setTimeout(1000); const carolNote = await post(carol, { text: 'hi' }); const bobNote = await post(bob, { text: 'hi', renoteId: carolNote.id }); @@ -1243,7 +1244,7 @@ describe('Timelines', () => { const [alice, bob] = await Promise.all([signup(), signup()]); await api('mute/create', { userId: bob.id }, alice); - await sleep(1000); + await setTimeout(1000); const bobNote1 = await post(bob, { text: 'hi' }); const bobNote2 = await post(bob, { text: 'hi', replyId: bobNote1.id }); const bobNote3 = await post(bob, { text: 'hi', renoteId: bobNote1.id }); diff --git a/packages/backend/test/unit/RoleService.ts b/packages/backend/test/unit/RoleService.ts index 69fa4162fbac..b6cbe4c520d1 100644 --- a/packages/backend/test/unit/RoleService.ts +++ b/packages/backend/test/unit/RoleService.ts @@ -5,6 +5,7 @@ process.env.NODE_ENV = 'test'; +import { setTimeout } from 'node:timers/promises'; import { jest } from '@jest/globals'; import { ModuleMocker } from 'jest-mock'; import { Test } from '@nestjs/testing'; @@ -29,7 +30,6 @@ import { secureRndstr } from '@/misc/secure-rndstr.js'; import { NotificationService } from '@/core/NotificationService.js'; import { RoleCondFormulaValue } from '@/models/Role.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; -import { sleep } from '../utils.js'; import type { TestingModule } from '@nestjs/testing'; import type { MockFunctionMetadata } from 'jest-mock'; @@ -278,7 +278,7 @@ describe('RoleService', () => { // ストリーミング経由で反映されるまでちょっと待つ clock.uninstall(); - await sleep(100); + await setTimeout(100); const resultAfter25hAgain = await roleService.getUserPolicies(user.id); expect(resultAfter25hAgain.canManageCustomEmojis).toBe(true); @@ -807,7 +807,7 @@ describe('RoleService', () => { await roleService.assign(user.id, role.id); clock.uninstall(); - await sleep(100); + await setTimeout(100); const assignments = await roleAssignmentsRepository.find({ where: { @@ -835,7 +835,7 @@ describe('RoleService', () => { await roleService.assign(user.id, role.id); clock.uninstall(); - await sleep(100); + await setTimeout(100); const assignments = await roleAssignmentsRepository.find({ where: { diff --git a/packages/backend/test/unit/SystemWebhookService.ts b/packages/backend/test/unit/SystemWebhookService.ts index 41b7f977ca8a..790cd1490eb5 100644 --- a/packages/backend/test/unit/SystemWebhookService.ts +++ b/packages/backend/test/unit/SystemWebhookService.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { setTimeout } from 'node:timers/promises'; import { afterEach, beforeEach, describe, expect, jest } from '@jest/globals'; import { Test, TestingModule } from '@nestjs/testing'; import { MiUser } from '@/models/User.js'; @@ -16,7 +17,7 @@ import { DI } from '@/di-symbols.js'; import { QueueService } from '@/core/QueueService.js'; import { LoggerService } from '@/core/LoggerService.js'; import { SystemWebhookService } from '@/core/SystemWebhookService.js'; -import { randomString, sleep } from '../utils.js'; +import { randomString } from '../utils.js'; describe('SystemWebhookService', () => { let app: TestingModule; @@ -358,7 +359,7 @@ describe('SystemWebhookService', () => { ); // redisでの配信経由で更新されるのでちょっと待つ - await sleep(500); + await setTimeout(500); const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); expect(fetchedWebhooks).toEqual([webhook]); @@ -377,7 +378,7 @@ describe('SystemWebhookService', () => { ); // redisでの配信経由で更新されるのでちょっと待つ - await sleep(500); + await setTimeout(500); const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); expect(fetchedWebhooks).toEqual([]); @@ -407,7 +408,7 @@ describe('SystemWebhookService', () => { ); // redisでの配信経由で更新されるのでちょっと待つ - await sleep(500); + await setTimeout(500); const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); expect(fetchedWebhooks).toEqual([webhook2]); @@ -434,7 +435,7 @@ describe('SystemWebhookService', () => { ); // redisでの配信経由で更新されるのでちょっと待つ - await sleep(500); + await setTimeout(500); const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); expect(fetchedWebhooks.length).toEqual(0); @@ -457,7 +458,7 @@ describe('SystemWebhookService', () => { ); // redisでの配信経由で更新されるのでちょっと待つ - await sleep(500); + await setTimeout(500); const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); expect(fetchedWebhooks).toEqual([webhook2]); @@ -481,7 +482,7 @@ describe('SystemWebhookService', () => { ); // redisでの配信経由で更新されるのでちょっと待つ - await sleep(500); + await setTimeout(500); const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); expect(fetchedWebhooks.length).toEqual(0); @@ -504,7 +505,7 @@ describe('SystemWebhookService', () => { ); // redisでの配信経由で更新されるのでちょっと待つ - await sleep(500); + await setTimeout(500); const fetchedWebhooks = await service.fetchActiveSystemWebhooks(); expect(fetchedWebhooks.length).toEqual(0); diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts index bf14d05ecaec..06c3f826011e 100644 --- a/packages/backend/test/utils.ts +++ b/packages/backend/test/utils.ts @@ -605,14 +605,6 @@ export async function initTestDb(justBorrow = false, initEntities?: any[]) { return db; } -export function sleep(msec: number) { - return new Promise(res => { - setTimeout(() => { - res(); - }, msec); - }); -} - export async function sendEnvUpdateRequest(params: { key: string, value?: string }) { const res = await fetch( `http://localhost:${port + 1000}/env`, From 5d03efa1bb230bf1f22cf4a86a20157cd8aca7c4 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Wed, 3 Jul 2024 06:40:31 +0900 Subject: [PATCH 071/268] dev: fix pnpm dev is broken (#14123) * dev: pnpm dev is broken * dev: fix crash pnpm dev because of unhandled promise --- packages/backend/scripts/dev.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/backend/scripts/dev.mjs b/packages/backend/scripts/dev.mjs index 2d0de0f91666..a3e0558abd97 100644 --- a/packages/backend/scripts/dev.mjs +++ b/packages/backend/scripts/dev.mjs @@ -30,6 +30,7 @@ function execStart() { async function killProc() { if (backendProcess) { + backendProcess.catch(() => {}); // backendProcess.kill()によって発生する例外を無視するためにcatch()を呼び出す backendProcess.kill(); await new Promise(resolve => backendProcess.on('exit', resolve)); backendProcess = undefined; @@ -46,6 +47,7 @@ async function killProc() { ], { stdio: [process.stdin, process.stdout, process.stderr, 'ipc'], + serialization: "json", }) .on('message', async (message) => { if (message.type === 'exit') { From fab7d5e484d86dc8c24850dd98ebc1ee3688910e Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Thu, 4 Jul 2024 12:33:43 +0900 Subject: [PATCH 072/268] fix(storybook): build skipping even after updating impl story files (#14124) --- packages/frontend/.storybook/changes.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/frontend/.storybook/changes.ts b/packages/frontend/.storybook/changes.ts index 7c70972e1e3d..bc7601441c32 100644 --- a/packages/frontend/.storybook/changes.ts +++ b/packages/frontend/.storybook/changes.ts @@ -47,7 +47,6 @@ await fs.readFile( ) ) .map((path) => path.replace(/(?:(?<=\.stories)\.(?:impl|meta)|\.msw)(?=\.ts$)/g, '')) - .map((path) => (path.startsWith('.') ? path : `./${path}`)) ); if ( micromatch(Array.from(modules), [ From 6dd2e9fc0b1eeea6b5f04ccac93ccfab658f976d Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 4 Jul 2024 13:14:49 +0900 Subject: [PATCH 073/268] refactor(frontend): refactor popup api and make sure call dispose callback Close #14122 --- packages/frontend/src/account.ts | 16 ++- packages/frontend/src/boot/main-boot.ts | 30 +++-- .../frontend/src/components/MkClickerGame.vue | 4 +- .../src/components/MkDrive.folder.vue | 5 +- .../frontend/src/components/MkEmojiPicker.vue | 4 +- packages/frontend/src/components/MkLink.vue | 6 +- packages/frontend/src/components/MkNote.vue | 16 ++- .../src/components/MkNoteDetailed.vue | 16 ++- .../frontend/src/components/MkPostForm.vue | 13 +- .../src/components/MkPostFormAttaches.vue | 5 +- packages/frontend/src/components/MkRange.vue | 10 +- .../src/components/MkReactionIcon.vue | 6 +- .../components/MkReactionsViewer.reaction.vue | 14 +- packages/frontend/src/components/MkSignin.vue | 5 +- .../components/MkSystemWebhookEditor.impl.ts | 6 +- .../frontend/src/components/MkUrlPreview.vue | 8 +- .../src/components/MkUserSetupDialog.vue | 6 +- .../src/components/MkVisitorDashboard.vue | 12 +- .../src/components/global/MkCustomEmoji.vue | 4 +- .../frontend/src/components/global/MkUrl.vue | 6 +- packages/frontend/src/directives/ripple.ts | 4 +- packages/frontend/src/directives/tooltip.ts | 6 +- .../frontend/src/directives/user-preview.ts | 5 +- packages/frontend/src/os.ts | 125 ++++++++++-------- packages/frontend/src/pages/admin-user.vue | 12 +- .../abuse-report/notification-recipient.vue | 6 +- .../src/pages/custom-emojis-manager.vue | 10 +- .../frontend/src/pages/drive.file.info.vue | 5 +- .../src/pages/drop-and-fusion.game.vue | 14 +- packages/frontend/src/pages/emojis.emoji.vue | 8 +- .../frontend/src/pages/reset-password.vue | 4 +- packages/frontend/src/pages/settings/2fa.vue | 6 +- .../frontend/src/pages/settings/accounts.vue | 10 +- packages/frontend/src/pages/settings/api.vue | 5 +- .../src/pages/settings/avatar-decoration.vue | 5 +- .../src/scripts/get-drive-file-menu.ts | 5 +- .../frontend/src/scripts/get-note-menu.ts | 18 ++- .../frontend/src/scripts/get-user-menu.ts | 6 +- .../frontend/src/scripts/install-plugin.ts | 5 +- packages/frontend/src/scripts/please-login.ts | 5 +- .../frontend/src/scripts/use-chart-tooltip.ts | 10 +- packages/frontend/src/ui/_common_/common.ts | 4 +- .../src/ui/_common_/navbar-for-mobile.vue | 5 +- packages/frontend/src/ui/_common_/navbar.vue | 5 +- packages/frontend/src/ui/classic.header.vue | 5 +- packages/frontend/src/ui/classic.sidebar.vue | 6 +- .../src/ui/deck/notifications-column.vue | 5 +- packages/frontend/src/ui/visitor.vue | 12 +- .../src/widgets/WidgetNotifications.vue | 5 +- 49 files changed, 317 insertions(+), 196 deletions(-) diff --git a/packages/frontend/src/account.ts b/packages/frontend/src/account.ts index f99b550a8344..4172016f8984 100644 --- a/packages/frontend/src/account.ts +++ b/packages/frontend/src/account.ts @@ -184,10 +184,12 @@ export async function refreshAccount() { export async function login(token: Account['token'], redirect?: string) { const showing = ref(true); - popup(defineAsyncComponent(() => import('@/components/MkWaitingDialog.vue')), { + const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkWaitingDialog.vue')), { success: false, showing: showing, - }, {}, 'closed'); + }, { + closed: () => dispose(), + }); if (_DEV_) console.log('logging as token ', token); const me = await fetchAccount(token, undefined, true) .catch(reason => { @@ -223,21 +225,23 @@ export async function openAccountMenu(opts: { if (!$i) return; function showSigninDialog() { - popup(defineAsyncComponent(() => import('@/components/MkSigninDialog.vue')), {}, { + const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkSigninDialog.vue')), {}, { done: res => { addAccount(res.id, res.i); success(); }, - }, 'closed'); + closed: () => dispose(), + }); } function createAccount() { - popup(defineAsyncComponent(() => import('@/components/MkSignupDialog.vue')), {}, { + const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkSignupDialog.vue')), {}, { done: res => { addAccount(res.id, res.i); switchAccountWithToken(res.i); }, - }, 'closed'); + closed: () => dispose(), + }); } async function switchAccount(account: Misskey.entities.UserDetailed) { diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts index 5cb19f388aee..faf230a1a293 100644 --- a/packages/frontend/src/boot/main-boot.ts +++ b/packages/frontend/src/boot/main-boot.ts @@ -35,7 +35,9 @@ export async function mainBoot() { emojiPicker.init(); if (isClientUpdated && $i) { - popup(defineAsyncComponent(() => import('@/components/MkUpdated.vue')), {}, {}, 'closed'); + const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkUpdated.vue')), {}, { + closed: () => dispose(), + }); } const stream = useStream(); @@ -96,7 +98,7 @@ export async function mainBoot() { }).render(); } } - } + } } catch (error) { // console.error(error); console.error('Failed to initialise the seasonal screen effect canvas context:', error); @@ -108,22 +110,28 @@ export async function mainBoot() { defaultStore.loaded.then(() => { if (defaultStore.state.accountSetupWizard !== -1) { - popup(defineAsyncComponent(() => import('@/components/MkUserSetupDialog.vue')), {}, {}, 'closed'); + const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkUserSetupDialog.vue')), {}, { + closed: () => dispose(), + }); } }); for (const announcement of ($i.unreadAnnouncements ?? []).filter(x => x.display === 'dialog')) { - popup(defineAsyncComponent(() => import('@/components/MkAnnouncementDialog.vue')), { + const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkAnnouncementDialog.vue')), { announcement, - }, {}, 'closed'); + }, { + closed: () => dispose(), + }); } stream.on('announcementCreated', (ev) => { const announcement = ev.announcement; if (announcement.display === 'dialog') { - popup(defineAsyncComponent(() => import('@/components/MkAnnouncementDialog.vue')), { + const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkAnnouncementDialog.vue')), { announcement, - }, {}, 'closed'); + }, { + closed: () => dispose(), + }); } }); @@ -247,13 +255,17 @@ export async function mainBoot() { const neverShowDonationInfo = miLocalStorage.getItem('neverShowDonationInfo'); if (neverShowDonationInfo !== 'true' && (createdAt.getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 3))) && !location.pathname.startsWith('/miauth')) { if (latestDonationInfoShownAt == null || (new Date(latestDonationInfoShownAt).getTime() < (Date.now() - (1000 * 60 * 60 * 24 * 30)))) { - popup(defineAsyncComponent(() => import('@/components/MkDonation.vue')), {}, {}, 'closed'); + const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkDonation.vue')), {}, { + closed: () => dispose(), + }); } } const modifiedVersionMustProminentlyOfferInAgplV3Section13Read = miLocalStorage.getItem('modifiedVersionMustProminentlyOfferInAgplV3Section13Read'); if (modifiedVersionMustProminentlyOfferInAgplV3Section13Read !== 'true' && instance.repositoryUrl !== 'https://github.com/misskey-dev/misskey') { - popup(defineAsyncComponent(() => import('@/components/MkSourceCodeAvailablePopup.vue')), {}, {}, 'closed'); + const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkSourceCodeAvailablePopup.vue')), {}, { + closed: () => dispose(), + }); } if ('Notification' in window) { diff --git a/packages/frontend/src/components/MkClickerGame.vue b/packages/frontend/src/components/MkClickerGame.vue index b592609e18bb..00506fb73513 100644 --- a/packages/frontend/src/components/MkClickerGame.vue +++ b/packages/frontend/src/components/MkClickerGame.vue @@ -35,7 +35,9 @@ const prevCookies = ref(0); function onClick(ev: MouseEvent) { const x = ev.clientX; const y = ev.clientY; - os.popup(MkPlusOneEffect, { x, y }, {}, 'end'); + const { dispose } = os.popup(MkPlusOneEffect, { x, y }, { + end: () => dispose(), + }); saveData.value!.cookies++; saveData.value!.totalCookies++; diff --git a/packages/frontend/src/components/MkDrive.folder.vue b/packages/frontend/src/components/MkDrive.folder.vue index 8da0d78f355f..1cc8b15b73fa 100644 --- a/packages/frontend/src/components/MkDrive.folder.vue +++ b/packages/frontend/src/components/MkDrive.folder.vue @@ -257,10 +257,11 @@ function onContextmenu(ev: MouseEvent) { text: i18n.ts.openInWindow, icon: 'ti ti-app-window', action: () => { - os.popup(defineAsyncComponent(() => import('@/components/MkDriveWindow.vue')), { + const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkDriveWindow.vue')), { initialFolder: props.folder, }, { - }, 'closed'); + closed: () => dispose(), + }); }, }, { type: 'divider' }, { text: i18n.ts.rename, diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue index 8a6bef54d83f..4bd4bee1e57c 100644 --- a/packages/frontend/src/components/MkEmojiPicker.vue +++ b/packages/frontend/src/components/MkEmojiPicker.vue @@ -402,7 +402,9 @@ function chosen(emoji: any, ev?: MouseEvent) { const rect = el.getBoundingClientRect(); const x = rect.left + (el.offsetWidth / 2); const y = rect.top + (el.offsetHeight / 2); - os.popup(MkRippleEffect, { x, y }, {}, 'end'); + const { dispose } = os.popup(MkRippleEffect, { x, y }, { + end: () => dispose(), + }); } const key = getKey(emoji); diff --git a/packages/frontend/src/components/MkLink.vue b/packages/frontend/src/components/MkLink.vue index 5d54a58e97d9..e842ec2d6ede 100644 --- a/packages/frontend/src/components/MkLink.vue +++ b/packages/frontend/src/components/MkLink.vue @@ -37,11 +37,13 @@ const el = ref(); if (isEnabledUrlPreview.value) { useTooltip(el, (showing) => { - os.popup(defineAsyncComponent(() => import('@/components/MkUrlPreviewPopup.vue')), { + const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkUrlPreviewPopup.vue')), { showing, url: props.url, source: el.value instanceof HTMLElement ? el.value : el.value?.$el, - }, {}, 'closed'); + }, { + closed: () => dispose(), + }); }); } diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 22b1691a8664..1313e4c58e5e 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -335,12 +335,14 @@ if (!props.mock) { if (users.length < 1) return; - os.popup(MkUsersTooltip, { + const { dispose } = os.popup(MkUsersTooltip, { showing, users, count: appearNote.value.renoteCount, targetElement: renoteButton.value, - }, {}, 'closed'); + }, { + closed: () => dispose(), + }); }); if (appearNote.value.reactionAcceptance === 'likeOnly') { @@ -355,13 +357,15 @@ if (!props.mock) { if (users.length < 1) return; - os.popup(MkReactionsViewerDetails, { + const { dispose } = os.popup(MkReactionsViewerDetails, { showing, reaction: '❤️', users, count: appearNote.value.reactionCount, targetElement: reactButton.value!, - }, {}, 'closed'); + }, { + closed: () => dispose(), + }); }); } } @@ -409,7 +413,9 @@ function react(viaKeyboard = false): void { const rect = el.getBoundingClientRect(); const x = rect.left + (el.offsetWidth / 2); const y = rect.top + (el.offsetHeight / 2); - os.popup(MkRippleEffect, { x, y }, {}, 'end'); + const { dispose } = os.popup(MkRippleEffect, { x, y }, { + end: () => dispose(), + }); } } else { blur(); diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index ed1c0a9e9693..bc1f41637386 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -346,12 +346,14 @@ useTooltip(renoteButton, async (showing) => { if (users.length < 1) return; - os.popup(MkUsersTooltip, { + const { dispose } = os.popup(MkUsersTooltip, { showing, users, count: appearNote.value.renoteCount, targetElement: renoteButton.value, - }, {}, 'closed'); + }, { + closed: () => dispose(), + }); }); if (appearNote.value.reactionAcceptance === 'likeOnly') { @@ -366,13 +368,15 @@ if (appearNote.value.reactionAcceptance === 'likeOnly') { if (users.length < 1) return; - os.popup(MkReactionsViewerDetails, { + const { dispose } = os.popup(MkReactionsViewerDetails, { showing, reaction: '❤️', users, count: appearNote.value.reactionCount, targetElement: reactButton.value!, - }, {}, 'closed'); + }, { + closed: () => dispose(), + }); }); } @@ -413,7 +417,9 @@ function react(viaKeyboard = false): void { const rect = el.getBoundingClientRect(); const x = rect.left + (el.offsetWidth / 2); const y = rect.top + (el.offsetHeight / 2); - os.popup(MkRippleEffect, { x, y }, {}, 'end'); + const { dispose } = os.popup(MkRippleEffect, { x, y }, { + end: () => dispose(), + }); } } else { blur(); diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index 1df90076818e..0dc1aa08915f 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -463,7 +463,7 @@ function setVisibility() { return; } - os.popup(defineAsyncComponent(() => import('@/components/MkVisibilityPicker.vue')), { + const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkVisibilityPicker.vue')), { currentVisibility: visibility.value, isSilenced: $i.isSilenced, localOnly: localOnly.value, @@ -476,7 +476,8 @@ function setVisibility() { defaultStore.set('visibility', visibility.value); } }, - }, 'closed'); + closed: () => dispose(), + }); } async function toggleLocalOnly() { @@ -624,8 +625,8 @@ async function onPaste(ev: ClipboardEvent) { return; } - const fileName = formatTimeString(new Date(), defaultStore.state.pastedFileName).replace(/{{number}}/g, "0"); - const file = new File([paste], `${fileName}.txt`, { type: "text/plain" }); + const fileName = formatTimeString(new Date(), defaultStore.state.pastedFileName).replace(/{{number}}/g, '0'); + const file = new File([paste], `${fileName}.txt`, { type: 'text/plain' }); upload(file, `${fileName}.txt`); }); } @@ -731,7 +732,9 @@ async function post(ev?: MouseEvent) { const rect = el.getBoundingClientRect(); const x = rect.left + (el.offsetWidth / 2); const y = rect.top + (el.offsetHeight / 2); - os.popup(MkRippleEffect, { x, y }, {}, 'end'); + const { dispose } = os.popup(MkRippleEffect, { x, y }, { + end: () => dispose(), + }); } } diff --git a/packages/frontend/src/components/MkPostFormAttaches.vue b/packages/frontend/src/components/MkPostFormAttaches.vue index 95eb36731827..8854babb6bf0 100644 --- a/packages/frontend/src/components/MkPostFormAttaches.vue +++ b/packages/frontend/src/components/MkPostFormAttaches.vue @@ -108,7 +108,7 @@ async function rename(file) { async function describe(file) { if (mock) return; - os.popup(defineAsyncComponent(() => import('@/components/MkFileCaptionEditWindow.vue')), { + const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkFileCaptionEditWindow.vue')), { default: file.comment !== null ? file.comment : '', file: file, }, { @@ -121,7 +121,8 @@ async function describe(file) { file.comment = comment; }); }, - }, 'closed'); + closed: () => dispose(), + }); } async function crop(file: Misskey.entities.DriveFile): Promise { diff --git a/packages/frontend/src/components/MkRange.vue b/packages/frontend/src/components/MkRange.vue index 15f8128e98bf..1eae6429378e 100644 --- a/packages/frontend/src/components/MkRange.vue +++ b/packages/frontend/src/components/MkRange.vue @@ -101,17 +101,19 @@ const steps = computed(() => { } }); -const onMousedown = (ev: MouseEvent | TouchEvent) => { +function onMousedown(ev: MouseEvent | TouchEvent) { ev.preventDefault(); const tooltipShowing = ref(true); - os.popup(defineAsyncComponent(() => import('@/components/MkTooltip.vue')), { + const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkTooltip.vue')), { showing: tooltipShowing, text: computed(() => { return props.textConverter(finalValue.value); }), targetElement: thumbEl, - }, {}, 'closed'); + }, { + closed: () => dispose(), + }); const style = document.createElement('style'); style.appendChild(document.createTextNode('* { cursor: grabbing !important; } body * { pointer-events: none !important; }')); @@ -152,7 +154,7 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => { window.addEventListener('touchmove', onDrag); window.addEventListener('mouseup', onMouseup, { once: true }); window.addEventListener('touchend', onMouseup, { once: true }); -}; +} + + + + + + diff --git a/packages/backend/assets/redoc.html b/packages/backend/assets/redoc.html deleted file mode 100644 index 2557b4532ec3..000000000000 --- a/packages/backend/assets/redoc.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - Misskey API - - - - - - - - - - - - - diff --git a/packages/backend/src/server/api/openapi/OpenApiServerService.ts b/packages/backend/src/server/api/openapi/OpenApiServerService.ts index 5210e4d2bc3c..f124aa9f39e8 100644 --- a/packages/backend/src/server/api/openapi/OpenApiServerService.ts +++ b/packages/backend/src/server/api/openapi/OpenApiServerService.ts @@ -25,7 +25,7 @@ export class OpenApiServerService { public createServer(fastify: FastifyInstance, _options: FastifyPluginOptions, done: (err?: Error) => void) { fastify.get('/api-doc', async (_request, reply) => { reply.header('Cache-Control', 'public, max-age=86400'); - return await reply.sendFile('/redoc.html', staticAssets); + return await reply.sendFile('/api-doc.html', staticAssets); }); fastify.get('/api.json', (_request, reply) => { reply.header('Cache-Control', 'public, max-age=600'); diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts index 2a14270a2497..efa47a698624 100644 --- a/packages/backend/src/server/api/openapi/gen-spec.ts +++ b/packages/backend/src/server/api/openapi/gen-spec.ts @@ -15,7 +15,6 @@ export function genOpenapiSpec(config: Config, includeSelfRef = false) { info: { version: config.version, title: 'Misskey API', - 'x-logo': { url: '/static-assets/api-doc.png' }, }, externalDocs: { From 02e0a86b12473265c2fc0f219349d2c662f89f0f 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, 10 Jul 2024 01:00:40 +0900 Subject: [PATCH 085/268] fix(frontend): remove unused statement fix #14162 --- packages/frontend/src/components/MkNote.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 5f1820a37935..fc728132851c 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -318,7 +318,7 @@ const keymap = { }, 'o': () => { if (renoteCollapsed.value) return; - galleryEl.value?.openGallery(); + showMenu(); }, 'v|enter': () => { if (renoteCollapsed.value) { From 52d8a54fc72b886fecb30a736b3ccf5057ea2a0c Mon Sep 17 00:00:00 2001 From: Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> Date: Wed, 10 Jul 2024 20:40:04 +0900 Subject: [PATCH 086/268] =?UTF-8?q?feat(misskey-js):=20`POST=20admin/roles?= =?UTF-8?q?/create`=E3=81=AE=E5=9E=8B=E3=82=92=E5=85=B7=E8=B1=A1=E5=8C=96?= =?UTF-8?q?=20(#14167)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(misskey-js): `POST admin/roles/create`の型を具象化 * fix * docs: CHANGELOG.md * test(misskey-js): admin/roles/createの型が合うことを表明 * test(misskey-js): single quote * test(misskey-js): 無を読もうとして爆発するのを修正 * test(misskey-js): fix comment --- CHANGELOG.md | 1 + packages/misskey-js/etc/misskey-js.api.md | 18 ++++++++++- packages/misskey-js/src/api.types.ts | 7 ++++- packages/misskey-js/src/entities.ts | 15 ++++++++- packages/misskey-js/test/api.ts | 38 +++++++++++++++++++++++ 5 files changed, 76 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b99a2cbc53bb..aec4e1868c25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ ### Misskey.js - Feat: `/drive/files/create` のリクエストに対応(`multipart/form-data`に対応) +- Feat: `/admin/role/create` のロールポリシーの型を修正 ## 2024.5.0 diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index be2f510ac279..d11d2a4f0617 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -1160,6 +1160,12 @@ export type Endpoints = Overwrite; + res: AdminRolesCreateResponse; + }; }>; // @public (undocumented) @@ -1185,6 +1191,7 @@ declare namespace entities { SignupPendingResponse, SigninRequest, SigninResponse, + PartialRolePolicyOverride, EmptyRequest, EmptyResponse, AdminMetaResponse, @@ -2725,6 +2732,15 @@ type PagesUpdateRequest = operations['pages___update']['requestBody']['content'] // @public (undocumented) function parse(acct: string): Acct; +// Warning: (ae-forgotten-export) The symbol "Values" needs to be exported by the entry point index.d.ts +// +// @public (undocumented) +type PartialRolePolicyOverride = Partial<{ + [k in keyof RolePolicies]: Omit, 'value'> & { + value: RolePolicies[k]; + }; +}>; + // @public (undocumented) export const permissions: readonly ["read:account", "write:account", "read:blocks", "write:blocks", "read:drive", "write:drive", "read:favorites", "write:favorites", "read:following", "write:following", "read:messaging", "write:messaging", "read:mutes", "write:mutes", "write:notes", "read:notifications", "write:notifications", "read:reactions", "write:reactions", "write:votes", "read:pages", "write:pages", "write:page-likes", "read:page-likes", "read:user-groups", "write:user-groups", "read:channels", "write:channels", "read:gallery", "write:gallery", "read:gallery-likes", "write:gallery-likes", "read:flash", "write:flash", "read:flash-likes", "write:flash-likes", "read:admin:abuse-user-reports", "write:admin:delete-account", "write:admin:delete-all-files-of-a-user", "read:admin:index-stats", "read:admin:table-stats", "read:admin:user-ips", "read:admin:meta", "write:admin:reset-password", "write:admin:resolve-abuse-user-report", "write:admin:send-email", "read:admin:server-info", "read:admin:show-moderation-log", "read:admin:show-user", "write:admin:suspend-user", "write:admin:unset-user-avatar", "write:admin:unset-user-banner", "write:admin:unsuspend-user", "write:admin:meta", "write:admin:user-note", "write:admin:roles", "read:admin:roles", "write:admin:relays", "read:admin:relays", "write:admin:invite-codes", "read:admin:invite-codes", "write:admin:announcements", "read:admin:announcements", "write:admin:avatar-decorations", "read:admin:avatar-decorations", "write:admin:federation", "write:admin:account", "read:admin:account", "write:admin:emoji", "read:admin:emoji", "write:admin:queue", "read:admin:queue", "write:admin:promo", "write:admin:drive", "read:admin:drive", "write:admin:ad", "read:admin:ad", "write:invite-codes", "read:invite-codes", "write:clip-favorite", "read:clip-favorite", "read:federation", "write:report-abuse"]; @@ -3213,7 +3229,7 @@ type UsersUpdateMemoRequest = operations['users___update-memo']['requestBody'][' // Warnings were encountered during analysis: // -// src/entities.ts:25:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts +// src/entities.ts:34:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/packages/misskey-js/src/api.types.ts b/packages/misskey-js/src/api.types.ts index af0bade5b3b4..8c403639b788 100644 --- a/packages/misskey-js/src/api.types.ts +++ b/packages/misskey-js/src/api.types.ts @@ -1,7 +1,8 @@ import { Endpoints as Gen } from './autogen/endpoint.js'; import { UserDetailed } from './autogen/models.js'; -import { UsersShowRequest } from './autogen/entities.js'; +import { AdminRolesCreateRequest, AdminRolesCreateResponse, UsersShowRequest } from './autogen/entities.js'; import { + PartialRolePolicyOverride, SigninRequest, SigninResponse, SignupPendingRequest, @@ -79,5 +80,9 @@ export type Endpoints = Overwrite< req: SigninRequest; res: SigninResponse; }, + 'admin/roles/create': { + req: Overwrite; + res: AdminRolesCreateResponse; + } } > diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts index 7a84cb6a1a63..7331a55a1cac 100644 --- a/packages/misskey-js/src/entities.ts +++ b/packages/misskey-js/src/entities.ts @@ -1,5 +1,14 @@ import { ModerationLogPayloads } from './consts.js'; -import { Announcement, EmojiDetailed, MeDetailed, Page, User, UserDetailedNotMe } from './autogen/models.js'; +import { + Announcement, + EmojiDetailed, + MeDetailed, + Page, + Role, + RolePolicies, + User, + UserDetailedNotMe +} from './autogen/models.js'; export * from './autogen/entities.js'; export * from './autogen/models.js'; @@ -236,3 +245,7 @@ export type SigninResponse = { id: User['id'], i: string, }; + +type Values> = T[keyof T]; + +export type PartialRolePolicyOverride = Partial<{[k in keyof RolePolicies]: Omit, 'value'> & { value: RolePolicies[k] }}>; diff --git a/packages/misskey-js/test/api.ts b/packages/misskey-js/test/api.ts index 95f1946fa27b..1a7574de25e7 100644 --- a/packages/misskey-js/test/api.ts +++ b/packages/misskey-js/test/api.ts @@ -259,4 +259,42 @@ describe('API', () => { expect(isAPIError(e)).toEqual(false); } }); + + test('admin/roles/create の型が合う', async() => { + fetchMock.resetMocks(); + fetchMock.mockResponse(async () => { + return { + // 本来返すべき値は`Role`型だが、テストなのでお茶を濁す + status: 200, + body: '{}' + }; + }); + + const cli = new APIClient({ + origin: 'https://misskey.test', + credential: 'TOKEN', + }); + await cli.request('admin/roles/create', { + name: 'aaa', + asBadge: false, + canEditMembersByModerator: false, + color: '#123456', + condFormula: {}, + description: '', + displayOrder: 0, + iconUrl: '', + isAdministrator: false, + isExplorable: false, + isModerator: false, + isPublic: false, + policies: { + ltlAvailable: { + value: true, + priority: 0, + useDefault: false, + }, + }, + target: 'manual', + }); + }) }); From 679318541afb789842db5f2cbf918b8acf284f1d Mon Sep 17 00:00:00 2001 From: woxtu Date: Thu, 11 Jul 2024 16:29:18 +0900 Subject: [PATCH 087/268] Improve background color specification (#14176) --- packages/frontend/src/pages/settings/drive-cleaner.vue | 6 +++--- packages/frontend/src/pages/settings/drive.vue | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/frontend/src/pages/settings/drive-cleaner.vue b/packages/frontend/src/pages/settings/drive-cleaner.vue index b20774c4ec50..8d2946db63f9 100644 --- a/packages/frontend/src/pages/settings/drive-cleaner.vue +++ b/packages/frontend/src/pages/settings/drive-cleaner.vue @@ -48,7 +48,7 @@ SPDX-License-Identifier: AGPL-3.0-only + + diff --git a/packages/frontend/src/pages/welcome.timeline.vue b/packages/frontend/src/pages/welcome.timeline.vue index 139b2e0a07d4..db326f9e6cf4 100644 --- a/packages/frontend/src/pages/welcome.timeline.vue +++ b/packages/frontend/src/pages/welcome.timeline.vue @@ -4,24 +4,17 @@ SPDX-License-Identifier: AGPL-3.0-only --> @@ -29,43 +22,54 @@ SPDX-License-Identifier: AGPL-3.0-only From 121af778a0925d5850e9d88261e9a8e8c6fd968b 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: Thu, 11 Jul 2024 18:44:18 +0900 Subject: [PATCH 090/268] =?UTF-8?q?enhance(frontend):=20=E6=9C=AA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=AE=E3=82=B5=E3=82=A6=E3=83=B3=E3=83=89=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A=E3=82=92=E5=89=8A=E9=99=A4=20(#14116)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance(frontend): 未使用のサウンド設定を削除 * Update Changelog * Update CHANGELOG.md --- CHANGELOG.md | 3 +++ locales/index.d.ts | 8 -------- locales/ja-JP.yml | 2 -- .../frontend/src/pages/settings/preferences-backups.vue | 2 -- packages/frontend/src/pages/settings/sounds.vue | 2 -- packages/frontend/src/scripts/sound.ts | 2 -- packages/frontend/src/store.ts | 8 -------- 7 files changed, 3 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 259420a6c608..cd123c938e18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## Unreleased +### Note +- デッキUIの新着ノートをサウンドで通知する機能の追加(v2024.5.0)に伴い、以前から動作しなくなっていたクライアント設定内の「アンテナ受信」「チャンネル通知」サウンドを削除しました。 + ### General - Feat: 通報を受けた際、または解決した際に、予め登録した宛先に通知を飛ばせるように(mail or webhook) #13705 - Fix: 配信停止したインスタンス一覧が見れなくなる問題を修正 diff --git a/locales/index.d.ts b/locales/index.d.ts index ebd980ed8555..5089f7802e82 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -7515,14 +7515,6 @@ export interface Locale extends ILocale { * 通知 */ "notification": string; - /** - * アンテナ受信 - */ - "antenna": string; - /** - * チャンネル通知 - */ - "channel": string; /** * リアクション選択時 */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 0d89d33abeec..a03d7921401d 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1971,8 +1971,6 @@ _sfx: note: "ノート" noteMy: "ノート(自分)" notification: "通知" - antenna: "アンテナ受信" - channel: "チャンネル通知" reaction: "リアクション選択時" _soundSettings: diff --git a/packages/frontend/src/pages/settings/preferences-backups.vue b/packages/frontend/src/pages/settings/preferences-backups.vue index b6f1043154d3..dace2cd84758 100644 --- a/packages/frontend/src/pages/settings/preferences-backups.vue +++ b/packages/frontend/src/pages/settings/preferences-backups.vue @@ -113,8 +113,6 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [ 'sound_note', 'sound_noteMy', 'sound_notification', - 'sound_antenna', - 'sound_channel', ]; const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [ 'lightTheme', diff --git a/packages/frontend/src/pages/settings/sounds.vue b/packages/frontend/src/pages/settings/sounds.vue index 090f0cf14c41..0f1b725fae39 100644 --- a/packages/frontend/src/pages/settings/sounds.vue +++ b/packages/frontend/src/pages/settings/sounds.vue @@ -54,8 +54,6 @@ const sounds = ref>>({ note: defaultStore.reactiveState.sound_note, noteMy: defaultStore.reactiveState.sound_noteMy, notification: defaultStore.reactiveState.sound_notification, - antenna: defaultStore.reactiveState.sound_antenna, - channel: defaultStore.reactiveState.sound_channel, reaction: defaultStore.reactiveState.sound_reaction, }); diff --git a/packages/frontend/src/scripts/sound.ts b/packages/frontend/src/scripts/sound.ts index fcd59510df18..bba855cd6437 100644 --- a/packages/frontend/src/scripts/sound.ts +++ b/packages/frontend/src/scripts/sound.ts @@ -74,8 +74,6 @@ export const soundsTypes = [ export const operationTypes = [ 'noteMy', 'note', - 'antenna', - 'channel', 'notification', 'reaction', ] as const; diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index e8eb5a1ed7db..9cb274206955 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -479,14 +479,6 @@ export const defaultStore = markRaw(new Storage('base', { where: 'device', default: { type: 'syuilo/n-ea', volume: 1 } as SoundStore, }, - sound_antenna: { - where: 'device', - default: { type: 'syuilo/triple', volume: 1 } as SoundStore, - }, - sound_channel: { - where: 'device', - default: { type: 'syuilo/square-pico', volume: 1 } as SoundStore, - }, sound_reaction: { where: 'device', default: { type: 'syuilo/bubble2', volume: 1 } as SoundStore, From 385969e9f56a39a1e5547b94901d155e1e811263 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: Fri, 12 Jul 2024 16:25:44 +0900 Subject: [PATCH 091/268] =?UTF-8?q?fix(frontend):=20=E3=83=95=E3=82=A9?= =?UTF-8?q?=E3=83=BC=E3=82=AB=E3=82=B9=E3=81=AE=E6=8C=99=E5=8B=95=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20(#14158)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(frontend): 直前のパターンを記録するように * fix(frontend): フォーカス/タブ移動に関する挙動を調整 (#226) Cherry-pick commit e8c030673326871edf3623cf2b8675d68f9e1b13 Co-authored-by: taiyme <53635909+taiyme@users.noreply.github.com> * focusのデザイン修正 * move scripts * Modalにfocus trapを追加 * 記録するホットキーはレートリミット式にする * escキーのハンドリングをMkModalに統一 * fix * enterで子メニューを開けるように * lint * fix focus trap * improve switch accessibility * 一部のmodalのフォーカストラップが外れない問題を修正 * fix * fix * Revert "記録するホットキーはレートリミット式にする" This reverts commit 40a7509286a87911ad4cc06d9482e8a2e5d0e7e8. * Revert "fix(frontend): 直前のパターンを記録するように" This reverts commit 5372b2594023952cff34aa62253ed4efef15b5dd. * Revert "Revert "fix(frontend): 直前のパターンを記録するように"" This reverts commit a9bb52e799e110927ad92cd8f26af980819334e1. * Revert "Revert "記録するホットキーはレートリミット式にする"" This reverts commit bdac34273e0bc5f13604c7e2f9fa6b1321a0df3d. * 試験的にCypressでのFocustrapを無効化 * fix * fix focus-trap * Update Changelog * :v: * fix focustrap invocation logic * スクロールがsticky headerを考慮するように * :art: * スタイルの微調整 * :art: * remove deprecated key aliases * focusElementが足りなかったので修正 * preview系にfocus時スタイルが足りなかったので修正 * `returnFocusElement` -> `returnFocusTo` * lint * Update packages/frontend/src/components/MkModalWindow.vue * Apply suggestions from code review Co-authored-by: taiy <53635909+taiyme@users.noreply.github.com> * keydownイベントをまとめる * use correct pesudo-element selector * fix * rename --------- Co-authored-by: taiyme <53635909+taiyme@users.noreply.github.com> Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> --- CHANGELOG.md | 2 + .../src/components/MkAchievements.vue | 4 +- packages/frontend/src/components/MkButton.vue | 1 - .../src/components/MkChannelFollowButton.vue | 12 +- .../src/components/MkChannelPreview.vue | 19 +- .../frontend/src/components/MkClipPreview.vue | 8 + .../frontend/src/components/MkContextMenu.vue | 2 +- .../frontend/src/components/MkCwButton.vue | 4 +- packages/frontend/src/components/MkDialog.vue | 16 +- .../frontend/src/components/MkDrive.file.vue | 32 +- .../src/components/MkDrive.folder.vue | 2 +- .../frontend/src/components/MkEmojiPicker.vue | 33 +- .../src/components/MkEmojiPickerDialog.vue | 2 + .../src/components/MkFlashPreview.vue | 6 +- packages/frontend/src/components/MkFolder.vue | 16 +- .../src/components/MkFollowButton.vue | 12 +- .../src/components/MkGalleryPostPreview.vue | 4 +- .../src/components/MkImgWithBlurhash.vue | 4 +- .../frontend/src/components/MkLaunchPad.vue | 2 +- .../frontend/src/components/MkMediaAudio.vue | 26 +- .../frontend/src/components/MkMediaList.vue | 54 ++- .../frontend/src/components/MkMediaVideo.vue | 10 +- .../frontend/src/components/MkMenu.child.vue | 5 +- packages/frontend/src/components/MkMenu.vue | 345 +++++++++++------- packages/frontend/src/components/MkModal.vue | 28 +- .../frontend/src/components/MkModalWindow.vue | 13 +- packages/frontend/src/components/MkNote.vue | 48 ++- .../src/components/MkNoteDetailed.vue | 62 ++-- .../frontend/src/components/MkNotePreview.vue | 2 +- .../src/components/MkNotification.vue | 2 +- .../frontend/src/components/MkPagePreview.vue | 19 +- .../frontend/src/components/MkPopupMenu.vue | 6 +- .../frontend/src/components/MkPostForm.vue | 10 + .../src/components/MkPostFormDialog.vue | 2 +- packages/frontend/src/components/MkRadio.vue | 10 +- packages/frontend/src/components/MkSelect.vue | 27 +- .../frontend/src/components/MkSuperMenu.vue | 10 +- packages/frontend/src/components/MkSwitch.vue | 10 +- .../components/MkTutorialDialog.PostNote.vue | 2 +- .../components/MkTutorialDialog.Sensitive.vue | 2 +- .../components/MkTutorialDialog.Timeline.vue | 2 +- .../src/components/MkVisibilityPicker.vue | 2 +- .../components/global/MkStickyContainer.vue | 6 +- packages/frontend/src/directives/hotkey.ts | 4 +- packages/frontend/src/os.ts | 27 +- .../frontend/src/pages/drive.file.info.vue | 1 + packages/frontend/src/pages/games.vue | 11 +- packages/frontend/src/pages/page.vue | 1 + .../frontend/src/pages/settings/profile.vue | 1 + .../frontend/src/pages/settings/theme.vue | 6 + packages/frontend/src/scripts/focus-trap.ts | 65 ++++ packages/frontend/src/scripts/focus.ts | 96 +++-- .../src/scripts/get-dom-node-or-null.ts | 19 + packages/frontend/src/scripts/hotkey.ts | 51 ++- packages/frontend/src/scripts/scroll.ts | 8 + packages/frontend/src/style.scss | 25 +- packages/frontend/src/ui/_common_/common.vue | 2 +- .../src/ui/_common_/navbar-for-mobile.vue | 6 +- packages/frontend/src/ui/_common_/navbar.vue | 86 ++++- packages/frontend/src/ui/deck/column.vue | 4 +- .../frontend/src/widgets/WidgetCalendar.vue | 2 +- 61 files changed, 920 insertions(+), 379 deletions(-) create mode 100644 packages/frontend/src/scripts/focus-trap.ts create mode 100644 packages/frontend/src/scripts/get-dom-node-or-null.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index cd123c938e18..c6f48684b904 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ ### Client - Enhance: 内蔵APIドキュメントのデザイン・パフォーマンスを改善 - Enhance: 非ログイン時のハイライトTLのデザインを改善 +- Enhance: フロントエンドのアクセシビリティ改善 + (Based on https://github.com/taiyme/misskey/pull/226) - Fix: `/about#federation` ページなどで各インスタンスのチャートが表示されなくなっていた問題を修正 - Fix: ユーザーページの追加情報のラベルを投稿者のサーバーの絵文字で表示する (#13968) - Fix: リバーシの対局を正しく共有できないことがある問題を修正 diff --git a/packages/frontend/src/components/MkAchievements.vue b/packages/frontend/src/components/MkAchievements.vue index 5d103fa789af..c8134416b506 100644 --- a/packages/frontend/src/components/MkAchievements.vue +++ b/packages/frontend/src/components/MkAchievements.vue @@ -153,7 +153,7 @@ onMounted(() => { background: linear-gradient(0deg, #ffee20, #eb7018); } - &:before { + &::before { content: ""; display: block; position: absolute; @@ -173,7 +173,7 @@ onMounted(() => { background: linear-gradient(0deg, #e1e1e1, #7c7c7c); } - &:before { + &::before { content: ""; display: block; position: absolute; diff --git a/packages/frontend/src/components/MkButton.vue b/packages/frontend/src/components/MkButton.vue index 25b003ba5a59..9560efb7d95f 100644 --- a/packages/frontend/src/components/MkButton.vue +++ b/packages/frontend/src/components/MkButton.vue @@ -250,7 +250,6 @@ function onMousedown(evt: MouseEvent): void { } &:focus-visible { - outline: solid 2px var(--focus); outline-offset: 2px; } diff --git a/packages/frontend/src/components/MkChannelFollowButton.vue b/packages/frontend/src/components/MkChannelFollowButton.vue index 841d37a56847..35dc3ad4bf83 100644 --- a/packages/frontend/src/components/MkChannelFollowButton.vue +++ b/packages/frontend/src/components/MkChannelFollowButton.vue @@ -87,17 +87,7 @@ async function onClick() { } &:focus-visible { - &:after { - content: ""; - pointer-events: none; - position: absolute; - top: -5px; - right: -5px; - bottom: -5px; - left: -5px; - border: 2px solid var(--focus); - border-radius: 32px; - } + outline-offset: 2px; } &:hover { diff --git a/packages/frontend/src/components/MkChannelPreview.vue b/packages/frontend/src/components/MkChannelPreview.vue index 4ff64dc4baff..c30cb66c078c 100644 --- a/packages/frontend/src/components/MkChannelPreview.vue +++ b/packages/frontend/src/components/MkChannelPreview.vue @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only diff --git a/packages/frontend/src/components/MkDialog.vue b/packages/frontend/src/components/MkDialog.vue index 5c3c6aa51dd2..16cf5b1b75c6 100644 --- a/packages/frontend/src/components/MkDialog.vue +++ b/packages/frontend/src/components/MkDialog.vue @@ -36,7 +36,12 @@ SPDX-License-Identifier: AGPL-3.0-only

@@ -67,11 +72,16 @@ type Input = { maxLength?: number; }; +type SelectItem = { + value: any; + text: string; +}; + type Select = { - items: { - value: any; - text: string; - }[]; + items: (SelectItem | { + sectionTitle: string; + items: SelectItem[]; + })[]; default: string | null; }; diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts index 3085f33e215f..a8dd99c85484 100644 --- a/packages/frontend/src/os.ts +++ b/packages/frontend/src/os.ts @@ -447,15 +447,20 @@ export function authenticateDialog(): Promise<{ }); } +type SelectItem = { + value: C; + text: string; +}; + // default が指定されていたら result は null になり得ないことを保証する overload function export function select(props: { title?: string; text?: string; default: string; - items: { - value: C; - text: string; - }[]; + items: (SelectItem | { + sectionTitle: string; + items: SelectItem[]; + } | undefined)[]; }): Promise<{ canceled: true; result: undefined; } | { @@ -465,10 +470,10 @@ export function select(props: { title?: string; text?: string; default?: string | null; - items: { - value: C; - text: string; - }[]; + items: (SelectItem | { + sectionTitle: string; + items: SelectItem[]; + } | undefined)[]; }): Promise<{ canceled: true; result: undefined; } | { @@ -478,10 +483,10 @@ export function select(props: { title?: string; text?: string; default?: string | null; - items: { - value: C; - text: string; - }[]; + items: (SelectItem | { + sectionTitle: string; + items: SelectItem[]; + } | undefined)[]; }): Promise<{ canceled: true; result: undefined; } | { @@ -492,7 +497,7 @@ export function select(props: { title: props.title, text: props.text, select: { - items: props.items, + items: props.items.filter(x => x !== undefined), default: props.default ?? null, }, }, { diff --git a/packages/frontend/src/pages/my-antennas/create.vue b/packages/frontend/src/pages/my-antennas/create.vue index 2d026d2fa976..2b8518747f2c 100644 --- a/packages/frontend/src/pages/my-antennas/create.vue +++ b/packages/frontend/src/pages/my-antennas/create.vue @@ -4,43 +4,33 @@ SPDX-License-Identifier: AGPL-3.0-only --> diff --git a/packages/frontend/src/pages/my-antennas/edit.vue b/packages/frontend/src/pages/my-antennas/edit.vue index 9471be85750d..9f927cd1a070 100644 --- a/packages/frontend/src/pages/my-antennas/edit.vue +++ b/packages/frontend/src/pages/my-antennas/edit.vue @@ -4,15 +4,17 @@ SPDX-License-Identifier: AGPL-3.0-only --> diff --git a/packages/frontend/src/scripts/merge.ts b/packages/frontend/src/scripts/merge.ts index 4e39a0fa06ec..9794a300da02 100644 --- a/packages/frontend/src/scripts/merge.ts +++ b/packages/frontend/src/scripts/merge.ts @@ -6,7 +6,7 @@ import { deepClone } from './clone.js'; import type { Cloneable } from './clone.js'; -type DeepPartial = { +export type DeepPartial = { [P in keyof T]?: T[P] extends Record ? DeepPartial : T[P]; }; diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue index bdb62dca15b5..af46b0641d83 100644 --- a/packages/frontend/src/ui/deck.vue +++ b/packages/frontend/src/ui/deck.vue @@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only :ref="id" :key="id" :class="$style.column" - :column="columns.find(c => c.id === id)" + :column="columns.find(c => c.id === id)!" :isStacked="ids.length > 1" @headerWheel="onWheel" /> @@ -95,7 +95,8 @@ SPDX-License-Identifier: AGPL-3.0-only import { computed, defineAsyncComponent, ref, watch, shallowRef } from 'vue'; import { v4 as uuid } from 'uuid'; import XCommon from './_common_/common.vue'; -import { deckStore, addColumn as addColumnToStore, loadDeck, getProfiles, deleteProfile as deleteProfile_ } from './deck/deck-store.js'; +import { deckStore, columnTypes, addColumn as addColumnToStore, loadDeck, getProfiles, deleteProfile as deleteProfile_ } from './deck/deck-store.js'; +import type { ColumnType } from './deck/deck-store.js'; import XSidebar from '@/ui/_common_/navbar.vue'; import XDrawerMenu from '@/ui/_common_/navbar-for-mobile.vue'; import MkButton from '@/components/MkButton.vue'; @@ -152,10 +153,12 @@ window.addEventListener('resize', () => { const snapScroll = deviceKind === 'smartphone' || deviceKind === 'tablet'; const drawerMenuShowing = ref(false); +/* const route = 'TODO'; watch(route, () => { drawerMenuShowing.value = false; }); +*/ const columns = deckStore.reactiveState.columns; const layout = deckStore.reactiveState.layout; @@ -174,32 +177,20 @@ function showSettings() { const columnsEl = shallowRef(); const addColumn = async (ev) => { - const columns = [ - 'main', - 'widgets', - 'notifications', - 'tl', - 'antenna', - 'list', - 'channel', - 'mentions', - 'direct', - 'roleTimeline', - ]; - const { canceled, result: column } = await os.select({ title: i18n.ts._deck.addColumn, - items: columns.map(column => ({ + items: columnTypes.map(column => ({ value: column, text: i18n.ts._deck._columns[column], })), }); - if (canceled) return; + if (canceled || column == null) return; addColumnToStore({ type: column, id: uuid(), name: i18n.ts._deck._columns[column], width: 330, + soundSetting: { type: null, volume: 1 }, }); }; @@ -211,7 +202,7 @@ const onContextmenu = (ev) => { }; function onWheel(ev: WheelEvent) { - if (ev.deltaX === 0) { + if (ev.deltaX === 0 && columnsEl.value != null) { columnsEl.value.scrollLeft += ev.deltaY; } } @@ -242,7 +233,7 @@ function changeProfile(ev: MouseEvent) { title: i18n.ts._deck.profile, minLength: 1, }); - if (canceled) return; + if (canceled || name == null) return; deckStore.set('profile', name); unisonReload(); diff --git a/packages/frontend/src/ui/deck/antenna-column.vue b/packages/frontend/src/ui/deck/antenna-column.vue index c3dc1e4fcec3..987bd4db557e 100644 --- a/packages/frontend/src/ui/deck/antenna-column.vue +++ b/packages/frontend/src/ui/deck/antenna-column.vue @@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only --> + diff --git a/packages/frontend/src/pages/search.stories.impl.ts b/packages/frontend/src/pages/search.stories.impl.ts new file mode 100644 index 000000000000..0110a7ab8ed1 --- /dev/null +++ b/packages/frontend/src/pages/search.stories.impl.ts @@ -0,0 +1,88 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { StoryObj } from '@storybook/vue3'; +import { HttpResponse, http } from 'msw'; +import search_ from './search.vue'; +import { userDetailed } from '@/../.storybook/fakes.js'; +import { commonHandlers } from '@/../.storybook/mocks.js'; + +const localUser = userDetailed('someuserid', 'miskist', null, 'Local Misskey User'); + +export const Default = { + render(args) { + return { + components: { + search_, + }, + setup() { + return { + args, + }; + }, + computed: { + props() { + return { + ...this.args, + }; + }, + }, + template: '', + }; + }, + args: { + ignoreNotesSearchAvailable: true, + }, + parameters: { + layout: 'fullscreen', + msw: { + handlers: [ + ...commonHandlers, + http.post('/api/users/show', () => { + return HttpResponse.json(userDetailed()); + }), + http.post('/api/users/search', () => { + return HttpResponse.json([userDetailed(), localUser]); + }), + ], + }, + }, +} satisfies StoryObj; + +export const NoteSearchDisabled = { + ...Default, + args: {}, +} satisfies StoryObj; + +export const WithUsernameLocal = { + ...Default, + + args: { + ...Default.args, + username: localUser.username, + host: localUser.host, + }, + parameters: { + layout: 'fullscreen', + msw: { + handlers: [ + ...commonHandlers, + http.post('/api/users/show', () => { + return HttpResponse.json(localUser); + }), + http.post('/api/users/search', () => { + return HttpResponse.json([userDetailed(), localUser]); + }), + ], + }, + }, +} satisfies StoryObj; + +export const WithUserType = { + ...Default, + args: { + type: 'user', + }, +} satisfies StoryObj; diff --git a/packages/frontend/src/pages/search.user.vue b/packages/frontend/src/pages/search.user.vue index b9c2704bc722..85d869d9cba7 100644 --- a/packages/frontend/src/pages/search.user.vue +++ b/packages/frontend/src/pages/search.user.vue @@ -25,7 +25,9 @@ SPDX-License-Identifier: AGPL-3.0-only diff --git a/packages/frontend/src/pages/emoji-edit-dialog.vue b/packages/frontend/src/pages/emoji-edit-dialog.vue index d0a6bba47bcc..853c1d6b0b5d 100644 --- a/packages/frontend/src/pages/emoji-edit-dialog.vue +++ b/packages/frontend/src/pages/emoji-edit-dialog.vue @@ -15,8 +15,8 @@ SPDX-License-Identifier: AGPL-3.0-only -
- +
+
@@ -239,6 +239,7 @@ async function del() { .footer { position: sticky; + z-index: 10000; bottom: 0; left: 0; padding: 12px; From 3137c104f23ac966340a66f7452f3a903d134633 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Wed, 31 Jul 2024 07:23:38 +0900 Subject: [PATCH 204/268] =?UTF-8?q?test:=20=E3=83=95=E3=82=A9=E3=83=AD?= =?UTF-8?q?=E3=83=BC=E3=81=97=E3=81=A6=E3=81=84=E3=81=AA=E3=81=84=E3=83=A6?= =?UTF-8?q?=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=8B=E3=82=89=E3=81=AE=E8=87=AA?= =?UTF-8?q?=E5=88=86=E3=81=B8=E3=81=AE=E8=BF=94=E4=BF=A1=E3=81=8C=E5=90=AB?= =?UTF-8?q?=E3=81=BE=E3=82=8C=E3=82=8B=E3=81=93=E3=81=A8=E3=82=92=E7=A2=BA?= =?UTF-8?q?=E8=AA=8D=E3=81=99=E3=82=8B=E3=83=86=E3=82=B9=E3=83=88=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=20(#14333)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/test/e2e/timelines.ts | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/backend/test/e2e/timelines.ts b/packages/backend/test/e2e/timelines.ts index b7069dd82c18..d12be2a9acdc 100644 --- a/packages/backend/test/e2e/timelines.ts +++ b/packages/backend/test/e2e/timelines.ts @@ -703,6 +703,21 @@ describe('Timelines', () => { assert.strictEqual(res.body.some(note => note.id === bobNote.id), true); }); + test.concurrent('withReplies: false でフォローしていないユーザーからの自分への返信が含まれる', async () => { + const [alice, bob] = await Promise.all([signup(), signup()]); + + await setTimeout(1000); + const aliceNote = await post(alice, { text: 'hi' }); + const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id }); + + await waitForPushToTl(); + + const res = await api('notes/local-timeline', { limit: 100 }, alice); + + assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true); + assert.strictEqual(res.body.some(note => note.id === bobNote.id), true); + }); + test.concurrent('[withReplies: true] 他人の他人への返信が含まれる', async () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); @@ -899,6 +914,21 @@ describe('Timelines', () => { assert.strictEqual(res.body.some(note => note.id === bobNote.id), true); }); + test.concurrent('withReplies: false でフォローしていないユーザーからの自分への返信が含まれる', async () => { + const [alice, bob] = await Promise.all([signup(), signup()]); + + await setTimeout(1000); + const aliceNote = await post(alice, { text: 'hi' }); + const bobNote = await post(bob, { text: 'hi', replyId: aliceNote.id }); + + await waitForPushToTl(); + + const res = await api('notes/local-timeline', { limit: 100 }, alice); + + assert.strictEqual(res.body.some(note => note.id === aliceNote.id), true); + assert.strictEqual(res.body.some(note => note.id === bobNote.id), true); + }); + test.concurrent('[withReplies: true] 他人の他人への返信が含まれる', async () => { const [alice, bob, carol] = await Promise.all([signup(), signup(), signup()]); From 9dacc20d67777185c729dd71899885db72874692 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Wed, 31 Jul 2024 07:23:58 +0900 Subject: [PATCH 205/268] New Crowdin updates (#14331) * New translations ja-jp.yml (Chinese Simplified) * New translations ja-jp.yml (Chinese Traditional) * New translations ja-jp.yml (English) * New translations ja-jp.yml (Chinese Simplified) * New translations ja-jp.yml (English) --- locales/en-US.yml | 10 ++++++++-- locales/zh-CN.yml | 10 ++++++++-- locales/zh-TW.yml | 6 ++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/locales/en-US.yml b/locales/en-US.yml index cfb5783a95ed..451300d9736d 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -167,7 +167,7 @@ emojiUrl: "Emoji URL" addEmoji: "Add an emoji" settingGuide: "Recommended settings" cacheRemoteFiles: "Cache remote files" -cacheRemoteFilesDescription: "When this setting is disabled, remote files are loaded directly from the remote instance. Disabling this will decrease storage usage, but increase traffic, as thumbnails will not be generated." +cacheRemoteFilesDescription: "When this setting is disabled, remote files are loaded directly from the remote servers. Disabling this will decrease storage usage, but increase traffic, as thumbnails will not be generated." youCanCleanRemoteFilesCache: "You can clear the cache by clicking the 🗑️ button in the file management view." cacheRemoteSensitiveFiles: "Cache sensitive remote files" cacheRemoteSensitiveFilesDescription: "When this setting is disabled, sensitive remote files are loaded directly from the remote instance without caching." @@ -212,6 +212,7 @@ perDay: "Per Day" stopActivityDelivery: "Stop sending activities" blockThisInstance: "Block this instance" silenceThisInstance: "Silence this instance" +mediaSilenceThisInstance: "Media-silence this server" operations: "Operations" software: "Software" version: "Version" @@ -232,7 +233,9 @@ clearCachedFilesConfirm: "Are you sure that you want to delete all cached remote blockedInstances: "Blocked Instances" blockedInstancesDescription: "List the hostnames of the instances you want to block separated by linebreaks. Listed instances will no longer be able to communicate with this instance." silencedInstances: "Silenced instances" -silencedInstancesDescription: "List the hostnames of the instances that you want to silence. All accounts of the listed instances will be treated as silenced, can only make follow requests, and cannot mention local accounts if not followed. This will not affect blocked instances." +silencedInstancesDescription: "List the host names of the servers that you want to silence, separated by a new line. All accounts belonging to the listed servers will be treated as silenced, and can only make follow requests, and cannot mention local accounts if not followed. This will not affect the blocked servers." +mediaSilencedInstances: "Media-silenced servers" +mediaSilencedInstancesDescription: "List the host names of the servers that you want to media-silence, separated by a new line. All accounts belonging to the listed servers will be treated as sensitive, and can't use custom emojis. This will not affect the blocked servers." muteAndBlock: "Mutes and Blocks" mutedUsers: "Muted users" blockedUsers: "Blocked users" @@ -1121,6 +1124,8 @@ preventAiLearning: "Reject usage in Machine Learning (Generative AI)" preventAiLearningDescription: "Requests crawlers to not use posted text or image material etc. in machine learning (Predictive / Generative AI) data sets. This is achieved by adding a \"noai\" HTML-Response flag to the respective content. A complete prevention can however not be achieved through this flag, as it may simply be ignored." options: "Options" specifyUser: "Specific user" +lookupConfirm: "Do you want to look up?" +openTagPageConfirm: "Do you want to open a hashtag page?" specifyHost: "Specify a host" failedToPreviewUrl: "Could not preview" update: "Update" @@ -1962,6 +1967,7 @@ _soundSettings: driveFileTypeWarnDescription: "Select an audio file" driveFileDurationWarn: "The audio is too long." driveFileDurationWarnDescription: "Long audio may disrupt using Misskey. Still continue?" + driveFileError: "It couldn't load the sound. Please change the setting." _ago: future: "Future" justNow: "Just now" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 8eae32ca3250..0a868aab4473 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -212,6 +212,7 @@ perDay: "每天" stopActivityDelivery: "停止发送活动" blockThisInstance: "阻止此服务器向本服务器推流" silenceThisInstance: "使服务器静音" +mediaSilenceThisInstance: "隐藏此服务器的媒体文件" operations: "操作" software: "软件" version: "版本" @@ -230,9 +231,11 @@ clearQueueConfirmText: "未送达的帖子将不会被投递。 通常无需执 clearCachedFiles: "清除缓存" clearCachedFilesConfirm: "确定要清除所有缓存的远程文件?" blockedInstances: "被封锁的服务器" -blockedInstancesDescription: "设定要封锁的服务器,以换行来进行分割。被封锁的服务器将无法与本服务器进行交换通讯。子域名也同样会被封锁。" +blockedInstancesDescription: "设定要封锁的服务器,以换行分隔。被封锁的服务器将无法与本服务器进行交换通讯。子域名也同样会被封锁。" silencedInstances: "被静音的服务器" -silencedInstancesDescription: "设置要静音的服务器,以换行符分隔。被静音的服务器内所有的账户将默认处于「静音」状态,仅能发送关注请求,并且在未关注状态下无法提及本地账户。被阻止的实例不受影响。" +silencedInstancesDescription: "设置要静音的服务器,以换行分隔。被静音的服务器内所有的账户将默认处于「静音」状态,仅能发送关注请求,并且在未关注状态下无法提及本地账户。被阻止的实例不受影响。" +mediaSilencedInstances: "已隐藏媒体文件的服务器" +mediaSilencedInstancesDescription: "设置要隐藏媒体文件的服务器,以换行分隔。被设置为隐藏媒体文件服务器内所有账号的文件均按照「敏感内容」处理,且将无法使用自定义表情符号。被阻止的实例不受影响。" muteAndBlock: "静音/拉黑" mutedUsers: "已静音用户" blockedUsers: "已拉黑的用户" @@ -1121,6 +1124,8 @@ preventAiLearning: "拒绝接受生成式 AI 的学习" preventAiLearningDescription: "要求文章生成 AI 或图像生成 AI 不能够以发布的帖子和图像等内容作为学习对象。这是通过在 HTML 响应中包含 noai 标志来实现的,这不能完全阻止 AI 学习你的发布内容,并不是所有 AI 都会遵守这类请求。" options: "选项" specifyUser: "用户指定" +lookupConfirm: "确定查询?" +openTagPageConfirm: "确定打开话题标签页面?" specifyHost: "指定主机名" failedToPreviewUrl: "无法预览" update: "更新" @@ -1961,6 +1966,7 @@ _soundSettings: driveFileTypeWarnDescription: "请选择音频文件" driveFileDurationWarn: "音频过长" driveFileDurationWarnDescription: "使用长音频可能会影响 Misskey 的使用。即使这样也要继续吗?" + driveFileError: "无法读取声音。请更改设置。" _ago: future: "未来" justNow: "最近" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 8b53273c3b4f..476ccd879997 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -212,6 +212,7 @@ perDay: "每日" stopActivityDelivery: "停止發送活動" blockThisInstance: "封鎖此伺服器" silenceThisInstance: "禁言此伺服器" +mediaSilenceThisInstance: "將這個伺服器的媒體設為禁言" operations: "操作" software: "軟體" version: "版本" @@ -233,6 +234,8 @@ blockedInstances: "已封鎖的伺服器" blockedInstancesDescription: "請逐行輸入需要封鎖的伺服器。已封鎖的伺服器將無法與本伺服器進行通訊。" silencedInstances: "被禁言的伺服器" silencedInstancesDescription: "設定要禁言的伺服器主機名稱,以換行分隔。隸屬於禁言伺服器的所有帳戶都將被視為「禁言帳戶」,只能發出「追隨請求」,而且無法提及未追隨的本地帳戶。這不會影響已封鎖的實例。" +mediaSilencedInstances: "媒體被禁言的伺服器" +mediaSilencedInstancesDescription: "設定您想要對媒體設定禁言的伺服器,以換行符號區隔。來自被媒體禁言的伺服器所屬帳戶的所有檔案都會被視為敏感檔案,且自訂表情符號不能使用。被封鎖的伺服器不受影響。" muteAndBlock: "靜音和封鎖" mutedUsers: "被靜音的使用者" blockedUsers: "被封鎖的使用者" @@ -1121,6 +1124,8 @@ preventAiLearning: "拒絕接受生成式AI的訓練" preventAiLearningDescription: "要求站外生成式 AI 不使用您發佈的內容訓練模型。此功能會使伺服器於 HTML 回應新增「noai」標籤,而因為要視乎 AI 會否遵守該標籤,所以此功能無法完全阻止所有 AI 使用您的內容。" options: "選項" specifyUser: "指定使用者" +lookupConfirm: "要查詢嗎?" +openTagPageConfirm: "要開啟標籤的頁面嗎?" specifyHost: "指定主機" failedToPreviewUrl: "無法預覽" update: "更新" @@ -1962,6 +1967,7 @@ _soundSettings: driveFileTypeWarnDescription: "請選擇音效檔案" driveFileDurationWarn: "音效太長了" driveFileDurationWarnDescription: "使用長音效檔可能會影響 Misskey 的使用體驗。仍要使用此檔案嗎?" + driveFileError: "無法載入語音。請更改設定" _ago: future: "未來" justNow: "剛剛" From d63b854f96d9437f9764f9170c3ed3537cc98a2c Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Wed, 31 Jul 2024 08:12:35 +0900 Subject: [PATCH 206/268] tweak localization --- locales/ja-JP.yml | 2 +- packages/frontend/src/components/MkSystemWebhookEditor.vue | 2 +- packages/frontend/src/pages/settings/webhook.edit.vue | 2 +- packages/frontend/src/pages/settings/webhook.new.vue | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 522ad7e22ac6..b493183974cc 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2492,7 +2492,7 @@ _webhookSettings: modifyWebhook: "Webhookを編集" name: "名前" secret: "シークレット" - events: "Webhookを実行するタイミング" + trigger: "トリガー" active: "有効" _events: follow: "フォローしたとき" diff --git a/packages/frontend/src/components/MkSystemWebhookEditor.vue b/packages/frontend/src/components/MkSystemWebhookEditor.vue index cad2e99e4d47..f5c7a3160bb4 100644 --- a/packages/frontend/src/components/MkSystemWebhookEditor.vue +++ b/packages/frontend/src/components/MkSystemWebhookEditor.vue @@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +
diff --git a/packages/frontend/src/pages/settings/webhook.edit.vue b/packages/frontend/src/pages/settings/webhook.edit.vue index e9fb1e471e16..058ef69c35e3 100644 --- a/packages/frontend/src/pages/settings/webhook.edit.vue +++ b/packages/frontend/src/pages/settings/webhook.edit.vue @@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +
{{ i18n.ts._webhookSettings._events.follow }} diff --git a/packages/frontend/src/pages/settings/webhook.new.vue b/packages/frontend/src/pages/settings/webhook.new.vue index 5bf85e48f426..d62357caaff8 100644 --- a/packages/frontend/src/pages/settings/webhook.new.vue +++ b/packages/frontend/src/pages/settings/webhook.new.vue @@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +
{{ i18n.ts._webhookSettings._events.follow }} From 4b04b2989b3c8957cee292326846b3e019b4a1c6 Mon Sep 17 00:00:00 2001 From: taichan <40626578+tai-cha@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:22:51 +0900 Subject: [PATCH 207/268] chore(locale): update index.d.ts (#14339) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/misskey-dev/misskey/commit/d63b854f96d9437f9764f9170c3ed3537cc98a2c での更新漏れ --- locales/index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/index.d.ts b/locales/index.d.ts index c58e4ace7b97..91d36a14a627 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -9402,9 +9402,9 @@ export interface Locale extends ILocale { */ "secret": string; /** - * Webhookを実行するタイミング + * トリガー */ - "events": string; + "trigger": string; /** * 有効 */ From d6ba12e24c78611d80a005efef4340681949931b Mon Sep 17 00:00:00 2001 From: taichan <40626578+tai-cha@users.noreply.github.com> Date: Wed, 31 Jul 2024 18:10:36 +0900 Subject: [PATCH 208/268] =?UTF-8?q?Fix(frontend):=20LTL=E7=84=A1=E5=8A=B9?= =?UTF-8?q?=E6=99=82=E3=81=AB=E3=83=98=E3=83=83=E3=83=80=E3=83=BC=E3=81=AB?= =?UTF-8?q?STL=E3=81=8C=E8=A1=A8=E7=A4=BA=E3=81=95=E3=82=8C=E3=81=A6?= =?UTF-8?q?=E3=81=97=E3=81=BE=E3=81=86=20&=20=E3=83=87=E3=83=95=E3=82=A9?= =?UTF-8?q?=E3=83=AB=E3=83=88=E3=80=81=E3=82=AF=E3=83=A9=E3=82=B7=E3=83=83?= =?UTF-8?q?=E3=82=AF=E3=81=A7=E3=83=AA=E3=82=B9=E3=83=88=E3=81=8C=E6=B6=88?= =?UTF-8?q?=E3=81=88=E3=81=A6=E3=81=84=E3=82=8B=20(#14337)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix condition of STL available * Fix: condition of stl * Listがタイムラインのヘッダーから消えている --- packages/frontend/src/pages/timeline.vue | 5 +++++ packages/frontend/src/timelines.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue index c5905c7adaf8..32f6dd0e5a6c 100644 --- a/packages/frontend/src/pages/timeline.vue +++ b/packages/frontend/src/pages/timeline.vue @@ -287,6 +287,11 @@ const headerTabs = computed(() => [...(defaultStore.reactiveState.pinnedUserList icon: basicTimelineIconClass(tl), iconOnly: true, })), { + icon: 'ti ti-list', + title: i18n.ts.lists, + iconOnly: true, + onClick: chooseList, +}, { icon: 'ti ti-antenna', title: i18n.ts.antennas, iconOnly: true, diff --git a/packages/frontend/src/timelines.ts b/packages/frontend/src/timelines.ts index 3ef95fd272ea..94eda3545e1f 100644 --- a/packages/frontend/src/timelines.ts +++ b/packages/frontend/src/timelines.ts @@ -39,7 +39,7 @@ export function isAvailableBasicTimeline(timeline: BasicTimelineType | undefined case 'local': return ($i == null && instance.policies.ltlAvailable) || ($i != null && $i.policies.ltlAvailable); case 'social': - return $i != null && instance.policies.ltlAvailable; + return $i != null && $i.policies.ltlAvailable; case 'global': return ($i == null && instance.policies.gtlAvailable) || ($i != null && $i.policies.gtlAvailable); default: From 1a521a44c0c0e3f5a8156a2cf4b2f8001ff3d004 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Wed, 31 Jul 2024 18:13:20 +0900 Subject: [PATCH 209/268] New Crowdin updates (#14335) * New translations ja-jp.yml (Japanese, Kansai) * New translations ja-jp.yml (Chinese Traditional) * New translations ja-jp.yml (English) * New translations ja-jp.yml (Chinese Simplified) * New translations ja-jp.yml (Vietnamese) * New translations ja-jp.yml (Spanish) * New translations ja-jp.yml (Czech) * New translations ja-jp.yml (German) * New translations ja-jp.yml (Italian) * New translations ja-jp.yml (Korean) * New translations ja-jp.yml (Polish) * New translations ja-jp.yml (Indonesian) * New translations ja-jp.yml (Thai) * New translations ja-jp.yml (English) * New translations ja-jp.yml (English) * New translations ja-jp.yml (Chinese Simplified) * New translations ja-jp.yml (Chinese Traditional) --- locales/cs-CZ.yml | 1 - locales/de-DE.yml | 1 - locales/en-US.yml | 4 ++-- locales/es-ES.yml | 1 - locales/id-ID.yml | 1 - locales/it-IT.yml | 1 - locales/ja-KS.yml | 1 - locales/ko-KR.yml | 1 - locales/pl-PL.yml | 1 - locales/th-TH.yml | 22 ++++++++++++++++++++-- locales/vi-VN.yml | 1 - locales/zh-CN.yml | 2 +- locales/zh-TW.yml | 2 +- 13 files changed, 24 insertions(+), 15 deletions(-) diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index aa970f823a6f..7db742476292 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -2010,7 +2010,6 @@ _webhookSettings: createWebhook: "Vytvořit Webhook" name: "Jméno" secret: "Tajné" - events: "Události Webhook" active: "Zapnuto" _events: follow: "Při sledování uživatele" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index a319af56cb94..8e44a3bbd4fc 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -2191,7 +2191,6 @@ _webhookSettings: createWebhook: "Webhook erstellen" name: "Name" secret: "Secret" - events: "Webhook-Ereignisse" active: "Aktiviert" _events: follow: "Wenn du jemandem folgst" diff --git a/locales/en-US.yml b/locales/en-US.yml index 451300d9736d..2cb76fa74652 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -398,7 +398,7 @@ mcaptcha: "mCaptcha" enableMcaptcha: "Enable mCaptcha" mcaptchaSiteKey: "Site key" mcaptchaSecretKey: "Secret key" -mcaptchaInstanceUrl: "mCaptcha instance URL" +mcaptchaInstanceUrl: "mCaptcha server URL" recaptcha: "reCAPTCHA" enableRecaptcha: "Enable reCAPTCHA" recaptchaSiteKey: "Site key" @@ -2426,7 +2426,7 @@ _webhookSettings: modifyWebhook: "Modify Webhook" name: "Name" secret: "Secret" - events: "Webhook Events" + trigger: "Trigger" active: "Enabled" _events: follow: "When following a user" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index 3ae3ba3b8aa2..ef066a37edd1 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -2382,7 +2382,6 @@ _webhookSettings: createWebhook: "Crear Webhook" name: "Nombre" secret: "Secreto" - events: "Eventos de webhook" active: "Activado" _events: follow: "Cuando se sigue a alguien" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index de50569e8947..24f7482fcaea 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -2403,7 +2403,6 @@ _webhookSettings: modifyWebhook: "Sunting Webhook" name: "Nama" secret: "Secret" - events: "Webhook Events" active: "Aktif" _events: follow: "Ketika mengikuti pengguna" diff --git a/locales/it-IT.yml b/locales/it-IT.yml index 64cd26878e1a..2b4b1e425e84 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -2412,7 +2412,6 @@ _webhookSettings: modifyWebhook: "Modifica Webhook" name: "Nome" secret: "Segreto" - events: "Quando eseguire il Webhook" active: "Attivo" _events: follow: "Quando segui un profilo" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 774031f6f563..5969082cf2a6 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -2391,7 +2391,6 @@ _webhookSettings: createWebhook: "Webhookをつくる" name: "名前" secret: "シークレット" - events: "Webhookを投げるタイミング" active: "有効" _events: follow: "フォローしたとき~!" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 7fcb681c9a56..34c1cc3ebfb5 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -2411,7 +2411,6 @@ _webhookSettings: modifyWebhook: "Webhook 수정" name: "이름" secret: "시크릿" - events: "Webhook을 실행할 타이밍" active: "활성화" _events: follow: "누군가를 팔로우했을 때" diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index 7513d056b43c..73eff0941a06 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -1544,7 +1544,6 @@ _webhookSettings: createWebhook: "Stwórz Webhook" name: "Nazwa" secret: "Sekret" - events: "Uruchomienie Webhooka" active: "Właczono" _events: follow: "Po zaobserwowaniu użytkownika" diff --git a/locales/th-TH.yml b/locales/th-TH.yml index eb7cdc23658c..63f27934283b 100644 --- a/locales/th-TH.yml +++ b/locales/th-TH.yml @@ -60,6 +60,7 @@ copyFileId: "คัดลอกไฟล์ ID" copyFolderId: "คัดลอกโฟลเดอร์ ID" copyProfileUrl: "คัดลอกโปรไฟล์ URL" searchUser: "ค้นหาผู้ใช้" +searchThisUsersNotes: "ค้นหาโน้ตของผู้ใช้" reply: "ตอบกลับ" loadMore: "แสดงเพิ่มเติม" showMore: "แสดงเพิ่มเติม" @@ -154,6 +155,7 @@ editList: "แก้ไขรายชื่อ" selectChannel: "เลือกช่อง" selectAntenna: "เลือกเสาอากาศ" editAntenna: "แก้ไขเสาอากาศ" +createAntenna: "สร้างเสาอากาศ" selectWidget: "เลือกวิดเจ็ต" editWidgets: "แก้ไขวิดเจ็ต" editWidgetsExit: "เรียบร้อย" @@ -194,6 +196,7 @@ followConfirm: "ต้องการติดตาม {name} ใช่ไห proxyAccount: "บัญชีพร็อกซี่" proxyAccountDescription: "บัญชีพร็อกซี คือ บัญชีที่ทำหน้าที่ติดตาม(ผู้ใช้)ระยะไกลภายใต้เงื่อนไขบางประการ ตัวอย่างเช่น เมื่อผู้ใช้ท้องถิ่นเพิ่มผู้ใช้ระยะไกลลงรายชื่อ หากไม่มีใครติดตามผู้ใช้ระยะไกลในรายชื่อนั้น กิจกรรมก็จะไม่ถูกส่งมายังเซิร์ฟเวอร์ ดังนั้นจึงมีบัญชีพร็อกซีไว้ติดตามผู้ใช้ระยะไกลเหล่านั้น" host: "โฮสต์" +selectSelf: "เลือกตัวเอง" selectUser: "เลือกผู้ใช้งาน" recipient: "ผู้รับ" annotation: "หมายเหตุประกอบ" @@ -209,6 +212,7 @@ perDay: "ต่อวัน" stopActivityDelivery: "หยุดส่งกิจกรรม" blockThisInstance: "บล็อกเซิร์ฟเวอร์นี้" silenceThisInstance: "ปิดปากเซิร์ฟเวอร์นี้" +mediaSilenceThisInstance: "ปิดปากสื่อของเซิร์ฟเวอร์นี้" operations: "ดำเนินการ" software: "ซอฟต์แวร์" version: "เวอร์ชั่น" @@ -230,6 +234,8 @@ blockedInstances: "เซิร์ฟเวอร์ที่ถูกบล็ blockedInstancesDescription: "ระบุโฮสต์ของเซิร์ฟเวอร์ที่ต้องการบล็อก คั่นด้วยการขึ้นบรรทัดใหม่ เซิร์ฟเวอร์ที่ถูกบล็อกจะไม่สามารถติดต่อกับอินสแตนซ์นี้ได้" silencedInstances: "ปิดปากเซิร์ฟเวอร์นี้แล้ว" silencedInstancesDescription: "ระบุโฮสต์ของเซิร์ฟเวอร์ที่ต้องการปิดปาก คั่นด้วยการขึ้นบรรทัดใหม่, บัญชีทั้งหมดของเซิร์ฟเวอร์ดังกล่าวจะถือว่าถูกปิดปากเช่นกัน ทำได้เฉพาะคำขอติดตามเท่านั้น และไม่สามารถกล่าวถึงบัญชีในเซิร์ฟเวอร์นี้ได้หากไม่ได้ถูกติดตามกลับ | สิ่งนี้ไม่มีผลต่ออินสแตนซ์ที่ถูกบล็อก" +mediaSilencedInstances: "เซิร์ฟเวอร์ที่ถูกปิดปากสื่อ" +mediaSilencedInstancesDescription: "ระบุโฮสต์ของเซิร์ฟเวอร์ที่ต้องการปิดปากสื่อ คั่นด้วยการขึ้นบรรทัดใหม่, ไฟล์ที่ถูกส่งจากบัญชีของเซิร์ฟเวอร์ดังกล่าวจะถือว่าถูกปิดปาก แล้วจะถูกติดเครื่องหมายว่ามีเนื้อหาละเอียดอ่อน และเอโมจิแบบกำหนดเองก็จะใช้ไม่ได้ด้วย | สิ่งนี้ไม่มีผลต่ออินสแตนซ์ที่ถูกบล็อก" muteAndBlock: "ปิดเสียงและบล็อก" mutedUsers: "ผู้ใช้ที่ถูกปิดเสียง" blockedUsers: "ผู้ใช้ที่ถูกบล็อก" @@ -1106,6 +1112,8 @@ preservedUsernames: "ชื่อผู้ใช้ที่สงวนไว preservedUsernamesDescription: "ระบุชื่อผู้ใช้ที่จะสงวนชื่อไว้ คั่นด้วยการขึ้นบรรทัดใหม่ ชื่อผู้ใช้ที่ระบุที่นี่จะไม่สามารถใช้งานได้อีกต่อไปเมื่อสร้างบัญชีใหม่ ยกเว้นเมื่อผู้ดูแลระบบสร้างบัญชี นอกจากนี้ บัญชีที่มีอยู่แล้วจะไม่ได้รับผลกระทบ" createNoteFromTheFile: "เรียบเรียงโน้ตจากไฟล์นี้" archive: "เก็บถาวร" +archived: "เก็บถาวรแล้ว" +unarchive: "เลิกการเก็บถาวร" channelArchiveConfirmTitle: "ต้องการเก็บถาวรเจ้า {name} ใช่ไหม?" channelArchiveConfirmDescription: "เมื่อเก็บถาวรแล้ว จะไม่ปรากฏในรายการช่องหรือผลการค้นหาอีกต่อไป และจะไม่สามารถโพสต์ใหม่ได้อีกต่อไป" thisChannelArchived: "ช่องนี้ถูกเก็บถาวรแล้วนะ" @@ -1116,6 +1124,9 @@ preventAiLearning: "ปฏิเสธการเรียนรู้ด้ว preventAiLearningDescription: "ส่งคำร้องขอไม่ให้ใช้ ข้อความในโน้ตที่โพสต์, หรือเนื้อหารูปภาพ ฯลฯ ในการเรียนรู้ของเครื่อง(machine learning) / Predictive AI / Generative AI โดยการเพิ่มแฟล็ก “noai” ลง HTML-Response ให้กับเนื้อหาที่เกี่ยวข้อง แต่ทั้งนี้ ไม่ได้ป้องกัน AI จากการเรียนรู้ได้อย่างสมบูรณ์ เนื่องจากมี AI บางตัวเท่านั้นที่จะเคารพคำขอดังกล่าว" options: "ตัวเลือกบทบาท" specifyUser: "ผู้ใช้เฉพาะ" +lookupConfirm: "ต้องการเรียกดูข้อมูลใช่ไหม?" +openTagPageConfirm: "ต้องการเปิดหน้าแฮชแท็กใช่ไหม?" +specifyHost: "ระบุโฮสต์" failedToPreviewUrl: "ไม่สามารถดูตัวอย่างได้" update: "อัปเดต" rolesThatCanBeUsedThisEmojiAsReaction: "บทบาทที่สามารถใช้เอโมจินี้เป็นรีแอคชั่นได้" @@ -1250,6 +1261,8 @@ inquiry: "ติดต่อเรา" tryAgain: "โปรดลองอีกครั้ง" confirmWhenRevealingSensitiveMedia: "ตรวจสอบก่อนแสดงสื่อที่มีเนื้อหาละเอียดอ่อน" sensitiveMediaRevealConfirm: "สื่อนี้มีเนื้อหาละเอียดอ่อน, ต้องการแสดงใช่ไหม?" +createdLists: "รายชื่อที่ถูกสร้าง" +createdAntennas: "เสาอากาศที่ถูกสร้าง" _delivery: status: "สถานะการจัดส่ง" stop: "ระงับการส่ง" @@ -1954,6 +1967,7 @@ _soundSettings: driveFileTypeWarnDescription: "กรุณาเลือกไฟล์เสียง" driveFileDurationWarn: "เสียงยาวเกินไป" driveFileDurationWarnDescription: "การใช้เสียงที่ยาว อาจรบกวนการใช้งาน Misskey, ต้องการดำเนินการต่อใช่ไหม?" + driveFileError: "ไม่สามารถโหลดไฟล์เสียงได้ กรุณาเปลี่ยนแปลงการตั้งค่า" _ago: future: "อนาคต" justNow: "เมื่อกี๊นี้" @@ -2412,7 +2426,6 @@ _webhookSettings: modifyWebhook: "แก้ไข Webhook" name: "ชื่อ" secret: "ความลับ" - events: "อีเว้นท์ Webhook" active: "เปิดใช้งาน" _events: follow: "เมื่อกำลังติดตามผู้ใช้" @@ -2536,7 +2549,7 @@ _externalResourceInstaller: description: "เกิดปัญหาระหว่างการติดตั้งธีม กรุณาลองอีกครั้ง. รายละเอียดข้อผิดพลาดสามารถดูได้ในคอนโซล Javascript" _dataSaver: _media: - title: "โหลดมีเดีย" + title: "โหลดสื่อ" description: "กันไม่ให้ภาพและวิดีโอโหลดโดยอัตโนมัติ แตะรูปภาพ/วิดีโอที่ซ่อนอยู่เพื่อโหลด" _avatar: title: "รูปไอคอน" @@ -2616,3 +2629,8 @@ _mediaControls: pip: "รูปภาพในรูปภาม" playbackRate: "ความเร็วในการเล่น" loop: "เล่นวนซ้ำ" +_contextMenu: + title: "เมนูเนื้อหา" + app: "แอปพลิเคชัน" + appWithShift: "แอปฟลิเคชันด้วยปุ่มยกแคร่ (Shift)" + native: "UI ของเบราว์เซอร์" diff --git a/locales/vi-VN.yml b/locales/vi-VN.yml index 317dea51504a..aadbf8b16f22 100644 --- a/locales/vi-VN.yml +++ b/locales/vi-VN.yml @@ -1918,7 +1918,6 @@ _webhookSettings: createWebhook: "Tạo Webhook" name: "Tên" secret: "Mã bí mật" - events: "Sự kiện Webhook" active: "Đã bật" _events: reaction: "Khi nhận được sự kiện" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 0a868aab4473..1deb0effc394 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -2425,7 +2425,7 @@ _webhookSettings: modifyWebhook: "编辑 webhook" name: "名称" secret: "密钥" - events: "何时运行 Webhook" + trigger: "触发器" active: "已启用" _events: follow: "关注时" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 476ccd879997..16dc464e352a 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -2426,7 +2426,7 @@ _webhookSettings: modifyWebhook: "編輯 Webhook" name: "名字" secret: "密鑰" - events: "何時運行 Webhook" + trigger: "觸發器" active: "已啟用" _events: follow: "當你追隨時" From 59e2e43a68ee39d40f7a95a068cb9cb4f235cfed Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 31 Jul 2024 11:20:28 +0000 Subject: [PATCH 210/268] Release: 2024.7.0 --- package.json | 2 +- packages/misskey-js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 42751be196ec..4bf7b0a9189c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2024.7.0-rc.8", + "version": "2024.7.0", "codename": "nasubi", "repository": { "type": "git", diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 45f42e1846b3..f0e8733e67a8 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "misskey-js", - "version": "2024.7.0-rc.8", + "version": "2024.7.0", "description": "Misskey SDK for JavaScript", "license": "MIT", "main": "./built/index.js", From 008a66d73f58956b6a9c30f2d48cd554df865ac9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 31 Jul 2024 11:20:33 +0000 Subject: [PATCH 211/268] [skip ci] Update CHANGELOG.md (prepend template) --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b996216ac174..86e33a827261 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## Unreleased + +### General +- + +### Client +- + +### Server +- + + ## 2024.7.0 ### Note From 6e3e7d7df1efb7d74d905b8ebdf704573ff2f930 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 8 Aug 2024 20:22:25 +0900 Subject: [PATCH 212/268] 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 8db71c88819c..9b5b4a50009a 100644 --- a/packages/frontend/src/pages/about-misskey.vue +++ b/packages/frontend/src/pages/about-misskey.vue @@ -264,6 +264,9 @@ const patronsWithIcon = [{ }, { name: 'ささくれりょう', icon: 'https://assets.misskey-hub.net/patrons/cf55022cee6c41da8e70a43587aaad9a.jpg', +}, { + name: 'Macop', + icon: 'https://assets.misskey-hub.net/patrons/ee052bf550014d36a643ce3dce595640.jpg', }]; const patrons = [ From 820becb4e47ba88e181ad6a225a5a904ea821376 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:51:18 +0900 Subject: [PATCH 213/268] fix import --- packages/backend/src/core/ModerationLogService.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/core/ModerationLogService.ts b/packages/backend/src/core/ModerationLogService.ts index 6c155c9a627c..2c02af217d91 100644 --- a/packages/backend/src/core/ModerationLogService.ts +++ b/packages/backend/src/core/ModerationLogService.ts @@ -9,7 +9,8 @@ import type { ModerationLogsRepository } from '@/models/_.js'; import type { MiUser } from '@/models/User.js'; import { IdService } from '@/core/IdService.js'; import { bindThis } from '@/decorators.js'; -import { ModerationLogPayloads, moderationLogTypes } from '@/types.js'; +import type { ModerationLogPayloads } from '@/types.js'; +import { moderationLogTypes } from '@/types.js'; @Injectable() export class ModerationLogService { From f244d425005ae662cfb94f2a18e38cedadfb3c0a Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Fri, 9 Aug 2024 12:05:28 +0900 Subject: [PATCH 214/268] ci: change prerelease channels to alpha, beta, and rc (#14376) --- .github/workflows/release-edit-with-push.yml | 2 +- .github/workflows/release-with-dispatch.yml | 14 +++++++++++--- .github/workflows/release-with-ready.yml | 2 ++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-edit-with-push.yml b/.github/workflows/release-edit-with-push.yml index f86c1948f8b0..57657a4ba7b5 100644 --- a/.github/workflows/release-edit-with-push.yml +++ b/.github/workflows/release-edit-with-push.yml @@ -6,7 +6,7 @@ on: - develop paths: - 'CHANGELOG.md' - # - .github/workflows/release-edit-with-push.yml + env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-with-dispatch.yml b/.github/workflows/release-with-dispatch.yml index 0936bc0ae8b9..ed2f822269a1 100644 --- a/.github/workflows/release-with-dispatch.yml +++ b/.github/workflows/release-with-dispatch.yml @@ -17,6 +17,10 @@ on: type: boolean description: 'MERGE RELEASE BRANCH TO MAIN' default: false + start-rc: + type: boolean + description: 'Start Release Candidate' + default: false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -56,13 +60,13 @@ jobs: ### General - - + ### Client - - + ### Server - - + use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }} indent: ${{ vars.INDENT }} secrets: @@ -79,6 +83,9 @@ jobs: package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }} use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }} indent: ${{ vars.INDENT }} + draft_prerelease_channel: alpha + ready_start_prerelease_channel: beta + prerelease_channel: ${{ inputs.start-rc && 'rc' || '' }} secrets: RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }} RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} @@ -122,6 +129,7 @@ jobs: use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }} indent: ${{ vars.INDENT }} stable_branch: ${{ vars.STABLE_BRANCH }} + draft_prerelease_channel: alpha secrets: RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }} RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} diff --git a/.github/workflows/release-with-ready.yml b/.github/workflows/release-with-ready.yml index 79b6ade01285..e863b5e2e822 100644 --- a/.github/workflows/release-with-ready.yml +++ b/.github/workflows/release-with-ready.yml @@ -39,6 +39,8 @@ jobs: package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }} use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }} indent: ${{ vars.INDENT }} + draft_prerelease_channel: alpha + ready_start_prerelease_channel: beta secrets: RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }} RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} From 0d508db8a7a36218d38231af4e718aff0e94d9bc Mon Sep 17 00:00:00 2001 From: Daiki Mizukami Date: Fri, 9 Aug 2024 12:10:51 +0900 Subject: [PATCH 215/268] fix(backend): check visibility of following/followers of remote users / feat: moderators can see following/followers of all users (#14375) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backend): check visibility of following/followers of remote users Resolves https://github.com/misskey-dev/misskey/issues/13362. * test(backend): add tests for visibility of following/followers of remote users * docs(changelog): update CHANGELOG.md * feat: moderators can see following/followers of all users * docs(changelog): update CHANGELOG.md * refactor(backend): minor refactoring `createPerson`と`if`の条件を統一するとともに、異常系の 処理をearly returnに追い出すための変更。 * feat(backend): moderators can see following/followers count of all users As per https://github.com/misskey-dev/misskey/pull/14375#issuecomment-2275044908. --- CHANGELOG.md | 3 +- .../activitypub/models/ApPersonService.ts | 50 ++++++++++++++++- packages/backend/src/core/activitypub/type.ts | 6 ++- .../src/core/entities/UserEntityService.ts | 4 +- .../server/api/endpoints/users/followers.ts | 34 ++++++------ .../server/api/endpoints/users/following.ts | 34 ++++++------ packages/backend/test/unit/activitypub.ts | 53 ++++++++++++++++++- .../frontend/src/scripts/isFfVisibleForMe.ts | 4 +- 8 files changed, 149 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86e33a827261..c18cccc44e83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ ## Unreleased ### General -- +- Fix: リモートユーザのフォロー・フォロワーの一覧が非公開設定の場合も表示できてしまう問題を修正 +- Enhance: モデレーターはすべてのユーザーのフォロー・フォロワーの一覧を見られるように ### Client - diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index 457205e0238e..f3ddf3952c84 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -48,7 +48,7 @@ import type { ApResolverService, Resolver } from '../ApResolverService.js'; import type { ApLoggerService } from '../ApLoggerService.js'; // eslint-disable-next-line @typescript-eslint/consistent-type-imports import type { ApImageService } from './ApImageService.js'; -import type { IActor, IObject } from '../type.js'; +import type { IActor, ICollection, IObject, IOrderedCollection } from '../type.js'; const nameLength = 128; const summaryLength = 2048; @@ -296,6 +296,21 @@ export class ApPersonService implements OnModuleInit { const isBot = getApType(object) === 'Service' || getApType(object) === 'Application'; + const [followingVisibility, followersVisibility] = await Promise.all( + [ + this.isPublicCollection(person.following, resolver), + this.isPublicCollection(person.followers, resolver), + ].map((p): Promise<'public' | 'private'> => p + .then(isPublic => isPublic ? 'public' : 'private') + .catch(err => { + if (!(err instanceof StatusError) || err.isRetryable) { + this.logger.error('error occurred while fetching following/followers collection', { stack: err }); + } + return 'private'; + }) + ) + ); + const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/); const url = getOneApHrefNullable(person.url); @@ -357,6 +372,8 @@ export class ApPersonService implements OnModuleInit { description: _description, url, fields, + followingVisibility, + followersVisibility, birthday: bday?.[0] ?? null, location: person['vcard:Address'] ?? null, userHost: host, @@ -464,6 +481,23 @@ export class ApPersonService implements OnModuleInit { const tags = extractApHashtags(person.tag).map(normalizeForSearch).splice(0, 32); + const [followingVisibility, followersVisibility] = await Promise.all( + [ + this.isPublicCollection(person.following, resolver), + this.isPublicCollection(person.followers, resolver), + ].map((p): Promise<'public' | 'private' | undefined> => p + .then(isPublic => isPublic ? 'public' : 'private') + .catch(err => { + if (!(err instanceof StatusError) || err.isRetryable) { + this.logger.error('error occurred while fetching following/followers collection', { stack: err }); + // Do not update the visibiility on transient errors. + return undefined; + } + return 'private'; + }) + ) + ); + const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/); const url = getOneApHrefNullable(person.url); @@ -532,6 +566,8 @@ export class ApPersonService implements OnModuleInit { url, fields, description: _description, + followingVisibility, + followersVisibility, birthday: bday?.[0] ?? null, location: person['vcard:Address'] ?? null, }); @@ -703,4 +739,16 @@ export class ApPersonService implements OnModuleInit { return 'ok'; } + + @bindThis + private async isPublicCollection(collection: string | ICollection | IOrderedCollection | undefined, resolver: Resolver): Promise { + if (collection) { + const resolved = await resolver.resolveCollection(collection); + if (resolved.first || (resolved as ICollection).items || (resolved as IOrderedCollection).orderedItems) { + return true; + } + } + + return false; + } } diff --git a/packages/backend/src/core/activitypub/type.ts b/packages/backend/src/core/activitypub/type.ts index 5b6c6c8ca6cb..131c518c0afa 100644 --- a/packages/backend/src/core/activitypub/type.ts +++ b/packages/backend/src/core/activitypub/type.ts @@ -97,13 +97,15 @@ export interface IActivity extends IObject { export interface ICollection extends IObject { type: 'Collection'; totalItems: number; - items: ApObject; + first?: IObject | string; + items?: ApObject; } export interface IOrderedCollection extends IObject { type: 'OrderedCollection'; totalItems: number; - orderedItems: ApObject; + first?: IObject | string; + orderedItems?: ApObject; } export const validPost = ['Note', 'Question', 'Article', 'Audio', 'Document', 'Image', 'Page', 'Video', 'Event']; diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 7fd093c1913a..9bf568bc9088 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -454,12 +454,12 @@ export class UserEntityService implements OnModuleInit { } const followingCount = profile == null ? null : - (profile.followingVisibility === 'public') || isMe ? user.followingCount : + (profile.followingVisibility === 'public') || isMe || iAmModerator ? user.followingCount : (profile.followingVisibility === 'followers') && (relation && relation.isFollowing) ? user.followingCount : null; const followersCount = profile == null ? null : - (profile.followersVisibility === 'public') || isMe ? user.followersCount : + (profile.followersVisibility === 'public') || isMe || iAmModerator ? user.followersCount : (profile.followersVisibility === 'followers') && (relation && relation.isFollowing) ? user.followersCount : null; diff --git a/packages/backend/src/server/api/endpoints/users/followers.ts b/packages/backend/src/server/api/endpoints/users/followers.ts index 7ce7734f53ff..a8b4319a61c1 100644 --- a/packages/backend/src/server/api/endpoints/users/followers.ts +++ b/packages/backend/src/server/api/endpoints/users/followers.ts @@ -11,6 +11,7 @@ import { QueryService } from '@/core/QueryService.js'; import { FollowingEntityService } from '@/core/entities/FollowingEntityService.js'; import { UtilityService } from '@/core/UtilityService.js'; import { DI } from '@/di-symbols.js'; +import { RoleService } from '@/core/RoleService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -81,6 +82,7 @@ export default class extends Endpoint { // eslint- private utilityService: UtilityService, private followingEntityService: FollowingEntityService, private queryService: QueryService, + private roleService: RoleService, ) { super(meta, paramDef, async (ps, me) => { const user = await this.usersRepository.findOneBy(ps.userId != null @@ -93,22 +95,24 @@ export default class extends Endpoint { // eslint- const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id }); - if (profile.followersVisibility === 'private') { - if (me == null || (me.id !== user.id)) { - throw new ApiError(meta.errors.forbidden); - } - } else if (profile.followersVisibility === 'followers') { - if (me == null) { - throw new ApiError(meta.errors.forbidden); - } else if (me.id !== user.id) { - const isFollowing = await this.followingsRepository.exists({ - where: { - followeeId: user.id, - followerId: me.id, - }, - }); - if (!isFollowing) { + if (profile.followersVisibility !== 'public' && !await this.roleService.isModerator(me)) { + if (profile.followersVisibility === 'private') { + if (me == null || (me.id !== user.id)) { + throw new ApiError(meta.errors.forbidden); + } + } else if (profile.followersVisibility === 'followers') { + if (me == null) { throw new ApiError(meta.errors.forbidden); + } else if (me.id !== user.id) { + const isFollowing = await this.followingsRepository.exists({ + where: { + followeeId: user.id, + followerId: me.id, + }, + }); + if (!isFollowing) { + throw new ApiError(meta.errors.forbidden); + } } } } diff --git a/packages/backend/src/server/api/endpoints/users/following.ts b/packages/backend/src/server/api/endpoints/users/following.ts index 6b3389f0b242..feda5bb353b3 100644 --- a/packages/backend/src/server/api/endpoints/users/following.ts +++ b/packages/backend/src/server/api/endpoints/users/following.ts @@ -12,6 +12,7 @@ import { QueryService } from '@/core/QueryService.js'; import { FollowingEntityService } from '@/core/entities/FollowingEntityService.js'; import { UtilityService } from '@/core/UtilityService.js'; import { DI } from '@/di-symbols.js'; +import { RoleService } from '@/core/RoleService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -90,6 +91,7 @@ export default class extends Endpoint { // eslint- private utilityService: UtilityService, private followingEntityService: FollowingEntityService, private queryService: QueryService, + private roleService: RoleService, ) { super(meta, paramDef, async (ps, me) => { const user = await this.usersRepository.findOneBy(ps.userId != null @@ -102,22 +104,24 @@ export default class extends Endpoint { // eslint- const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id }); - if (profile.followingVisibility === 'private') { - if (me == null || (me.id !== user.id)) { - throw new ApiError(meta.errors.forbidden); - } - } else if (profile.followingVisibility === 'followers') { - if (me == null) { - throw new ApiError(meta.errors.forbidden); - } else if (me.id !== user.id) { - const isFollowing = await this.followingsRepository.exists({ - where: { - followeeId: user.id, - followerId: me.id, - }, - }); - if (!isFollowing) { + if (profile.followingVisibility !== 'public' && !await this.roleService.isModerator(me)) { + if (profile.followingVisibility === 'private') { + if (me == null || (me.id !== user.id)) { + throw new ApiError(meta.errors.forbidden); + } + } else if (profile.followingVisibility === 'followers') { + if (me == null) { throw new ApiError(meta.errors.forbidden); + } else if (me.id !== user.id) { + const isFollowing = await this.followingsRepository.exists({ + where: { + followeeId: user.id, + followerId: me.id, + }, + }); + if (!isFollowing) { + throw new ApiError(meta.errors.forbidden); + } } } } diff --git a/packages/backend/test/unit/activitypub.ts b/packages/backend/test/unit/activitypub.ts index 696260810677..763ce2b336b6 100644 --- a/packages/backend/test/unit/activitypub.ts +++ b/packages/backend/test/unit/activitypub.ts @@ -20,7 +20,8 @@ import { CoreModule } from '@/core/CoreModule.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import { LoggerService } from '@/core/LoggerService.js'; import type { IActor, IApDocument, ICollection, IObject, IPost } from '@/core/activitypub/type.js'; -import { MiMeta, MiNote } from '@/models/_.js'; +import { MiMeta, MiNote, UserProfilesRepository } from '@/models/_.js'; +import { DI } from '@/di-symbols.js'; import { secureRndstr } from '@/misc/secure-rndstr.js'; import { DownloadService } from '@/core/DownloadService.js'; import { MetaService } from '@/core/MetaService.js'; @@ -86,6 +87,7 @@ async function createRandomRemoteUser( } describe('ActivityPub', () => { + let userProfilesRepository: UserProfilesRepository; let imageService: ApImageService; let noteService: ApNoteService; let personService: ApPersonService; @@ -127,6 +129,8 @@ describe('ActivityPub', () => { await app.init(); app.enableShutdownHooks(); + userProfilesRepository = app.get(DI.userProfilesRepository); + noteService = app.get(ApNoteService); personService = app.get(ApPersonService); rendererService = app.get(ApRendererService); @@ -205,6 +209,53 @@ describe('ActivityPub', () => { }); }); + describe('Collection visibility', () => { + test('Public following/followers', async () => { + const actor = createRandomActor(); + actor.following = { + id: `${actor.id}/following`, + type: 'OrderedCollection', + totalItems: 0, + first: `${actor.id}/following?page=1`, + }; + actor.followers = `${actor.id}/followers`; + + resolver.register(actor.id, actor); + resolver.register(actor.followers, { + id: actor.followers, + type: 'OrderedCollection', + totalItems: 0, + first: `${actor.followers}?page=1`, + }); + + const user = await personService.createPerson(actor.id, resolver); + const userProfile = await userProfilesRepository.findOneByOrFail({ userId: user.id }); + + assert.deepStrictEqual(userProfile.followingVisibility, 'public'); + assert.deepStrictEqual(userProfile.followersVisibility, 'public'); + }); + + test('Private following/followers', async () => { + const actor = createRandomActor(); + actor.following = { + id: `${actor.id}/following`, + type: 'OrderedCollection', + totalItems: 0, + // first: … + }; + actor.followers = `${actor.id}/followers`; + + resolver.register(actor.id, actor); + //resolver.register(actor.followers, { … }); + + const user = await personService.createPerson(actor.id, resolver); + const userProfile = await userProfilesRepository.findOneByOrFail({ userId: user.id }); + + assert.deepStrictEqual(userProfile.followingVisibility, 'private'); + assert.deepStrictEqual(userProfile.followersVisibility, 'private'); + }); + }); + describe('Renderer', () => { test('Render an announce with visibility: followers', () => { rendererService.renderAnnounce('https://example.com/notes/00example', { diff --git a/packages/frontend/src/scripts/isFfVisibleForMe.ts b/packages/frontend/src/scripts/isFfVisibleForMe.ts index 406404c4622c..e28e5725bc91 100644 --- a/packages/frontend/src/scripts/isFfVisibleForMe.ts +++ b/packages/frontend/src/scripts/isFfVisibleForMe.ts @@ -7,7 +7,7 @@ import * as Misskey from 'misskey-js'; import { $i } from '@/account.js'; export function isFollowingVisibleForMe(user: Misskey.entities.UserDetailed): boolean { - if ($i && $i.id === user.id) return true; + if ($i && ($i.id === user.id || $i.isAdmin || $i.isModerator)) return true; if (user.followingVisibility === 'private') return false; if (user.followingVisibility === 'followers' && !user.isFollowing) return false; @@ -15,7 +15,7 @@ export function isFollowingVisibleForMe(user: Misskey.entities.UserDetailed): bo return true; } export function isFollowersVisibleForMe(user: Misskey.entities.UserDetailed): boolean { - if ($i && $i.id === user.id) return true; + if ($i && ($i.id === user.id || $i.isAdmin || $i.isModerator)) return true; if (user.followersVisibility === 'private') return false; if (user.followersVisibility === 'followers' && !user.isFollowing) return false; From f50941389d8724442ce2d7326afe9fbdadd3b58e Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Fri, 9 Aug 2024 16:04:41 +0900 Subject: [PATCH 216/268] fix: readAllNotifications message not working (#14374) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: add and use isJsonObject * fix: readNotification message without body is not working * docs(changelog): WSの`readAllNotifications` メッセージが `body` を持たない場合に動作しない問題 * Update CHANGELOG.md Co-authored-by: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com> --------- Co-authored-by: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com> --- CHANGELOG.md | 4 ++- packages/backend/src/misc/json-value.ts | 4 +++ .../src/server/api/stream/Connection.ts | 27 +++++++++++-------- .../server/api/stream/channels/queue-stats.ts | 3 ++- .../api/stream/channels/reversi-game.ts | 7 ++--- .../api/stream/channels/server-stats.ts | 3 ++- 6 files changed, 31 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c18cccc44e83..fa0bc6282b86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,9 @@ - ### Server -- +- Fix: WSの`readAllNotifications` メッセージが `body` を持たない場合に動作しない問題 #14374 + - 通知ページや通知カラム(デッキ)を開いている状態において、新たに発生した通知が既読されない問題が修正されます。 + - これにより、プッシュ通知が有効な同条件下の環境において、プッシュ通知が常に発生してしまう問題も修正されます。 ## 2024.7.0 diff --git a/packages/backend/src/misc/json-value.ts b/packages/backend/src/misc/json-value.ts index 79944417915e..bd7fe12058a0 100644 --- a/packages/backend/src/misc/json-value.ts +++ b/packages/backend/src/misc/json-value.ts @@ -6,3 +6,7 @@ export type JsonValue = JsonArray | JsonObject | string | number | boolean | null; export type JsonObject = {[K in string]?: JsonValue}; export type JsonArray = JsonValue[]; + +export function isJsonObject(value: JsonValue | undefined): value is JsonObject { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} diff --git a/packages/backend/src/server/api/stream/Connection.ts b/packages/backend/src/server/api/stream/Connection.ts index 96082827f81f..7773150b74d5 100644 --- a/packages/backend/src/server/api/stream/Connection.ts +++ b/packages/backend/src/server/api/stream/Connection.ts @@ -14,7 +14,8 @@ import { CacheService } from '@/core/CacheService.js'; import { MiFollowing, MiUserProfile } from '@/models/_.js'; import type { StreamEventEmitter, GlobalEvents } from '@/core/GlobalEventService.js'; import { ChannelFollowingService } from '@/core/ChannelFollowingService.js'; -import type { JsonObject } from '@/misc/json-value.js'; +import { isJsonObject } from '@/misc/json-value.js'; +import type { JsonObject, JsonValue } from '@/misc/json-value.js'; import type { ChannelsService } from './ChannelsService.js'; import type { EventEmitter } from 'events'; import type Channel from './channel.js'; @@ -112,8 +113,6 @@ export default class Connection { const { type, body } = obj; - if (typeof body !== 'object' || body === null || Array.isArray(body)) return; - switch (type) { case 'readNotification': this.onReadNotification(body); break; case 'subNote': this.onSubscribeNote(body); break; @@ -154,7 +153,8 @@ export default class Connection { } @bindThis - private readNote(body: JsonObject) { + private readNote(body: JsonValue | undefined) { + if (!isJsonObject(body)) return; const id = body.id; const note = this.cachedNotes.find(n => n.id === id); @@ -166,7 +166,7 @@ export default class Connection { } @bindThis - private onReadNotification(payload: JsonObject) { + private onReadNotification(payload: JsonValue | undefined) { this.notificationService.readAllNotification(this.user!.id); } @@ -174,7 +174,8 @@ export default class Connection { * 投稿購読要求時 */ @bindThis - private onSubscribeNote(payload: JsonObject) { + private onSubscribeNote(payload: JsonValue | undefined) { + if (!isJsonObject(payload)) return; if (!payload.id || typeof payload.id !== 'string') return; const current = this.subscribingNotes[payload.id] ?? 0; @@ -190,7 +191,8 @@ export default class Connection { * 投稿購読解除要求時 */ @bindThis - private onUnsubscribeNote(payload: JsonObject) { + private onUnsubscribeNote(payload: JsonValue | undefined) { + if (!isJsonObject(payload)) return; if (!payload.id || typeof payload.id !== 'string') return; const current = this.subscribingNotes[payload.id]; @@ -216,12 +218,13 @@ export default class Connection { * チャンネル接続要求時 */ @bindThis - private onChannelConnectRequested(payload: JsonObject) { + private onChannelConnectRequested(payload: JsonValue | undefined) { + if (!isJsonObject(payload)) return; const { channel, id, params, pong } = payload; if (typeof id !== 'string') return; if (typeof channel !== 'string') return; if (typeof pong !== 'boolean' && typeof pong !== 'undefined' && pong !== null) return; - if (typeof params !== 'undefined' && (typeof params !== 'object' || params === null || Array.isArray(params))) return; + if (typeof params !== 'undefined' && !isJsonObject(params)) return; this.connectChannel(id, params, channel, pong ?? undefined); } @@ -229,7 +232,8 @@ export default class Connection { * チャンネル切断要求時 */ @bindThis - private onChannelDisconnectRequested(payload: JsonObject) { + private onChannelDisconnectRequested(payload: JsonValue | undefined) { + if (!isJsonObject(payload)) return; const { id } = payload; if (typeof id !== 'string') return; this.disconnectChannel(id); @@ -297,7 +301,8 @@ export default class Connection { * @param data メッセージ */ @bindThis - private onChannelMessageRequested(data: JsonObject) { + private onChannelMessageRequested(data: JsonValue | undefined) { + if (!isJsonObject(data)) return; if (typeof data.id !== 'string') return; if (typeof data.type !== 'string') return; if (typeof data.body === 'undefined') return; diff --git a/packages/backend/src/server/api/stream/channels/queue-stats.ts b/packages/backend/src/server/api/stream/channels/queue-stats.ts index ff7e7402261b..91b62255b4f6 100644 --- a/packages/backend/src/server/api/stream/channels/queue-stats.ts +++ b/packages/backend/src/server/api/stream/channels/queue-stats.ts @@ -6,6 +6,7 @@ import Xev from 'xev'; import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; +import { isJsonObject } from '@/misc/json-value.js'; import type { JsonObject, JsonValue } from '@/misc/json-value.js'; import Channel, { type MiChannelService } from '../channel.js'; @@ -36,7 +37,7 @@ class QueueStatsChannel extends Channel { public onMessage(type: string, body: JsonValue) { switch (type) { case 'requestLog': - if (typeof body !== 'object' || body === null || Array.isArray(body)) return; + if (!isJsonObject(body)) return; if (typeof body.id !== 'string') return; if (typeof body.length !== 'number') return; ev.once(`queueStatsLog:${body.id}`, statsLog => { diff --git a/packages/backend/src/server/api/stream/channels/reversi-game.ts b/packages/backend/src/server/api/stream/channels/reversi-game.ts index 17823a164a2d..c6f4a4ae3b9a 100644 --- a/packages/backend/src/server/api/stream/channels/reversi-game.ts +++ b/packages/backend/src/server/api/stream/channels/reversi-game.ts @@ -9,6 +9,7 @@ import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import { ReversiService } from '@/core/ReversiService.js'; import { ReversiGameEntityService } from '@/core/entities/ReversiGameEntityService.js'; +import { isJsonObject } from '@/misc/json-value.js'; import type { JsonObject, JsonValue } from '@/misc/json-value.js'; import Channel, { type MiChannelService } from '../channel.js'; @@ -44,16 +45,16 @@ class ReversiGameChannel extends Channel { this.ready(body); break; case 'updateSettings': - if (typeof body !== 'object' || body === null || Array.isArray(body)) return; + if (!isJsonObject(body)) return; if (typeof body.key !== 'string') return; - if (typeof body.value !== 'object' || body.value === null || Array.isArray(body.value)) return; + if (!isJsonObject(body.value)) return; this.updateSettings(body.key, body.value); break; case 'cancel': this.cancelGame(); break; case 'putStone': - if (typeof body !== 'object' || body === null || Array.isArray(body)) return; + if (!isJsonObject(body)) return; if (typeof body.pos !== 'number') return; if (typeof body.id !== 'string') return; this.putStone(body.pos, body.id); diff --git a/packages/backend/src/server/api/stream/channels/server-stats.ts b/packages/backend/src/server/api/stream/channels/server-stats.ts index 6258afba35c3..ec5352d12dba 100644 --- a/packages/backend/src/server/api/stream/channels/server-stats.ts +++ b/packages/backend/src/server/api/stream/channels/server-stats.ts @@ -6,6 +6,7 @@ import Xev from 'xev'; import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; +import { isJsonObject } from '@/misc/json-value.js'; import type { JsonObject, JsonValue } from '@/misc/json-value.js'; import Channel, { type MiChannelService } from '../channel.js'; @@ -36,7 +37,7 @@ class ServerStatsChannel extends Channel { public onMessage(type: string, body: JsonValue) { switch (type) { case 'requestLog': - if (typeof body !== 'object' || body === null || Array.isArray(body)) return; + if (!isJsonObject(body)) return; ev.once(`serverStatsLog:${body.id}`, statsLog => { this.send('statsLog', statsLog); }); From 01a815f8a716f65dbd977d533d638eb69561136a Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Sat, 10 Aug 2024 09:34:49 +0900 Subject: [PATCH 217/268] fix(general): some fixes and improvements of Play visibility (#14384) * fix(backend): missing `visibility` param in packing flash * fix(frontend): use `visibility` value got from API * enhance(frontend): change preview appearance of private Play * Update CHANGELOG.md --- CHANGELOG.md | 4 +- .../src/core/entities/FlashEntityService.ts | 1 + .../backend/src/models/json-schema/flash.ts | 5 ++ packages/frontend/.storybook/fakes.ts | 35 ++++++++++++ packages/frontend/.storybook/generate.tsx | 1 + .../components/MkFlashPreview.stories.impl.ts | 53 +++++++++++++++++++ .../src/components/MkFlashPreview.vue | 12 +++-- .../frontend/src/pages/flash/flash-edit.vue | 2 +- packages/misskey-js/src/autogen/types.ts | 2 + 9 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 packages/frontend/src/components/MkFlashPreview.stories.impl.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index fa0bc6282b86..7128499c7992 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,14 @@ - Enhance: モデレーターはすべてのユーザーのフォロー・フォロワーの一覧を見られるように ### Client -- +- Enhance: 「自分のPlay」ページにおいてPlayが非公開かどうかが一目でわかるように +- Fix: Play編集時に公開範囲が「パブリック」にリセットされる問題を修正 ### Server - Fix: WSの`readAllNotifications` メッセージが `body` を持たない場合に動作しない問題 #14374 - 通知ページや通知カラム(デッキ)を開いている状態において、新たに発生した通知が既読されない問題が修正されます。 - これにより、プッシュ通知が有効な同条件下の環境において、プッシュ通知が常に発生してしまう問題も修正されます。 +- Fix: Play各種エンドポイントの返り値に`visibility`が含まれていない問題を修正 ## 2024.7.0 diff --git a/packages/backend/src/core/entities/FlashEntityService.ts b/packages/backend/src/core/entities/FlashEntityService.ts index d110f7afc632..4aa7104c1e32 100644 --- a/packages/backend/src/core/entities/FlashEntityService.ts +++ b/packages/backend/src/core/entities/FlashEntityService.ts @@ -49,6 +49,7 @@ export class FlashEntityService { title: flash.title, summary: flash.summary, script: flash.script, + visibility: flash.visibility, likedCount: flash.likedCount, isLiked: meId ? await this.flashLikesRepository.exists({ where: { flashId: flash.id, userId: meId } }) : undefined, }); diff --git a/packages/backend/src/models/json-schema/flash.ts b/packages/backend/src/models/json-schema/flash.ts index 952df649adad..42b2172409e9 100644 --- a/packages/backend/src/models/json-schema/flash.ts +++ b/packages/backend/src/models/json-schema/flash.ts @@ -44,6 +44,11 @@ export const packedFlashSchema = { type: 'string', optional: false, nullable: false, }, + visibility: { + type: 'string', + optional: false, nullable: false, + enum: ['private', 'public'], + }, likedCount: { type: 'number', optional: false, nullable: true, diff --git a/packages/frontend/.storybook/fakes.ts b/packages/frontend/.storybook/fakes.ts index ab04d3e60c78..fc3b0334e470 100644 --- a/packages/frontend/.storybook/fakes.ts +++ b/packages/frontend/.storybook/fakes.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { AISCRIPT_VERSION } from '@syuilo/aiscript'; import type { entities } from 'misskey-js' export function abuseUserReport() { @@ -114,6 +115,40 @@ export function file(isSensitive = false) { }; } +const script = `/// @ ${AISCRIPT_VERSION} + +var name = "" + +Ui:render([ + Ui:C:textInput({ + label: "Your name" + onInput: @(v) { name = v } + }) + Ui:C:button({ + text: "Hello" + onClick: @() { + Mk:dialog(null, \`Hello, {name}!\`) + } + }) +]) +`; + +export function flash(): entities.Flash { + return { + id: 'someflashid', + createdAt: '2016-12-28T22:49:51.000Z', + updatedAt: '2016-12-28T22:49:51.000Z', + userId: 'someuserid', + user: userLite(), + title: 'Some Play title', + summary: 'Some Play summary', + script, + visibility: 'public', + likedCount: 0, + isLiked: false, + }; +} + export function folder(id = 'somefolderid', name = 'Some Folder', parentId: string | null = null): entities.DriveFolder { return { id, diff --git a/packages/frontend/.storybook/generate.tsx b/packages/frontend/.storybook/generate.tsx index 52c01aaf702c..490a441b7055 100644 --- a/packages/frontend/.storybook/generate.tsx +++ b/packages/frontend/.storybook/generate.tsx @@ -398,6 +398,7 @@ function toStories(component: string): Promise { glob('src/components/global/Mk*.vue'), glob('src/components/global/RouterView.vue'), glob('src/components/Mk[A-E]*.vue'), + glob('src/components/MkFlashPreview.vue'), glob('src/components/MkGalleryPostPreview.vue'), glob('src/components/MkSignupServerRules.vue'), glob('src/components/MkUserSetupDialog.vue'), diff --git a/packages/frontend/src/components/MkFlashPreview.stories.impl.ts b/packages/frontend/src/components/MkFlashPreview.stories.impl.ts new file mode 100644 index 000000000000..fa5288b73da0 --- /dev/null +++ b/packages/frontend/src/components/MkFlashPreview.stories.impl.ts @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { StoryObj } from '@storybook/vue3'; +import MkFlashPreview from './MkFlashPreview.vue'; +import { flash } from './../../.storybook/fakes.js'; +export const Public = { + render(args) { + return { + components: { + MkFlashPreview, + }, + setup() { + return { + args, + }; + }, + computed: { + props() { + return { + ...this.args, + }; + }, + }, + template: '', + }; + }, + args: { + flash: { + ...flash(), + visibility: 'public', + }, + }, + parameters: { + layout: 'fullscreen', + }, + decorators: [ + () => ({ + template: '
', + }), + ], +} satisfies StoryObj; +export const Private = { + ...Public, + args: { + flash: { + ...flash(), + visibility: 'private', + }, + }, +} satisfies StoryObj; diff --git a/packages/frontend/src/components/MkFlashPreview.vue b/packages/frontend/src/components/MkFlashPreview.vue index 6783804cc587..8a2a4386240a 100644 --- a/packages/frontend/src/components/MkFlashPreview.vue +++ b/packages/frontend/src/components/MkFlashPreview.vue @@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only -->