@@ -147,7 +147,7 @@ private static async Task<int> WatchComposeAsync(
147
147
cancellationToken ) ;
148
148
149
149
// set up file watcher for source schema files
150
- fileWatcher . Filter = "*.graphqls " ;
150
+ fileWatcher . Filter = "*.graphql* " ;
151
151
fileWatcher . IncludeSubdirectories = true ;
152
152
fileWatcher . NotifyFilter = NotifyFilters . CreationTime | NotifyFilters . LastWrite | NotifyFilters . FileName ;
153
153
@@ -208,10 +208,20 @@ private static async Task<int> WatchComposeAsync(
208
208
209
209
void OnSourceSchemaFileChanged ( FileSystemEventArgs e )
210
210
{
211
+ // skip if this is the gateway file as this is handled somewhere else.
212
+ if ( compositeSchemaFile is not null )
213
+ {
214
+ var compositeSchemaPath = Path . Combine ( workingDirectory , compositeSchemaFile ) ;
215
+ if ( string . Equals ( e . FullPath , compositeSchemaPath , StringComparison . OrdinalIgnoreCase ) )
216
+ {
217
+ return ;
218
+ }
219
+ }
220
+
211
221
// only process files that are in our source schema paths or match the pattern
212
222
var isRelevantFile = sourceSchemaFilePaths . Any ( path =>
213
223
string . Equals ( path , e . FullPath , StringComparison . OrdinalIgnoreCase ) )
214
- || e . Name ? . EndsWith ( ".graphqls" , StringComparison . OrdinalIgnoreCase ) == true ;
224
+ || IsGraphQLSchemaFile ( e . Name ) ;
215
225
216
226
if ( ! isRelevantFile )
217
227
{
@@ -222,7 +232,17 @@ void OnSourceSchemaFileChanged(FileSystemEventArgs e)
222
232
}
223
233
224
234
void OnGatewayFileDeleted ( FileSystemEventArgs e )
225
- => TriggerComposition ( $ "Gateway file deleted: { e . Name } ") ;
235
+ {
236
+ // we wait 500ms to see if the gateway file is recreated.
237
+ Thread . Sleep ( 500 ) ;
238
+
239
+ // if it's still missing we trigger a new composition.
240
+ var compositeSchemaPath = Path . Combine ( workingDirectory , compositeSchemaFile ) ;
241
+ if ( ! File . Exists ( compositeSchemaPath ) )
242
+ {
243
+ TriggerComposition ( $ "Gateway file deleted: { e . Name } ") ;
244
+ }
245
+ }
226
246
227
247
void TriggerComposition ( string reason )
228
248
=> compositionChannel . Writer . TryWrite ( reason ) ;
@@ -255,29 +275,44 @@ private static async Task ProcessCompositionRequestsAsync(
255
275
lastComposition = DateTime . UtcNow ;
256
276
257
277
console . Out . WriteLine ( $ "\n 🔄 { reason } ") ;
258
- console . Out . WriteLine ( "Recomposing schema..." ) ;
259
278
260
279
// Add a small delay to ensure file operations are complete
261
- await Task . Delay ( 100 , cancellationToken ) ;
262
-
263
- await ComposeAsync ( console , workingDirectory , sourceSchemaFiles , compositeSchemaFile , cancellationToken ) ;
264
-
265
- console . Out . WriteLine ( "✅ Recomposition complete" ) ;
266
- console . Out . WriteLine ( "👀 Watching for changes..." ) ;
280
+ await Task . Delay ( 200 , cancellationToken ) ;
281
+
282
+ await ComposeAsync (
283
+ console ,
284
+ workingDirectory ,
285
+ sourceSchemaFiles ,
286
+ compositeSchemaFile ,
287
+ cancellationToken ) ;
267
288
}
268
289
catch ( Exception ex ) when ( ex is not OperationCanceledException )
269
290
{
270
291
console . Error . WriteLine ( $ "❌ Error during recomposition: { ex . Message } ") ;
292
+ }
293
+ finally
294
+ {
271
295
console . Out . WriteLine ( "👀 Watching for changes..." ) ;
272
296
}
273
297
}
274
298
}
275
299
300
+ private static bool IsGraphQLSchemaFile ( string ? fileName )
301
+ {
302
+ if ( fileName is null )
303
+ {
304
+ return false ;
305
+ }
306
+
307
+ return fileName . EndsWith ( ".graphql" , StringComparison . OrdinalIgnoreCase )
308
+ || fileName . EndsWith ( ".graphqls" , StringComparison . OrdinalIgnoreCase ) ;
309
+ }
310
+
276
311
private static ImmutableSortedSet < string > GetSourceSchemaFilePaths (
277
312
List < string > sourceSchemaFiles ,
278
313
string workingDirectory )
279
314
{
280
- // If no source schema files were specified, scan the working directory for *.graphqls files
315
+ // if no source schema files were specified, scan the working directory for *.graphql* files
281
316
if ( sourceSchemaFiles . Count > 0 )
282
317
{
283
318
return sourceSchemaFiles
@@ -286,7 +321,8 @@ private static ImmutableSortedSet<string> GetSourceSchemaFilePaths(
286
321
}
287
322
288
323
var foundFiles = new DirectoryInfo ( workingDirectory )
289
- . GetFiles ( "*.graphqls" , SearchOption . AllDirectories )
324
+ . GetFiles ( "*.graphql*" , SearchOption . AllDirectories )
325
+ . Where ( f => IsGraphQLSchemaFile ( f . Name ) )
290
326
. Select ( i => i . FullName )
291
327
. ToImmutableSortedSet ( ) ;
292
328
@@ -317,13 +353,11 @@ private static async Task<int> ComposeAsync(
317
353
catch ( Exception e )
318
354
{
319
355
console . Error . WriteLine ( e . Message ) ;
320
-
321
356
return 1 ;
322
357
}
323
358
324
359
var compositionLog = new CompositionLog ( ) ;
325
360
var schemaComposer = new SchemaComposer ( sourceSchemas , compositionLog ) ;
326
-
327
361
var result = schemaComposer . Compose ( ) ;
328
362
329
363
WriteCompositionLog (
@@ -416,13 +450,13 @@ private static async Task<IEnumerable<string>> ReadSourceSchemasAsync(
416
450
{
417
451
ImmutableSortedSet < string > sourceSchemaFilePaths ;
418
452
419
- // If no source schema files were specified, scan the working directory for *.graphqls
420
- // files.
453
+ // If no source schema files were specified, scan the working directory for *.graphql* files
421
454
if ( sourceSchemaFiles . Count == 0 )
422
455
{
423
456
sourceSchemaFilePaths =
424
457
new DirectoryInfo ( workingDirectory )
425
- . GetFiles ( "*.graphqls" )
458
+ . GetFiles ( "*.graphql*" )
459
+ . Where ( f => IsGraphQLSchemaFile ( f . Name ) )
426
460
. Select ( i => i . FullName )
427
461
. ToImmutableSortedSet ( ) ;
428
462
0 commit comments