@@ -36,7 +36,7 @@ export abstract class DeployCoreCommand extends Command {
3636
3737export abstract class DeployConfCommand extends DeployCoreCommand {
3838
39- protected readonly optionsToPlistKeys = {
39+ protected readonly optionsToPlistKeys : { [ key : string ] : string } = {
4040 'app-id' : 'IonAppId' ,
4141 'channel-name' : 'IonChannelName' ,
4242 'update-method' : 'IonUpdateMethod' ,
@@ -53,6 +53,24 @@ export abstract class DeployConfCommand extends DeployCoreCommand {
5353 'update-api' : 'ionic_update_api' ,
5454 } ;
5555
56+ protected readonly requiredOptionsDefaults : { [ key : string ] : string } = {
57+ 'max-store' : '2' ,
58+ 'min-background-duration' : '30' ,
59+ 'update-api' : 'https://api.ionicjs.com' ,
60+ }
61+
62+ protected readonly requiredOptionsFromPlistVal : { [ key : string ] : string } = {
63+ 'IonMaxVersions' : 'max-store' ,
64+ 'IonMinBackgroundDuration' : 'min-background-duration' ,
65+ 'IonApi' : 'update-api' ,
66+ }
67+
68+ protected readonly requiredOptionsFromXmlVal = {
69+ 'ionic_max_versions' : 'max-store' ,
70+ 'ionic_min_background_duration' : 'min-background-duration' ,
71+ 'ionic_update_api' : 'update-api' ,
72+ }
73+
5674 protected async getAppId ( ) : Promise < string | undefined > {
5775 if ( this . project ) {
5876 return this . project . config . get ( 'id' ) ;
@@ -132,7 +150,10 @@ export abstract class DeployConfCommand extends DeployCoreCommand {
132150 return false ;
133151 }
134152 if ( ! plistPath ) {
135- this . env . log . info ( `No Capacitor iOS project found.` ) ;
153+ this . env . log . warn (
154+ `No ${ strong ( 'Capacitor iOS' ) } project found\n` +
155+ `You will need to rerun ${ input ( 'ionic deploy configure' ) } if you add it later.\n`
156+ ) ;
136157 return false ;
137158 }
138159 // try to load the plist file first
@@ -169,6 +190,7 @@ export abstract class DeployConfCommand extends DeployCoreCommand {
169190 }
170191 // check which options are set (configure might not have all of them set)
171192 const setOptions : { [ key : string ] : string } = { } ;
193+
172194 for ( const [ optionKey , plistKey ] of Object . entries ( this . optionsToPlistKeys ) ) {
173195 if ( options [ optionKey ] ) {
174196 setOptions [ optionKey ] = plistKey ;
@@ -183,19 +205,39 @@ export abstract class DeployConfCommand extends DeployCoreCommand {
183205 const pdictChildren = pdict . getchildren ( ) ;
184206 // there is no way to refer to a first right sibling in elementtree, so we use flags
185207 let removeNextStringTag = false ;
208+ let existingRequiredKeys = [ ] ;
186209 for ( const element of pdictChildren ) {
210+
211+ // find required options and keep track of what is already existing
212+ if ( ( element . tag === 'key' ) && ( element . text ) && this . requiredOptionsFromPlistVal [ element . text as string ] != undefined ) {
213+ existingRequiredKeys . push ( this . requiredOptionsFromPlistVal [ element . text as string ] )
214+ }
215+
187216 // we remove all the existing element if there
188217 if ( ( element . tag === 'key' ) && ( element . text ) && Object . values ( setOptions ) . includes ( element . text as string ) ) {
189218 pdict . remove ( element ) ;
190219 removeNextStringTag = true ;
191220 continue ;
192221 }
222+
193223 // and remove the first right sibling (this will happen at the next iteration of the loop
194224 if ( ( element . tag === 'string' ) && removeNextStringTag ) {
195225 pdict . remove ( element ) ;
196226 removeNextStringTag = false ;
197227 }
198228 }
229+
230+ // set any missing required keys to default
231+ for ( const key of Object . keys ( this . requiredOptionsDefaults ) ) {
232+ if ( existingRequiredKeys . includes ( key ) ) {
233+ continue ;
234+ }
235+ setOptions [ key ] = this . optionsToPlistKeys [ key ] ;
236+ if ( ! options [ key ] ) {
237+ options [ key ] = this . requiredOptionsDefaults [ key ] ;
238+ }
239+ }
240+
199241 // add again the new settings
200242 for ( const [ optionKey , plistKey ] of Object . entries ( setOptions ) ) {
201243 const plistValue = options [ optionKey ] ;
@@ -237,7 +279,9 @@ export abstract class DeployConfCommand extends DeployCoreCommand {
237279 return false ;
238280 }
239281 if ( ! stringXmlPath ) {
240- this . env . log . info ( `No Capacitor Android project found.` ) ;
282+ this . env . log . warn (
283+ `No ${ strong ( 'Capacitor Android' ) } project found\n` +
284+ `You will need to rerun ${ input ( 'ionic deploy configure' ) } if you add it later.\n` ) ;
241285 return false ;
242286 }
243287 // try to load the plist file first
@@ -289,6 +333,22 @@ export abstract class DeployConfCommand extends DeployCoreCommand {
289333 element . text = options [ optionKey ] as string ;
290334 }
291335 }
336+
337+ // make sure required keys are set
338+ for ( const [ stringKey , optionKey ] of Object . entries ( this . requiredOptionsFromXmlVal ) ) {
339+ let element = root . find ( `./string[@name="${ stringKey } "]` ) ;
340+ // if the tag already exists, just update the content
341+ if ( element ) {
342+ continue ;
343+ } else {
344+ // otherwise create the tag and set to default
345+ element = et . SubElement ( root , 'string' ) ;
346+ element . set ( 'name' , stringKey ) ;
347+ console . log ( optionKey , 'opoitn key' ) ;
348+ element . text = this . requiredOptionsDefaults [ optionKey ] ;
349+ }
350+ }
351+
292352 // write back the modified plist
293353 const newXML = etree . write ( {
294354 encoding : 'utf-8' ,
0 commit comments