@@ -16,7 +16,7 @@ import { SchemaChecksFilter } from '../../../__generated__/types';
16
16
import * as GraphQLSchema from '../../../__generated__/types' ;
17
17
import {
18
18
DateRange ,
19
- NativeFederationCompatibilityStatus ,
19
+ NativeFederationCompatibilityStatusType ,
20
20
Organization ,
21
21
Project ,
22
22
ProjectType ,
@@ -1123,64 +1123,69 @@ export class SchemaManager {
1123
1123
return true ;
1124
1124
}
1125
1125
1126
- async getNativeFederationCompatibilityStatus ( project : Project ) {
1126
+ async getNativeFederationCompatibilityStatus ( project : Project ) : Promise < {
1127
+ status : NativeFederationCompatibilityStatusType ;
1128
+ results : Array < null | {
1129
+ schemaVersion : SchemaVersion ;
1130
+ target : Target ;
1131
+ nativeCompositionResult : {
1132
+ supergraphSdl : string | null ;
1133
+ errors : Array < { message : string } > | null ;
1134
+ } ;
1135
+ currentSupergraphSdl : string ;
1136
+ } > ;
1137
+ } > {
1127
1138
this . logger . debug (
1128
1139
'Get native Federation compatibility status (organization=%s, project=%s)' ,
1129
1140
project . orgId ,
1130
1141
project . id ,
1131
1142
) ;
1132
1143
1133
1144
if ( project . type !== ProjectType . FEDERATION ) {
1134
- return NativeFederationCompatibilityStatus . NOT_APPLICABLE ;
1145
+ return {
1146
+ status : NativeFederationCompatibilityStatusType . NOT_APPLICABLE ,
1147
+ results : [ ] ,
1148
+ } ;
1135
1149
}
1136
1150
1137
1151
const targets = await this . targetManager . getTargets ( {
1138
1152
organizationId : project . orgId ,
1139
1153
projectId : project . id ,
1140
1154
} ) ;
1141
1155
1142
- const possibleVersions = await Promise . all (
1143
- targets . map ( target => this . getMaybeLatestValidVersion ( target ) ) ,
1144
- ) ;
1145
-
1146
- const versions = possibleVersions . filter ( ( v ) : v is SchemaVersion => ! ! v ) ;
1147
-
1148
- this . logger . debug ( 'Found %s targets and %s versions' , targets . length , versions . length ) ;
1156
+ const results = await Promise . all (
1157
+ targets . map ( async target => {
1158
+ const schemaVersion = await this . getMaybeLatestValidVersion ( target ) ;
1149
1159
1150
- // If there are no composable versions available, we can't determine the compatibility status.
1151
- if (
1152
- versions . length === 0 ||
1153
- ! versions . every (
1154
- version => version && version . isComposable && typeof version . supergraphSDL === 'string' ,
1155
- )
1156
- ) {
1157
- this . logger . debug ( 'No composable versions available (status: unknown)' ) ;
1158
- return NativeFederationCompatibilityStatus . UNKNOWN ;
1159
- }
1160
+ if ( schemaVersion === null ) {
1161
+ return null ;
1162
+ }
1160
1163
1161
- const schemasPerVersion = await Promise . all (
1162
- versions . map ( async version =>
1163
- this . getSchemasOfVersion ( {
1164
- organizationId : version . organizationId ,
1165
- projectId : version . projectId ,
1166
- targetId : version . targetId ,
1167
- versionId : version . id ,
1168
- } ) ,
1169
- ) ,
1170
- ) ;
1164
+ const currentSupergraphSdl = print (
1165
+ removeDescriptions (
1166
+ sortSDL (
1167
+ parseGraphQLSource (
1168
+ schemaVersion . supergraphSDL ! ,
1169
+ 'parsing native supergraph in getNativeFederationCompatibilityStatus' ,
1170
+ ) ,
1171
+ ) ,
1172
+ ) ,
1173
+ ) ;
1171
1174
1172
- this . logger . debug ( 'Checking compatibility of %s versions' , versions . length ) ;
1175
+ const schemas = await this . getSchemasOfVersion ( {
1176
+ organizationId : target . orgId ,
1177
+ projectId : target . projectId ,
1178
+ targetId : target . id ,
1179
+ versionId : schemaVersion . id ,
1180
+ } ) ;
1173
1181
1174
- const compatibilityResults = await Promise . all (
1175
- versions . map ( async ( version , i ) => {
1176
- if ( schemasPerVersion [ i ] . length === 0 ) {
1177
- this . logger . debug ( 'No schemas (version=%s)' , version . id ) ;
1178
- return NativeFederationCompatibilityStatus . UNKNOWN ;
1182
+ if ( schemas . length === 0 ) {
1183
+ return null ;
1179
1184
}
1180
1185
1181
1186
const compositionResult = await this . compositionOrchestrator . composeAndValidate (
1182
1187
'federation' ,
1183
- ensureCompositeSchemas ( schemasPerVersion [ i ] ) . map ( s =>
1188
+ ensureCompositeSchemas ( schemas ) . map ( s =>
1184
1189
this . schemaHelper . createSchemaObject ( {
1185
1190
sdl : s . sdl ,
1186
1191
service_name : s . service_name ,
@@ -1196,53 +1201,52 @@ export class SchemaManager {
1196
1201
} ,
1197
1202
) ;
1198
1203
1199
- if ( compositionResult . supergraph ) {
1200
- const sortedExistingSupergraph = print (
1201
- removeDescriptions (
1202
- sortSDL (
1203
- parseGraphQLSource (
1204
- compositionResult . supergraph ,
1205
- 'parsing existing supergraph in getNativeFederationCompatibilityStatus' ,
1206
- ) ,
1207
- ) ,
1208
- ) ,
1209
- ) ;
1210
- const sortedNativeSupergraph = print (
1211
- removeDescriptions (
1212
- sortSDL (
1213
- parseGraphQLSource (
1214
- version . supergraphSDL ! ,
1215
- 'parsing native supergraph in getNativeFederationCompatibilityStatus' ,
1204
+ const supergraphSdl = compositionResult . supergraph
1205
+ ? print (
1206
+ removeDescriptions (
1207
+ sortSDL (
1208
+ parseGraphQLSource (
1209
+ compositionResult . supergraph ,
1210
+ 'parsing native supergraph in getNativeFederationCompatibilityStatus' ,
1211
+ ) ,
1216
1212
) ,
1217
1213
) ,
1218
- ) ,
1219
- ) ;
1220
-
1221
- if ( sortedNativeSupergraph === sortedExistingSupergraph ) {
1222
- return NativeFederationCompatibilityStatus . COMPATIBLE ;
1223
- }
1224
-
1225
- this . logger . debug ( 'Produced different supergraph (version=%s)' , version . id ) ;
1226
- } else {
1227
- this . logger . debug ( 'Failed to produce supergraph (version=%s)' , version . id ) ;
1228
- }
1214
+ )
1215
+ : null ;
1229
1216
1230
- return NativeFederationCompatibilityStatus . INCOMPATIBLE ;
1217
+ return {
1218
+ target,
1219
+ schemaVersion,
1220
+ currentSupergraphSdl,
1221
+ nativeCompositionResult : {
1222
+ supergraphSdl,
1223
+ errors : compositionResult . errors ,
1224
+ } ,
1225
+ } ;
1231
1226
} ) ,
1232
1227
) ;
1233
1228
1234
- if ( compatibilityResults . includes ( NativeFederationCompatibilityStatus . UNKNOWN ) ) {
1235
- this . logger . debug ( 'One of the versions seems empty (status: unknown)' ) ;
1236
- return NativeFederationCompatibilityStatus . UNKNOWN ;
1237
- }
1229
+ let status = NativeFederationCompatibilityStatusType . INCOMPATIBLE ;
1238
1230
1239
- if ( compatibilityResults . every ( r => r === NativeFederationCompatibilityStatus . COMPATIBLE ) ) {
1231
+ if ( results . every ( result => result === null ) ) {
1232
+ this . logger . debug ( 'No composable versions available (status: unknown)' ) ;
1233
+ status = NativeFederationCompatibilityStatusType . UNKNOWN ;
1234
+ } else if (
1235
+ results . every (
1236
+ result =>
1237
+ result === null ||
1238
+ ( result . nativeCompositionResult &&
1239
+ result . currentSupergraphSdl === result . nativeCompositionResult . supergraphSdl ) ,
1240
+ )
1241
+ ) {
1240
1242
this . logger . debug ( 'All versions are compatible (status: compatible)' ) ;
1241
- return NativeFederationCompatibilityStatus . COMPATIBLE ;
1243
+ status = NativeFederationCompatibilityStatusType . COMPATIBLE ;
1242
1244
}
1243
1245
1244
- this . logger . debug ( 'Some versions are incompatible (status: incompatible)' ) ;
1245
- return NativeFederationCompatibilityStatus . INCOMPATIBLE ;
1246
+ return {
1247
+ status,
1248
+ results,
1249
+ } ;
1246
1250
}
1247
1251
1248
1252
async getGitHubMetadata ( schemaVersion : SchemaVersion ) : Promise < null | {
0 commit comments