|
4 | 4 | * Leaderboard Data Dump Script |
5 | 5 | * Fetches all leaderboard data from mainnet and testnet GraphQL endpoints |
6 | 6 | * Output: __fixtures__/leaderboard/ |
| 7 | + * |
| 8 | + * Usage: |
| 9 | + * node scripts/dumpLeaderboardData.mjs # Fetch and save new data |
| 10 | + * node scripts/dumpLeaderboardData.mjs --clear # Clear old data before fetching (interactive) |
| 11 | + * node scripts/dumpLeaderboardData.mjs --clear -y # Clear without confirmation (CI/non-interactive) |
7 | 12 | */ |
8 | 13 |
|
9 | | -import { writeFileSync, mkdirSync } from 'fs'; |
| 14 | +import { writeFileSync, mkdirSync, readdirSync, rmSync, existsSync } from 'fs'; |
10 | 15 | import { join } from 'path'; |
| 16 | +import { createInterface } from 'readline'; |
11 | 17 |
|
12 | 18 | const OUTPUT_DIR = join(process.cwd(), '__fixtures__/leaderboard'); |
13 | 19 |
|
@@ -220,11 +226,60 @@ function saveJson(timestamp, filename, data) { |
220 | 226 | console.log(`Saved: ${filepath}`); |
221 | 227 | } |
222 | 228 |
|
| 229 | +async function confirm(message) { |
| 230 | + const rl = createInterface({ input: process.stdin, output: process.stdout }); |
| 231 | + return new Promise((resolve) => { |
| 232 | + rl.question(`${message} (y/N): `, (answer) => { |
| 233 | + rl.close(); |
| 234 | + resolve(answer.toLowerCase() === 'y'); |
| 235 | + }); |
| 236 | + }); |
| 237 | +} |
| 238 | + |
| 239 | +async function clearPreviousData(skipConfirmation = false) { |
| 240 | + if (!existsSync(OUTPUT_DIR)) { |
| 241 | + console.log('No existing data to clear.'); |
| 242 | + return true; |
| 243 | + } |
| 244 | + |
| 245 | + const files = readdirSync(OUTPUT_DIR).filter((f) => f.endsWith('.json')); |
| 246 | + if (files.length === 0) { |
| 247 | + console.log('No existing data to clear.'); |
| 248 | + return true; |
| 249 | + } |
| 250 | + |
| 251 | + console.log(`\nFound ${files.length} existing file(s):`); |
| 252 | + files.forEach((f) => console.log(` - ${f}`)); |
| 253 | + |
| 254 | + if (!skipConfirmation) { |
| 255 | + const confirmed = await confirm(`\nDelete all ${files.length} file(s)?`); |
| 256 | + if (!confirmed) { |
| 257 | + console.log('Aborted.'); |
| 258 | + return false; |
| 259 | + } |
| 260 | + } |
| 261 | + |
| 262 | + files.forEach((f) => rmSync(join(OUTPUT_DIR, f))); |
| 263 | + console.log(`Deleted ${files.length} file(s).\n`); |
| 264 | + return true; |
| 265 | +} |
| 266 | + |
223 | 267 | async function main() { |
| 268 | + const args = process.argv.slice(2); |
| 269 | + const shouldClear = args.includes('--clear'); |
| 270 | + const skipConfirmation = args.includes('-y') || args.includes('--yes'); |
224 | 271 | const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); |
225 | 272 | console.log('=== Leaderboard Data Dump ==='); |
226 | 273 | console.log(`Timestamp: ${timestamp}`); |
227 | 274 |
|
| 275 | + // Handle --clear flag |
| 276 | + if (shouldClear) { |
| 277 | + const proceed = await clearPreviousData(skipConfirmation); |
| 278 | + if (!proceed) { |
| 279 | + process.exit(0); |
| 280 | + } |
| 281 | + } |
| 282 | + |
228 | 283 | // Ensure output directory exists |
229 | 284 | mkdirSync(OUTPUT_DIR, { recursive: true }); |
230 | 285 |
|
|
0 commit comments