@iksdev/shard-cli 0.1.48 → 0.1.50
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/bin/shard.js +111 -58
- package/package.json +1 -1
package/bin/shard.js
CHANGED
|
@@ -702,49 +702,12 @@ async function shareFile(positionals, flags) {
|
|
|
702
702
|
if (Number.isFinite(n) && n > 0) createdShareId = n;
|
|
703
703
|
}
|
|
704
704
|
|
|
705
|
-
//
|
|
706
|
-
|
|
707
|
-
const hr = (l, m, r, col) => `${c(col, l + m.repeat(WS) + r)}`;
|
|
708
|
-
const rowS = (content, col) => {
|
|
709
|
-
const vis = content.replace(/\x1b\[[0-9;]*m/g, '');
|
|
710
|
-
const pad = WS - vis.length;
|
|
711
|
-
return `${c(col, '│')}${content}${' '.repeat(Math.max(0, pad))}${c(col, '│')}`;
|
|
712
|
-
};
|
|
705
|
+
// Ecran "Partage actif" - affiché après connexion
|
|
706
|
+
printShareActiveScreen(share, fileName, limits, temps);
|
|
713
707
|
|
|
714
|
-
|
|
715
|
-
console.log('');
|
|
716
|
-
console.log(hr('┌', '─', '┐', '\x1b[32m'));
|
|
717
|
-
const titleShare = '\x1b[1m\x1b[32m' + ' PARTAGE ACTIF' + '\x1b[0m';
|
|
718
|
-
console.log(rowS(titleShare + ' '.repeat(WS - 15), '\x1b[32m'));
|
|
719
|
-
console.log(hr('├', '─', '┤', '\x1b[32m'));
|
|
720
|
-
console.log(rowS('', '\x1b[32m'));
|
|
721
|
-
if (share.url) {
|
|
722
|
-
const urlLabel = ' \x1b[90mURL \x1b[0m \x1b[1m\x1b[97m' + share.url + '\x1b[0m';
|
|
723
|
-
console.log(rowS(urlLabel, '\x1b[32m'));
|
|
724
|
-
}
|
|
725
|
-
if (share.token) {
|
|
726
|
-
const tokLabel = ' \x1b[90mToken \x1b[0m \x1b[36m' + share.token + '\x1b[0m';
|
|
727
|
-
console.log(rowS(tokLabel, '\x1b[32m'));
|
|
728
|
-
}
|
|
729
|
-
const fileLabel = ' \x1b[90mFichier \x1b[0m \x1b[97m' + fileName + '\x1b[0m';
|
|
730
|
-
console.log(rowS(fileLabel, '\x1b[32m'));
|
|
731
|
-
const dlLabel = ' \x1b[90mLimite \x1b[0m \x1b[97m' + (limits && limits > 0 ? String(limits) + ' telechargement(s)' : 'illimite') + '\x1b[0m';
|
|
732
|
-
console.log(rowS(dlLabel, '\x1b[32m'));
|
|
733
|
-
const expLabel = ' \x1b[90mExpire \x1b[0m \x1b[97m' + (temps && temps > 0 ? `dans ${temps} jour(s)` : 'jamais') + '\x1b[0m';
|
|
734
|
-
console.log(rowS(expLabel, '\x1b[32m'));
|
|
735
|
-
console.log(rowS('', '\x1b[32m'));
|
|
736
|
-
console.log(hr('├', '─', '┤', '\x1b[90m'));
|
|
737
|
-
const hint = ' \x1b[90mTape \x1b[0m\x1b[1m\x1b[97m q \x1b[0m\x1b[90m + Entree pour cloture le partage et revenir au menu\x1b[0m';
|
|
738
|
-
console.log(rowS(hint, '\x1b[90m'));
|
|
739
|
-
console.log(hr('└', '─', '┘', '\x1b[90m'));
|
|
740
|
-
console.log('');
|
|
741
|
-
|
|
742
|
-
// Attend soit la fermeture du socket, soit que l'utilisateur tape 'q'
|
|
708
|
+
// Attend 'q' + Entree ou fermeture du socket
|
|
743
709
|
await new Promise((resolve) => {
|
|
744
|
-
// Fermeture côté serveur
|
|
745
710
|
relaySocket.on('close', () => resolve('closed'));
|
|
746
|
-
|
|
747
|
-
// Écoute clavier : 'q' + Entrée = clôture manuelle
|
|
748
711
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
749
712
|
const onLine = (line) => {
|
|
750
713
|
if (line.trim().toLowerCase() === 'q') {
|
|
@@ -753,21 +716,15 @@ async function shareFile(positionals, flags) {
|
|
|
753
716
|
}
|
|
754
717
|
};
|
|
755
718
|
rl.on('line', onLine);
|
|
756
|
-
// Nettoyer si le socket se ferme en premier
|
|
757
719
|
relaySocket.once('close', () => {
|
|
758
720
|
rl.removeListener('line', onLine);
|
|
759
|
-
rl.close();
|
|
721
|
+
try { rl.close(); } catch (_) {}
|
|
760
722
|
});
|
|
761
723
|
});
|
|
762
724
|
|
|
763
|
-
if (heartbeat) {
|
|
764
|
-
clearInterval(heartbeat);
|
|
765
|
-
heartbeat = null;
|
|
766
|
-
}
|
|
725
|
+
if (heartbeat) { clearInterval(heartbeat); heartbeat = null; }
|
|
767
726
|
await revokeCreatedShare();
|
|
768
|
-
for (const sig of stopSignals)
|
|
769
|
-
process.off(sig, stopRelayShare);
|
|
770
|
-
}
|
|
727
|
+
for (const sig of stopSignals) process.off(sig, stopRelayShare);
|
|
771
728
|
closeRelay();
|
|
772
729
|
return;
|
|
773
730
|
} catch (error) {
|
|
@@ -1198,7 +1155,8 @@ function strip(s) { return s.replace(/\x1b\[[0-9;]*m/g, ''); }
|
|
|
1198
1155
|
|
|
1199
1156
|
// ─── Panel interactif ────────────────────────────────────────────────────────
|
|
1200
1157
|
|
|
1201
|
-
const
|
|
1158
|
+
function getW() { const cols = process.stdout.columns || 80; return Math.min(90, Math.max(60, cols - 4)); }
|
|
1159
|
+
const W = getW();
|
|
1202
1160
|
|
|
1203
1161
|
function clearScreen() {
|
|
1204
1162
|
process.stdout.write('\x1Bc');
|
|
@@ -1209,7 +1167,7 @@ function hr(left = '├', mid = '─', right = '┤', color = C.gray) {
|
|
|
1209
1167
|
return c(color, `${left}${mid.repeat(W)}${right}`);
|
|
1210
1168
|
}
|
|
1211
1169
|
|
|
1212
|
-
// Ligne avec bordures latérales
|
|
1170
|
+
// Ligne avec bordures latérales
|
|
1213
1171
|
function row(content = '', color = C.gray) {
|
|
1214
1172
|
const vis = strip(content);
|
|
1215
1173
|
const pad = W - vis.length;
|
|
@@ -1223,6 +1181,99 @@ function rowCentered(content, color = C.gray) {
|
|
|
1223
1181
|
return row(' '.repeat(l) + content + ' '.repeat(r), color);
|
|
1224
1182
|
}
|
|
1225
1183
|
|
|
1184
|
+
// ── Écran de partage actif ────────────────────────────────────────────────────
|
|
1185
|
+
|
|
1186
|
+
function printShareActiveScreen(share, fileName, limits, temps) {
|
|
1187
|
+
const GRN = '\x1b[32m';
|
|
1188
|
+
const DGRN = '\x1b[90m';
|
|
1189
|
+
const WHT = '\x1b[97m';
|
|
1190
|
+
const BWHT = '\x1b[1m\x1b[97m';
|
|
1191
|
+
const CYN = '\x1b[36m';
|
|
1192
|
+
const RST = '\x1b[0m';
|
|
1193
|
+
|
|
1194
|
+
// Recalcule W au moment de l'affichage pour coller à la taille réelle du terminal
|
|
1195
|
+
const WW = getW();
|
|
1196
|
+
const LABEL_W = 10;
|
|
1197
|
+
const valW = WW - 2 - LABEL_W - 2; // espace dispo pour la valeur
|
|
1198
|
+
|
|
1199
|
+
// Ligne simple label + valeur (valeur tronquée si elle dépasse)
|
|
1200
|
+
const rowShare = (label, value, valColor, border = GRN) => {
|
|
1201
|
+
const lbl = ` ${DGRN}${label.padEnd(LABEL_W)}${RST}`;
|
|
1202
|
+
const v = value.length > valW ? value.slice(0, valW - 1) + '…' : value;
|
|
1203
|
+
const val = `${valColor}${v}${RST}`;
|
|
1204
|
+
const vis = strip(lbl + val);
|
|
1205
|
+
const pad = WW - vis.length;
|
|
1206
|
+
return `${border}│${RST}${lbl}${val}${' '.repeat(Math.max(0, pad))}${border}│${RST}`;
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
// Ligne URL sur 2 lignes si trop longue (jamais tronquée)
|
|
1210
|
+
const rowUrl = (label, value) => {
|
|
1211
|
+
const lines = [];
|
|
1212
|
+
const lbl = ` ${DGRN}${label.padEnd(LABEL_W)}${RST}`;
|
|
1213
|
+
const lblVis = strip(lbl);
|
|
1214
|
+
const available = WW - lblVis.length; // espace pour la valeur sur la 1ère ligne
|
|
1215
|
+
const available2 = WW - 2; // espace pour la continuation (indentée)
|
|
1216
|
+
|
|
1217
|
+
if (value.length <= available) {
|
|
1218
|
+
// Rentre sur une seule ligne
|
|
1219
|
+
const val = `${BWHT}${value}${RST}`;
|
|
1220
|
+
const vis = strip(lbl + val);
|
|
1221
|
+
const pad = WW - vis.length;
|
|
1222
|
+
lines.push(`${GRN}│${RST}${lbl}${val}${' '.repeat(Math.max(0, pad))}${GRN}│${RST}`);
|
|
1223
|
+
} else {
|
|
1224
|
+
// Première ligne : label + début de l'URL
|
|
1225
|
+
const part1 = value.slice(0, available);
|
|
1226
|
+
const val1 = `${BWHT}${part1}${RST}`;
|
|
1227
|
+
const vis1 = strip(lbl + val1);
|
|
1228
|
+
lines.push(`${GRN}│${RST}${lbl}${val1}${' '.repeat(Math.max(0, WW - vis1.length))}${GRN}│${RST}`);
|
|
1229
|
+
// Deuxième ligne : suite de l'URL indentée sous la valeur
|
|
1230
|
+
const indent = ' '.repeat(lblVis.length);
|
|
1231
|
+
let rest = value.slice(available);
|
|
1232
|
+
while (rest.length > 0) {
|
|
1233
|
+
const chunk = rest.slice(0, available2 - lblVis.length);
|
|
1234
|
+
rest = rest.slice(chunk.length);
|
|
1235
|
+
const val2 = `${BWHT}${chunk}${RST}`;
|
|
1236
|
+
const vis2 = strip(indent + val2);
|
|
1237
|
+
lines.push(`${GRN}│${RST}${indent}${val2}${' '.repeat(Math.max(0, WW - vis2.length))}${GRN}│${RST}`);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
return lines.join('\n');
|
|
1241
|
+
};
|
|
1242
|
+
|
|
1243
|
+
const dlLabel = limits && limits > 0 ? `${limits} telechargement(s)` : 'illimite';
|
|
1244
|
+
const expLabel = temps && temps > 0 ? `dans ${temps} jour(s)` : 'jamais';
|
|
1245
|
+
|
|
1246
|
+
clearScreen();
|
|
1247
|
+
console.log('');
|
|
1248
|
+
|
|
1249
|
+
// ── Titre ─────────────────────────────────────────────────────────────────
|
|
1250
|
+
console.log(`${GRN}┌${'─'.repeat(WW)}┐${RST}`);
|
|
1251
|
+
const badge = `${GRN}▸${RST} ${BWHT}PARTAGE ACTIF${RST}`;
|
|
1252
|
+
const badgeVis = strip(badge);
|
|
1253
|
+
const bL = Math.floor((WW - badgeVis.length) / 2);
|
|
1254
|
+
const bR = WW - badgeVis.length - bL;
|
|
1255
|
+
console.log(`${GRN}│${RST}${' '.repeat(bL)}${badge}${' '.repeat(bR)}${GRN}│${RST}`);
|
|
1256
|
+
console.log(`${GRN}├${'─'.repeat(WW)}┤${RST}`);
|
|
1257
|
+
|
|
1258
|
+
// ── Infos ─────────────────────────────────────────────────────────────────
|
|
1259
|
+
console.log(`${GRN}│${RST}${' '.repeat(WW)}${GRN}│${RST}`);
|
|
1260
|
+
if (share.url) console.log(rowUrl('URL', share.url));
|
|
1261
|
+
if (share.token) console.log(rowShare('Token', share.token, CYN));
|
|
1262
|
+
console.log(rowShare('Fichier', fileName, WHT));
|
|
1263
|
+
console.log(rowShare('Limite', dlLabel, WHT));
|
|
1264
|
+
console.log(rowShare('Expire', expLabel, WHT));
|
|
1265
|
+
console.log(`${GRN}│${RST}${' '.repeat(WW)}${GRN}│${RST}`);
|
|
1266
|
+
|
|
1267
|
+
// ── Footer ────────────────────────────────────────────────────────────────
|
|
1268
|
+
console.log(`${DGRN}├${'─'.repeat(WW)}┤${RST}`);
|
|
1269
|
+
const hint = ` Tape ${BWHT}q${RST}${DGRN} + Entree pour cloture et revenir au menu${RST}`;
|
|
1270
|
+
const hintVis = strip(hint);
|
|
1271
|
+
const hPad = WW - hintVis.length;
|
|
1272
|
+
console.log(`${DGRN}│${RST}${hint}${' '.repeat(Math.max(0, hPad))}${DGRN}│${RST}`);
|
|
1273
|
+
console.log(`${DGRN}└${'─'.repeat(WW)}┘${RST}`);
|
|
1274
|
+
console.log('');
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1226
1277
|
function printPanel(username, plan, statusMsg) {
|
|
1227
1278
|
const now = new Date();
|
|
1228
1279
|
const timeStr = now.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' });
|
|
@@ -1332,24 +1383,26 @@ async function panelShare() {
|
|
|
1332
1383
|
if (parseInt(limits, 10) > 0) flags.limits = limits;
|
|
1333
1384
|
if (parseInt(temps, 10) > 0) flags.temps = temps;
|
|
1334
1385
|
|
|
1386
|
+
// Écran de chargement pendant la connexion au relay
|
|
1335
1387
|
clearScreen();
|
|
1336
|
-
printSubHeader('
|
|
1337
|
-
console.log(` ${c(C.gray, '
|
|
1388
|
+
printSubHeader('Connexion au relay...');
|
|
1389
|
+
console.log(` ${c(C.gray, 'Initialisation du partage, patiente...')}\n`);
|
|
1338
1390
|
|
|
1339
1391
|
try {
|
|
1340
1392
|
await shareFile([target], flags);
|
|
1341
|
-
//
|
|
1342
|
-
|
|
1393
|
+
// Retour au menu : shareFile a déjà révoqué et fermé
|
|
1394
|
+
clearScreen();
|
|
1395
|
+
printSubHeader('Partager un fichier');
|
|
1396
|
+
printSuccess('Partage cloture avec succes.');
|
|
1343
1397
|
} catch (err) {
|
|
1398
|
+
clearScreen();
|
|
1399
|
+
printSubHeader('Partager un fichier');
|
|
1344
1400
|
if (err?.data?.code === 'PLAN_FILE_LIMIT_EXCEEDED') {
|
|
1345
1401
|
printPlanLimitBox(err);
|
|
1346
1402
|
} else {
|
|
1347
1403
|
printError(err.message);
|
|
1348
1404
|
}
|
|
1349
|
-
await pressEnter();
|
|
1350
|
-
return;
|
|
1351
1405
|
}
|
|
1352
|
-
|
|
1353
1406
|
await pressEnter();
|
|
1354
1407
|
}
|
|
1355
1408
|
|