fix: overwrite the deprecated googledrive extension config (#7974)

This commit is contained in:
Lifei Zhou 2026-03-18 21:38:42 +11:00 committed by GitHub
parent 8d714a04c8
commit 493566dff2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 222 additions and 10 deletions

View file

@ -0,0 +1,189 @@
import { describe, it, expect, vi } from 'vitest';
import { isDeprecatedGoogleDriveExtension, syncBundledExtensions } from './bundled-extensions';
import type { FixedExtensionEntry } from '../../ConfigContext';
vi.mock('./bundled-extensions.json', () => ({
default: [
{
id: 'developer',
name: 'developer',
display_name: 'Developer',
description: 'General development tools.',
enabled: true,
type: 'builtin',
timeout: 300,
},
{
id: 'googledrive',
name: 'googledrive',
display_name: 'Google Drive',
description: 'Google Drive integration.',
enabled: true,
type: 'stdio',
cmd: 'googledrive-mcp',
args: [],
env_keys: [],
timeout: 300,
},
],
}));
describe('isDeprecatedGoogleDriveExtension', () => {
it('returns true for builtin googledrive', () => {
const ext = {
name: 'Google Drive',
type: 'builtin',
description: 'Google Drive extension',
enabled: true,
bundled: true,
} as FixedExtensionEntry;
expect(isDeprecatedGoogleDriveExtension(ext)).toBe(true);
});
it('returns true for builtin google_drive', () => {
const ext = {
name: 'google_drive',
type: 'builtin',
description: 'Google Drive extension',
enabled: true,
bundled: true,
} as FixedExtensionEntry;
expect(isDeprecatedGoogleDriveExtension(ext)).toBe(true);
});
it('returns true for stdio googledrive with GOOGLE_DRIVE_CREDENTIALS_PATH', () => {
const ext = {
name: 'Google Drive',
type: 'stdio',
description: 'Google Drive extension',
cmd: 'some-cmd',
args: [],
env_keys: ['GOOGLE_DRIVE_CREDENTIALS_PATH'],
enabled: true,
bundled: true,
} as FixedExtensionEntry;
expect(isDeprecatedGoogleDriveExtension(ext)).toBe(true);
});
it('returns true for stdio googledrive with GOOGLE_DRIVE_OAUTH_PATH', () => {
const ext = {
name: 'Google Drive',
type: 'stdio',
description: 'Google Drive extension',
cmd: 'some-cmd',
args: [],
env_keys: ['GOOGLE_DRIVE_OAUTH_PATH'],
enabled: true,
bundled: true,
} as FixedExtensionEntry;
expect(isDeprecatedGoogleDriveExtension(ext)).toBe(true);
});
it('returns false for stdio googledrive without deprecated env keys', () => {
const ext = {
name: 'Google Drive',
type: 'stdio',
description: 'Google Drive extension',
cmd: 'some-cmd',
args: [],
env_keys: [],
enabled: true,
bundled: true,
} as FixedExtensionEntry;
expect(isDeprecatedGoogleDriveExtension(ext)).toBe(false);
});
it('returns false for non-googledrive extensions', () => {
const ext = {
name: 'developer',
type: 'builtin',
description: 'Developer tools',
enabled: true,
bundled: true,
} as FixedExtensionEntry;
expect(isDeprecatedGoogleDriveExtension(ext)).toBe(false);
});
it('returns false for non-googledrive stdio with those env keys', () => {
const ext = {
name: 'some-other-ext',
type: 'stdio',
description: 'Other extension',
cmd: 'some-cmd',
args: [],
env_keys: ['GOOGLE_DRIVE_CREDENTIALS_PATH'],
enabled: true,
bundled: true,
} as FixedExtensionEntry;
expect(isDeprecatedGoogleDriveExtension(ext)).toBe(false);
});
});
describe('syncBundledExtensions', () => {
it('overwrites deprecated builtin googledrive extension', async () => {
const addExtensionFn = vi.fn().mockResolvedValue(undefined);
const existingExtensions = [
{
name: 'googledrive',
type: 'builtin',
description: 'Google Drive',
enabled: true,
bundled: true,
},
] as FixedExtensionEntry[];
await syncBundledExtensions(existingExtensions, addExtensionFn);
expect(addExtensionFn).toHaveBeenCalledWith(
'googledrive',
expect.objectContaining({ type: 'stdio', bundled: true }),
true
);
});
it('overwrites stdio googledrive with deprecated env keys', async () => {
const addExtensionFn = vi.fn().mockResolvedValue(undefined);
const existingExtensions = [
{
name: 'googledrive',
type: 'stdio',
description: 'Google Drive',
cmd: 'some-cmd',
args: [],
env_keys: ['GOOGLE_DRIVE_CREDENTIALS_PATH'],
enabled: true,
bundled: true,
},
] as FixedExtensionEntry[];
await syncBundledExtensions(existingExtensions, addExtensionFn);
expect(addExtensionFn).toHaveBeenCalledWith(
'googledrive',
expect.objectContaining({ type: 'stdio', bundled: true, env_keys: [] }),
true
);
});
it('skips already bundled non-deprecated extensions', async () => {
const addExtensionFn = vi.fn().mockResolvedValue(undefined);
const existingExtensions = [
{
name: 'developer',
type: 'builtin',
description: 'Developer tools',
enabled: true,
bundled: true,
timeout: 300,
},
] as FixedExtensionEntry[];
await syncBundledExtensions(existingExtensions, addExtensionFn);
expect(addExtensionFn).not.toHaveBeenCalledWith(
'developer',
expect.anything(),
expect.anything()
);
});
});

View file

@ -20,7 +20,29 @@ type BundledExtension = {
allow_configure?: boolean;
};
const DEPRECATED_BUILTINS = ['googledrive', 'google_drive'];
const DEPRECATED_GOOGLE_DRIVE_IDS = ['googledrive', 'google_drive'];
const DEPRECATED_GOOGLE_DRIVE_ENV_KEYS = [
'GOOGLE_DRIVE_CREDENTIALS_PATH',
'GOOGLE_DRIVE_OAUTH_PATH',
];
export function isDeprecatedGoogleDriveExtension(ext: FixedExtensionEntry): boolean {
if (!DEPRECATED_GOOGLE_DRIVE_IDS.includes(nameToKey(ext.name))) {
return false;
}
if (ext.type === 'builtin') {
return true;
}
if (
ext.type === 'stdio' &&
'env_keys' in ext &&
Array.isArray(ext.env_keys) &&
ext.env_keys.some((key: string) => DEPRECATED_GOOGLE_DRIVE_ENV_KEYS.includes(key))
) {
return true;
}
return false;
}
/**
* Synchronizes built-in extensions with the config system.
@ -39,20 +61,21 @@ export async function syncBundledExtensions(
// Cast the imported JSON data to the expected type
const bundledExtensions = bundledExtensionsData as BundledExtension[];
for (let i = existingExtensions.length - 1; i >= 0; i--) {
const ext = existingExtensions[i];
if (ext.type == 'builtin' && DEPRECATED_BUILTINS.includes(ext.name)) {
existingExtensions.splice(i, 1);
}
}
// Process each bundled extension
for (const bundledExt of bundledExtensions) {
// Find if this extension already exists
const existingExt = existingExtensions.find((ext) => nameToKey(ext.name) === bundledExt.id);
// Skip if extension exists and is already marked as bundled
if (existingExt && 'bundled' in existingExt && existingExt.bundled) continue;
// Skip if extension exists and is already marked as bundled, except when
// we must migrate deprecated extensions.
if (
existingExt &&
'bundled' in existingExt &&
existingExt.bundled &&
!isDeprecatedGoogleDriveExtension(existingExt)
) {
continue;
}
// Create the config for this extension
let extConfig: ExtensionConfig;