mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-22 02:54:31 -07:00
Reduce bundle size & check it in CI (#7395)
This commit is contained in:
@@ -18,7 +18,8 @@ import * as actualNodeFs from 'node:fs'; // For setup/teardown
|
||||
import fsPromises from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import mime from 'mime-types';
|
||||
// eslint-disable-next-line import/no-internal-modules
|
||||
import mime from 'mime/lite';
|
||||
|
||||
import {
|
||||
isWithinRoot,
|
||||
@@ -30,12 +31,12 @@ import {
|
||||
} from './fileUtils.js';
|
||||
import { StandardFileSystemService } from '../services/fileSystemService.js';
|
||||
|
||||
vi.mock('mime-types', () => ({
|
||||
default: { lookup: vi.fn() },
|
||||
lookup: vi.fn(),
|
||||
vi.mock('mime/lite', () => ({
|
||||
default: { getType: vi.fn() },
|
||||
getType: vi.fn(),
|
||||
}));
|
||||
|
||||
const mockMimeLookup = mime.lookup as Mock;
|
||||
const mockMimeGetType = mime.getType as Mock;
|
||||
|
||||
describe('fileUtils', () => {
|
||||
let tempRootDir: string;
|
||||
@@ -49,7 +50,7 @@ describe('fileUtils', () => {
|
||||
let directoryPath: string;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks(); // Reset all mocks, including mime.lookup
|
||||
vi.resetAllMocks(); // Reset all mocks, including mime.getType
|
||||
|
||||
tempRootDir = actualNodeFs.mkdtempSync(
|
||||
path.join(os.tmpdir(), 'fileUtils-test-'),
|
||||
@@ -570,12 +571,12 @@ describe('fileUtils', () => {
|
||||
});
|
||||
|
||||
it('should detect image type by extension (png)', async () => {
|
||||
mockMimeLookup.mockReturnValueOnce('image/png');
|
||||
mockMimeGetType.mockReturnValueOnce('image/png');
|
||||
expect(await detectFileType('file.png')).toBe('image');
|
||||
});
|
||||
|
||||
it('should detect image type by extension (jpeg)', async () => {
|
||||
mockMimeLookup.mockReturnValueOnce('image/jpeg');
|
||||
mockMimeGetType.mockReturnValueOnce('image/jpeg');
|
||||
expect(await detectFileType('file.jpg')).toBe('image');
|
||||
});
|
||||
|
||||
@@ -585,31 +586,31 @@ describe('fileUtils', () => {
|
||||
});
|
||||
|
||||
it('should detect pdf type by extension', async () => {
|
||||
mockMimeLookup.mockReturnValueOnce('application/pdf');
|
||||
mockMimeGetType.mockReturnValueOnce('application/pdf');
|
||||
expect(await detectFileType('file.pdf')).toBe('pdf');
|
||||
});
|
||||
|
||||
it('should detect audio type by extension', async () => {
|
||||
mockMimeLookup.mockReturnValueOnce('audio/mpeg');
|
||||
mockMimeGetType.mockReturnValueOnce('audio/mpeg');
|
||||
expect(await detectFileType('song.mp3')).toBe('audio');
|
||||
});
|
||||
|
||||
it('should detect video type by extension', async () => {
|
||||
mockMimeLookup.mockReturnValueOnce('video/mp4');
|
||||
mockMimeGetType.mockReturnValueOnce('video/mp4');
|
||||
expect(await detectFileType('movie.mp4')).toBe('video');
|
||||
});
|
||||
|
||||
it('should detect known binary extensions as binary (e.g. .zip)', async () => {
|
||||
mockMimeLookup.mockReturnValueOnce('application/zip');
|
||||
mockMimeGetType.mockReturnValueOnce('application/zip');
|
||||
expect(await detectFileType('archive.zip')).toBe('binary');
|
||||
});
|
||||
it('should detect known binary extensions as binary (e.g. .exe)', async () => {
|
||||
mockMimeLookup.mockReturnValueOnce('application/octet-stream'); // Common for .exe
|
||||
mockMimeGetType.mockReturnValueOnce('application/octet-stream'); // Common for .exe
|
||||
expect(await detectFileType('app.exe')).toBe('binary');
|
||||
});
|
||||
|
||||
it('should use isBinaryFile for unknown extensions and detect as binary', async () => {
|
||||
mockMimeLookup.mockReturnValueOnce(false); // Unknown mime type
|
||||
mockMimeGetType.mockReturnValueOnce(false); // Unknown mime type
|
||||
// Create a file that isBinaryFile will identify as binary
|
||||
const binaryContent = Buffer.from([
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
@@ -619,7 +620,7 @@ describe('fileUtils', () => {
|
||||
});
|
||||
|
||||
it('should default to text if mime type is unknown and content is not binary', async () => {
|
||||
mockMimeLookup.mockReturnValueOnce(false); // Unknown mime type
|
||||
mockMimeGetType.mockReturnValueOnce(false); // Unknown mime type
|
||||
// filePathForDetectTest is already a text file by default from beforeEach
|
||||
expect(await detectFileType(filePathForDetectTest)).toBe('text');
|
||||
});
|
||||
@@ -677,7 +678,7 @@ describe('fileUtils', () => {
|
||||
|
||||
it('should handle read errors for image/pdf files', async () => {
|
||||
actualNodeFs.writeFileSync(testImageFilePath, 'content'); // File must exist
|
||||
mockMimeLookup.mockReturnValue('image/png');
|
||||
mockMimeGetType.mockReturnValue('image/png');
|
||||
const readError = new Error('Simulated image read error');
|
||||
vi.spyOn(fsPromises, 'readFile').mockRejectedValueOnce(readError);
|
||||
|
||||
@@ -693,7 +694,7 @@ describe('fileUtils', () => {
|
||||
it('should process an image file', async () => {
|
||||
const fakePngData = Buffer.from('fake png data');
|
||||
actualNodeFs.writeFileSync(testImageFilePath, fakePngData);
|
||||
mockMimeLookup.mockReturnValue('image/png');
|
||||
mockMimeGetType.mockReturnValue('image/png');
|
||||
const result = await processSingleFileContent(
|
||||
testImageFilePath,
|
||||
tempRootDir,
|
||||
@@ -715,7 +716,7 @@ describe('fileUtils', () => {
|
||||
it('should process a PDF file', async () => {
|
||||
const fakePdfData = Buffer.from('fake pdf data');
|
||||
actualNodeFs.writeFileSync(testPdfFilePath, fakePdfData);
|
||||
mockMimeLookup.mockReturnValue('application/pdf');
|
||||
mockMimeGetType.mockReturnValue('application/pdf');
|
||||
const result = await processSingleFileContent(
|
||||
testPdfFilePath,
|
||||
tempRootDir,
|
||||
@@ -743,7 +744,7 @@ describe('fileUtils', () => {
|
||||
const testSvgFilePath = path.join(tempRootDir, 'test.svg');
|
||||
actualNodeFs.writeFileSync(testSvgFilePath, svgContent, 'utf-8');
|
||||
|
||||
mockMimeLookup.mockReturnValue('image/svg+xml');
|
||||
mockMimeGetType.mockReturnValue('image/svg+xml');
|
||||
|
||||
const result = await processSingleFileContent(
|
||||
testSvgFilePath,
|
||||
@@ -760,7 +761,7 @@ describe('fileUtils', () => {
|
||||
testBinaryFilePath,
|
||||
Buffer.from([0x00, 0x01, 0x02]),
|
||||
);
|
||||
mockMimeLookup.mockReturnValueOnce('application/octet-stream');
|
||||
mockMimeGetType.mockReturnValueOnce('application/octet-stream');
|
||||
// isBinaryFile will operate on the real file.
|
||||
|
||||
const result = await processSingleFileContent(
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import type { PartUnion } from '@google/genai';
|
||||
import mime from 'mime-types';
|
||||
// eslint-disable-next-line import/no-internal-modules
|
||||
import mime from 'mime/lite';
|
||||
import type { FileSystemService } from '../services/fileSystemService.js';
|
||||
import { ToolErrorType } from '../tools/tool-error.js';
|
||||
import { BINARY_EXTENSIONS } from './ignorePatterns.js';
|
||||
@@ -157,7 +158,7 @@ export async function readFileWithEncoding(filePath: string): Promise<string> {
|
||||
* @returns The specific MIME type string (e.g., 'text/python', 'application/javascript') or undefined if not found or ambiguous.
|
||||
*/
|
||||
export function getSpecificMimeType(filePath: string): string | undefined {
|
||||
const lookedUpMime = mime.lookup(filePath);
|
||||
const lookedUpMime = mime.getType(filePath);
|
||||
return typeof lookedUpMime === 'string' ? lookedUpMime : undefined;
|
||||
}
|
||||
|
||||
@@ -261,7 +262,7 @@ export async function detectFileType(
|
||||
return 'svg';
|
||||
}
|
||||
|
||||
const lookedUpMimeType = mime.lookup(filePath); // Returns false if not found, or the mime type string
|
||||
const lookedUpMimeType = mime.getType(filePath); // Returns null if not found, or the mime type string
|
||||
if (lookedUpMimeType) {
|
||||
if (lookedUpMimeType.startsWith('image/')) {
|
||||
return 'image';
|
||||
@@ -437,7 +438,7 @@ export async function processSingleFileContent(
|
||||
llmContent: {
|
||||
inlineData: {
|
||||
data: base64Data,
|
||||
mimeType: mime.lookup(filePath) || 'application/octet-stream',
|
||||
mimeType: mime.getType(filePath) || 'application/octet-stream',
|
||||
},
|
||||
},
|
||||
returnDisplay: `Read ${fileType} file: ${relativePathForDisplay}`,
|
||||
|
||||
Reference in New Issue
Block a user