refactor(backend): retire unused native bridge entry points

This commit is contained in:
zarzet committed 2026-09-30 21:47:15 +07:00
1 parent b8e3a4c166
commit fe88048db2
45 files changed
+20 -1832

No files matched your search

+2 -79
View File
@@ -257,8 +257,8 @@ import UniformTypeIdentifiers
private func handleMethodCall(call: FlutterMethodCall, result: @escaping FlutterResult) {
let osMethods: Set<String> = ["getBackendImplementations", "startWebAuthSession", "beginBackgroundDownloadTask", "endBackgroundDownloadTask",
"pickIosDirectory", "createIosBookmarkFromPath", "resolveIosBookmark", "startAccessingIosBookmark", "stopAccessingIosBookmark", "downloadCoverToFile", "releaseMemory", "releaseMemoryUnderPressure",
"setLibraryCoverCacheDir", "scanLibraryFolder", "scanLibraryFolderToNDJSONFile", "scanLibraryFolderIncremental",
"pickIosDirectory", "startAccessingIosBookmark", "stopAccessingIosBookmark", "downloadCoverToFile", "releaseMemory", "releaseMemoryUnderPressure",
"setLibraryCoverCacheDir", "scanLibraryFolderToNDJSONFile", "scanLibraryFolderIncremental",
"getLibraryScanProgress", "cancelLibraryScan", "parseCueSheet", "extractCoverToFile",
"rewriteSplitArtistTags", "writeM4AFreeformTags", "ensureAC4Config", "writeAC4Metadata", "reEnrichFile",
"checkHiResAuthenticity"]
@@ -546,11 +546,6 @@ import UniformTypeIdentifiers
try coreBackend.setLibraryCoverCacheDirectory(path: cacheDir)
return nil
case "scanLibraryFolder":
let args = call.arguments as! [String: Any]
let folderPath = args["folder_path"] as! String
return bridgeJsonResult(try coreBackend.scanLibraryFolder(folder: folderPath))
case "scanLibraryFolderToNDJSONFile":
guard
let args = call.arguments as? [String: Any],
@@ -582,11 +577,6 @@ import UniformTypeIdentifiers
return nil
case "resolveIosBookmark":
let args = call.arguments as! [String: Any]
let bookmarkBase64 = args["bookmark"] as! String
return try resolveIosBookmark(bookmarkBase64)
case "startAccessingIosBookmark":
guard
let args = call.arguments as? [String: Any],
@@ -608,11 +598,6 @@ import UniformTypeIdentifiers
stopAccessingIosBookmark(token: token)
return nil
case "createIosBookmarkFromPath":
let args = call.arguments as! [String: Any]
let path = args["path"] as! String
return try createIosBookmarkFromPath(path)
case "parseCueSheet":
let args = call.arguments as! [String: Any]
@@ -663,68 +648,6 @@ import UniformTypeIdentifiers
// MARK: - iOS Security-Scoped Bookmark Helpers
/// Create a security-scoped bookmark from a filesystem path (e.g. from FilePicker).
/// The path must currently be accessible (within the same picker session).
/// Returns base64-encoded bookmark data.
private func createIosBookmarkFromPath(_ path: String) throws -> String {
let url = URL(fileURLWithPath: path)
do {
#if os(macOS)
let options: URL.BookmarkCreationOptions = .withSecurityScope
#else
let options: URL.BookmarkCreationOptions = []
#endif
let bookmarkData = try url.bookmarkData(
options: options,
includingResourceValuesForKeys: nil,
relativeTo: nil
)
return bookmarkData.base64EncodedString()
} catch {
throw NSError(
domain: "SpotiFLAC",
code: -1,
userInfo: [NSLocalizedDescriptionKey: "Failed to create bookmark for path \(path): \(error.localizedDescription)"]
)
}
}
/// Resolve a base64-encoded security-scoped bookmark and return the resolved path.
/// Does NOT start accessing the resource.
private func resolveIosBookmark(_ bookmarkBase64: String) throws -> String {
guard let bookmarkData = Data(base64Encoded: bookmarkBase64) else {
throw NSError(
domain: "SpotiFLAC",
code: -1,
userInfo: [NSLocalizedDescriptionKey: "Invalid base64 bookmark data"]
)
}
var isStale = false
let url: URL
do {
#if os(macOS)
let options: URL.BookmarkResolutionOptions = .withSecurityScope
#else
let options: URL.BookmarkResolutionOptions = []
#endif
url = try URL(
resolvingBookmarkData: bookmarkData,
options: options,
relativeTo: nil,
bookmarkDataIsStale: &isStale
)
} catch {
throw NSError(
domain: "SpotiFLAC",
code: -1,
userInfo: [NSLocalizedDescriptionKey: "Failed to resolve bookmark: \(error.localizedDescription)"]
)
}
return url.path
}
private func invalidArgumentsError(_ method: String) -> NSError {
return NSError(
domain: "SpotiFLAC",
+3 -40
View File
@@ -173,7 +173,6 @@ protocol CoreBackend {
func ensureAc4Config(path: String, reference: String) throws -> String
func writeAc4Metadata(path: String, metadataJson: String, coverPath: String) throws -> String
func setLibraryCoverCacheDirectory(path: String) throws
func scanLibraryFolder(folder: String) throws -> String
func scanLibraryFolderToNdjsonFile(folder: String, output: String) throws -> Int
func scanLibraryFolderIncremental(folder: String, existing: String) throws -> String
func getLibraryScanProgress() throws -> String
@@ -340,12 +339,6 @@ final class RustCoreBackend: CoreBackend {
libraryCoverScope = next
}
func scanLibraryFolder(folder: String) throws -> String {
try withLibraryDirectories([folder]) {
try $0.scanLibraryFolder(folder: URL(fileURLWithPath: folder).resolvingSymlinksInPath().standardizedFileURL.path, lease: nil)
}
}
func scanLibraryFolderToNdjsonFile(folder: String, output: String) throws -> Int {
guard output.hasPrefix("/"), URL(fileURLWithPath: output).pathExtension.lowercased() == "ndjson" else {
throw failure("Library scan output must be an absolute NDJSON path")
@@ -632,11 +625,7 @@ final class RustCoreBackend: CoreBackend {
case "setRepoRegistryUrl": try repositoryOwner().setRegistryUrl(url: string("registry_url")); return nil
case "clearRepoRegistryUrl": try repositoryOwner().clearRegistryUrl(); return nil
case "getRepoExtensions": return try repositoryOwner().extensions(forceRefresh: args["force_refresh"] as? Bool ?? false)
case "searchRepoExtensions": return try repositoryOwner().search(query: string("query"), category: string("category"))
case "getRepoCategories":
return String(decoding: try JSONSerialization.data(withJSONObject: repositoryOwner().categories()), as: UTF8.self)
case "downloadRepoExtension": return try repositoryOwner().download(extensionId: string("extension_id"), destinationDirectory: string("dest_dir"))
case "clearRepoCache": try repositoryOwner().clearCache(); return nil
case "cleanupExtensions": shutdownOwner(); return nil
case "buildFilename": return try buildFilename(template: string("template"), metadataJson: string("metadata", "{}"))
case "sanitizeFilename": return sanitizeFilename(filename: string("filename"))
@@ -651,7 +640,7 @@ final class RustCoreBackend: CoreBackend {
defer { ownerLock.unlock() }
try manager?.environment().logBuffer().clear()
return nil
case "setLoggingEnabled", "setAllowPrivateNetwork", "setDownloadFallbackExtensionIds", "setLyricsProviders", "setLyricsFetchOptions", "setNetworkCompatibilityOptions", "setSongLinkNetworkOptions":
case "setLoggingEnabled", "setAllowPrivateNetwork", "setDownloadFallbackExtensionIds", "setLyricsProviders", "setLyricsFetchOptions", "setNetworkCompatibilityOptions":
ownerLock.lock()
defer { ownerLock.unlock() }
switch method {
@@ -663,7 +652,7 @@ final class RustCoreBackend: CoreBackend {
let allowed = args["allowed"] as? Bool ?? false
try manager?.environment().setAllowPrivateNetwork(allow: allowed)
allowPrivateNetwork = allowed
case "setNetworkCompatibilityOptions", "setSongLinkNetworkOptions":
case "setNetworkCompatibilityOptions":
let allowed = args["allow_http"] as? Bool ?? false
let insecureTLS = args["insecure_tls"] as? Bool ?? false
try manager?.environment().setNetworkCompatibilityOptions(allowHttp: allowed, insecureTls: insecureTLS)
@@ -702,7 +691,6 @@ final class RustCoreBackend: CoreBackend {
case "checkExtensionUpgrade": return try current.checkUpgrade(packagePath: string("file_path"))
case "getInstalledExtensions": return try current.installed()
case "setExtensionEnabled": try current.setEnabled(extensionId: string("extension_id"), enabled: args["enabled"] as? Bool ?? false); return nil
case "unloadExtension": try current.unload(extensionId: string("extension_id")); return nil
case "removeExtension": try current.remove(extensionId: string("extension_id")); return nil
case "getExtensionSettings": return try current.environment().settings(extensionId: string("extension_id"))
case "setExtensionSettings": try current.updateSettings(extensionId: string("extension_id"), settingsJson: string("settings", "{}")); return nil
@@ -716,14 +704,11 @@ final class RustCoreBackend: CoreBackend {
return try current.getProviderMetadataJson(providerId: string("provider_id"), resourceType: string("resource_type"), resourceId: string("resource_id"), lease: nil)
case "findCollectionAcrossExtensions":
return try current.findCollectionAcrossExtensionsJson(requestJson: arguments as? String ?? "{}", lease: nil)
case "enrichTrackWithExtension": return try current.enrichTrackJson(extensionId: string("extension_id"), trackJson: string("track", "{}"))
case "handleURLWithExtension": return try current.handleUrlJson(url: string("url"))
case "findURLHandler": return try current.findUrlHandler(url: string("url")) ?? ""
case "searchDeezerByISRC": return try current.searchDeezerByIsrcForItemId(isrc: string("isrc"), itemId: string("item_id"), lease: nil)
case "getDeezerExtendedMetadata": return try current.getDeezerExtendedMetadata(trackId: string("track_id"), lease: nil)
case "convertSpotifyToDeezer": return try current.convertSpotifyToDeezer(resourceType: string("resource_type"), spotifyId: string("spotify_id"), lease: nil)
case "getSpotifyIDFromDeezerTrack": return try current.getSpotifyIdFromDeezerTrack(trackId: string("deezer_track_id"), lease: nil)
case "getTidalURLFromDeezerTrack": return try current.getTidalUrlFromDeezerTrack(trackId: string("deezer_track_id"), lease: nil)
case "getTrackPlatformLinks": return try current.getTrackPlatformLinksJson(spotifyId: string("spotify_id"), isrc: string("isrc"), lease: nil)
case "fetchMusicBrainzTags":
let genre = (try? current.fetchMusicBrainzGenreByIsrc(isrc: string("isrc"), lease: nil)) ?? ""
@@ -737,12 +722,11 @@ final class RustCoreBackend: CoreBackend {
}
case "clearTrackCache": try current.clearTrackIdCache(); return nil
case "setMetadataLanguage": try current.setMetadataLanguage(tag: string("tag")); return nil
case "downloadByStrategy", "downloadWithExtensions":
case "downloadByStrategy":
guard let request = arguments as? String else {
throw NSError(domain: "CoreBackend", code: 1, userInfo: [NSLocalizedDescriptionKey: "Download request must be a JSON string"])
}
return try withFFmpegCommands(current) {
if method == "downloadWithExtensions" { return try current.downloadWithExtensionsJson(requestJson: request) }
return try current.downloadByStrategy(requestJson: request)
}
case "getAllDownloadProgress": return try current.environment().downloadState().allProgress()
@@ -751,16 +735,9 @@ final class RustCoreBackend: CoreBackend {
case "cancelDownload": try current.environment().downloadState().cancelDownload(itemId: string("item_id")); return nil
case "resetDownloadCancel": try current.environment().downloadState().resetDownloadCancel(itemId: string("item_id")); return nil
case "getExtensionPendingAuth": return try current.getExtensionPendingAuthJson(extensionId: string("extension_id"))
case "setExtensionAuthCode": try current.environment().setAuthCode(extensionId: string("extension_id"), code: string("auth_code")); return nil
case "completeExtensionSessionGrant":
try completeSessionGrant(current, id: string("extension_id"), grant: string("grant"))
return true
case "setExtensionTokens":
try current.environment().setAuthTokens(extensionId: string("extension_id"), accessToken: string("access_token"), refreshToken: string("refresh_token"), expiresIn: (args["expires_in"] as? NSNumber)?.int64Value ?? 0)
return nil
case "clearExtensionPendingAuth": try current.environment().clearPendingAuth(extensionId: string("extension_id")); return nil
case "isExtensionAuthenticated": return try current.environment().isAuthenticated(extensionId: string("extension_id"))
case "getAllPendingAuthRequests": return try current.environment().allPendingAuth()
case "getLyricsLRC", "getLyricsLRCWithSource", "fetchAndSaveLyrics":
let request = LyricsRequest(
spotifyId: string("spotify_id"),
@@ -773,18 +750,6 @@ final class RustCoreBackend: CoreBackend {
if method == "getLyricsLRCWithSource" { return try current.getLyricsLrcWithSource(request: request, lease: nil) }
try current.fetchAndSaveLyrics(request: request, outputPath: string("output_path"), lease: nil)
return "{\"success\":true}"
case "getPendingFFmpegCommand":
return try current.environment().ffmpegCommands().getCommand(commandId: string("command_id"))
case "getAllPendingFFmpegCommands":
return try current.environment().ffmpegCommands().pending()
case "setFFmpegCommandResult":
_ = try current.environment().ffmpegCommands().complete(
commandId: string("command_id"),
success: args["success"] as? Bool ?? false,
output: string("output"),
error: string("error")
)
return nil
case "runPostProcessingV2":
return try withFFmpegCommands(current) {
try current.runPostProcessing(inputJson: string("input"), metadataJson: string("metadata"), timeoutMs: 120_000)
@@ -798,8 +763,6 @@ final class RustCoreBackend: CoreBackend {
let priorities = try JSONSerialization.jsonObject(with: Data(current.providerPriorities().utf8)) as! [String: Any]
let value = priorities[method == "getProviderPriority" ? "download" : "metadata"] as? [String] ?? []
return String(decoding: try JSONSerialization.data(withJSONObject: value), as: UTF8.self)
case "getLyricsProviders": return try current.getLyricsProvidersJson()
case "getLyricsFetchOptions": return try current.getLyricsFetchOptionsJson()
case "getAvailableLyricsProviders": return try current.getAvailableLyricsProvidersJson()
default: throw failure("Rust application method is not connected yet: \(method)")
}