mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
refactor(api): collapse src/api into src/lib/api
The seven remaining src/api/ modules (analysis, azuracast, bandsintown, coverCache, migration, network, runtimeLogs) were the last IPC-layer files outside src/lib/api/, where the rest of the FE IPC clients already live. Move them (+ the colocated coverCache test) into lib/api and repoint every consumer; relative-up imports in the moved files become the depth-independent @/ alias. Pure move + import updates — no behavior change. The layering baseline is regenerated in the same commit: the moved files' pre-existing store/cover edges are only now caught under lib/, and the cover<->coverCache cycles are the same edges re-keyed to the new path (E4 shrinks the allowlist later).
This commit is contained in:
@@ -8,7 +8,7 @@ import { open as shellOpen } from '@tauri-apps/plugin-shell';
|
||||
import { usePlayerStore } from '@/features/playback/store/playerStore';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { usePlaybackServerId } from '@/features/playback/hooks/usePlaybackServerId';
|
||||
import { fetchBandsintownEvents, type BandsintownEvent } from '@/api/bandsintown';
|
||||
import { fetchBandsintownEvents, type BandsintownEvent } from '@/lib/api/bandsintown';
|
||||
import CachedImage from '@/ui/CachedImage';
|
||||
import OverlayScrollArea from '@/ui/OverlayScrollArea';
|
||||
import { primaryTrackArtistRef } from '@/features/playback/utils/playback/trackArtistRefs';
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { memo, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Calendar, Info } from 'lucide-react';
|
||||
import { open as shellOpen } from '@tauri-apps/plugin-shell';
|
||||
import type { BandsintownEvent } from '@/api/bandsintown';
|
||||
import type { BandsintownEvent } from '@/lib/api/bandsintown';
|
||||
import { isoToParts } from '@/features/nowPlaying/utils/nowPlayingHelpers';
|
||||
|
||||
interface TourCardProps {
|
||||
|
||||
@@ -15,7 +15,7 @@ import type { SubsonicArtistInfo, SubsonicSong, SubsonicAlbum, SubsonicArtist }
|
||||
|
||||
vi.mock('@/lib/api/subsonicArtists');
|
||||
vi.mock('@/lib/api/subsonicLibrary');
|
||||
vi.mock('@/api/bandsintown');
|
||||
vi.mock('@/lib/api/bandsintown');
|
||||
vi.mock('@/lib/network/subsonicNetworkGuard', () => ({
|
||||
shouldAttemptSubsonicForServer: vi.fn(() => true),
|
||||
}));
|
||||
@@ -23,7 +23,7 @@ vi.mock('@/lib/network/subsonicNetworkGuard', () => ({
|
||||
import { shouldAttemptSubsonicForServer } from '@/lib/network/subsonicNetworkGuard';
|
||||
import { getArtistForServer, getArtistInfoForServer, getTopSongsForServer } from '@/lib/api/subsonicArtists';
|
||||
import { getAlbumForServer, getSongForServer } from '@/lib/api/subsonicLibrary';
|
||||
import { fetchBandsintownEvents } from '@/api/bandsintown';
|
||||
import { fetchBandsintownEvents } from '@/lib/api/bandsintown';
|
||||
import { useNowPlayingFetchers, type NowPlayingFetchersDeps } from '@/features/nowPlaying/hooks/useNowPlayingFetchers';
|
||||
|
||||
// Resolved return shapes of the mocked API calls — used to cast deliberately
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
|
||||
import { getArtistInfoForServer } from '@/lib/api/subsonicArtists';
|
||||
import type { SubsonicAlbum, SubsonicArtistInfo, SubsonicSong } from '@/lib/api/subsonicTypes';
|
||||
import { resolveNpAlbum, resolveNpDiscography, resolveNpSongMeta, resolveNpTopSongs } from '@/features/nowPlaying/utils/nowPlayingMetadataResolve';
|
||||
import { fetchBandsintownEvents, type BandsintownEvent } from '@/api/bandsintown';
|
||||
import { fetchBandsintownEvents, type BandsintownEvent } from '@/lib/api/bandsintown';
|
||||
import type { ArtistStats, TrackStats } from '@/music-network';
|
||||
import { getMusicNetworkRuntimeOrNull } from '@/music-network';
|
||||
import { makeCache } from '@/lib/cache/nowPlayingCache';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { coverCacheEnsure, coverCachePeekBatch } from '@/api/coverCache';
|
||||
import { coverCacheEnsure, coverCachePeekBatch } from '@/lib/api/coverCache';
|
||||
import { coverIndexKeyFromRef } from '@/cover/storageKeys';
|
||||
import { useNowPlayingPrewarm } from '@/features/nowPlaying/hooks/useNowPlayingPrewarm';
|
||||
import { prewarmNowPlayingFetchers } from '@/features/nowPlaying/hooks/useNowPlayingFetchers';
|
||||
@@ -10,8 +10,8 @@ import { makeTrack } from '@/test/helpers/factories';
|
||||
import { resetAllStores } from '@/test/helpers/storeReset';
|
||||
import { toQueueItemRefs } from '@/features/playback/store/queueItemRef';
|
||||
|
||||
vi.mock('@/api/coverCache', async importOriginal => {
|
||||
const actual = await importOriginal<typeof import('@/api/coverCache')>();
|
||||
vi.mock('@/lib/api/coverCache', async importOriginal => {
|
||||
const actual = await importOriginal<typeof import('@/lib/api/coverCache')>();
|
||||
return {
|
||||
...actual,
|
||||
coverCachePeekBatch: vi.fn(async () => ({})),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect } from 'react';
|
||||
import { coverCacheEnsure, coverCachePeekBatch } from '@/api/coverCache';
|
||||
import { coverCacheEnsure, coverCachePeekBatch } from '@/lib/api/coverCache';
|
||||
import { albumCoverRef } from '@/cover/ref';
|
||||
import { resolvePlaybackCoverScope } from '@/cover/ref';
|
||||
import { resolveTrackCoverRefFromLibrary } from '@/cover/resolveEntryLibrary';
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
isOfflinePinComplete,
|
||||
pendingOfflinePinSongs,
|
||||
} from '@/features/offline/utils/offlineLibraryHelpers';
|
||||
import { librarySqlServerId } from '@/api/coverCache';
|
||||
import { librarySqlServerId } from '@/lib/api/coverCache';
|
||||
import { resolveIndexKey, serverIndexKeyForProfile } from '@/lib/server/serverIndexKey';
|
||||
import { isSmartPlaylistName } from '@/lib/format/playlistDetailHelpers';
|
||||
import {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { libraryUpsertSongsFromApi } from '@/lib/api/library';
|
||||
import { librarySqlServerId } from '@/api/coverCache';
|
||||
import { librarySqlServerId } from '@/lib/api/coverCache';
|
||||
import { getAlbumForServer } from '@/lib/api/subsonicLibrary';
|
||||
import { getArtistForServer } from '@/lib/api/subsonicArtists';
|
||||
import { getStarredForServer } from '@/lib/api/subsonicStarRating';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { libraryUpsertSongsFromApi } from '@/lib/api/library';
|
||||
import { librarySqlServerId } from '@/api/coverCache';
|
||||
import { librarySqlServerId } from '@/lib/api/coverCache';
|
||||
import type { SubsonicSong } from '@/lib/api/subsonicTypes';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
|
||||
@@ -22,7 +22,7 @@ vi.mock('@/lib/api/subsonicStreamUrl', () => ({
|
||||
buildStreamUrlForServer: (_sid: string, id: string) => `https://mock/stream/${id}`,
|
||||
}));
|
||||
|
||||
vi.mock('@/api/coverCache', () => ({
|
||||
vi.mock('@/lib/api/coverCache', () => ({
|
||||
librarySqlServerId: (k: string) => k,
|
||||
}));
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Track } from '@/lib/media/trackTypes';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { useHotCacheStore } from '@/features/playback/store/hotCacheStore';
|
||||
import { getMediaDir } from '@/lib/media/mediaDir';
|
||||
import { librarySqlServerId } from '@/api/coverCache';
|
||||
import { librarySqlServerId } from '@/lib/api/coverCache';
|
||||
import { hasLocalPersistentPlaybackBytes } from '@/store/localPlaybackResolve';
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
fetchAzuraCastNowPlaying,
|
||||
type AzuraCastNowPlaying,
|
||||
type AzuraCastSong,
|
||||
} from '@/api/azuracast';
|
||||
} from '@/lib/api/azuracast';
|
||||
|
||||
// ─── Public types ─────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { AddServerForm } from '@/features/settings/components/AddServerForm';
|
||||
import { encodeServerMagicString } from '@/lib/server/serverMagicString';
|
||||
|
||||
// resolve_host_addresses Tauri command — hint-only, must not block save.
|
||||
vi.mock('@/api/network', () => ({
|
||||
vi.mock('@/lib/api/network', () => ({
|
||||
resolveHostAddresses: vi.fn(async () => [] as string[]),
|
||||
}));
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from '@/lib/server/serverMagicString';
|
||||
import { shortHostFromServerUrl } from '@/lib/server/serverDisplayName';
|
||||
import { isLanUrl } from '@/lib/server/serverEndpoint';
|
||||
import { resolveHostAddresses } from '@/api/network';
|
||||
import { resolveHostAddresses } from '@/lib/api/network';
|
||||
|
||||
type FormState = {
|
||||
name: string;
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
type AnalysisFailedTrackDto,
|
||||
libraryAnalysisProgress,
|
||||
type LibraryAnalysisProgressDto,
|
||||
} from '@/api/analysis';
|
||||
} from '@/lib/api/analysis';
|
||||
import { libraryGetTracksBatch, type LibraryTrackDto, type TrackRefDto } from '@/lib/api/library';
|
||||
import { buildStreamUrlForServer } from '@/lib/api/subsonicStreamUrl';
|
||||
import { serverListDisplayLabel } from '@/lib/server/serverDisplayName';
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
coverCacheStatsServer,
|
||||
libraryCoverCatalogSize,
|
||||
libraryCoverProgress,
|
||||
} from '@/api/coverCache';
|
||||
} from '@/lib/api/coverCache';
|
||||
import { clearDiskSrcCacheForServer } from '@/cover/diskSrcCache';
|
||||
import { serverListDisplayLabel } from '@/lib/server/serverDisplayName';
|
||||
import { serverIndexKeyForProfile } from '@/lib/server/serverIndexKey';
|
||||
|
||||
@@ -10,7 +10,7 @@ import { BackdropSourceList } from '@/features/settings/components/BackdropSourc
|
||||
import type { BackdropSurface } from '@/store/themeStore';
|
||||
import type { BackdropSource } from '@/cover/artistBackdrop';
|
||||
import { MusicNetworkSection } from '@/features/settings/components/musicNetwork/MusicNetworkSection';
|
||||
import { purgeExternalArtworkAllServers } from '@/api/coverCache';
|
||||
import { purgeExternalArtworkAllServers } from '@/lib/api/coverCache';
|
||||
|
||||
export function IntegrationsTab() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
libraryCoverBackfillResetCursor,
|
||||
libraryCoverBackfillRunFullPass,
|
||||
libraryCoverBackfillSetParallel,
|
||||
} from '@/api/coverCache';
|
||||
} from '@/lib/api/coverCache';
|
||||
|
||||
const COVER_THREADS_MIN = 1;
|
||||
const COVER_THREADS_MAX = 16;
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Copy, Download, Pause, Play, Trash2 } from 'lucide-react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { save as saveDialog } from '@tauri-apps/plugin-dialog';
|
||||
import { writeFile } from '@tauri-apps/plugin-fs';
|
||||
import { getLoggingMode, tailRuntimeLogs, type RuntimeLogLine } from '@/api/runtimeLogs';
|
||||
import { getLoggingMode, tailRuntimeLogs, type RuntimeLogLine } from '@/lib/api/runtimeLogs';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import type { LoggingMode } from '@/store/authStoreTypes';
|
||||
|
||||
Reference in New Issue
Block a user