1
- import { writeText , log , progress } from '@serverless/utils/log' ;
2
1
import Serverless from 'serverless/lib/Serverless' ;
3
2
import Provider from 'serverless/lib/plugins/aws/provider.js' ;
4
3
import { forEach , last , merge } from 'lodash' ;
@@ -68,6 +67,23 @@ import terminalLink from 'terminal-link';
68
67
69
68
const CONSOLE_BASE_URL = 'https://console.aws.amazon.com' ;
70
69
70
+ type Progress = {
71
+ remove : ( ) => void ;
72
+ } ;
73
+
74
+ type ServerlessPluginUtils = {
75
+ log : {
76
+ success : ( message : string ) => void ;
77
+ warning : ( message : string ) => void ;
78
+ error : ( message : string ) => void ;
79
+ info : ( message : string ) => void ;
80
+ } ;
81
+ progress : {
82
+ create : ( params : { name ?: string ; message : string } ) => Progress ;
83
+ } ;
84
+ writeText : ( message : string ) => void ;
85
+ } ;
86
+
71
87
class ServerlessAppsyncPlugin {
72
88
private provider : Provider ;
73
89
private gatheredData : {
@@ -90,6 +106,7 @@ class ServerlessAppsyncPlugin {
90
106
constructor (
91
107
public serverless : Serverless ,
92
108
private options : Record < string , string > ,
109
+ public utils : ServerlessPluginUtils ,
93
110
) {
94
111
this . gatheredData = {
95
112
apis : [ ] ,
@@ -98,7 +115,7 @@ class ServerlessAppsyncPlugin {
98
115
this . serverless = serverless ;
99
116
this . options = options ;
100
117
this . provider = this . serverless . getProvider ( 'aws' ) ;
101
-
118
+ this . utils = utils ;
102
119
// We are using a newer version of AJV than Serverless Framework
103
120
// and some customizations (eg: custom errors, $merge, filter irrelevant errors)
104
121
// For SF, just validate the type of input to allow us to use a custom
@@ -304,7 +321,7 @@ class ServerlessAppsyncPlugin {
304
321
'appsync:validate-schema:run' : ( ) => {
305
322
this . loadConfig ( ) ;
306
323
this . validateSchemas ( ) ;
307
- log . success ( 'AppSync schema valid' ) ;
324
+ this . utils . log . success ( 'AppSync schema valid' ) ;
308
325
} ,
309
326
'appsync:get-introspection:run' : ( ) => this . getIntrospection ( ) ,
310
327
'appsync:flush-cache:run' : ( ) => this . flushCache ( ) ,
@@ -327,7 +344,7 @@ class ServerlessAppsyncPlugin {
327
344
this . initDomainCommand ( ) ,
328
345
'appsync:domain:delete-record:run' : async ( ) => this . deleteRecord ( ) ,
329
346
finalize : ( ) => {
330
- writeText (
347
+ this . utils . writeText (
331
348
'\nLooking for a better AppSync development experience? Have you tried GraphBolt? https://graphbolt.dev' ,
332
349
) ;
333
350
} ,
@@ -431,20 +448,22 @@ class ServerlessAppsyncPlugin {
431
448
try {
432
449
const filePath = path . resolve ( this . options . output ) ;
433
450
fs . writeFileSync ( filePath , schema . toString ( ) ) ;
434
- log . success ( `Introspection schema exported to ${ filePath } ` ) ;
451
+ this . utils . log . success ( `Introspection schema exported to ${ filePath } ` ) ;
435
452
} catch ( error ) {
436
- log . error ( `Could not save to file: ${ ( error as Error ) . message } ` ) ;
453
+ this . utils . log . error (
454
+ `Could not save to file: ${ ( error as Error ) . message } ` ,
455
+ ) ;
437
456
}
438
457
return ;
439
458
}
440
459
441
- writeText ( schema . toString ( ) ) ;
460
+ this . utils . writeText ( schema . toString ( ) ) ;
442
461
}
443
462
444
463
async flushCache ( ) {
445
464
const apiId = await this . getApiId ( ) ;
446
465
await this . provider . request ( 'AppSync' , 'flushApiCache' , { apiId } ) ;
447
- log . success ( 'Cache flushed successfully' ) ;
466
+ this . utils . log . success ( 'Cache flushed successfully' ) ;
448
467
}
449
468
450
469
async openConsole ( ) {
@@ -486,7 +505,7 @@ class ServerlessAppsyncPlugin {
486
505
487
506
events ?. forEach ( ( event ) => {
488
507
const { timestamp, message } = event ;
489
- writeText (
508
+ this . utils . writeText (
490
509
`${ chalk . gray (
491
510
DateTime . fromMillis ( timestamp || 0 ) . toISO ( ) ,
492
511
) } \t${ message } `,
@@ -512,7 +531,7 @@ class ServerlessAppsyncPlugin {
512
531
const domain = this . getDomain ( ) ;
513
532
514
533
if ( domain . useCloudFormation !== false ) {
515
- log . warning (
534
+ this . utils . log . warning (
516
535
'You are using the CloudFormation integration for domain configuration.\n' +
517
536
'To avoid CloudFormation drifts, you should not use it in combination with this command.\n' +
518
537
'Set the `domain.useCloudFormation` attribute to false to use the CLI integration.\n' +
@@ -568,7 +587,7 @@ class ServerlessAppsyncPlugin {
568
587
( { DomainName } ) => DomainName === match ,
569
588
) ;
570
589
if ( cert ) {
571
- log . info (
590
+ this . utils . log . info (
572
591
`Found matching certificate for ${ match } : ${ cert . CertificateArn } ` ,
573
592
) ;
574
593
return cert . CertificateArn ;
@@ -595,13 +614,13 @@ class ServerlessAppsyncPlugin {
595
614
domainName : domain . name ,
596
615
certificateArn,
597
616
} ) ;
598
- log . success ( `Domain '${ domain . name } ' created successfully` ) ;
617
+ this . utils . log . success ( `Domain '${ domain . name } ' created successfully` ) ;
599
618
} catch ( error ) {
600
619
if (
601
620
error instanceof this . serverless . classes . Error &&
602
621
this . options . quiet
603
622
) {
604
- log . error ( error . message ) ;
623
+ this . utils . log . error ( error . message ) ;
605
624
} else {
606
625
throw error ;
607
626
}
@@ -611,7 +630,7 @@ class ServerlessAppsyncPlugin {
611
630
async deleteDomain ( ) {
612
631
try {
613
632
const domain = this . getDomain ( ) ;
614
- log . warning ( `The domain '${ domain . name } will be deleted.` ) ;
633
+ this . utils . log . warning ( `The domain '${ domain . name } will be deleted.` ) ;
615
634
if ( ! this . options . yes && ! ( await confirmAction ( ) ) ) {
616
635
return ;
617
636
}
@@ -621,13 +640,13 @@ class ServerlessAppsyncPlugin {
621
640
> ( 'AppSync' , 'deleteDomainName' , {
622
641
domainName : domain . name ,
623
642
} ) ;
624
- log . success ( `Domain '${ domain . name } ' deleted successfully` ) ;
643
+ this . utils . log . success ( `Domain '${ domain . name } ' deleted successfully` ) ;
625
644
} catch ( error ) {
626
645
if (
627
646
error instanceof this . serverless . classes . Error &&
628
647
this . options . quiet
629
648
) {
630
- log . error ( error . message ) ;
649
+ this . utils . log . error ( error . message ) ;
631
650
} else {
632
651
throw error ;
633
652
}
@@ -663,8 +682,7 @@ class ServerlessAppsyncPlugin {
663
682
message : string ;
664
683
desiredStatus : 'SUCCESS' | 'NOT_FOUND' ;
665
684
} ) {
666
- const progressInstance = progress . create ( { message } ) ;
667
-
685
+ const progressInstance = this . utils . progress . create ( { message } ) ;
668
686
let status : string ;
669
687
do {
670
688
status =
@@ -683,14 +701,14 @@ class ServerlessAppsyncPlugin {
683
701
const assoc = await this . getApiAssocStatus ( domain . name ) ;
684
702
685
703
if ( assoc ?. associationStatus !== 'NOT_FOUND' && assoc ?. apiId !== apiId ) {
686
- log . warning (
704
+ this . utils . log . warning (
687
705
`The domain ${ domain . name } is currently associated to another API (${ assoc ?. apiId } )` ,
688
706
) ;
689
707
if ( ! this . options . yes && ! ( await confirmAction ( ) ) ) {
690
708
return ;
691
709
}
692
710
} else if ( assoc ?. apiId === apiId ) {
693
- log . success ( 'The domain is already associated to this API' ) ;
711
+ this . utils . log . success ( 'The domain is already associated to this API' ) ;
694
712
return ;
695
713
}
696
714
@@ -709,7 +727,9 @@ class ServerlessAppsyncPlugin {
709
727
message,
710
728
desiredStatus : 'SUCCESS' ,
711
729
} ) ;
712
- log . success ( `API successfully associated to domain '${ domain . name } '` ) ;
730
+ this . utils . log . success (
731
+ `API successfully associated to domain '${ domain . name } '` ,
732
+ ) ;
713
733
}
714
734
715
735
async disassocDomain ( ) {
@@ -718,7 +738,7 @@ class ServerlessAppsyncPlugin {
718
738
const assoc = await this . getApiAssocStatus ( domain . name ) ;
719
739
720
740
if ( assoc ?. associationStatus === 'NOT_FOUND' ) {
721
- log . warning (
741
+ this . utils . log . warning (
722
742
`The domain ${ domain . name } is currently not associated to any API` ,
723
743
) ;
724
744
return ;
@@ -730,7 +750,7 @@ class ServerlessAppsyncPlugin {
730
750
`Try running this command from that API's stack or stage, or use the --force / -f flag` ,
731
751
) ;
732
752
}
733
- log . warning (
753
+ this . utils . log . warning (
734
754
`The domain ${ domain . name } will be disassociated from API '${ apiId } '` ,
735
755
) ;
736
756
@@ -752,7 +772,9 @@ class ServerlessAppsyncPlugin {
752
772
desiredStatus : 'NOT_FOUND' ,
753
773
} ) ;
754
774
755
- log . success ( `API successfully disassociated from domain '${ domain . name } '` ) ;
775
+ this . utils . log . success (
776
+ `API successfully disassociated from domain '${ domain . name } '` ,
777
+ ) ;
756
778
}
757
779
758
780
async getHostedZoneId ( ) {
@@ -798,7 +820,7 @@ class ServerlessAppsyncPlugin {
798
820
}
799
821
800
822
async createRecord ( ) {
801
- const progressInstance = progress . create ( {
823
+ const progressInstance = this . utils . progress . create ( {
802
824
message : 'Creating route53 record' ,
803
825
} ) ;
804
826
@@ -813,10 +835,10 @@ class ServerlessAppsyncPlugin {
813
835
if ( changeId ) {
814
836
await this . checkRoute53RecordStatus ( changeId ) ;
815
837
progressInstance . remove ( ) ;
816
- log . info (
838
+ this . utils . log . info (
817
839
`Alias record for '${ domain . name } ' was created in Hosted Zone '${ hostedZoneId } '` ,
818
840
) ;
819
- log . success ( 'Route53 record created successfuly' ) ;
841
+ this . utils . log . success ( 'Route53 record created successfuly' ) ;
820
842
}
821
843
}
822
844
@@ -825,14 +847,14 @@ class ServerlessAppsyncPlugin {
825
847
const appsyncDomainName = await this . getAppSyncDomainName ( ) ;
826
848
const hostedZoneId = await this . getHostedZoneId ( ) ;
827
849
828
- log . warning (
850
+ this . utils . log . warning (
829
851
`Alias record for '${ domain . name } ' will be deleted from Hosted Zone '${ hostedZoneId } '` ,
830
852
) ;
831
853
if ( ! this . options . yes && ! ( await confirmAction ( ) ) ) {
832
854
return ;
833
855
}
834
856
835
- const progressInstance = progress . create ( {
857
+ const progressInstance = this . utils . progress . create ( {
836
858
message : 'Deleting route53 record' ,
837
859
} ) ;
838
860
@@ -844,10 +866,10 @@ class ServerlessAppsyncPlugin {
844
866
if ( changeId ) {
845
867
await this . checkRoute53RecordStatus ( changeId ) ;
846
868
progressInstance . remove ( ) ;
847
- log . info (
869
+ this . utils . log . info (
848
870
`Alias record for '${ domain . name } ' was deleted from Hosted Zone '${ hostedZoneId } '` ,
849
871
) ;
850
- log . success ( 'Route53 record deleted successfuly' ) ;
872
+ this . utils . log . success ( 'Route53 record deleted successfuly' ) ;
851
873
}
852
874
}
853
875
@@ -905,7 +927,7 @@ class ServerlessAppsyncPlugin {
905
927
error instanceof this . serverless . classes . Error &&
906
928
this . options . quiet
907
929
) {
908
- log . error ( error . message ) ;
930
+ this . utils . log . error ( error . message ) ;
909
931
} else {
910
932
throw error ;
911
933
}
@@ -949,7 +971,7 @@ class ServerlessAppsyncPlugin {
949
971
}
950
972
951
973
loadConfig ( ) {
952
- log . info ( 'Loading AppSync config' ) ;
974
+ this . utils . log . info ( 'Loading AppSync config' ) ;
953
975
954
976
const { appSync } = this . serverless . configurationInput ;
955
977
@@ -969,15 +991,15 @@ class ServerlessAppsyncPlugin {
969
991
970
992
validateSchemas ( ) {
971
993
try {
972
- log . info ( 'Validating AppSync schema' ) ;
994
+ this . utils . log . info ( 'Validating AppSync schema' ) ;
973
995
if ( ! this . api ) {
974
996
throw new this . serverless . classes . Error (
975
997
'Could not load the API. This should not happen.' ,
976
998
) ;
977
999
}
978
1000
this . api . compileSchema ( ) ;
979
1001
} catch ( error ) {
980
- log . info ( 'Error' ) ;
1002
+ this . utils . log . info ( 'Error' ) ;
981
1003
if ( error instanceof GraphQLError ) {
982
1004
this . handleError ( error . message ) ;
983
1005
}
@@ -1057,7 +1079,7 @@ class ServerlessAppsyncPlugin {
1057
1079
if ( configValidationMode === 'error' ) {
1058
1080
throw new this . serverless . classes . Error ( message ) ;
1059
1081
} else if ( configValidationMode === 'warn' ) {
1060
- log . warning ( message ) ;
1082
+ this . utils . log . warning ( message ) ;
1061
1083
}
1062
1084
}
1063
1085
}
0 commit comments