Compare commits

...

12 Commits

Author SHA1 Message Date
かっこかり 0589deaf88
Merge 77b2bb20db into 7d7a12d7d6 2024-09-15 22:04:24 +09:00
かっこかり 7d7a12d7d6
fix(deps): broken lockfile (#14556) 2024-09-15 21:57:22 +09:00
dependabot[bot] 887c709647
chore(deps): bump body-parser from 1.20.2 to 1.20.3 in /packages/backend (#14550)
Bumps [body-parser](https://github.com/expressjs/body-parser) from 1.20.2 to 1.20.3.
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/1.20.2...1.20.3)

---
updated-dependencies:
- dependency-name: body-parser
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-15 20:54:26 +09:00
かっこかり 0e4b6d1dad
enhance(frontend): adminのファイルリストでセンシティブファイルに枠線を追加 (#14510)
* enhance(frontend): adminのファイルリストでセンシティブファイルに枠線を追加

* Update Changelog
2024-09-15 17:50:25 +09:00
Juan Aguilar Santillana 07f26bc8dd
refactor(backend): use Reflet for autobind deco (#14482)
Using Reflect.defineProperty instead of Object.defineProperty
gives a more consistent behavior with the rest of the modern
JavaScript features.
2024-09-15 17:43:24 +09:00
kakkokari-gtyih 77b2bb20db Merge branch 'develop' into feat-14456 2024-09-13 11:12:08 +09:00
かっこかり 9c27da00ef
Merge branch 'develop' into feat-14456 2024-09-06 14:48:33 +09:00
kakkokari-gtyih b167d94ba1 fix icon 2024-09-01 17:54:33 +09:00
kakkokari-gtyih 162cf4071f fix: ペイロードを含むように 2024-09-01 15:06:21 +09:00
kakkokari-gtyih dacf79191e entitity -> entity 2024-09-01 15:01:30 +09:00
kakkokari-gtyih 2444b52892 Update Changelog 2024-09-01 13:33:51 +09:00
kakkokari-gtyih a61e638a3b feat: エクスポート完了時に通知を発行するように 2024-09-01 13:30:21 +09:00
26 changed files with 374 additions and 148 deletions

View File

@ -1,13 +1,14 @@
## Unreleased
### General
-
- Feat: データエクスポートが完了した際に通知を発行するように
### Client
- Feat: ノート単体・ユーザーのノート・クリップのノートの埋め込み機能
- 埋め込みコードやウェブサイトへの実装方法の詳細はMisskey Hubに掲載予定です
- Enhance: サイズ制限を超過するファイルをアップロードしようとした際にエラーを出すように
- Enhance: アイコンデコレーション管理画面にプレビューを追加
- Enhance: コントロールパネル内のファイル一覧でセンシティブなファイルを区別しやすく
- Fix: サーバーメトリクスが2つ以上あるとリロード直後の表示がおかしくなる問題を修正
- Fix: 月の違う同じ日はセパレータが表示されないのを修正

16
locales/index.d.ts vendored
View File

@ -1352,6 +1352,10 @@ export interface Locale extends ILocale {
*
*/
"addFile": string;
/**
*
*/
"showFile": string;
/**
*
*/
@ -9177,6 +9181,10 @@ export interface Locale extends ILocale {
*
*/
"flushNotification": string;
/**
* {x}
*/
"exportOfXCompleted": ParameterizedString<"x">;
"_types": {
/**
*
@ -9230,6 +9238,14 @@ export interface Locale extends ILocale {
*
*/
"achievementEarned": string;
/**
*
*/
"exportCompleted": string;
/**
*
*/
"test": string;
/**
*
*/

View File

@ -334,6 +334,7 @@ renameFolder: "フォルダー名を変更"
deleteFolder: "フォルダーを削除"
folder: "フォルダー"
addFile: "ファイルを追加"
showFile: "ファイルを表示"
emptyDrive: "ドライブは空です"
emptyFolder: "フォルダーは空です"
unableToDelete: "削除できません"
@ -2424,6 +2425,7 @@ _notification:
renotedBySomeUsers: "{n}人がリノートしました"
followedBySomeUsers: "{n}人にフォローされました"
flushNotification: "通知の履歴をリセットする"
exportOfXCompleted: "{x}のエクスポートが完了しました"
_types:
all: "すべて"
@ -2439,6 +2441,8 @@ _notification:
followRequestAccepted: "フォローが受理された"
roleAssigned: "ロールが付与された"
achievementEarned: "実績の獲得"
exportCompleted: "エクスポートが完了した"
test: "通知のテスト"
app: "連携アプリからの通知"
_actions:

View File

@ -100,7 +100,7 @@
"async-mutex": "0.5.0",
"bcryptjs": "2.4.3",
"blurhash": "2.0.5",
"body-parser": "1.20.2",
"body-parser": "1.20.3",
"bullmq": "5.10.4",
"cacheable-lookup": "7.0.0",
"cbor": "9.0.2",

View File

@ -162,6 +162,10 @@ export class NotificationEntityService implements OnModuleInit {
...(notification.type === 'achievementEarned' ? {
achievement: notification.achievement,
} : {}),
...(notification.type === 'exportCompleted' ? {
exportedEntity: notification.exportedEntity,
fileId: notification.fileId,
} : {}),
...(notification.type === 'app' ? {
body: notification.customBody,
header: notification.customHeader,

View File

@ -10,8 +10,9 @@
* The getter will return a .bind version of the function
* and memoize the result against a symbol on the instance
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function bindThis(target: any, key: string, descriptor: any) {
let fn = descriptor.value;
const fn = descriptor.value;
if (typeof fn !== 'function') {
throw new TypeError(`@bindThis decorator can only be applied to methods not: ${typeof fn}`);
@ -21,26 +22,18 @@ export function bindThis(target: any, key: string, descriptor: any) {
configurable: true,
get() {
// eslint-disable-next-line no-prototype-builtins
if (this === target.prototype || this.hasOwnProperty(key) ||
typeof fn !== 'function') {
if (this === target.prototype || this.hasOwnProperty(key)) {
return fn;
}
const boundFn = fn.bind(this);
Object.defineProperty(this, key, {
Reflect.defineProperty(this, key, {
value: boundFn,
configurable: true,
get() {
return boundFn;
},
set(value) {
fn = value;
delete this[key];
},
writable: true,
});
return boundFn;
},
set(value: any) {
fn = value;
},
};
}

View File

@ -7,6 +7,8 @@ import { MiUser } from './User.js';
import { MiNote } from './Note.js';
import { MiAccessToken } from './AccessToken.js';
import { MiRole } from './Role.js';
import { MiDriveFile } from './DriveFile.js';
import { exportableEntities } from '@/types.js';
export type MiNotification = {
type: 'note';
@ -77,6 +79,12 @@ export type MiNotification = {
id: string;
createdAt: string;
achievement: string;
} | {
type: 'exportCompleted';
id: string;
createdAt: string;
exportedEntity: typeof exportableEntities[number];
fileId: MiDriveFile['id'];
} | {
type: 'app';
id: string;

View File

@ -4,7 +4,7 @@
*/
import { ACHIEVEMENT_TYPES } from '@/core/AchievementService.js';
import { notificationTypes } from '@/types.js';
import { notificationTypes, exportableEntities } from '@/types.js';
const baseSchema = {
type: 'object',
@ -298,6 +298,26 @@ export const packedNotificationSchema = {
enum: ACHIEVEMENT_TYPES,
},
},
}, {
type: 'object',
properties: {
...baseSchema.properties,
type: {
type: 'string',
optional: false, nullable: false,
enum: ['exportCompleted'],
},
exportedEntity: {
type: 'string',
optional: false, nullable: false,
enum: exportableEntities,
},
fileId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
},
}, {
type: 'object',
properties: {

View File

@ -14,6 +14,7 @@ import { DriveService } from '@/core/DriveService.js';
import { bindThis } from '@/decorators.js';
import { createTemp } from '@/misc/create-temp.js';
import { UtilityService } from '@/core/UtilityService.js';
import { NotificationService } from '@/core/NotificationService.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type { DBExportAntennasData } from '../types.js';
import type * as Bull from 'bullmq';
@ -35,6 +36,7 @@ export class ExportAntennasProcessorService {
private driveService: DriveService,
private utilityService: UtilityService,
private queueLoggerService: QueueLoggerService,
private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('export-antennas');
}
@ -95,6 +97,11 @@ export class ExportAntennasProcessorService {
const fileName = 'antennas-' + DateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.json';
const driveFile = await this.driveService.addFile({ user, path, name: fileName, force: true, ext: 'json' });
this.logger.succ('Exported to: ' + driveFile.id);
this.notificationService.createNotification(user.id, 'exportCompleted', {
exportedEntity: 'antenna',
fileId: driveFile.id,
});
} finally {
cleanup();
}

View File

@ -13,6 +13,7 @@ import type Logger from '@/logger.js';
import { DriveService } from '@/core/DriveService.js';
import { createTemp } from '@/misc/create-temp.js';
import { UtilityService } from '@/core/UtilityService.js';
import { NotificationService } from '@/core/NotificationService.js';
import { bindThis } from '@/decorators.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type * as Bull from 'bullmq';
@ -30,6 +31,7 @@ export class ExportBlockingProcessorService {
private blockingsRepository: BlockingsRepository,
private utilityService: UtilityService,
private notificationService: NotificationService,
private driveService: DriveService,
private queueLoggerService: QueueLoggerService,
) {
@ -109,6 +111,11 @@ export class ExportBlockingProcessorService {
const driveFile = await this.driveService.addFile({ user, path, name: fileName, force: true, ext: 'csv' });
this.logger.succ(`Exported to: ${driveFile.id}`);
this.notificationService.createNotification(user.id, 'exportCompleted', {
exportedEntity: 'blocking',
fileId: driveFile.id,
});
} finally {
cleanup();
}

View File

@ -19,6 +19,7 @@ import { bindThis } from '@/decorators.js';
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
import { Packed } from '@/misc/json-schema.js';
import { IdService } from '@/core/IdService.js';
import { NotificationService } from '@/core/NotificationService.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type * as Bull from 'bullmq';
import type { DbJobDataWithUser } from '../types.js';
@ -43,6 +44,7 @@ export class ExportClipsProcessorService {
private driveService: DriveService,
private queueLoggerService: QueueLoggerService,
private idService: IdService,
private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('export-clips');
}
@ -79,6 +81,11 @@ export class ExportClipsProcessorService {
const driveFile = await this.driveService.addFile({ user, path, name: fileName, force: true, ext: 'json' });
this.logger.succ(`Exported to: ${driveFile.id}`);
this.notificationService.createNotification(user.id, 'exportCompleted', {
exportedEntity: 'clip',
fileId: driveFile.id,
});
} finally {
cleanup();
}

View File

@ -16,6 +16,7 @@ import type Logger from '@/logger.js';
import { DriveService } from '@/core/DriveService.js';
import { createTemp, createTempDir } from '@/misc/create-temp.js';
import { DownloadService } from '@/core/DownloadService.js';
import { NotificationService } from '@/core/NotificationService.js';
import { bindThis } from '@/decorators.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type * as Bull from 'bullmq';
@ -37,6 +38,7 @@ export class ExportCustomEmojisProcessorService {
private driveService: DriveService,
private downloadService: DownloadService,
private queueLoggerService: QueueLoggerService,
private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('export-custom-emojis');
}
@ -134,6 +136,12 @@ export class ExportCustomEmojisProcessorService {
const driveFile = await this.driveService.addFile({ user, path: archivePath, name: fileName, force: true });
this.logger.succ(`Exported to: ${driveFile.id}`);
this.notificationService.createNotification(user.id, 'exportCompleted', {
exportedEntity: 'customEmoji',
fileId: driveFile.id,
});
cleanup();
archiveCleanup();
resolve();

View File

@ -16,6 +16,7 @@ import type { MiPoll } from '@/models/Poll.js';
import type { MiNote } from '@/models/Note.js';
import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { NotificationService } from '@/core/NotificationService.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type * as Bull from 'bullmq';
import type { DbJobDataWithUser } from '../types.js';
@ -37,6 +38,7 @@ export class ExportFavoritesProcessorService {
private driveService: DriveService,
private queueLoggerService: QueueLoggerService,
private idService: IdService,
private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('export-favorites');
}
@ -123,6 +125,11 @@ export class ExportFavoritesProcessorService {
const driveFile = await this.driveService.addFile({ user, path, name: fileName, force: true, ext: 'json' });
this.logger.succ(`Exported to: ${driveFile.id}`);
this.notificationService.createNotification(user.id, 'exportCompleted', {
exportedEntity: 'favorite',
fileId: driveFile.id,
});
} finally {
cleanup();
}

View File

@ -14,6 +14,7 @@ import { DriveService } from '@/core/DriveService.js';
import { createTemp } from '@/misc/create-temp.js';
import type { MiFollowing } from '@/models/Following.js';
import { UtilityService } from '@/core/UtilityService.js';
import { NotificationService } from '@/core/NotificationService.js';
import { bindThis } from '@/decorators.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type * as Bull from 'bullmq';
@ -36,6 +37,7 @@ export class ExportFollowingProcessorService {
private utilityService: UtilityService,
private driveService: DriveService,
private queueLoggerService: QueueLoggerService,
private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('export-following');
}
@ -113,6 +115,11 @@ export class ExportFollowingProcessorService {
const driveFile = await this.driveService.addFile({ user, path, name: fileName, force: true, ext: 'csv' });
this.logger.succ(`Exported to: ${driveFile.id}`);
this.notificationService.createNotification(user.id, 'exportCompleted', {
exportedEntity: 'following',
fileId: driveFile.id,
});
} finally {
cleanup();
}

View File

@ -13,6 +13,7 @@ import type Logger from '@/logger.js';
import { DriveService } from '@/core/DriveService.js';
import { createTemp } from '@/misc/create-temp.js';
import { UtilityService } from '@/core/UtilityService.js';
import { NotificationService } from '@/core/NotificationService.js';
import { bindThis } from '@/decorators.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type * as Bull from 'bullmq';
@ -32,6 +33,7 @@ export class ExportMutingProcessorService {
private utilityService: UtilityService,
private driveService: DriveService,
private queueLoggerService: QueueLoggerService,
private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('export-muting');
}
@ -110,6 +112,11 @@ export class ExportMutingProcessorService {
const driveFile = await this.driveService.addFile({ user, path, name: fileName, force: true, ext: 'csv' });
this.logger.succ(`Exported to: ${driveFile.id}`);
this.notificationService.createNotification(user.id, 'exportCompleted', {
exportedEntity: 'muting',
fileId: driveFile.id,
});
} finally {
cleanup();
}

View File

@ -18,6 +18,7 @@ import { bindThis } from '@/decorators.js';
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
import { Packed } from '@/misc/json-schema.js';
import { IdService } from '@/core/IdService.js';
import { NotificationService } from '@/core/NotificationService.js';
import { JsonArrayStream } from '@/misc/JsonArrayStream.js';
import { FileWriterStream } from '@/misc/FileWriterStream.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
@ -112,6 +113,7 @@ export class ExportNotesProcessorService {
private queueLoggerService: QueueLoggerService,
private driveFileEntityService: DriveFileEntityService,
private idService: IdService,
private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('export-notes');
}
@ -150,6 +152,11 @@ export class ExportNotesProcessorService {
const driveFile = await this.driveService.addFile({ user, path, name: fileName, force: true, ext: 'json' });
this.logger.succ(`Exported to: ${driveFile.id}`);
this.notificationService.createNotification(user.id, 'exportCompleted', {
exportedEntity: 'note',
fileId: driveFile.id,
});
} finally {
cleanup();
}

View File

@ -13,6 +13,7 @@ import type Logger from '@/logger.js';
import { DriveService } from '@/core/DriveService.js';
import { createTemp } from '@/misc/create-temp.js';
import { UtilityService } from '@/core/UtilityService.js';
import { NotificationService } from '@/core/NotificationService.js';
import { bindThis } from '@/decorators.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type * as Bull from 'bullmq';
@ -35,6 +36,7 @@ export class ExportUserListsProcessorService {
private utilityService: UtilityService,
private driveService: DriveService,
private queueLoggerService: QueueLoggerService,
private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('export-user-lists');
}
@ -89,6 +91,11 @@ export class ExportUserListsProcessorService {
const driveFile = await this.driveService.addFile({ user, path, name: fileName, force: true, ext: 'csv' });
this.logger.succ(`Exported to: ${driveFile.id}`);
this.notificationService.createNotification(user.id, 'exportCompleted', {
exportedEntity: 'userList',
fileId: driveFile.id,
});
} finally {
cleanup();
}

View File

@ -16,6 +16,7 @@
* followRequestAccepted -
* roleAssigned -
* achievementEarned -
* exportCompleted -
* app -
* test -
*/
@ -32,6 +33,7 @@ export const notificationTypes = [
'followRequestAccepted',
'roleAssigned',
'achievementEarned',
'exportCompleted',
'app',
'test',
] as const;
@ -51,6 +53,10 @@ export const mutedNoteReasons = ['word', 'manual', 'spam', 'other'] as const;
export const followingVisibilities = ['public', 'followers', 'private'] as const;
export const followersVisibilities = ['public', 'followers', 'private'] as const;
export const exportableEntities = ['antenna', 'blocking', 'clip', 'customEmoji', 'favorite', 'following', 'muting', 'note', 'userList'] as const;
export const importableEntities = ['antenna', 'blocking', 'customEmoji', 'following', 'muting', 'userList'] as const;
export const moderationLogTypes = [
'updateServerSettings',
'suspend',

View File

@ -67,6 +67,8 @@ export const notificationTypes = [
'followRequestAccepted',
'roleAssigned',
'achievementEarned',
'exportCompleted',
'test',
'app',
] as const;
export const obsoleteNotificationTypes = ['pollVote', 'groupInvited'] as const;

View File

@ -4,7 +4,13 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div ref="thumbnail" :class="$style.root">
<div
ref="thumbnail"
:class="[
$style.root,
{ [$style.sensitiveHighlight]: highlightWhenSensitive && file.isSensitive },
]"
>
<ImgWithBlurhash v-if="isThumbnailAvailable" :hash="file.blurhash" :src="file.thumbnailUrl" :alt="file.name" :title="file.name" :cover="fit !== 'contain'"/>
<i v-else-if="is === 'image'" class="ti ti-photo" :class="$style.icon"></i>
<i v-else-if="is === 'video'" class="ti ti-video" :class="$style.icon"></i>
@ -27,6 +33,7 @@ import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue';
const props = defineProps<{
file: Misskey.entities.DriveFile;
fit: 'cover' | 'contain';
highlightWhenSensitive?: boolean;
}>();
const is = computed(() => {
@ -67,6 +74,18 @@ const isThumbnailAvailable = computed(() => {
overflow: clip;
}
.sensitiveHighlight::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
border-radius: inherit;
box-shadow: inset 0 0 0 4px var(--warn);
}
.iconSub {
position: absolute;
width: 30%;

View File

@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
class="file _button"
>
<div v-if="file.isSensitive" class="sensitive-label">{{ i18n.ts.sensitive }}</div>
<MkDriveFileThumbnail class="thumbnail" :file="file" fit="contain"/>
<MkDriveFileThumbnail class="thumbnail" :file="file" fit="contain" :highlightWhenSensitive="true"/>
<div v-if="viewMode === 'list'" class="body">
<div>
<small style="opacity: 0.7;">{{ file.name }}</small>

View File

@ -13,7 +13,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-else-if="notification.type === 'renote:grouped'" :class="[$style.icon, $style.icon_renoteGroup]"><i class="ti ti-repeat" style="line-height: 1;"></i></div>
<img v-else-if="notification.type === 'test'" :class="$style.icon" :src="infoImageUrl"/>
<MkAvatar v-else-if="'user' in notification" :class="$style.icon" :user="notification.user" link preview/>
<img v-else-if="'icon' in notification" :class="[$style.icon, $style.icon_app]" :src="notification.icon" alt=""/>
<MkAvatar v-else-if="notification.type === 'exportCompleted'" :class="$style.icon" :user="$i" link preview/>
<img v-else-if="'icon' in notification && notification.icon != null" :class="[$style.icon, $style.icon_app]" :src="notification.icon" alt=""/>
<div
:class="[$style.subIcon, {
[$style.t_follow]: notification.type === 'follow',
@ -25,6 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
[$style.t_quote]: notification.type === 'quote',
[$style.t_pollEnded]: notification.type === 'pollEnded',
[$style.t_achievementEarned]: notification.type === 'achievementEarned',
[$style.t_exportCompleted]: notification.type === 'exportCompleted',
[$style.t_roleAssigned]: notification.type === 'roleAssigned' && notification.role.iconUrl == null,
}]"
>
@ -37,6 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<i v-else-if="notification.type === 'quote'" class="ti ti-quote"></i>
<i v-else-if="notification.type === 'pollEnded'" class="ti ti-chart-arrows"></i>
<i v-else-if="notification.type === 'achievementEarned'" class="ti ti-medal"></i>
<i v-else-if="notification.type === 'exportCompleted'" class="ti ti-archive"></i>
<template v-else-if="notification.type === 'roleAssigned'">
<img v-if="notification.role.iconUrl" style="height: 1.3em; vertical-align: -22%;" :src="notification.role.iconUrl" alt=""/>
<i v-else class="ti ti-badges"></i>
@ -57,6 +60,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span v-else-if="notification.type === 'roleAssigned'">{{ i18n.ts._notification.roleAssigned }}</span>
<span v-else-if="notification.type === 'achievementEarned'">{{ i18n.ts._notification.achievementEarned }}</span>
<span v-else-if="notification.type === 'test'">{{ i18n.ts._notification.testNotification }}</span>
<span v-else-if="notification.type === 'exportCompleted'">{{ i18n.tsx._notification.exportOfXCompleted({ x: exportEntityName[notification.exportedEntity] }) }}</span>
<MkA v-else-if="notification.type === 'follow' || notification.type === 'mention' || notification.type === 'reply' || notification.type === 'renote' || notification.type === 'quote' || notification.type === 'reaction' || notification.type === 'receiveFollowRequest' || notification.type === 'followRequestAccepted'" v-user-preview="notification.user.id" :class="$style.headerName" :to="userPage(notification.user)"><MkUserName :user="notification.user"/></MkA>
<span v-else-if="notification.type === 'reaction:grouped' && notification.note.reactionAcceptance === 'likeOnly'">{{ i18n.tsx._notification.likedBySomeUsers({ n: getActualReactedUsersCount(notification) }) }}</span>
<span v-else-if="notification.type === 'reaction:grouped'">{{ i18n.tsx._notification.reactedBySomeUsers({ n: getActualReactedUsersCount(notification) }) }}</span>
@ -98,6 +102,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkA v-else-if="notification.type === 'achievementEarned'" :class="$style.text" to="/my/achievements">
{{ i18n.ts._achievements._types['_' + notification.achievement].title }}
</MkA>
<MkA v-else-if="notification.type === 'exportCompleted'" :class="$style.text" :to="`/my/drive/file/${notification.fileId}`">
{{ i18n.ts.showFile }}
</MkA>
<template v-else-if="notification.type === 'follow'">
<span :class="$style.text" style="opacity: 0.6;">{{ i18n.ts.youGotNewFollower }}</span>
</template>
@ -161,6 +168,20 @@ const props = withDefaults(defineProps<{
full: false,
});
type ExportCompletedNotification = Misskey.entities.Notification & { type: 'exportCompleted' };
const exportEntityName = {
antenna: i18n.ts.antennas,
blocking: i18n.ts.blockedUsers,
clip: i18n.ts.clips,
customEmoji: i18n.ts.customEmojis,
favorite: i18n.ts.favorites,
following: i18n.ts.following,
muting: i18n.ts.mutedUsers,
note: i18n.ts.notes,
userList: i18n.ts.lists,
} as const satisfies Record<ExportCompletedNotification['exportedEntity'], string>;
const followRequestDone = ref(false);
const acceptFollowRequest = () => {
@ -298,6 +319,12 @@ function getActualReactedUsersCount(notification: Misskey.entities.Notification)
pointer-events: none;
}
.t_exportCompleted {
padding: 3px;
background: var(--eventOther);
pointer-events: none;
}
.t_roleAssigned {
padding: 3px;
background: var(--eventOther);

View File

@ -73,7 +73,7 @@ import { notificationTypes } from '@@/js/const.js';
const $i = signinRequired();
const nonConfigurableNotificationTypes = ['note', 'roleAssigned', 'followRequestAccepted', 'achievementEarned'];
const nonConfigurableNotificationTypes = ['note', 'roleAssigned', 'followRequestAccepted', 'achievementEarned', 'test', 'exportCompleted'] as const satisfies (typeof notificationTypes[number])[];
const allowButton = shallowRef<InstanceType<typeof MkPushNotificationAllowButton>>();
const pushRegistrationInServer = computed(() => allowButton.value?.pushRegistrationInServer);

View File

@ -4254,6 +4254,17 @@ export type components = {
type: 'achievementEarned';
/** @enum {string} */
achievement: 'notes1' | 'notes10' | 'notes100' | 'notes500' | 'notes1000' | 'notes5000' | 'notes10000' | 'notes20000' | 'notes30000' | 'notes40000' | 'notes50000' | 'notes60000' | 'notes70000' | 'notes80000' | 'notes90000' | 'notes100000' | 'login3' | 'login7' | 'login15' | 'login30' | 'login60' | 'login100' | 'login200' | 'login300' | 'login400' | 'login500' | 'login600' | 'login700' | 'login800' | 'login900' | 'login1000' | 'passedSinceAccountCreated1' | 'passedSinceAccountCreated2' | 'passedSinceAccountCreated3' | 'loggedInOnBirthday' | 'loggedInOnNewYearsDay' | 'noteClipped1' | 'noteFavorited1' | 'myNoteFavorited1' | 'profileFilled' | 'markedAsCat' | 'following1' | 'following10' | 'following50' | 'following100' | 'following300' | 'followers1' | 'followers10' | 'followers50' | 'followers100' | 'followers300' | 'followers500' | 'followers1000' | 'collectAchievements30' | 'viewAchievements3min' | 'iLoveMisskey' | 'foundTreasure' | 'client30min' | 'client60min' | 'noteDeletedWithin1min' | 'postedAtLateNight' | 'postedAt0min0sec' | 'selfQuote' | 'htl20npm' | 'viewInstanceChart' | 'outputHelloWorldOnScratchpad' | 'open3windows' | 'driveFolderCircularReference' | 'reactWithoutRead' | 'clickedClickHere' | 'justPlainLucky' | 'setNameToSyuilo' | 'cookieClicked' | 'brainDiver' | 'smashTestNotificationButton' | 'tutorialCompleted' | 'bubbleGameExplodingHead' | 'bubbleGameDoubleExplodingHead';
}) | ({
/** Format: id */
id: string;
/** Format: date-time */
createdAt: string;
/** @enum {string} */
type: 'exportCompleted';
/** @enum {string} */
exportedEntity: 'antenna' | 'blocking' | 'clip' | 'customEmoji' | 'favorite' | 'following' | 'muting' | 'note' | 'userList';
/** Format: id */
fileId: string;
}) | ({
/** Format: id */
id: string;
@ -18438,8 +18449,8 @@ export type operations = {
untilId?: string;
/** @default true */
markAsRead?: boolean;
includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
};
};
};
@ -18506,8 +18517,8 @@ export type operations = {
untilId?: string;
/** @default true */
markAsRead?: boolean;
includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[];
excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[];
includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[];
excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[];
};
};
};

View File

@ -210,6 +210,25 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif
tag: `achievement:${data.body.achievement}`,
}];
case 'exportCompleted': {
const entityName = {
antenna: i18n.ts.antennas,
blocking: i18n.ts.blockedUsers,
clip: i18n.ts.clips,
customEmoji: i18n.ts.customEmojis,
favorite: i18n.ts.favorites,
following: i18n.ts.following,
muting: i18n.ts.mutedUsers,
note: i18n.ts.notes,
userList: i18n.ts.lists,
} as const satisfies Record<typeof data.body.exportedEntity, string>;
return [i18n.tsx._notification.exportOfXCompleted({ x: entityName[data.body.exportedEntity] }), {
badge: iconUrl('circle-check'),
data,
}];
}
case 'pollEnded':
return [i18n.ts._notification.pollEnded, {
body: data.body.note.text ?? '',

View File

@ -189,8 +189,8 @@ importers:
specifier: 2.0.5
version: 2.0.5
body-parser:
specifier: 1.20.2
version: 1.20.2
specifier: 1.20.3
version: 1.20.3
bullmq:
specifier: 5.10.4
version: 5.10.4
@ -1202,7 +1202,7 @@ importers:
version: 7.17.0(eslint@9.8.0)(typescript@5.5.4)
'@vitest/coverage-v8':
specifier: 1.6.0
version: 1.6.0(vitest@1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.77.8)(terser@5.31.3))
version: 1.6.0(vitest@1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.77.8)(terser@5.31.3))
'@vue/runtime-core':
specifier: 3.4.37
version: 3.4.37
@ -6132,6 +6132,10 @@ packages:
resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
body-parser@1.20.3:
resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
boolbase@1.0.0:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
@ -6258,6 +6262,10 @@ packages:
call-bind@1.0.2:
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
call-bind@1.0.7:
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
engines: {node: '>= 0.4'}
call-me-maybe@1.0.2:
resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==}
@ -6847,6 +6855,10 @@ packages:
resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
engines: {node: '>=10'}
define-data-property@1.1.4:
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
engines: {node: '>= 0.4'}
define-lazy-prop@2.0.0:
resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
engines: {node: '>=8'}
@ -7055,6 +7067,14 @@ packages:
resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==}
engines: {node: '>= 0.4'}
es-define-property@1.0.0:
resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
engines: {node: '>= 0.4'}
es-errors@1.3.0:
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
engines: {node: '>= 0.4'}
es-get-iterator@1.1.3:
resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==}
@ -7615,6 +7635,10 @@ packages:
get-intrinsic@1.2.1:
resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
get-intrinsic@1.2.4:
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
engines: {node: '>= 0.4'}
get-package-type@0.1.0:
resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==}
engines: {node: '>=8.0.0'}
@ -7813,6 +7837,9 @@ packages:
has-property-descriptors@1.0.0:
resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
has-property-descriptors@1.0.2:
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
has-proto@1.0.1:
resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
engines: {node: '>= 0.4'}
@ -9487,6 +9514,10 @@ packages:
object-inspect@1.12.3:
resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
object-inspect@1.13.2:
resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==}
engines: {node: '>= 0.4'}
object-is@1.1.5:
resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==}
engines: {node: '>= 0.4'}
@ -10286,6 +10317,10 @@ packages:
resolution: {integrity: sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==}
engines: {node: '>=0.6'}
qs@6.13.0:
resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
engines: {node: '>=0.6'}
qs@6.5.3:
resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
engines: {node: '>=0.6'}
@ -10692,6 +10727,10 @@ packages:
set-cookie-parser@2.6.0:
resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==}
set-function-length@1.2.2:
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
engines: {node: '>= 0.4'}
setimmediate@1.0.5:
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
@ -10735,6 +10774,10 @@ packages:
side-channel@1.0.4:
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
side-channel@1.0.6:
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
engines: {node: '>= 0.4'}
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
@ -11337,6 +11380,7 @@ packages:
ts-case-convert@2.0.2:
resolution: {integrity: sha512-vdKfx1VAdpvEBOBv5OpVu5ZFqRg9HdTI4sYt6qqMeICBeNyXvitrarCnFWNDAki51IKwCyx+ZssY46Q9jH5otA==}
bundledDependencies: []
ts-dedent@2.2.0:
resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==}
@ -12678,7 +12722,7 @@ snapshots:
'@babel/traverse': 7.23.5
'@babel/types': 7.24.7
convert-source-map: 2.0.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
@ -12698,7 +12742,7 @@ snapshots:
'@babel/traverse': 7.24.7
'@babel/types': 7.24.7
convert-source-map: 2.0.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
@ -12773,7 +12817,7 @@ snapshots:
'@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@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
lodash.debounce: 4.0.8
resolve: 1.22.8
transitivePeerDependencies:
@ -13640,7 +13684,7 @@ snapshots:
'@babel/helper-split-export-declaration': 7.22.6
'@babel/parser': 7.24.7
'@babel/types': 7.24.7
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@ -13655,7 +13699,7 @@ snapshots:
'@babel/helper-split-export-declaration': 7.24.7
'@babel/parser': 7.24.7
'@babel/types': 7.24.7
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@ -14115,7 +14159,7 @@ snapshots:
'@eslint/config-array@0.17.1':
dependencies:
'@eslint/object-schema': 2.1.4
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@ -14123,7 +14167,7 @@ snapshots:
'@eslint/eslintrc@3.1.0':
dependencies:
ajv: 6.12.6
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
espree: 10.1.0
globals: 14.0.0
ignore: 5.3.1
@ -17289,7 +17333,7 @@ snapshots:
'@typescript-eslint/types': 7.17.0
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 7.17.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
eslint: 9.8.0
optionalDependencies:
typescript: 5.5.4
@ -17315,7 +17359,7 @@ snapshots:
dependencies:
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3)
'@typescript-eslint/utils': 6.11.0(eslint@9.8.0)(typescript@5.3.3)
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
eslint: 9.8.0
ts-api-utils: 1.0.1(typescript@5.3.3)
optionalDependencies:
@ -17327,7 +17371,7 @@ snapshots:
dependencies:
'@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
'@typescript-eslint/utils': 7.1.0(eslint@9.8.0)(typescript@5.3.3)
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
eslint: 9.8.0
ts-api-utils: 1.0.1(typescript@5.3.3)
optionalDependencies:
@ -17339,7 +17383,7 @@ snapshots:
dependencies:
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.4)
'@typescript-eslint/utils': 7.17.0(eslint@9.8.0)(typescript@5.5.4)
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
eslint: 9.8.0
ts-api-utils: 1.3.0(typescript@5.5.4)
optionalDependencies:
@ -17357,7 +17401,7 @@ snapshots:
dependencies:
'@typescript-eslint/types': 6.11.0
'@typescript-eslint/visitor-keys': 6.11.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
semver: 7.6.0
@ -17371,7 +17415,7 @@ snapshots:
dependencies:
'@typescript-eslint/types': 7.1.0
'@typescript-eslint/visitor-keys': 7.1.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.3
@ -17386,7 +17430,7 @@ snapshots:
dependencies:
'@typescript-eslint/types': 7.17.0
'@typescript-eslint/visitor-keys': 7.17.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.4
@ -17462,7 +17506,7 @@ snapshots:
dependencies:
'@ampproject/remapping': 2.2.1
'@bcoe/v8-coverage': 0.2.3
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 5.0.4
@ -17477,25 +17521,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.77.8)(terser@5.31.3))':
dependencies:
'@ampproject/remapping': 2.2.1
'@bcoe/v8-coverage': 0.2.3
debug: 4.3.5(supports-color@5.5.0)
istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 5.0.4
istanbul-reports: 3.1.6
magic-string: 0.30.10
magicast: 0.3.4
picocolors: 1.0.1
std-env: 3.7.0
strip-literal: 2.1.0
test-exclude: 6.0.0
vitest: 1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.77.8)(terser@5.31.3)
transitivePeerDependencies:
- supports-color
'@vitest/expect@1.6.0':
dependencies:
'@vitest/spy': 1.6.0
@ -17723,13 +17748,13 @@ snapshots:
agent-base@6.0.2:
dependencies:
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
agent-base@7.1.0:
dependencies:
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
@ -17987,7 +18012,7 @@ snapshots:
dependencies:
'@fastify/error': 3.4.0
archy: 1.0.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
fastq: 1.17.1
transitivePeerDependencies:
- supports-color
@ -18169,6 +18194,23 @@ snapshots:
transitivePeerDependencies:
- supports-color
body-parser@1.20.3:
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.13.0
raw-body: 2.5.2
type-is: 1.6.18
unpipe: 1.0.0
transitivePeerDependencies:
- supports-color
boolbase@1.0.0: {}
bowser@2.11.0: {}
@ -18334,6 +18376,14 @@ snapshots:
function-bind: 1.1.2
get-intrinsic: 1.2.1
call-bind@1.0.7:
dependencies:
es-define-property: 1.0.0
es-errors: 1.3.0
function-bind: 1.1.2
get-intrinsic: 1.2.4
set-function-length: 1.2.2
call-me-maybe@1.0.2: {}
callsites@3.1.0: {}
@ -19006,6 +19056,12 @@ snapshots:
defer-to-connect@2.0.1: {}
define-data-property@1.1.4:
dependencies:
es-define-property: 1.0.0
es-errors: 1.3.0
gopd: 1.0.1
define-lazy-prop@2.0.0: {}
define-properties@1.2.0:
@ -19041,7 +19097,7 @@ snapshots:
detect-port@1.5.1:
dependencies:
address: 1.2.2
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
@ -19212,6 +19268,12 @@ snapshots:
unbox-primitive: 1.0.2
which-typed-array: 1.1.11
es-define-property@1.0.0:
dependencies:
get-intrinsic: 1.2.4
es-errors@1.3.0: {}
es-get-iterator@1.1.3:
dependencies:
call-bind: 1.0.2
@ -19254,7 +19316,7 @@ snapshots:
esbuild-register@3.5.0(esbuild@0.19.11):
dependencies:
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
esbuild: 0.19.11
transitivePeerDependencies:
- supports-color
@ -19484,7 +19546,7 @@ snapshots:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
escape-string-regexp: 4.0.0
eslint-scope: 8.0.2
eslint-visitor-keys: 4.0.0
@ -19937,7 +19999,7 @@ snapshots:
follow-redirects@1.15.2(debug@4.3.5):
optionalDependencies:
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
for-each@0.3.3:
dependencies:
@ -20056,6 +20118,14 @@ snapshots:
has-proto: 1.0.1
has-symbols: 1.0.3
get-intrinsic@1.2.4:
dependencies:
es-errors: 1.3.0
function-bind: 1.1.2
has-proto: 1.0.1
has-symbols: 1.0.3
hasown: 2.0.0
get-package-type@0.1.0: {}
get-pixels-frame-info-update@3.3.2:
@ -20221,7 +20291,7 @@ snapshots:
gopd@1.0.1:
dependencies:
get-intrinsic: 1.2.1
get-intrinsic: 1.2.4
got@11.8.5:
dependencies:
@ -20318,6 +20388,10 @@ snapshots:
dependencies:
get-intrinsic: 1.2.1
has-property-descriptors@1.0.2:
dependencies:
es-define-property: 1.0.0
has-proto@1.0.1: {}
has-symbols@1.0.3: {}
@ -20403,7 +20477,7 @@ snapshots:
http-proxy-agent@7.0.2:
dependencies:
agent-base: 7.1.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
@ -20442,28 +20516,28 @@ snapshots:
https-proxy-agent@5.0.1:
dependencies:
agent-base: 6.0.2
debug: 4.3.5(supports-color@5.5.0)
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.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
https-proxy-agent@7.0.4:
dependencies:
agent-base: 7.1.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
https-proxy-agent@7.0.5:
dependencies:
agent-base: 7.1.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
@ -20811,7 +20885,7 @@ snapshots:
istanbul-lib-source-maps@4.0.1:
dependencies:
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
istanbul-lib-coverage: 3.2.2
source-map: 0.6.1
transitivePeerDependencies:
@ -20820,7 +20894,7 @@ snapshots:
istanbul-lib-source-maps@5.0.4:
dependencies:
'@jridgewell/trace-mapping': 0.3.25
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
istanbul-lib-coverage: 3.2.2
transitivePeerDependencies:
- supports-color
@ -21244,35 +21318,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
jsdom@24.1.1:
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.2
https-proxy-agent: 7.0.5
is-potential-custom-element-name: 1.0.1
nwsapi: 2.2.12
parse5: 7.1.2
rrweb-cssom: 0.7.1
saxes: 6.0.0
symbol-tree: 3.2.4
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.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
xml-name-validator: 5.0.0
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
optional: true
jsdom@24.1.1(bufferutil@4.0.7)(utf-8-validate@6.0.3):
dependencies:
cssstyle: 4.0.1
@ -21958,7 +22003,7 @@ snapshots:
micromark@4.0.0:
dependencies:
'@types/debug': 4.1.12
debug: 4.3.5(supports-color@5.5.0)
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
@ -22433,6 +22478,8 @@ snapshots:
object-inspect@1.12.3: {}
object-inspect@1.13.2: {}
object-is@1.1.5:
dependencies:
call-bind: 1.0.2
@ -23219,6 +23266,10 @@ snapshots:
dependencies:
side-channel: 1.0.4
qs@6.13.0:
dependencies:
side-channel: 1.0.6
qs@6.5.3: {}
querystringify@2.2.0: {}
@ -23515,7 +23566,7 @@ snapshots:
require-in-the-middle@7.3.0:
dependencies:
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
module-details-from-path: 1.0.3
resolve: 1.22.8
transitivePeerDependencies:
@ -23722,6 +23773,15 @@ snapshots:
set-cookie-parser@2.6.0: {}
set-function-length@1.2.2:
dependencies:
define-data-property: 1.1.4
es-errors: 1.3.0
function-bind: 1.1.2
get-intrinsic: 1.2.4
gopd: 1.0.1
has-property-descriptors: 1.0.2
setimmediate@1.0.5: {}
setprototypeof@1.2.0: {}
@ -23786,6 +23846,13 @@ snapshots:
get-intrinsic: 1.2.1
object-inspect: 1.12.3
side-channel@1.0.6:
dependencies:
call-bind: 1.0.7
es-errors: 1.3.0
get-intrinsic: 1.2.4
object-inspect: 1.13.2
siginfo@2.0.0: {}
signal-exit@3.0.7: {}
@ -23796,7 +23863,7 @@ snapshots:
dependencies:
'@hapi/hoek': 11.0.4
'@hapi/wreck': 18.0.1
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
joi: 17.11.0
transitivePeerDependencies:
- supports-color
@ -23896,7 +23963,7 @@ snapshots:
socks-proxy-agent@8.0.2:
dependencies:
agent-base: 7.1.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
socks: 2.7.1
transitivePeerDependencies:
- supports-color
@ -23991,7 +24058,7 @@ snapshots:
arg: 5.0.2
bluebird: 3.7.2
check-more-types: 2.24.0
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
execa: 5.1.1
lazy-ass: 1.6.0
ps-tree: 1.2.0
@ -24732,7 +24799,7 @@ snapshots:
vite-node@1.6.0(@types/node@20.14.12)(sass@1.77.8)(terser@5.31.3):
dependencies:
cac: 6.7.14
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
pathe: 1.1.2
picocolors: 1.0.1
vite: 5.3.5(@types/node@20.14.12)(sass@1.77.8)(terser@5.31.3)
@ -24801,41 +24868,6 @@ snapshots:
- supports-color
- terser
vitest@1.6.0(@types/node@20.14.12)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.77.8)(terser@5.31.3):
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
chai: 4.3.10
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: 2.1.0
tinybench: 2.6.0
tinypool: 0.8.4
vite: 5.3.5(@types/node@20.14.12)(sass@1.77.8)(terser@5.31.3)
vite-node: 1.6.0(@types/node@20.14.12)(sass@1.77.8)(terser@5.31.3)
why-is-node-running: 2.2.2
optionalDependencies:
'@types/node': 20.14.12
happy-dom: 10.0.3
jsdom: 24.1.1
transitivePeerDependencies:
- less
- lightningcss
- sass
- stylus
- sugarss
- supports-color
- terser
void-elements@3.1.0: {}
vscode-jsonrpc@8.2.0: {}
@ -24899,7 +24931,7 @@ snapshots:
vue-eslint-parser@9.4.3(eslint@9.8.0):
dependencies:
debug: 4.3.5(supports-color@5.5.0)
debug: 4.3.5(supports-color@8.1.1)
eslint: 9.8.0
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3