11import  yargs  from  'yargs' ; 
22import  chalk  from  'chalk' ; 
3- import  {  getDuplicates ,  getSuccessfullyExecutedMigrations ,  getMigrationFilepath ,  loadMigrationFiles ,  loadModule ,  runMigration  }  from  '../../utils/migrationUtils' ; 
3+ import  {  getDuplicates ,  getSuccessfullyExecutedMigrations ,  getMigrationFilepath ,  loadMigrationFiles ,  loadModule ,  runMigration ,   getMigrationsWithInvalidOrder  }  from  '../../utils/migrationUtils' ; 
44import  {  fileExists ,  getFileWithExtension ,  isAllowedExtension  }  from  '../../utils/fileUtils' ; 
55import  {  environmentConfigExists ,  getEnvironmentsConfig  }  from  '../../utils/environmentUtils' ; 
66import  {  createManagementClient  }  from  '../../managementClientFactory' ; 
@@ -38,6 +38,11 @@ const runMigrationCommand: yargs.CommandModule = {
3838                    describe : 'Run all migration scripts in the specified order' , 
3939                    type : 'boolean' , 
4040                } , 
41+                 range : { 
42+                     alias : 'r' , 
43+                     describe : 'Run all migration scripts in the specified range, eg.: 3:5 will run migrations with the "order" property set to 3, 4 and 5' , 
44+                     type : 'string' , 
45+                 } , 
4146                force : { 
4247                    alias : 'f' , 
4348                    describe : 'Enforces run of already executed scripts.' , 
@@ -58,6 +63,8 @@ const runMigrationCommand: yargs.CommandModule = {
5863                } , 
5964            } ) 
6065            . conflicts ( 'all' ,  'name' ) 
66+             . conflicts ( 'range' ,  'name' ) 
67+             . conflicts ( 'all' ,  'range' ) 
6168            . conflicts ( 'environment' ,  'api-key' ) 
6269            . conflicts ( 'environment' ,  'project-id' ) 
6370            . check ( ( args : any )  =>  { 
@@ -66,7 +73,11 @@ const runMigrationCommand: yargs.CommandModule = {
6673                } 
6774
6875                if  ( ! args . all )  { 
69-                     if  ( args . name )  { 
76+                     if  ( args . range )  { 
77+                         if  ( ! getRange ( args . range ) )  { 
78+                             throw  new  Error ( chalk . red ( `The range has to be a string of a format "number:number" where the first number is less or equal to the second, eg.: "2:5".` ) ) ; 
79+                         } 
80+                     }  else  if  ( args . name )  { 
7081                        if  ( ! isAllowedExtension ( args . name ) )  { 
7182                            throw  new  Error ( chalk . red ( `File ${ args . name }  ) ) ; 
7283                        } 
@@ -76,7 +87,7 @@ const runMigrationCommand: yargs.CommandModule = {
7687                            throw  new  Error ( chalk . red ( `Cannot find the specified migration script: ${ migrationFilePath }  ) ) ; 
7788                        } 
7889                    }  else  { 
79-                         throw  new  Error ( chalk . red ( 'Either the migration script name or all migration options needs to be specified.' ) ) ; 
90+                         throw  new  Error ( chalk . red ( 'Either the migration script name, range  or all migration options needs to be specified.' ) ) ; 
8091                    } 
8192                } 
8293
@@ -99,6 +110,7 @@ const runMigrationCommand: yargs.CommandModule = {
99110        let  apiKey  =  argv . apiKey ; 
100111        const  migrationName  =  argv . name ; 
101112        const  runAll  =  argv . all ; 
113+         const  runRange  =  getRange ( argv . range ) ; 
102114        const  debugMode  =  argv . debug ; 
103115        const  continueOnError  =  argv . continueOnError ; 
104116        let  migrationsResults : number  =  0 ; 
@@ -119,10 +131,15 @@ const runMigrationCommand: yargs.CommandModule = {
119131
120132        loadMigrationsExecutionStatus ( ) ; 
121133
122-         if  ( runAll )  { 
134+         if  ( runAll   ||   runRange )  { 
123135            let  migrationsToRun  =  await  loadMigrationFiles ( ) ; 
124136
125137            checkForDuplicates ( migrationsToRun ) ; 
138+             checkForInvalidOrder ( migrationsToRun ) ; 
139+ 
140+             if  ( runRange )  { 
141+                 migrationsToRun  =  getMigrationsByRange ( migrationsToRun ,  runRange ) ; 
142+             } 
126143
127144            if  ( runForce )  { 
128145                console . log ( 'Skipping to check already executed migrations' ) ; 
@@ -165,6 +182,17 @@ const runMigrationCommand: yargs.CommandModule = {
165182    } , 
166183} ; 
167184
185+ export  const  getRange  =  ( range : string ) : [ number ,  number ]  |  null  =>  { 
186+     const  match  =  range . match ( / ^ ( [ 0 - 9 ] + ) : ( [ 0 - 9 ] + ) $ / ) ; 
187+     if  ( ! match )  { 
188+         return  null ; 
189+     } 
190+     const  from  =  Number ( match [ 1 ] ) ; 
191+     const  to  =  Number ( match [ 2 ] ) ; 
192+ 
193+     return  from  <=  to  ? [ from ,  to ]  : null ; 
194+ } ; 
195+ 
168196const  checkForDuplicates  =  ( migrationsToRun : IMigration [ ] ) : void =>  { 
169197    const  duplicateMigrationsOrder  =  getDuplicates ( migrationsToRun ,  ( migration )  =>  migration . module . order ) ; 
170198
@@ -176,6 +204,29 @@ const checkForDuplicates = (migrationsToRun: IMigration[]): void => {
176204    } 
177205} ; 
178206
207+ const  getMigrationsByRange  =  ( migrationsToRun : IMigration [ ] ,  range : [ number ,  number ] ) : IMigration [ ]  =>  { 
208+     const  migrations : IMigration [ ]  =  [ ] ; 
209+ 
210+     for  ( const  migration  of  migrationsToRun )  { 
211+         if  ( migration . module . order  >=  range [ 0 ]  &&  migration . module . order  <=  range [ 1 ] )  { 
212+             migrations . push ( migration ) ; 
213+         } 
214+     } 
215+ 
216+     return  migrations . filter ( String ) ; 
217+ } ; 
218+ 
219+ const  checkForInvalidOrder  =  ( migrationsToRun : IMigration [ ] ) : void =>  { 
220+     const  migrationsWithInvalidOrder : IMigration [ ]  =  getMigrationsWithInvalidOrder ( migrationsToRun ) ; 
221+ 
222+     if  ( migrationsWithInvalidOrder . length  >  0 )  { 
223+         console . log ( 'Migration order has to be positive integer or zero:' ) ; 
224+         migrationsWithInvalidOrder . map ( ( migration )  =>  console . error ( chalk . red ( `Migration: ${ migration . name } ${ migration . module . order }  ) ) ) ; 
225+ 
226+         process . exit ( 1 ) ; 
227+     } 
228+ } ; 
229+ 
179230const  skipExecutedMigrations  =  ( migrations : IMigration [ ] ,  projectId : string ) : IMigration [ ]  =>  { 
180231    const  executedMigrations  =  getSuccessfullyExecutedMigrations ( migrations ,  projectId ) ; 
181232    const  result : IMigration [ ]  =  [ ] ; 
0 commit comments