@@ -2,9 +2,10 @@ import { z } from 'zod'
22import * as fs from 'fs'
33
44// Helper transformers
5- const parseBoolean = ( val ?: string ) => val ? ! ! + val : false
6- const parseNumber = ( val ?: string ) => val ? parseInt ( val ) || undefined : undefined
7- const parseARNs = ( val ?: string ) => val ?. length ? val . split ( ',' ) : undefined
5+ const parseBoolean = ( val ?: string ) => ( val ? ! ! + val : false )
6+ const parseNumber = ( val ?: string ) =>
7+ val ? parseInt ( val ) || undefined : undefined
8+ const parseARNs = ( val ?: string ) => ( val ?. length ? val . split ( ',' ) : undefined )
89const parseTags = ( val ?: string ) => {
910 if ( ! val ) return undefined
1011 try {
@@ -15,7 +16,7 @@ const parseTags = (val?: string) => {
1516}
1617const parseParameters = ( val ?: string ) => {
1718 if ( ! val ) return undefined
18-
19+
1920 try {
2021 const path = new URL ( val )
2122 const rawParameters = fs . readFileSync ( path , 'utf-8' )
@@ -28,21 +29,20 @@ const parseParameters = (val?: string) => {
2829 }
2930
3031 const parameters = new Map < string , string > ( )
31- val . split ( / , (? = (?: (?: [ ^ " ' ] * [ " | ' ] ) { 2 } ) * [ ^ " ' ] * $ ) / g)
32- . forEach ( parameter => {
33- const values = parameter . trim ( ) . split ( '=' )
34- const key = values [ 0 ]
35- const value = values . slice ( 1 ) . join ( '=' )
36- let param = parameters . get ( key )
37- param = ! param ? value : [ param , value ] . join ( ',' )
38- if (
39- ( param . startsWith ( "'" ) && param . endsWith ( "'" ) ) ||
40- ( param . startsWith ( '"' ) && param . endsWith ( '"' ) )
41- ) {
42- param = param . substring ( 1 , param . length - 1 )
43- }
44- parameters . set ( key , param )
45- } )
32+ val . split ( / , (? = (?: (?: [ ^ " ' ] * [ " | ' ] ) { 2 } ) * [ ^ " ' ] * $ ) / g) . forEach ( parameter => {
33+ const values = parameter . trim ( ) . split ( '=' )
34+ const key = values [ 0 ]
35+ const value = values . slice ( 1 ) . join ( '=' )
36+ let param = parameters . get ( key )
37+ param = ! param ? value : [ param , value ] . join ( ',' )
38+ if (
39+ ( param . startsWith ( "'" ) && param . endsWith ( "'" ) ) ||
40+ ( param . startsWith ( '"' ) && param . endsWith ( '"' ) )
41+ ) {
42+ param = param . substring ( 1 , param . length - 1 )
43+ }
44+ parameters . set ( key , param )
45+ } )
4646
4747 return [ ...parameters . keys ( ) ] . map ( key => ( {
4848 ParameterKey : key ,
@@ -51,17 +51,22 @@ const parseParameters = (val?: string) => {
5151}
5252
5353const baseSchema = z . object ( {
54- mode : z . enum ( [ 'create-and-execute' , 'create-only' , 'execute-only' ] ) . default ( 'create-and-execute' ) ,
54+ mode : z
55+ . enum ( [ 'create-and-execute' , 'create-only' , 'execute-only' ] )
56+ . default ( 'create-and-execute' ) ,
5557 name : z . string ( ) . min ( 1 , 'Stack name is required' ) ,
5658 'http-proxy' : z . string ( ) . optional ( )
5759} )
5860
5961const createSchema = baseSchema . extend ( {
6062 mode : z . enum ( [ 'create-and-execute' , 'create-only' ] ) ,
6163 template : z . string ( ) . min ( 1 , 'Template is required for create modes' ) ,
62- capabilities : z . string ( ) . optional ( ) . transform ( val =>
63- val ? val . split ( ',' ) . map ( cap => cap . trim ( ) ) : [ 'CAPABILITY_IAM' ]
64- ) ,
64+ capabilities : z
65+ . string ( )
66+ . optional ( )
67+ . transform ( val =>
68+ val ? val . split ( ',' ) . map ( cap => cap . trim ( ) ) : [ 'CAPABILITY_IAM' ]
69+ ) ,
6570 'parameter-overrides' : z . string ( ) . optional ( ) . transform ( parseParameters ) ,
6671 'no-fail-on-empty-changeset' : z . string ( ) . optional ( ) . transform ( parseBoolean ) ,
6772 'no-execute-changeset' : z . string ( ) . optional ( ) . transform ( parseBoolean ) ,
@@ -73,18 +78,28 @@ const createSchema = baseSchema.extend({
7378 tags : z . string ( ) . optional ( ) . transform ( parseTags ) ,
7479 'termination-protection' : z . string ( ) . optional ( ) . transform ( parseBoolean ) ,
7580 'change-set-name' : z . string ( ) . optional ( ) ,
76- 'include-nested-stacks-change-set' : z . string ( ) . optional ( ) . transform ( parseBoolean ) ,
77- 'deployment-mode' : z . string ( ) . optional ( ) . transform ( val => {
78- if ( ! val ) return undefined
79- if ( val === 'REVERT_DRIFT' ) return val
80- throw new Error ( `Invalid deployment-mode: ${ val } . Only 'REVERT_DRIFT' is supported.` )
81- } ) ,
81+ 'include-nested-stacks-change-set' : z
82+ . string ( )
83+ . optional ( )
84+ . transform ( parseBoolean ) ,
85+ 'deployment-mode' : z
86+ . string ( )
87+ . optional ( )
88+ . transform ( val => {
89+ if ( ! val ) return undefined
90+ if ( val === 'REVERT_DRIFT' ) return val
91+ throw new Error (
92+ `Invalid deployment-mode: ${ val } . Only 'REVERT_DRIFT' is supported.`
93+ )
94+ } ) ,
8295 'execute-change-set-id' : z . undefined ( )
8396} )
8497
8598const executeSchema = baseSchema . extend ( {
8699 mode : z . literal ( 'execute-only' ) ,
87- 'execute-change-set-id' : z . string ( ) . min ( 1 , 'Change set ID is required for execute-only mode' ) ,
100+ 'execute-change-set-id' : z
101+ . string ( )
102+ . min ( 1 , 'Change set ID is required for execute-only mode' ) ,
88103 template : z . undefined ( ) ,
89104 'parameter-overrides' : z . undefined ( ) ,
90105 'deployment-mode' : z . undefined ( ) ,
@@ -102,9 +117,11 @@ const executeSchema = baseSchema.extend({
102117 'include-nested-stacks-change-set' : z . undefined ( )
103118} )
104119
105- export function validateAndParseInputs ( inputs : Record < string , string | undefined > ) {
120+ export function validateAndParseInputs (
121+ inputs : Record < string , string | undefined >
122+ ) {
106123 const mode = inputs . mode || 'create-and-execute'
107-
124+
108125 if ( mode === 'execute-only' ) {
109126 return executeSchema . parse ( inputs )
110127 } else {
0 commit comments