compareVersions
Compare two versions of content in Adobe Experience Manager to identify differences and track changes.
Instructions
Compare two versions of content
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| version1 | Yes | ||
| version2 | Yes |
Implementation Reference
- Core handler function that fetches two versions from AEM via HTTP, compares their properties recursively, computes difference summary, and returns structured response with added/removed/modified changes.async compareVersions(path: string, version1: string, version2: string): Promise<CompareVersionsResponse> { return safeExecute<CompareVersionsResponse>(async () => { if (!isValidContentPath(path)) { throw createAEMError( AEM_ERROR_CODES.INVALID_PARAMETERS, `Invalid content path: ${path}`, { path } ); } if (!version1 || !version2 || version1 === version2) { throw createAEMError( AEM_ERROR_CODES.INVALID_PARAMETERS, 'Two different version names are required for comparison', { version1, version2 } ); } try { // Get both versions const version1Response = await this.httpClient.get(`${path}.version.${version1}.json`, { params: { ':depth': '2' } }); const version2Response = await this.httpClient.get(`${path}.version.${version2}.json`, { params: { ':depth': '2' } }); // Compare the versions const differences = this.compareVersionData( version1Response.data, version2Response.data ); const summary = { added: differences.filter(d => d.type === 'added').length, removed: differences.filter(d => d.type === 'removed').length, modified: differences.filter(d => d.type === 'modified').length }; this.logger.info(`Compared versions for path: ${path}`, { version1, version2, differencesCount: differences.length, summary }); return createSuccessResponse({ path, version1, version2, differences, summary }, 'compareVersions') as CompareVersionsResponse; } catch (error: any) { throw handleAEMHttpError(error, 'compareVersions'); } }, 'compareVersions'); }
- src/mcp-server.ts:551-563 (registration)MCP tool registration including name, description, and input schema definition.{ name: 'compareVersions', description: 'Compare two versions of content', inputSchema: { type: 'object', properties: { path: { type: 'string' }, version1: { type: 'string' }, version2: { type: 'string' } }, required: ['path', 'version1', 'version2'], }, },
- src/mcp-server.ts:807-811 (handler)Top-level MCP server handler that extracts parameters and delegates to AEMConnector.compareVersions.case 'compareVersions': { const { path, version1, version2 } = args as { path: string; version1: string; version2: string }; const result = await aemConnector.compareVersions(path, version1, version2); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; }
- Type definition for the output response structure including differences array and summary counts.export interface CompareVersionsResponse { success: boolean; operation: string; timestamp: string; data: { path: string; version1: string; version2: string; differences: Array<{ property: string; type: 'added' | 'removed' | 'modified'; oldValue?: unknown; newValue?: unknown; }>; summary: { added: number; removed: number; modified: number; }; }; }
- Recursive helper function that computes property-level differences between two version objects, supporting nested properties via prefix.private compareVersionData(data1: any, data2: any, prefix = ''): Array<{ property: string; type: 'added' | 'removed' | 'modified'; oldValue?: unknown; newValue?: unknown; }> { const differences: Array<{ property: string; type: 'added' | 'removed' | 'modified'; oldValue?: unknown; newValue?: unknown; }> = []; const keys1 = new Set(Object.keys(data1 || {})); const keys2 = new Set(Object.keys(data2 || {})); // Check for added and modified properties for (const key of keys2) { const fullKey = prefix ? `${prefix}.${key}` : key; if (!keys1.has(key)) { differences.push({ property: fullKey, type: 'added', newValue: data2[key] }); } else if (JSON.stringify(data1[key]) !== JSON.stringify(data2[key])) { differences.push({ property: fullKey, type: 'modified', oldValue: data1[key], newValue: data2[key] }); } } // Check for removed properties for (const key of keys1) { if (!keys2.has(key)) { const fullKey = prefix ? `${prefix}.${key}` : key; differences.push({ property: fullKey, type: 'removed', oldValue: data1[key] }); } } return differences; }