@@ -15,6 +15,12 @@ import { BackupStorageAvailability } from '../lib/backup-storage-availability/ba
1515import * as exit from '../lib/cli/exit' ;
1616import { unzipFile } from '../lib/client-file-uploader' ;
1717import { fixMyDumperTransform , getSqlDumpDetails , SqlDumpType } from '../lib/database' ;
18+ import {
19+ DBLiveCopyConfig ,
20+ downloadFile ,
21+ getDownloadURL ,
22+ startLiveBackupCopy ,
23+ } from '../lib/live-backup-copy' ;
1824import { makeTempDir } from '../lib/utils' ;
1925import { getReadInterface } from '../lib/validations/line-by-line' ;
2026
@@ -91,33 +97,31 @@ export class DevEnvSyncSQLCommand {
9197 public tmpDir : string ;
9298 public siteUrls : string [ ] = [ ] ;
9399 public searchReplaceMap : Record < string , string > = { } ;
100+ public configFile ?: string ;
94101 public _track : TrackFunction ;
95102 private _sqlDumpType ?: SqlDumpType ;
96103
97104 /**
98105 * Creates a new instance of the command
99- *
100- * @param app The app object
101- * @param env The environment object
102- * @param slug The site slug
103- * @param lando The lando object
104- * @param trackerFn Function to call for tracking
105106 */
106107 constructor (
107108 public app : App ,
108109 public env : AppEnvironment ,
109110 public slug : string ,
110111 public lando : Lando ,
111- trackerFn : TrackFunction = ( ) => { }
112+ trackerFn : TrackFunction = ( ) => { } ,
113+ configFile ?: string
112114 ) {
113115 this . _track = trackerFn ;
114116 this . tmpDir = makeTempDir ( ) ;
117+ this . configFile = configFile ;
115118 }
116119
117120 public track ( name : string , eventProps : Record < string , unknown > ) {
118121 return this . _track ( name , {
119122 ...eventProps ,
120123 sqldump_type : this . _sqlDumpType ,
124+ live_backup_copy : Boolean ( this . configFile ) ,
121125 } ) ;
122126 }
123127
@@ -156,6 +160,12 @@ export class DevEnvSyncSQLCommand {
156160 * the latest backup
157161 */
158162 public async generateExport ( ) : Promise < void > {
163+ if ( this . configFile ) {
164+ await this . generateLiveBackupCopy ( ) ;
165+
166+ return ;
167+ }
168+
159169 const exportCommand = new ExportSQLCommand (
160170 this . app ,
161171 this . env ,
@@ -165,6 +175,51 @@ export class DevEnvSyncSQLCommand {
165175 await exportCommand . run ( ) ;
166176 }
167177
178+ private async generateLiveBackupCopy ( ) : Promise < void > {
179+ if ( ! this . configFile ) {
180+ throw new Error ( 'Configuration file is required for live backup copy.' ) ;
181+ }
182+
183+ if ( ! this . app . id || ! this . env . id ) {
184+ throw new Error ( 'App ID and Environment ID are required to start live backup copy.' ) ;
185+ }
186+
187+ const config = JSON . parse ( fs . readFileSync ( this . configFile , 'utf-8' ) ) as DBLiveCopyConfig ;
188+ if ( ! config . type ) {
189+ throw new Error ( 'Invalid configuration file. Missing tool or type.' ) ;
190+ }
191+
192+ try {
193+ console . log ( `${ chalk . green ( '✓' ) } Creating backup copy` ) ;
194+
195+ const copyId = await startLiveBackupCopy ( {
196+ appId : this . app . id ,
197+ environmentId : this . env . id ,
198+ config,
199+ } ) ;
200+
201+ const downloadURL = await getDownloadURL ( {
202+ appId : this . app . id ,
203+ environmentId : this . env . id ,
204+ copyId,
205+ } ) ;
206+
207+ console . log ( `${ chalk . green ( '✓' ) } Downloading file` ) ;
208+
209+ await downloadFile ( downloadURL , this . gzFile ) ;
210+ } catch ( err ) {
211+ const message = err instanceof Error ? err . message : 'Unknown error' ;
212+
213+ await this . track ( 'error' , {
214+ error_type : 'live_backup_copy' ,
215+ error_message : message ,
216+ stack : err instanceof Error ? err . stack : undefined ,
217+ } ) ;
218+
219+ exit . withError ( `Error creating backup copy: ${ message } ` ) ;
220+ }
221+ }
222+
168223 /**
169224 * Runs the search-replace operation on the SQL file
170225 * to replace the site urls with the lando domain
0 commit comments