refactor: remove unused normalizeDataUrlsToFilePaths function

- Function was only used in tests, not in production code
- Dual-storage approach (images + imagesBase64) eliminated need for base64→file conversion
- Removed ~60 lines of function code + ~90 lines of tests
- Simplified imageDataUrl module to focus on production use case
- Kept normalizeImageRefsToDataUrls which is used in production (Task.ts)
This commit is contained in:
daniel-lxs 2025-11-03 16:58:01 -05:00
parent 7ddfa4e529
commit 3ff9b21dae
No known key found for this signature in database
GPG key ID: 21C74479048B3AA6
2 changed files with 3 additions and 163 deletions

View file

@ -1,8 +1,7 @@
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"
import { normalizeImageRefsToDataUrls, normalizeDataUrlsToFilePaths } from "../imageDataUrl"
import { describe, it, expect, vi, beforeEach } from "vitest"
import { normalizeImageRefsToDataUrls } from "../imageDataUrl"
import * as fs from "fs/promises"
import * as path from "path"
import * as os from "os"
// Mock fs module
vi.mock("fs/promises")
@ -64,97 +63,3 @@ describe("normalizeImageRefsToDataUrls", () => {
expect(result).toEqual([])
})
})
describe("normalizeDataUrlsToFilePaths", () => {
const testGlobalStoragePath = path.join(os.tmpdir(), "test-roo-code-storage")
beforeEach(async () => {
vi.clearAllMocks()
// Mock mkdir to succeed
vi.mocked(fs.mkdir).mockResolvedValue(undefined)
// Mock writeFile to succeed
vi.mocked(fs.writeFile).mockResolvedValue(undefined)
// Mock access to fail initially (file doesn't exist)
vi.mocked(fs.access).mockRejectedValue(new Error("File not found"))
})
afterEach(() => {
vi.clearAllMocks()
})
it("should pass through non-data URLs unchanged", async () => {
const filePath = "/path/to/image.png"
const result = await normalizeDataUrlsToFilePaths([filePath], testGlobalStoragePath)
expect(result).toEqual([filePath])
expect(fs.writeFile).not.toHaveBeenCalled()
})
it("should convert data URLs to file paths", async () => {
const dataUrl =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=="
const result = await normalizeDataUrlsToFilePaths([dataUrl], testGlobalStoragePath)
expect(result).toHaveLength(1)
expect(result[0]).toMatch(/temp-images/)
expect(result[0]).toMatch(/\.png$/)
expect(fs.mkdir).toHaveBeenCalledWith(
expect.stringContaining("temp-images"),
expect.objectContaining({ recursive: true }),
)
expect(fs.writeFile).toHaveBeenCalledWith(expect.stringMatching(/temp-images.*\.png$/), expect.any(Buffer))
})
it("should handle mixed arrays of data URLs and file paths", async () => {
const dataUrl = "data:image/jpeg;base64,test123"
const filePath = "/existing/image.png"
const result = await normalizeDataUrlsToFilePaths([filePath, dataUrl], testGlobalStoragePath)
expect(result).toHaveLength(2)
expect(result[0]).toBe(filePath) // File path unchanged
expect(result[1]).toMatch(/temp-images/) // Data URL converted
expect(result[1]).toMatch(/\.jpeg$/) // Correct extension from MIME type
})
it("should handle errors gracefully", async () => {
const dataUrl = "data:image/png;base64,test"
// Mock writeFile to fail
vi.mocked(fs.writeFile).mockRejectedValue(new Error("Write failed"))
const result = await normalizeDataUrlsToFilePaths([dataUrl], testGlobalStoragePath)
// Should return original data URL as fallback
expect(result).toEqual([dataUrl])
})
it("should handle invalid data URL format", async () => {
const invalidDataUrl = "data:image/png" // Missing base64 data
const result = await normalizeDataUrlsToFilePaths([invalidDataUrl], testGlobalStoragePath)
// Should skip invalid URLs
expect(result).toHaveLength(0)
})
it("should handle empty arrays", async () => {
const result = await normalizeDataUrlsToFilePaths([], testGlobalStoragePath)
expect(result).toEqual([])
})
it("should extract correct file extensions from MIME types", async () => {
const testCases = [
{ dataUrl: "data:image/png;base64,test", expectedExt: ".png" },
{ dataUrl: "data:image/jpeg;base64,test", expectedExt: ".jpeg" },
{ dataUrl: "data:image/gif;base64,test", expectedExt: ".gif" },
{ dataUrl: "data:image/webp;base64,test", expectedExt: ".webp" },
]
for (const { dataUrl, expectedExt } of testCases) {
const result = await normalizeDataUrlsToFilePaths([dataUrl], testGlobalStoragePath)
expect(result[0]).toMatch(new RegExp(`${expectedExt.replace(".", "\\.")}$`))
}
})
})

View file

@ -1,7 +1,6 @@
import * as fs from "fs/promises"
import * as path from "path"
import * as crypto from "crypto"
import { getImageBase64ForPath, setImageBase64ForPath } from "./image-cache"
import { getImageBase64ForPath } from "./image-cache"
/**
* Converts webview URIs to base64 data URLs for API calls.
@ -44,70 +43,6 @@ export async function normalizeImageRefsToDataUrls(imageRefs: string[]): Promise
return results
}
/**
* Converts base64 data URLs to file paths suitable for webview URIs.
* Writes base64 images to temporary files and returns their paths.
*
* NOTE: This function is primarily used for testing. In production, the dual-storage
* approach (images + imagesBase64 in ClineMessage) eliminates the need for this conversion.
* No caching is implemented since this is a test utility.
*/
export async function normalizeDataUrlsToFilePaths(dataUrls: string[], globalStoragePath: string): Promise<string[]> {
const results: string[] = []
// Ensure temp directory exists
const tempDir = path.join(globalStoragePath, "temp-images")
try {
await fs.mkdir(tempDir, { recursive: true })
} catch (error) {
console.error("Failed to create temp-images directory:", error)
return dataUrls // Return original data URLs as fallback
}
for (const dataUrl of dataUrls) {
// If it's not a data URL, keep it as is (might be a file path already)
if (!dataUrl.startsWith("data:image/")) {
results.push(dataUrl)
continue
}
try {
// Extract base64 data and MIME type
const commaIndex = dataUrl.indexOf(",")
if (commaIndex === -1) {
console.error("Invalid data URL format:", dataUrl.substring(0, 50))
continue
}
const header = dataUrl.substring(0, commaIndex)
const base64Data = dataUrl.substring(commaIndex + 1)
// Determine file extension from MIME type
const mimeMatch = header.match(/data:image\/([^;]+)/)
const extension = mimeMatch ? `.${mimeMatch[1]}` : ".png"
// Create a unique hash for this image
const hash = crypto.createHash("md5").update(dataUrl).digest("hex")
// Write to temp file
const filePath = path.join(tempDir, `${hash}${extension}`)
const buffer = Buffer.from(base64Data, "base64")
await fs.writeFile(filePath, buffer)
// Cache the reverse mapping for image-cache lookups
setImageBase64ForPath(filePath, dataUrl)
results.push(filePath)
} catch (error) {
console.error("Failed to convert base64 data URL to file path:", error)
// Keep the original data URL as fallback
results.push(dataUrl)
}
}
return results
}
/**
* Converts a webview URI to a file system path
*/