From 7c0806f208d85e29b9fc99f86844349e3708aa2d Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Tue, 15 Apr 2025 15:36:53 +0900 Subject: feat(frontend): chat column Resolve #15830 --- .../frontend/src/components/MkChatHistories.vue | 208 +++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 packages/frontend/src/components/MkChatHistories.vue (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkChatHistories.vue b/packages/frontend/src/components/MkChatHistories.vue new file mode 100644 index 0000000000..c508ea8451 --- /dev/null +++ b/packages/frontend/src/components/MkChatHistories.vue @@ -0,0 +1,208 @@ + + + + + + + -- cgit v1.2.3-freya From 6bd45a27b13c4c00d627ad056bc7b57047b9493d Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Tue, 15 Apr 2025 16:09:04 +0900 Subject: fix: フォルダを開いた状態でメニューからアップロードしてもルートフォルダにアップロードされる問題 (#15836) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: フォルダを開いた状態でメニューからアップロードしてもルートフォルダにアップロードされる問題 * docs(changelog): Fix: フォルダを開いた状態でメニューからアップロードしてもルートフォルダにアップロードされる問題を修正 #15836 --- CHANGELOG.md | 1 + packages/frontend/src/components/MkDrive.vue | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'packages/frontend/src/components') diff --git a/CHANGELOG.md b/CHANGELOG.md index 38563da555..3214ef936f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Feat: デッキにチャットカラムを追加 - Fix: ログアウトした際に処理が終了しない問題を修正 - Fix: 自動バックアップが設定されている環境でログアウト直前に設定をバックアップするように +- Fix: フォルダを開いた状態でメニューからアップロードしてもルートフォルダにアップロードされる問題を修正 #15836 ### Server - Enhance: フォローしているユーザーならフォロワー限定投稿のノートでもアンテナで検知できるように diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue index c212167c8f..6270ac8314 100644 --- a/packages/frontend/src/components/MkDrive.vue +++ b/packages/frontend/src/components/MkDrive.vue @@ -626,13 +626,13 @@ function getMenu() { text: i18n.ts.upload + ' (' + i18n.ts.compress + ')', icon: 'ti ti-upload', action: () => { - chooseFileFromPc(true, { keepOriginal: false }); + chooseFileFromPc(true, { uploadFolder: folder.value?.id, keepOriginal: false }); }, }, { text: i18n.ts.upload, icon: 'ti ti-upload', action: () => { - chooseFileFromPc(true, { keepOriginal: true }); + chooseFileFromPc(true, { uploadFolder: folder.value?.id, keepOriginal: true }); }, }, { text: i18n.ts.fromUrl, -- cgit v1.2.3-freya From 165830d6c8331f14da455cedcb4cd695aaa6c9b3 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Tue, 15 Apr 2025 20:34:00 +0900 Subject: コミット忘れ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/MkNotes.vue | 4 ++-- packages/frontend/src/pages/timeline.vue | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkNotes.vue b/packages/frontend/src/components/MkNotes.vue index ad6210816d..214d52ec7f 100644 --- a/packages/frontend/src/components/MkNotes.vue +++ b/packages/frontend/src/components/MkNotes.vue @@ -23,13 +23,13 @@ SPDX-License-Identifier: AGPL-3.0-only tag="div" > diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue index 644b2d3d13..d2bf162ce5 100644 --- a/packages/frontend/src/pages/timeline.vue +++ b/packages/frontend/src/pages/timeline.vue @@ -52,12 +52,15 @@ import { miLocalStorage } from '@/local-storage.js'; import { availableBasicTimelines, hasWithReplies, isAvailableBasicTimeline, isBasicTimeline, basicTimelineIconClass } from '@/timelines.js'; import { prefer } from '@/preferences.js'; import { useRouter } from '@/router.js'; +import { useScrollPositionKeeper } from '@/use/use-scroll-position-keeper.js'; provide('shouldOmitHeaderTitle', true); const tlComponent = useTemplateRef('tlComponent'); const rootEl = useTemplateRef('rootEl'); +useScrollPositionKeeper(rootEl); + const router = useRouter(); router.useListener('same', () => { top(); -- cgit v1.2.3-freya From de19d9a4d429b4ce9d4713e647659fe6460bdd11 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Tue, 15 Apr 2025 20:48:25 +0900 Subject: refactor(frontend): MkHorizontalSwipe -> MkSwiper --- .../frontend/src/components/MkHorizontalSwipe.vue | 238 --------------------- packages/frontend/src/components/MkSwiper.vue | 238 +++++++++++++++++++++ packages/frontend/src/pages/about.vue | 6 +- packages/frontend/src/pages/announcements.vue | 6 +- packages/frontend/src/pages/channel.vue | 6 +- packages/frontend/src/pages/channels.vue | 6 +- packages/frontend/src/pages/chat/home.vue | 6 +- packages/frontend/src/pages/drive.file.vue | 6 +- packages/frontend/src/pages/explore.vue | 6 +- packages/frontend/src/pages/flash/flash-index.vue | 6 +- packages/frontend/src/pages/follow-requests.vue | 6 +- packages/frontend/src/pages/gallery/index.vue | 6 +- packages/frontend/src/pages/instance-info.vue | 6 +- packages/frontend/src/pages/my-clips/index.vue | 6 +- packages/frontend/src/pages/notifications.vue | 2 +- packages/frontend/src/pages/pages.vue | 6 +- packages/frontend/src/pages/search.vue | 6 +- packages/frontend/src/pages/user/index.vue | 6 +- packages/frontend/src/utility/touch.ts | 2 +- 19 files changed, 285 insertions(+), 285 deletions(-) delete mode 100644 packages/frontend/src/components/MkHorizontalSwipe.vue create mode 100644 packages/frontend/src/components/MkSwiper.vue (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkHorizontalSwipe.vue b/packages/frontend/src/components/MkHorizontalSwipe.vue deleted file mode 100644 index 1d0ffaea11..0000000000 --- a/packages/frontend/src/components/MkHorizontalSwipe.vue +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - diff --git a/packages/frontend/src/components/MkSwiper.vue b/packages/frontend/src/components/MkSwiper.vue new file mode 100644 index 0000000000..1d0ffaea11 --- /dev/null +++ b/packages/frontend/src/components/MkSwiper.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/packages/frontend/src/pages/about.vue b/packages/frontend/src/pages/about.vue index b4315a5cfa..ec286f109f 100644 --- a/packages/frontend/src/pages/about.vue +++ b/packages/frontend/src/pages/about.vue @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -28,7 +28,7 @@ import { instance } from '@/instance.js'; import { i18n } from '@/i18n.js'; import { claimAchievement } from '@/utility/achievements.js'; import { definePage } from '@/page.js'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; const XOverview = defineAsyncComponent(() => import('@/pages/about.overview.vue')); const XEmojis = defineAsyncComponent(() => import('@/pages/about.emojis.vue')); diff --git a/packages/frontend/src/pages/announcements.vue b/packages/frontend/src/pages/announcements.vue index 1902267a6a..7a04914dd7 100644 --- a/packages/frontend/src/pages/announcements.vue +++ b/packages/frontend/src/pages/announcements.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -50,7 +50,7 @@ import { ref, computed } from 'vue'; import MkPagination from '@/components/MkPagination.vue'; import MkButton from '@/components/MkButton.vue'; import MkInfo from '@/components/MkInfo.vue'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; import * as os from '@/os.js'; import { misskeyApi } from '@/utility/misskey-api.js'; import { i18n } from '@/i18n.js'; diff --git a/packages/frontend/src/pages/channel.vue b/packages/frontend/src/pages/channel.vue index a62e035198..e71d372722 100644 --- a/packages/frontend/src/pages/channel.vue +++ b/packages/frontend/src/pages/channel.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only - + @@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only - + @@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { computed, ref, defineAsyncComponent } from 'vue'; import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; const props = defineProps<{ fileId: string; diff --git a/packages/frontend/src/pages/explore.vue b/packages/frontend/src/pages/explore.vue index 85b9fe4932..bcece47e35 100644 --- a/packages/frontend/src/pages/explore.vue +++ b/packages/frontend/src/pages/explore.vue @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -25,7 +25,7 @@ import XFeatured from './explore.featured.vue'; import XUsers from './explore.users.vue'; import XRoles from './explore.roles.vue'; import MkFoldableSection from '@/components/MkFoldableSection.vue'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; import { definePage } from '@/page.js'; import { i18n } from '@/i18n.js'; diff --git a/packages/frontend/src/pages/flash/flash-index.vue b/packages/frontend/src/pages/flash/flash-index.vue index 98ab587b55..4ef33cbe0f 100644 --- a/packages/frontend/src/pages/flash/flash-index.vue +++ b/packages/frontend/src/pages/flash/flash-index.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -43,7 +43,7 @@ import { computed, ref } from 'vue'; import MkFlashPreview from '@/components/MkFlashPreview.vue'; import MkPagination from '@/components/MkPagination.vue'; import MkButton from '@/components/MkButton.vue'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; import { useRouter } from '@/router.js'; diff --git a/packages/frontend/src/pages/follow-requests.vue b/packages/frontend/src/pages/follow-requests.vue index 36643b1acb..d467d875fd 100644 --- a/packages/frontend/src/pages/follow-requests.vue +++ b/packages/frontend/src/pages/follow-requests.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -52,7 +52,7 @@ import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; import { infoImageUrl } from '@/instance.js'; import { $i } from '@/i.js'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; const paginationComponent = useTemplateRef('paginationComponent'); diff --git a/packages/frontend/src/pages/gallery/index.vue b/packages/frontend/src/pages/gallery/index.vue index 4cf3fca83b..c6ce773ab0 100644 --- a/packages/frontend/src/pages/gallery/index.vue +++ b/packages/frontend/src/pages/gallery/index.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -50,7 +50,7 @@ import { watch, ref, computed } from 'vue'; import MkFoldableSection from '@/components/MkFoldableSection.vue'; import MkPagination from '@/components/MkPagination.vue'; import MkGalleryPostPreview from '@/components/MkGalleryPostPreview.vue'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; import { definePage } from '@/page.js'; import { i18n } from '@/i18n.js'; import { useRouter } from '@/router.js'; diff --git a/packages/frontend/src/pages/instance-info.vue b/packages/frontend/src/pages/instance-info.vue index 66ddf627e4..fde462944c 100644 --- a/packages/frontend/src/pages/instance-info.vue +++ b/packages/frontend/src/pages/instance-info.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -153,7 +153,7 @@ import { definePage } from '@/page.js'; import { i18n } from '@/i18n.js'; import MkUserCardMini from '@/components/MkUserCardMini.vue'; import MkPagination from '@/components/MkPagination.vue'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; import { getProxiedImageUrlNullable } from '@/utility/media-proxy.js'; import { dateString } from '@/filters/date.js'; import MkTextarea from '@/components/MkTextarea.vue'; diff --git a/packages/frontend/src/pages/my-clips/index.vue b/packages/frontend/src/pages/my-clips/index.vue index 1525bbef9b..5b9b3af90b 100644 --- a/packages/frontend/src/pages/my-clips/index.vue +++ b/packages/frontend/src/pages/my-clips/index.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -33,7 +33,7 @@ import { misskeyApi } from '@/utility/misskey-api.js'; import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; import { clipsCache } from '@/cache.js'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; const pagination = { endpoint: 'clips/list' as const, diff --git a/packages/frontend/src/pages/notifications.vue b/packages/frontend/src/pages/notifications.vue index 0a2bc02de5..61a1b2725c 100644 --- a/packages/frontend/src/pages/notifications.vue +++ b/packages/frontend/src/pages/notifications.vue @@ -24,7 +24,7 @@ import { computed, ref } from 'vue'; import { notificationTypes } from '@@/js/const.js'; import XNotifications from '@/components/MkNotifications.vue'; import MkNotes from '@/components/MkNotes.vue'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; import * as os from '@/os.js'; import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; diff --git a/packages/frontend/src/pages/pages.vue b/packages/frontend/src/pages/pages.vue index c99d7f1a0f..d412bad616 100644 --- a/packages/frontend/src/pages/pages.vue +++ b/packages/frontend/src/pages/pages.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -41,7 +41,7 @@ import { computed, ref } from 'vue'; import MkPagePreview from '@/components/MkPagePreview.vue'; import MkPagination from '@/components/MkPagination.vue'; import MkButton from '@/components/MkButton.vue'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; import { useRouter } from '@/router.js'; diff --git a/packages/frontend/src/pages/search.vue b/packages/frontend/src/pages/search.vue index e0cb2dcbab..814ddf3cb9 100644 --- a/packages/frontend/src/pages/search.vue +++ b/packages/frontend/src/pages/search.vue @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -28,7 +28,7 @@ import { i18n } from '@/i18n.js'; import { definePage } from '@/page.js'; import { notesSearchAvailable } from '@/utility/check-permissions.js'; import MkInfo from '@/components/MkInfo.vue'; -import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import MkSwiper from '@/components/MkSwiper.vue'; const props = withDefaults(defineProps<{ query?: string, diff --git a/packages/frontend/src/pages/user/index.vue b/packages/frontend/src/pages/user/index.vue index 58f44d7591..83c7bf45bb 100644 --- a/packages/frontend/src/pages/user/index.vue +++ b/packages/frontend/src/pages/user/index.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only diff --git a/packages/frontend/src/components/global/PageWithHeader.vue b/packages/frontend/src/components/global/PageWithHeader.vue index 7ea0b5c97f..99f8df0780 100644 --- a/packages/frontend/src/components/global/PageWithHeader.vue +++ b/packages/frontend/src/components/global/PageWithHeader.vue @@ -20,6 +20,7 @@ import { useTemplateRef } from 'vue'; import { scrollInContainer } from '@@/js/scroll.js'; import type { PageHeaderItem } from '@/types/page-header.js'; import type { Tab } from './MkPageHeader.tabs.vue'; +import { useScrollPositionKeeper } from '@/use/use-scroll-position-keeper.js'; const props = withDefaults(defineProps<{ tabs?: Tab[]; @@ -35,6 +36,8 @@ const props = withDefaults(defineProps<{ const tab = defineModel('tab'); const rootEl = useTemplateRef('rootEl'); +useScrollPositionKeeper(rootEl); + defineExpose({ scrollToTop: () => { if (rootEl.value) scrollInContainer(rootEl.value, { top: 0, behavior: 'smooth' }); diff --git a/packages/frontend/src/use/use-scroll-position-keeper.ts b/packages/frontend/src/use/use-scroll-position-keeper.ts index 00cc51a459..f7b3015cc9 100644 --- a/packages/frontend/src/use/use-scroll-position-keeper.ts +++ b/packages/frontend/src/use/use-scroll-position-keeper.ts @@ -4,19 +4,22 @@ */ import { throttle } from 'throttle-debounce'; -import { nextTick, onActivated, onUnmounted, watch } from 'vue'; +import { nextTick, onActivated, onDeactivated, onUnmounted, watch } from 'vue'; import type { Ref } from 'vue'; // note render skippingがオンだとズレるため、遷移直前にスクロール範囲に表示されているdata-scroll-anchor要素を特定して、復元時に当該要素までスクロールするようにする export function useScrollPositionKeeper(scrollContainerRef: Ref): void { let anchorId: string | null = null; + let ready = true; watch(scrollContainerRef, (el) => { if (!el) return; const onScroll = () => { if (!el) return; + if (!ready) return; + const scrollContainerRect = el.getBoundingClientRect(); const viewPosition = scrollContainerRect.height / 2; @@ -41,18 +44,32 @@ export function useScrollPositionKeeper(scrollContainerRef: Ref { + if (!anchorId) return; + const scrollContainer = scrollContainerRef.value; + if (!scrollContainer) return; + const scrollAnchorEl = scrollContainer.querySelector(`[data-scroll-anchor="${anchorId}"]`); + if (!scrollAnchorEl) return; + scrollAnchorEl.scrollIntoView({ + behavior: 'instant', + block: 'center', + inline: 'center', + }); + }; + + onDeactivated(() => { + ready = false; + }); + onActivated(() => { + restore(); nextTick(() => { - if (!anchorId) return; - const scrollContainer = scrollContainerRef.value; - if (!scrollContainer) return; - const scrollAnchorEl = scrollContainer.querySelector(`[data-scroll-anchor="${anchorId}"]`); - if (!scrollAnchorEl) return; - scrollAnchorEl.scrollIntoView({ - behavior: 'instant', - block: 'center', - inline: 'center', - }); + restore(); + window.setTimeout(() => { + restore(); + + ready = true; + }, 100); }); }); } -- cgit v1.2.3-freya From 17e7340933887fb4044bdee4798ed87c873f1dad Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Wed, 16 Apr 2025 10:59:05 +0900 Subject: enhance(frontend): テーマでページヘッダーの色を変更できるように MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend-shared/themes/_dark.json5 | 2 ++ packages/frontend-shared/themes/_light.json5 | 2 ++ packages/frontend/src/components/MkThemePreview.vue | 5 ++++- packages/frontend/src/components/global/MkPageHeader.vue | 11 +++++++++-- 4 files changed, 17 insertions(+), 3 deletions(-) (limited to 'packages/frontend/src/components') diff --git a/packages/frontend-shared/themes/_dark.json5 b/packages/frontend-shared/themes/_dark.json5 index 924be27455..8ebaf20b64 100644 --- a/packages/frontend-shared/themes/_dark.json5 +++ b/packages/frontend-shared/themes/_dark.json5 @@ -33,6 +33,8 @@ navFg: '@fg', navActive: '@accent', navIndicator: '@indicator', + pageHeaderBg: '@bg', + pageHeaderFg: '@fg', link: '#44a4c1', hashtag: '#ff9156', mention: '@accent', diff --git a/packages/frontend-shared/themes/_light.json5 b/packages/frontend-shared/themes/_light.json5 index e3c62ff543..63ad95ff84 100644 --- a/packages/frontend-shared/themes/_light.json5 +++ b/packages/frontend-shared/themes/_light.json5 @@ -33,6 +33,8 @@ navFg: '@fg', navActive: '@accent', navIndicator: '@indicator', + pageHeaderBg: '@bg', + pageHeaderFg: '@fg', link: '#44a4c1', hashtag: '#ff9156', mention: '@accent', diff --git a/packages/frontend/src/components/MkThemePreview.vue b/packages/frontend/src/components/MkThemePreview.vue index 013ab9d6a4..cc4254a2f6 100644 --- a/packages/frontend/src/components/MkThemePreview.vue +++ b/packages/frontend/src/components/MkThemePreview.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only - + @@ -62,6 +62,7 @@ const themeVariables = ref<{ accent: string; accentedBg: string; navBg: string; + pageHeaderBg: string; success: string; warn: string; error: string; @@ -76,6 +77,7 @@ const themeVariables = ref<{ accent: 'var(--MI_THEME-accent)', accentedBg: 'var(--MI_THEME-accentedBg)', navBg: 'var(--MI_THEME-navBg)', + pageHeaderBg: 'var(--MI_THEME-pageHeaderBg)', success: 'var(--MI_THEME-success)', warn: 'var(--MI_THEME-warn)', error: 'var(--MI_THEME-error)', @@ -104,6 +106,7 @@ watch(() => props.theme, (theme) => { accent: compiled.accent ?? 'var(--MI_THEME-accent)', accentedBg: compiled.accentedBg ?? 'var(--MI_THEME-accentedBg)', navBg: compiled.navBg ?? 'var(--MI_THEME-navBg)', + pageHeaderBg: compiled.pageHeaderBg ?? 'var(--MI_THEME-pageHeaderBg)', success: compiled.success ?? 'var(--MI_THEME-success)', warn: compiled.warn ?? 'var(--MI_THEME-warn)', error: compiled.error ?? 'var(--MI_THEME-error)', diff --git a/packages/frontend/src/components/global/MkPageHeader.vue b/packages/frontend/src/components/global/MkPageHeader.vue index 93f46a866a..dc0b52b141 100644 --- a/packages/frontend/src/components/global/MkPageHeader.vue +++ b/packages/frontend/src/components/global/MkPageHeader.vue @@ -124,11 +124,18 @@ onUnmounted(() => { diff --git a/packages/frontend/src/components/MkTl.vue b/packages/frontend/src/components/MkTl.vue new file mode 100644 index 0000000000..95cc4d2a2a --- /dev/null +++ b/packages/frontend/src/components/MkTl.vue @@ -0,0 +1,173 @@ + + + + + + + diff --git a/packages/frontend/src/pages/admin/federation-job-queue.chart.chart.vue b/packages/frontend/src/pages/admin/federation-job-queue.chart.chart.vue new file mode 100644 index 0000000000..5dd2887024 --- /dev/null +++ b/packages/frontend/src/pages/admin/federation-job-queue.chart.chart.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/packages/frontend/src/pages/admin/federation-job-queue.chart.vue b/packages/frontend/src/pages/admin/federation-job-queue.chart.vue new file mode 100644 index 0000000000..4b10d682a5 --- /dev/null +++ b/packages/frontend/src/pages/admin/federation-job-queue.chart.vue @@ -0,0 +1,160 @@ + + + + + + + diff --git a/packages/frontend/src/pages/admin/federation-job-queue.vue b/packages/frontend/src/pages/admin/federation-job-queue.vue new file mode 100644 index 0000000000..df976ba999 --- /dev/null +++ b/packages/frontend/src/pages/admin/federation-job-queue.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/packages/frontend/src/pages/admin/index.vue b/packages/frontend/src/pages/admin/index.vue index 8d03838a8f..d2246b7512 100644 --- a/packages/frontend/src/pages/admin/index.vue +++ b/packages/frontend/src/pages/admin/index.vue @@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only -
+
@@ -138,11 +138,16 @@ const menuDef = computed(() => [{ text: i18n.ts.federation, to: '/admin/federation', active: currentPage.value?.route.name === 'federation', + }, { + icon: 'ti ti-clock-play', + text: i18n.ts.federationJobs, + to: '/admin/federation-job-queue', + active: currentPage.value?.route.name === 'federationJobQueue', }, { icon: 'ti ti-clock-play', text: i18n.ts.jobQueue, - to: '/admin/queue', - active: currentPage.value?.route.name === 'queue', + to: '/admin/job-queue', + active: currentPage.value?.route.name === 'jobQueue', }, { icon: 'ti ti-cloud', text: i18n.ts.files, @@ -329,6 +334,8 @@ defineExpose({ diff --git a/packages/frontend/src/pages/admin/job-queue.vue b/packages/frontend/src/pages/admin/job-queue.vue new file mode 100644 index 0000000000..528c473c4f --- /dev/null +++ b/packages/frontend/src/pages/admin/job-queue.vue @@ -0,0 +1,370 @@ + + + + + + + diff --git a/packages/frontend/src/pages/admin/queue.chart.chart.vue b/packages/frontend/src/pages/admin/queue.chart.chart.vue deleted file mode 100644 index 5dd2887024..0000000000 --- a/packages/frontend/src/pages/admin/queue.chart.chart.vue +++ /dev/null @@ -1,139 +0,0 @@ - - - - - diff --git a/packages/frontend/src/pages/admin/queue.chart.vue b/packages/frontend/src/pages/admin/queue.chart.vue deleted file mode 100644 index 1ba02d6e0e..0000000000 --- a/packages/frontend/src/pages/admin/queue.chart.vue +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - diff --git a/packages/frontend/src/pages/admin/queue.vue b/packages/frontend/src/pages/admin/queue.vue deleted file mode 100644 index ee56c258c9..0000000000 --- a/packages/frontend/src/pages/admin/queue.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/packages/frontend/src/router.definition.ts b/packages/frontend/src/router.definition.ts index d59b160b8b..a0a22b4338 100644 --- a/packages/frontend/src/router.definition.ts +++ b/packages/frontend/src/router.definition.ts @@ -392,9 +392,13 @@ export const ROUTE_DEF = [{ name: 'avatarDecorations', component: page(() => import('@/pages/avatar-decorations.vue')), }, { - path: '/queue', - name: 'queue', - component: page(() => import('@/pages/admin/queue.vue')), + path: '/federation-job-queue', + name: 'federationJobQueue', + component: page(() => import('@/pages/admin/federation-job-queue.vue')), + }, { + path: '/job-queue', + name: 'jobQueue', + component: page(() => import('@/pages/admin/job-queue.vue')), }, { path: '/files', name: 'files', diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index 5237d5bbf8..b43906109f 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -267,7 +267,22 @@ type AdminQueueDeliverDelayedResponse = operations['admin___queue___deliver-dela type AdminQueueInboxDelayedResponse = operations['admin___queue___inbox-delayed']['responses']['200']['content']['application/json']; // @public (undocumented) -type AdminQueuePromoteRequest = operations['admin___queue___promote']['requestBody']['content']['application/json']; +type AdminQueueJobsRequest = operations['admin___queue___jobs']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminQueuePromoteJobsRequest = operations['admin___queue___promote-jobs']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminQueueQueueStatsRequest = operations['admin___queue___queue-stats']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminQueueRemoveJobRequest = operations['admin___queue___remove-job']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminQueueRetryJobRequest = operations['admin___queue___retry-job']['requestBody']['content']['application/json']; + +// @public (undocumented) +type AdminQueueShowJobRequest = operations['admin___queue___show-job']['requestBody']['content']['application/json']; // @public (undocumented) type AdminQueueStatsResponse = operations['admin___queue___stats']['responses']['200']['content']['application/json']; @@ -1531,7 +1546,12 @@ declare namespace entities { AdminQueueClearRequest, AdminQueueDeliverDelayedResponse, AdminQueueInboxDelayedResponse, - AdminQueuePromoteRequest, + AdminQueueJobsRequest, + AdminQueuePromoteJobsRequest, + AdminQueueQueueStatsRequest, + AdminQueueRemoveJobRequest, + AdminQueueRetryJobRequest, + AdminQueueShowJobRequest, AdminQueueStatsResponse, AdminRelaysAddRequest, AdminRelaysAddResponse, diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts index ae97084116..b607c93e1e 100644 --- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts +++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts @@ -636,12 +636,78 @@ declare module '../api.js' { credential?: string | null, ): Promise>; + /** + * No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Credential required**: *Yes* / **Permission**: *write:admin:queue* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Credential required**: *Yes* / **Permission**: *write:admin:queue* + */ + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + /** * No description provided. * * **Credential required**: *Yes* / **Permission**: *write:admin:queue* */ - request( + request( + endpoint: E, + params: P, + credential?: string | null, + ): Promise>; + + /** + * No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + request( endpoint: E, params: P, credential?: string | null, diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index d22395e866..6390314429 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -78,7 +78,12 @@ import type { AdminQueueClearRequest, AdminQueueDeliverDelayedResponse, AdminQueueInboxDelayedResponse, - AdminQueuePromoteRequest, + AdminQueueJobsRequest, + AdminQueuePromoteJobsRequest, + AdminQueueQueueStatsRequest, + AdminQueueRemoveJobRequest, + AdminQueueRetryJobRequest, + AdminQueueShowJobRequest, AdminQueueStatsResponse, AdminRelaysAddRequest, AdminRelaysAddResponse, @@ -694,7 +699,13 @@ export type Endpoints = { 'admin/queue/clear': { req: AdminQueueClearRequest; res: EmptyResponse }; 'admin/queue/deliver-delayed': { req: EmptyRequest; res: AdminQueueDeliverDelayedResponse }; 'admin/queue/inbox-delayed': { req: EmptyRequest; res: AdminQueueInboxDelayedResponse }; - 'admin/queue/promote': { req: AdminQueuePromoteRequest; res: EmptyResponse }; + 'admin/queue/jobs': { req: AdminQueueJobsRequest; res: EmptyResponse }; + 'admin/queue/promote-jobs': { req: AdminQueuePromoteJobsRequest; res: EmptyResponse }; + 'admin/queue/queue-stats': { req: AdminQueueQueueStatsRequest; res: EmptyResponse }; + 'admin/queue/queues': { req: EmptyRequest; res: EmptyResponse }; + 'admin/queue/remove-job': { req: AdminQueueRemoveJobRequest; res: EmptyResponse }; + 'admin/queue/retry-job': { req: AdminQueueRetryJobRequest; res: EmptyResponse }; + 'admin/queue/show-job': { req: AdminQueueShowJobRequest; res: EmptyResponse }; 'admin/queue/stats': { req: EmptyRequest; res: AdminQueueStatsResponse }; 'admin/relays/add': { req: AdminRelaysAddRequest; res: AdminRelaysAddResponse }; 'admin/relays/list': { req: EmptyRequest; res: AdminRelaysListResponse }; diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index a772c1559d..f814d7b3da 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -81,7 +81,12 @@ export type AdminPromoCreateRequest = operations['admin___promo___create']['requ export type AdminQueueClearRequest = operations['admin___queue___clear']['requestBody']['content']['application/json']; export type AdminQueueDeliverDelayedResponse = operations['admin___queue___deliver-delayed']['responses']['200']['content']['application/json']; export type AdminQueueInboxDelayedResponse = operations['admin___queue___inbox-delayed']['responses']['200']['content']['application/json']; -export type AdminQueuePromoteRequest = operations['admin___queue___promote']['requestBody']['content']['application/json']; +export type AdminQueueJobsRequest = operations['admin___queue___jobs']['requestBody']['content']['application/json']; +export type AdminQueuePromoteJobsRequest = operations['admin___queue___promote-jobs']['requestBody']['content']['application/json']; +export type AdminQueueQueueStatsRequest = operations['admin___queue___queue-stats']['requestBody']['content']['application/json']; +export type AdminQueueRemoveJobRequest = operations['admin___queue___remove-job']['requestBody']['content']['application/json']; +export type AdminQueueRetryJobRequest = operations['admin___queue___retry-job']['requestBody']['content']['application/json']; +export type AdminQueueShowJobRequest = operations['admin___queue___show-job']['requestBody']['content']['application/json']; export type AdminQueueStatsResponse = operations['admin___queue___stats']['responses']['200']['content']['application/json']; export type AdminRelaysAddRequest = operations['admin___relays___add']['requestBody']['content']['application/json']; export type AdminRelaysAddResponse = operations['admin___relays___add']['responses']['200']['content']['application/json']; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 3c51bedb5c..bb7ba30f1b 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -531,14 +531,68 @@ export type paths = { */ post: operations['admin___queue___inbox-delayed']; }; - '/admin/queue/promote': { + '/admin/queue/jobs': { /** - * admin/queue/promote + * admin/queue/jobs + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + post: operations['admin___queue___jobs']; + }; + '/admin/queue/promote-jobs': { + /** + * admin/queue/promote-jobs * @description No description provided. * * **Credential required**: *Yes* / **Permission**: *write:admin:queue* */ - post: operations['admin___queue___promote']; + post: operations['admin___queue___promote-jobs']; + }; + '/admin/queue/queue-stats': { + /** + * admin/queue/queue-stats + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + post: operations['admin___queue___queue-stats']; + }; + '/admin/queue/queues': { + /** + * admin/queue/queues + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + post: operations['admin___queue___queues']; + }; + '/admin/queue/remove-job': { + /** + * admin/queue/remove-job + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *write:admin:queue* + */ + post: operations['admin___queue___remove-job']; + }; + '/admin/queue/retry-job': { + /** + * admin/queue/retry-job + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *write:admin:queue* + */ + post: operations['admin___queue___retry-job']; + }; + '/admin/queue/show-job': { + /** + * admin/queue/show-job + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + post: operations['admin___queue___show-job']; }; '/admin/queue/stats': { /** @@ -8809,9 +8863,9 @@ export type operations = { content: { 'application/json': { /** @enum {string} */ - type: 'system' | 'endedPollNotification' | 'deliver' | 'inbox' | 'db' | 'relationship' | 'objectStorage' | 'userWebhookDeliver' | 'systemWebhookDeliver'; + queue: 'system' | 'endedPollNotification' | 'deliver' | 'inbox' | 'db' | 'relationship' | 'objectStorage' | 'userWebhookDeliver' | 'systemWebhookDeliver'; /** @enum {string} */ - state: '*' | 'wait' | 'delayed'; + state: '*' | 'completed' | 'wait' | 'active' | 'paused' | 'prioritized' | 'delayed' | 'failed'; }; }; }; @@ -8945,17 +8999,326 @@ export type operations = { }; }; /** - * admin/queue/promote + * admin/queue/jobs + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + admin___queue___jobs: { + requestBody: { + content: { + 'application/json': { + /** @enum {string} */ + queue: 'system' | 'endedPollNotification' | 'deliver' | 'inbox' | 'db' | 'relationship' | 'objectStorage' | 'userWebhookDeliver' | 'systemWebhookDeliver'; + state: ('active' | 'wait' | 'delayed' | 'completed' | 'failed')[]; + search?: 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/queue/promote-jobs * @description No description provided. * * **Credential required**: *Yes* / **Permission**: *write:admin:queue* */ - admin___queue___promote: { + 'admin___queue___promote-jobs': { + requestBody: { + content: { + 'application/json': { + /** @enum {string} */ + queue: 'system' | 'endedPollNotification' | 'deliver' | 'inbox' | 'db' | 'relationship' | 'objectStorage' | 'userWebhookDeliver' | 'systemWebhookDeliver'; + }; + }; + }; + 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/queue/queue-stats + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + 'admin___queue___queue-stats': { + requestBody: { + content: { + 'application/json': { + /** @enum {string} */ + queue: 'system' | 'endedPollNotification' | 'deliver' | 'inbox' | 'db' | 'relationship' | 'objectStorage' | 'userWebhookDeliver' | 'systemWebhookDeliver'; + }; + }; + }; + 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/queue/queues + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + admin___queue___queues: { + 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/queue/remove-job + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *write:admin:queue* + */ + 'admin___queue___remove-job': { + requestBody: { + content: { + 'application/json': { + /** @enum {string} */ + queue: 'system' | 'endedPollNotification' | 'deliver' | 'inbox' | 'db' | 'relationship' | 'objectStorage' | 'userWebhookDeliver' | 'systemWebhookDeliver'; + jobId: 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/queue/retry-job + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *write:admin:queue* + */ + 'admin___queue___retry-job': { + requestBody: { + content: { + 'application/json': { + /** @enum {string} */ + queue: 'system' | 'endedPollNotification' | 'deliver' | 'inbox' | 'db' | 'relationship' | 'objectStorage' | 'userWebhookDeliver' | 'systemWebhookDeliver'; + jobId: 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/queue/show-job + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:admin:queue* + */ + 'admin___queue___show-job': { requestBody: { content: { 'application/json': { /** @enum {string} */ - type: 'deliver' | 'inbox'; + queue: 'system' | 'endedPollNotification' | 'deliver' | 'inbox' | 'db' | 'relationship' | 'objectStorage' | 'userWebhookDeliver' | 'systemWebhookDeliver'; + jobId: string; }; }; }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d142cde7b7..858060b731 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -170,6 +170,9 @@ importers: '@twemoji/parser': specifier: 15.1.1 version: 15.1.1 + '@types/redis-info': + specifier: 3.0.3 + version: 3.0.3 accepts: specifier: 1.3.8 version: 1.3.8 @@ -368,6 +371,9 @@ importers: re2: specifier: 1.21.4 version: 1.21.4(patch_hash=018babd22b7ce951bcd10d6246f1e541a7ac7ba212f7fa8985e774ece67d08e1) + redis-info: + specifier: 3.1.0 + version: 3.1.0 redis-lock: specifier: 0.1.4 version: 0.1.4 @@ -4462,6 +4468,9 @@ packages: '@types/readdir-glob@1.1.1': resolution: {integrity: sha512-ImM6TmoF8bgOwvehGviEj3tRdRBbQujr1N+0ypaln/GWjaerOB26jb93vsRHmdMtvVQZQebOlqt2HROark87mQ==} + '@types/redis-info@3.0.3': + resolution: {integrity: sha512-VIkNy6JbYI/RLdbPHdm9JQvv6RVld2uE2/6Hdid38Qdq+zvDli2FTpImI8pC5zwp8xS8qVqfzlfyAub8xZEd5g==} + '@types/rename@1.0.7': resolution: {integrity: sha512-E9qapfghUGfBMi3jNhsmCKPIp3f2zvNKpaX1BDGLGJNjzpgsZ/RTx7NaNksFjGoJ+r9NvWF1NSM5vVecnNjVmw==} @@ -9429,6 +9438,9 @@ packages: resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} engines: {node: '>=4'} + redis-info@3.1.0: + resolution: {integrity: sha512-ER4L9Sh/vm63DkIE0bkSjxluQlioBiBgf5w1UuldaW/3vPcecdljVDisZhmnCMvsxHNiARTTDDHGg9cGwTfrKg==} + redis-lock@0.1.4: resolution: {integrity: sha512-7/+zu86XVQfJVx1nHTzux5reglDiyUCDwmW7TSlvVezfhH2YLc/Rc8NE0ejQG+8/0lwKzm29/u/4+ogKeLosiA==} engines: {node: '>=0.6'} @@ -14937,6 +14949,8 @@ snapshots: dependencies: '@types/node': 22.14.0 + '@types/redis-info@3.0.3': {} + '@types/rename@1.0.7': {} '@types/resolve@1.20.3': {} @@ -21162,6 +21176,10 @@ snapshots: redis-errors@1.2.0: {} + redis-info@3.1.0: + dependencies: + lodash: 4.17.21 + redis-lock@0.1.4: {} redis-parser@3.0.0: -- cgit v1.2.3-freya