@iksdev/shard-cli 0.1.18 → 0.1.20

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.
Files changed (2) hide show
  1. package/bin/shard.js +76 -23
  2. package/package.json +1 -1
package/bin/shard.js CHANGED
@@ -16,24 +16,32 @@ const STATE_FILE = '.shard-sync-state.json';
16
16
  const DEFAULT_SERVER = 'https://shard-0ow4.onrender.com';
17
17
  const IGNORED_DIRS = new Set(['.git', 'node_modules']);
18
18
 
19
- function printHelp() {
20
- console.log(`Shard CLI
21
-
22
- Usage:
23
- shard login --username <name> --password <pass> [--server <url>]
24
- shard whoami [--server <url>]
25
- shard sync <folder> [--server <url>] [--dry-run] [--force] [--once] [--interval-ms <n>]
26
- shard share <file> [--server <url>] [--limits <n>] [--temps <jours>] [--upload]
27
- shard logout
28
- shard config show
29
- shard config set-server <url>
30
-
31
- Examples:
32
- shard login --server https://shard-0ow4.onrender.com --username admin --password secret
33
- shard sync ./MonDossier
34
- shard sync ./MonDossier --once
35
- shard sync ./MonDossier --dry-run
36
- shard share ./MonFichier.mp4 --limits 0 --temps 0
19
+ function printHelp() {
20
+ console.log(`Shard CLI
21
+
22
+ Commandes:
23
+ shard login
24
+ shard whoami
25
+ shard sync
26
+ shard share
27
+ shard logout
28
+ shard config show
29
+ shard config set-server <url>
30
+
31
+ Mode interactif:
32
+ La CLI pose les questions (fichier, dossier, serveur, identifiants) si tu ne passes pas d'arguments.
33
+
34
+ Options avancees (optionnelles):
35
+ login: --username <name> --password <pass> --server <url>
36
+ whoami: --server <url>
37
+ sync: <folder> --server <url> --dry-run --force --once --interval-ms <n>
38
+ share: <file> --server <url> --limits <n> --temps <jours> --upload
39
+
40
+ Examples:
41
+ shard login
42
+ shard sync
43
+ shard share
44
+ shard sync ./MonDossier --once
37
45
  shard share ./MonFichier.mp4 --upload
38
46
  `);
39
47
  }
@@ -455,6 +463,24 @@ async function shareFile(positionals, flags) {
455
463
 
456
464
  let relayClientId = '';
457
465
  let closed = false;
466
+ let heartbeat = null;
467
+ let createdShareId = null;
468
+ let shareRevoked = false;
469
+
470
+ const revokeCreatedShare = async () => {
471
+ if (!createdShareId || shareRevoked) return;
472
+ shareRevoked = true;
473
+ try {
474
+ await httpJson(`${server}/api/share/${createdShareId}`, {
475
+ method: 'DELETE',
476
+ headers: { Authorization: `Bearer ${token}` }
477
+ });
478
+ console.log('Lien relay revoque.');
479
+ } catch (err) {
480
+ console.error(`Impossible de revoquer le lien automatiquement: ${err.message}`);
481
+ }
482
+ };
483
+
458
484
  const closeRelay = () => {
459
485
  if (closed) return;
460
486
  closed = true;
@@ -462,8 +488,23 @@ async function shareFile(positionals, flags) {
462
488
  };
463
489
 
464
490
  const stopSignals = ['SIGINT', 'SIGTERM'];
491
+ const stopRelayShare = (signal) => {
492
+ if (closed) return;
493
+ console.log(`Arret du partage (${signal}). Revocation du lien...`);
494
+ Promise.resolve()
495
+ .then(async () => {
496
+ if (heartbeat) {
497
+ clearInterval(heartbeat);
498
+ heartbeat = null;
499
+ }
500
+ await revokeCreatedShare();
501
+ })
502
+ .finally(() => {
503
+ closeRelay();
504
+ });
505
+ };
465
506
  for (const sig of stopSignals) {
466
- process.on(sig, closeRelay);
507
+ process.on(sig, stopRelayShare);
467
508
  }
468
509
 
469
510
  const openPromise = new Promise((resolve, reject) => {
@@ -544,7 +585,7 @@ async function shareFile(positionals, flags) {
544
585
  }
545
586
  });
546
587
 
547
- const heartbeat = setInterval(() => {
588
+ heartbeat = setInterval(() => {
548
589
  if (relaySocket.readyState === WebSocket.OPEN) {
549
590
  relaySocket.send(JSON.stringify({ type: 'heartbeat', ts: Date.now() }));
550
591
  }
@@ -571,6 +612,10 @@ async function shareFile(positionals, flags) {
571
612
  });
572
613
 
573
614
  const share = created?.share || {};
615
+ if (share?.id) {
616
+ const n = Number(share.id);
617
+ if (Number.isFinite(n) && n > 0) createdShareId = n;
618
+ }
574
619
  console.log(`Partage relay cree pour: ${fileName}`);
575
620
  if (share.url) console.log(`URL Shard: ${share.url}`);
576
621
  if (share.token) console.log(`Token: ${share.token}`);
@@ -583,14 +628,22 @@ async function shareFile(positionals, flags) {
583
628
  await new Promise((resolve) => {
584
629
  relaySocket.on('close', () => resolve());
585
630
  });
586
- clearInterval(heartbeat);
631
+ if (heartbeat) {
632
+ clearInterval(heartbeat);
633
+ heartbeat = null;
634
+ }
587
635
  for (const sig of stopSignals) {
588
- process.off(sig, closeRelay);
636
+ process.off(sig, stopRelayShare);
589
637
  }
590
638
  return;
591
639
  } catch (error) {
640
+ if (heartbeat) {
641
+ clearInterval(heartbeat);
642
+ heartbeat = null;
643
+ }
644
+ await revokeCreatedShare();
592
645
  for (const sig of stopSignals) {
593
- process.off(sig, closeRelay);
646
+ process.off(sig, stopRelayShare);
594
647
  }
595
648
  closeRelay();
596
649
  throw error;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iksdev/shard-cli",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "CLI pour synchroniser un dossier local avec Shard",
5
5
  "bin": {
6
6
  "shard": "bin/shard.js"