1
+ import colors = require( 'colors/safe' ) ;
2
+ import table = require( 'table' ) ;
3
+ import yargs = require( 'yargs' ) ;
4
+ import { print } from '../../lib/logging' ;
5
+ import { DEFAULTS , loadProjectConfig , saveProjectConfig } from '../settings' ;
6
+
7
+ export const command = 'context' ;
8
+ export const describe = 'Manage cached context values' ;
9
+ export const builder = {
10
+ reset : {
11
+ alias : 'e' ,
12
+ desc : 'The context key (or its index) to reset' ,
13
+ type : 'string' ,
14
+ requiresArg : 'KEY'
15
+ } ,
16
+ clear : {
17
+ desc : 'Clear all context' ,
18
+ type : 'boolean' ,
19
+ } ,
20
+ } ;
21
+
22
+ export async function handler ( args : yargs . Arguments ) : Promise < number > {
23
+ const settings = await loadProjectConfig ( ) ;
24
+ const context = settings . get ( [ 'context' ] ) || { } ;
25
+
26
+ if ( args . clear ) {
27
+ settings . set ( [ 'context' ] , { } ) ;
28
+ await saveProjectConfig ( settings ) ;
29
+ print ( 'All context values cleared.' ) ;
30
+ } else if ( args . reset ) {
31
+ invalidateContext ( context , args . reset ) ;
32
+ settings . set ( [ 'context' ] , context ) ;
33
+ await saveProjectConfig ( settings ) ;
34
+ } else {
35
+ // List -- support '--json' flag
36
+ if ( args . json ) {
37
+ process . stdout . write ( JSON . stringify ( context , undefined , 2 ) ) ;
38
+ } else {
39
+ listContext ( context ) ;
40
+ }
41
+ }
42
+
43
+ return 0 ;
44
+ }
45
+
46
+ function listContext ( context : any ) {
47
+ const keys = contextKeys ( context ) ;
48
+
49
+ // Print config by default
50
+ const data : any [ ] = [ [ colors . green ( '#' ) , colors . green ( 'Key' ) , colors . green ( 'Value' ) ] ] ;
51
+ for ( const [ i , key ] of keys ) {
52
+ const jsonWithoutNewlines = JSON . stringify ( context [ key ] , undefined , 2 ) . replace ( / \s + / g, ' ' ) ;
53
+ data . push ( [ i , key , jsonWithoutNewlines ] ) ;
54
+ }
55
+
56
+ print ( `Context found in ${ colors . blue ( DEFAULTS ) } :\n` ) ;
57
+
58
+ print ( table . table ( data , {
59
+ border : table . getBorderCharacters ( 'norc' ) ,
60
+ columns : {
61
+ 1 : { width : 50 , wrapWord : true } as any ,
62
+ 2 : { width : 50 , wrapWord : true } as any
63
+ }
64
+ } ) ) ;
65
+
66
+ // tslint:disable-next-line:max-line-length
67
+ print ( `Run ${ colors . blue ( 'cdk context --reset KEY_OR_NUMBER' ) } to remove a context key. It will be refreshed on the next CDK synthesis run.` ) ;
68
+ }
69
+
70
+ function invalidateContext ( context : any , key : string ) {
71
+ const i = parseInt ( key , 10 ) ;
72
+ if ( `${ i } ` === key ) {
73
+ // Twas a number and we fully parsed it.
74
+ key = keyByNumber ( context , i ) ;
75
+ }
76
+
77
+ // Unset!
78
+ if ( key in context ) {
79
+ delete context [ key ] ;
80
+ print ( `Context value ${ colors . blue ( key ) } reset. It will be refreshed on the next SDK synthesis run.` ) ;
81
+ } else {
82
+ print ( `No context value with key ${ colors . blue ( key ) } ` ) ;
83
+ }
84
+ }
85
+
86
+ function keyByNumber ( context : any , n : number ) {
87
+ for ( const [ i , key ] of contextKeys ( context ) ) {
88
+ if ( n === i ) {
89
+ return key ;
90
+ }
91
+ }
92
+ throw new Error ( `No context key with number: ${ n } ` ) ;
93
+ }
94
+
95
+ /**
96
+ * Return enumerated keys in a definitive order
97
+ */
98
+ function contextKeys ( context : any ) {
99
+ const keys = Object . keys ( context ) ;
100
+ keys . sort ( ) ;
101
+ return enumerate1 ( keys ) ;
102
+ }
103
+
104
+ function enumerate1 < T > ( xs : T [ ] ) : Array < [ number , T ] > {
105
+ const ret = new Array < [ number , T ] > ( ) ;
106
+ let i = 1 ;
107
+ for ( const x of xs ) {
108
+ ret . push ( [ i , x ] ) ;
109
+ i += 1 ;
110
+ }
111
+ return ret ;
112
+ }
0 commit comments