@@ -5,6 +5,7 @@ import * as fs from 'fs'
55import { createServer } from 'net'
66import * as path from 'path'
77import { Pool } from 'pg'
8+ import { createInterface } from 'readline'
89import { setTimeout as delay } from 'timers/promises'
910import { createPublicClient , http } from 'viem'
1011
@@ -22,13 +23,14 @@ type ProcessorName =
2223function parseArgs ( ) {
2324 const args = process . argv . slice ( 2 )
2425 if ( args . length === 0 ) {
25- console . error ( 'Usage: tsx create-db-dump.ts <processor-name> [--profile <aws-profile>] [--continue]' )
26+ console . error ( 'Usage: tsx create-db-dump.ts <processor-name> [--profile <aws-profile>] [--continue] [-y|--yes] ' )
2627 process . exit ( 1 )
2728 }
2829
2930 const processorName = args [ 0 ] as ProcessorName
3031 let awsProfile : string | undefined
3132 let continueRun = false
33+ let assumeYes = false
3234
3335 for ( let i = 1 ; i < args . length ; i ++ ) {
3436 const arg = args [ i ]
@@ -40,9 +42,12 @@ function parseArgs() {
4042 if ( arg === '--continue' ) {
4143 continueRun = true
4244 }
45+ if ( arg === '-y' || arg === '--yes' ) {
46+ assumeYes = true
47+ }
4348 }
4449
45- return { processorName, awsProfile, continueRun }
50+ return { processorName, awsProfile, continueRun, assumeYes }
4651}
4752
4853function getProcessorAlias ( processorName : ProcessorName ) : string {
@@ -131,6 +136,23 @@ async function findFreePort(preferredStart = 24000, preferredEnd = 65000): Promi
131136 throw new Error ( 'No free port found' )
132137}
133138
139+ async function promptYNC ( message : string ) : Promise < 'y' | 'n' | 'c' > {
140+ if ( ! process . stdin . isTTY ) {
141+ console . error ( 'Non-interactive shell: refusing to wipe existing data. Re-run with --continue or use -y.' )
142+ process . exit ( 1 )
143+ }
144+ const rl = createInterface ( { input : process . stdin , output : process . stdout } )
145+ try {
146+ const answer : string = await new Promise ( ( resolve ) => rl . question ( message , resolve ) )
147+ const a = answer . trim ( ) . toLowerCase ( )
148+ if ( a === 'y' || a === 'yes' ) return 'y'
149+ if ( a === 'c' || a === 'continue' ) return 'c'
150+ return 'n'
151+ } finally {
152+ rl . close ( )
153+ }
154+ }
155+
134156async function getExistingDbPort ( composeProject : string ) : Promise < number | null > {
135157 try {
136158 const { stdout } = await runCmd ( `docker ps --filter "name=^\/${ composeProject } -db-1$" --format "{{.Ports}}"` , {
@@ -227,7 +249,9 @@ async function main() {
227249 dotenv . config ( { path : devEnvPath , override : false } )
228250 }
229251
230- const { processorName, awsProfile, continueRun } = parseArgs ( )
252+ const parsed = parseArgs ( )
253+ const { processorName, awsProfile, assumeYes } = parsed
254+ let continueRun = parsed . continueRun
231255 const alias = getProcessorAlias ( processorName )
232256
233257 // Determine RPC URL for the chain
@@ -255,13 +279,41 @@ async function main() {
255279 const composeProject = `squid_${ alias } `
256280 let DB_PORT = 0
257281 let startedCompose = false
282+ const existingPort = await getExistingDbPort ( composeProject )
283+
284+ // Guard against the common mistake: forgetting --continue, which would wipe the in-progress dump.
285+ if ( existingPort && ! continueRun && ! assumeYes ) {
286+ console . warn ( `` )
287+ console . warn ( `Existing dockerized Postgres found for '${ processorName } '` )
288+ console . warn ( ` compose project: ${ composeProject } ` )
289+ console . warn ( ` port: ${ existingPort } ` )
290+ console . warn ( `` )
291+ console . warn ( `Running without --continue would WIPE this data (--volumes) and restart from scratch.` )
292+ console . warn ( `Each full reprocess takes hours — this is almost certainly NOT what you want.` )
293+ console . warn ( `` )
294+ console . warn ( ` [y] yes, wipe and start over from scratch` )
295+ console . warn ( ` [c] continue from existing data (acts as if --continue was passed)` )
296+ console . warn ( ` [n] no, abort (default)` )
297+ console . warn ( `` )
298+ const choice = await promptYNC ( `choice [y/c/N]: ` )
299+ if ( choice === 'n' ) {
300+ console . log ( 'Aborted.' )
301+ process . exit ( 0 )
302+ }
303+ if ( choice === 'c' ) {
304+ console . log ( `→ continuing from existing data` )
305+ continueRun = true
306+ } else {
307+ console . log ( `→ wiping existing data and starting over` )
308+ }
309+ }
310+
258311 if ( continueRun ) {
259- const existingPort = await getExistingDbPort ( composeProject )
260312 if ( existingPort ) {
261313 DB_PORT = existingPort
262314 console . log ( `Reusing existing dockerized Postgres at port ${ DB_PORT } (project ${ composeProject } )...` )
263315 } else {
264- console . log ( `No existing Postgres found.` )
316+ console . log ( `No existing Postgres found; --continue requires existing data. Aborting .` )
265317 process . exit ( 1 )
266318 }
267319 } else {
0 commit comments