@@ -24,9 +24,14 @@ import { RESOURCE_TYPE_METADATA, ResourceType } from '../models/resource-types.j
2424import { ApimServiceContext , ResourceDescriptor } from '../models/types.js' ;
2525import { CompareConfig , OverrideConfig } from '../models/config.js' ;
2626import { LogLevel } from '../lib/logger.js' ;
27+ import { getRelativeResourceId } from '../lib/resource-uri.js' ;
2728import { loadLocalArtifacts } from './local-artifact-loader.js' ;
2829
30+ const resolveRelativeResourceId = getRelativeResourceId ;
31+
2932export interface CompareResult {
33+ sourceResourceId ?: string ;
34+ targetResourceId ?: string ;
3035 totalDifferences : number ;
3136 differences : ComparisonDifference [ ] ;
3237}
@@ -36,25 +41,22 @@ export interface ComparisonDifference {
3641 resourceType : string ;
3742 resourceName : string ;
3843 displayName ?: string ;
44+ relativeResourceId ?: string ;
3945 diffType : 'missing' | 'extra' | 'property-diff' ;
4046 diffs ?: ResourceDiff [ ] ;
4147}
42-
43- // Built-in resources to exclude from comparison
44- const EXCLUDE_GROUPS = new Set ( [ 'administrators' , 'developers' , 'guests' ] ) ;
45- const EXCLUDE_PRODUCTS = new Set ( [ 'starter' , 'unlimited' ] ) ;
46- const EXCLUDE_SUBSCRIPTIONS = new Set ( [ 'master' ] ) ;
47- const EXCLUDE_APIS = new Set ( [ 'echo-api' ] ) ;
48-
4948/**
5049 * Compares two APIM instances and returns differences
5150 */
5251export async function compareApimInstances (
5352 config : CompareConfig ,
5453) : Promise < CompareResult > {
55- logger . info (
56- `Comparing ${ config . source . serviceName } → ${ config . target . serviceName } ` ,
57- ) ;
54+ const shouldLogInfo = config . format !== 'json' ;
55+ if ( shouldLogInfo ) {
56+ logger . info (
57+ `Comparing ${ config . source . serviceName } → ${ config . target . serviceName } ` ,
58+ ) ;
59+ }
5860
5961 const normalizeContext : NormalizeContext = {
6062 sourceServiceName : config . source . serviceName ,
@@ -83,14 +85,14 @@ export async function compareApimInstances(
8385 { type : ResourceType . Gateway } ,
8486 { type : ResourceType . VersionSet } ,
8587 { type : ResourceType . Backend } ,
86- { type : ResourceType . Group , exclude : EXCLUDE_GROUPS } ,
88+ { type : ResourceType . Group } ,
8789 { type : ResourceType . PolicyFragment } ,
8890 { type : ResourceType . GlobalSchema } ,
8991 { type : ResourceType . Logger , skipLoggerCreds : true } ,
9092 { type : ResourceType . Diagnostic } ,
9193 { type : ResourceType . ServicePolicy } ,
92- { type : ResourceType . Product , exclude : EXCLUDE_PRODUCTS } ,
93- { type : ResourceType . Subscription , exclude : EXCLUDE_SUBSCRIPTIONS } ,
94+ { type : ResourceType . Product } ,
95+ { type : ResourceType . Subscription } ,
9496 // Note: Workspace types not yet defined in ResourceType enum
9597 // { type: ResourceType.Workspace },
9698 { type : ResourceType . Documentation } ,
@@ -121,7 +123,6 @@ export async function compareApimInstances(
121123 normalizeContext ,
122124 config . source ,
123125 config . target ,
124- EXCLUDE_APIS ,
125126 ) ;
126127 differences . push ( ...apiDiffs ) ;
127128
@@ -137,7 +138,7 @@ export async function compareApimInstances(
137138 if ( typeof id !== 'string' ) return '' ;
138139 return extractResourceName ( id ) ;
139140 } )
140- . filter ( ( name ) => name && ! EXCLUDE_APIS . has ( name ) ) ;
141+ . filter ( Boolean ) ;
141142
142143 // Compare API children
143144 for ( const apiName of apiNames ) {
@@ -225,7 +226,7 @@ export async function compareApimInstances(
225226 if ( typeof id !== 'string' ) return '' ;
226227 return extractResourceName ( id ) ;
227228 } )
228- . filter ( ( name ) => name && ! EXCLUDE_PRODUCTS . has ( name ) ) ;
229+ . filter ( Boolean ) ;
229230
230231 for ( const productName of productNames ) {
231232 const productChildTypes : readonly ResourceType [ ] = [
@@ -319,6 +320,8 @@ export async function compareApimInstances(
319320 ) . length ;
320321
321322 return {
323+ sourceResourceId : config . source . baseUrl ,
324+ targetResourceId : config . target . baseUrl ,
322325 totalDifferences,
323326 differences,
324327 } ;
@@ -639,12 +642,21 @@ function compareResourceLists(
639642 if ( ! targetMap . has ( name ) ) {
640643 const sourceResource = sourceMap . get ( name ) ! ;
641644 const displayName = getComparisonDisplayName ( sourceResource ) ;
645+ const sourceResourceId =
646+ typeof sourceResource . id === 'string' ? sourceResource . id : undefined ;
647+ const relativeResourceId = resolveRelativeResourceId (
648+ sourceResourceId ?? '' ,
649+ normalizeContext . sourceServiceName ,
650+ ) ;
642651
643652 differences . push ( {
644653 resourceType : typeLabel ,
645654 resourceName : name ,
646655 diffType : 'missing' ,
647656 ...( displayName === undefined ? { } : { displayName } ) ,
657+ ...( relativeResourceId === undefined
658+ ? { }
659+ : { relativeResourceId } ) ,
648660 instance : 'source' ,
649661 } ) ;
650662 }
@@ -655,12 +667,21 @@ function compareResourceLists(
655667 if ( ! sourceMap . has ( name ) ) {
656668 const targetResource = targetMap . get ( name ) ! ;
657669 const displayName = getComparisonDisplayName ( targetResource ) ;
670+ const targetResourceId =
671+ typeof targetResource . id === 'string' ? targetResource . id : undefined ;
672+ const relativeResourceId = resolveRelativeResourceId (
673+ targetResourceId ?? '' ,
674+ normalizeContext . targetServiceName ,
675+ ) ;
658676
659677 differences . push ( {
660678 resourceType : typeLabel ,
661679 resourceName : name ,
662680 diffType : 'extra' ,
663681 ...( displayName === undefined ? { } : { displayName } ) ,
682+ ...( relativeResourceId === undefined
683+ ? { }
684+ : { relativeResourceId } ) ,
664685 instance : 'target' ,
665686 } ) ;
666687 }
@@ -675,6 +696,13 @@ function compareResourceLists(
675696 const displayName =
676697 getComparisonDisplayName ( sourceResource ) ??
677698 getComparisonDisplayName ( targetResource ) ;
699+ const sourceResourceId =
700+ typeof sourceResource . id === 'string' ? sourceResource . id : undefined ;
701+ const targetResourceId =
702+ typeof targetResource . id === 'string' ? targetResource . id : undefined ;
703+ const relativeResourceId =
704+ resolveRelativeResourceId ( sourceResourceId ?? '' , normalizeContext . sourceServiceName ) ??
705+ resolveRelativeResourceId ( targetResourceId ?? '' , normalizeContext . targetServiceName ) ;
678706
679707 const sourceNorm = normalizeResource ( sourceResource , normalizeContext ) ;
680708 const targetNorm = normalizeResource ( targetResource , normalizeContext ) ;
@@ -722,6 +750,9 @@ function compareResourceLists(
722750 resourceName : name ,
723751 diffType : 'property-diff' ,
724752 ...( displayName === undefined ? { } : { displayName } ) ,
753+ ...( relativeResourceId === undefined
754+ ? { }
755+ : { relativeResourceId } ) ,
725756 diffs,
726757 } ) ;
727758 }
@@ -831,7 +862,10 @@ export async function compareLocalArtifacts(
831862 _format : 'text' | 'json' | 'table' = 'text' ,
832863 _logLevel ?: LogLevel ,
833864) : Promise < CompareResult > {
834- logger . info ( `Comparing local artifacts: ${ sourceDir } → ${ targetDir } ` ) ;
865+ const shouldLogInfo = _format !== 'json' ;
866+ if ( shouldLogInfo ) {
867+ logger . info ( `Comparing local artifacts: ${ sourceDir } → ${ targetDir } ` ) ;
868+ }
835869
836870 // Load artifacts from both directories
837871 const sourceArtifacts = await loadLocalArtifacts (
0 commit comments