@arela/uploader 1.0.14 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arela/uploader",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "CLI to upload files/directories to Arela",
5
5
  "bin": {
6
6
  "arela": "./src/index.js"
@@ -283,6 +283,11 @@ export class PushCommand {
283
283
  // After each batch upload, those files are no longer "pending", so the next query
284
284
  // at offset=0 will naturally return the next batch of unprocessed files
285
285
 
286
+ // Track seen file IDs to detect infinite loops (scan table update failures)
287
+ const seenFileIds = new Set();
288
+ let consecutiveRepeats = 0;
289
+ const MAX_CONSECUTIVE_REPEATS = 3;
290
+
286
291
  // Start progress bar with known total
287
292
  progressBar.start(totalToProcess, 0, {
288
293
  speed: 0,
@@ -303,6 +308,23 @@ export class PushCommand {
303
308
  break;
304
309
  }
305
310
 
311
+ // Infinite loop protection: if the same files keep coming back,
312
+ // the scan table update is failing and they stay "pending" forever.
313
+ const allSeen = files.every((f) => seenFileIds.has(f.id));
314
+ if (allSeen) {
315
+ consecutiveRepeats++;
316
+ if (consecutiveRepeats >= MAX_CONSECUTIVE_REPEATS) {
317
+ const msg = `Aborting: same ${files.length} files returned ${MAX_CONSECUTIVE_REPEATS} times — scan table updates are likely failing.`;
318
+ logger.error(msg);
319
+ console.error(`\n⚠ ${msg}`);
320
+ hasMore = false;
321
+ break;
322
+ }
323
+ } else {
324
+ consecutiveRepeats = 0;
325
+ }
326
+ files.forEach((f) => seenFileIds.add(f.id));
327
+
306
328
  // Upload files in smaller batches using new CLI upload endpoint
307
329
  for (let i = 0; i < files.length; i += uploadBatchSize) {
308
330
  const uploadBatch = files.slice(i, i + uploadBatchSize);
@@ -328,9 +350,9 @@ export class PushCommand {
328
350
  try {
329
351
  await this.scanApiService.batchUpdateUpload(tableName, batchResults);
330
352
  } catch (updateError) {
331
- logger.error(
332
- `Failed to update scan table for batch: ${updateError.message}`,
333
- );
353
+ const msg = `Failed to update scan table for batch: ${updateError.message}`;
354
+ logger.error(msg);
355
+ console.error(`\n⚠ ${msg}`);
334
356
  // Don't fail the entire process, just log the error
335
357
  }
336
358
 
@@ -482,7 +504,13 @@ export class PushCommand {
482
504
  if (apiResult.uploaded && apiResult.uploaded.length > 0) {
483
505
  const uploadedFile = apiResult.uploaded[0];
484
506
  result.uploaded = true;
485
- result.uploadedToStorageId = uploadedFile.storageId;
507
+ // Only assign storageId if it is a valid UUID; ignore placeholder values
508
+ const UUID_RE =
509
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
510
+ result.uploadedToStorageId =
511
+ uploadedFile.storageId && UUID_RE.test(uploadedFile.storageId)
512
+ ? uploadedFile.storageId
513
+ : null;
486
514
  logger.info(`✓ Uploaded: ${file.file_name} → ${uploadPath}`);
487
515
  } else if (apiResult.errors && apiResult.errors.length > 0) {
488
516
  const error = apiResult.errors[0];
@@ -34,10 +34,10 @@ class Config {
34
34
  const __dirname = path.dirname(__filename);
35
35
  const packageJsonPath = path.resolve(__dirname, '../../package.json');
36
36
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
37
- return packageJson.version || '1.0.14';
37
+ return packageJson.version || '1.0.15';
38
38
  } catch (error) {
39
39
  console.warn('⚠️ Could not read package.json version, using fallback');
40
- return '1.0.14';
40
+ return '1.0.15';
41
41
  }
42
42
  }
43
43