pinggy 0.4.5 → 0.4.6
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/dist/{chunk-HUN2MRZO.js → chunk-3RTRUYNW.js} +3 -1
- package/dist/{chunk-MBN3YBO4.js → chunk-STEISST3.js} +203 -41
- package/dist/index.cjs +339 -90
- package/dist/index.d.cts +20 -11
- package/dist/index.d.ts +20 -11
- package/dist/index.js +10 -7
- package/dist/{main-2RDHMQT7.js → main-XKFFUSKJ.js} +130 -46
- package/dist/workers/file_serve_worker.js +1 -1
- package/package.json +3 -2
package/dist/index.d.cts
CHANGED
|
@@ -589,15 +589,15 @@ interface TunnelResponseV2 {
|
|
|
589
589
|
greetmsg?: string;
|
|
590
590
|
}
|
|
591
591
|
interface TunnelHandler {
|
|
592
|
-
handleStart(config: TunnelConfig): Promise<TunnelResponse | ErrorResponse>;
|
|
593
|
-
handleStartV2(config: TunnelConfigV1): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
594
|
-
handleUpdateConfig(config: TunnelConfig): Promise<TunnelResponse | ErrorResponse>;
|
|
595
|
-
handleUpdateConfigV2(config: TunnelConfigV1): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
592
|
+
handleStart(config: TunnelConfig, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
593
|
+
handleStartV2(config: TunnelConfigV1, noWait?: boolean): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
594
|
+
handleUpdateConfig(config: TunnelConfig, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
595
|
+
handleUpdateConfigV2(config: TunnelConfigV1, noWait?: boolean): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
596
596
|
handleList(): Promise<TunnelResponse[] | ErrorResponse>;
|
|
597
597
|
handleListV2(): Promise<TunnelResponseV2[] | ErrorResponse>;
|
|
598
598
|
handleStop(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
599
599
|
handleGet(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
600
|
-
handleRestart(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
600
|
+
handleRestart(tunnelid: string, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
601
601
|
handleRegisterStatsListener(tunnelid: string, listener: (tunnelId: string, stats: TunnelUsageType) => void): void;
|
|
602
602
|
handleUnregisterStatsListener(tunnelid: string, listnerId: string): void;
|
|
603
603
|
handleGetTunnelStats(tunnelid: string): TunnelUsageType[] | ErrorResponse;
|
|
@@ -609,18 +609,20 @@ declare class TunnelOperations implements TunnelHandler {
|
|
|
609
609
|
private tunnelManager;
|
|
610
610
|
constructor();
|
|
611
611
|
private buildStatus;
|
|
612
|
+
private buildPendingTunnelResponse;
|
|
613
|
+
private buildPendingTunnelResponseV2;
|
|
612
614
|
private buildTunnelResponse;
|
|
613
615
|
private buildTunnelResponseV2;
|
|
614
616
|
private error;
|
|
615
|
-
handleStart(config: TunnelConfig): Promise<TunnelResponse | ErrorResponse>;
|
|
616
|
-
handleStartV2(config: TunnelConfigV1): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
617
|
-
handleUpdateConfig(config: TunnelConfig): Promise<TunnelResponse | ErrorResponse>;
|
|
618
|
-
handleUpdateConfigV2(config: TunnelConfigV1): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
617
|
+
handleStart(config: TunnelConfig, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
618
|
+
handleStartV2(config: TunnelConfigV1, noWait?: boolean): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
619
|
+
handleUpdateConfig(config: TunnelConfig, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
620
|
+
handleUpdateConfigV2(config: TunnelConfigV1, noWait?: boolean): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
619
621
|
handleListV2(): Promise<TunnelResponseV2[] | ErrorResponse>;
|
|
620
622
|
handleList(): Promise<TunnelResponse[] | ErrorResponse>;
|
|
621
623
|
handleStop(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
622
624
|
handleGet(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
623
|
-
handleRestart(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
625
|
+
handleRestart(tunnelid: string, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
624
626
|
handleRegisterStatsListener(tunnelid: string, listener: (tunnelId: string, stats: TunnelUsageType) => void): void;
|
|
625
627
|
handleUnregisterStatsListener(tunnelid: string, listnerId: string): void;
|
|
626
628
|
handleGetTunnelStats(tunnelid: string): TunnelUsageType[] | ErrorResponse;
|
|
@@ -640,6 +642,9 @@ interface BaseLogConfig {
|
|
|
640
642
|
type BaseLogConfigType = BaseLogConfig;
|
|
641
643
|
declare function enablePackageLogging(opts?: BaseLogConfigType): winston.Logger;
|
|
642
644
|
|
|
645
|
+
declare class RemoteManagementUnauthorizedError extends Error {
|
|
646
|
+
constructor();
|
|
647
|
+
}
|
|
643
648
|
/**
|
|
644
649
|
* Initiate remote management mode with a WebSocket connection.
|
|
645
650
|
* - Connect with Authorization: Bearer <token>
|
|
@@ -649,6 +654,10 @@ declare function enablePackageLogging(opts?: BaseLogConfigType): winston.Logger;
|
|
|
649
654
|
*/
|
|
650
655
|
declare function initiateRemoteManagement(remoteManagementConfig: RemoteManagementConfig): Promise<RemoteManagementState>;
|
|
651
656
|
declare function closeRemoteManagement(timeoutMs?: number): Promise<RemoteManagementState>;
|
|
657
|
+
/**
|
|
658
|
+
* Start remote management loop in background; returns after first connection attempt.
|
|
659
|
+
*/
|
|
660
|
+
declare function startRemoteManagement(remoteManagementConfig: RemoteManagementConfig): Promise<RemoteManagementState>;
|
|
652
661
|
declare function getRemoteManagementState(): RemoteManagementState;
|
|
653
662
|
|
|
654
|
-
export { type AdditionalForwarding, type DisconnectListener, type ErrorListener, type FinalConfig, type ITunnelManager, type ManagedTunnel, type ReconnectingListener, type ReconnectionCompletedListener, type ReconnectionFailedListener, type StartListener, type StatsListener, type Status, TunnelErrorCodeType, type TunnelList, TunnelManager, TunnelOperations, type TunnelResponse, TunnelStateType, type TunnelStatus, TunnelWarningCode, type TunnelWorkerErrorListner, type Warning, type WillReconnectListener, closeRemoteManagement, enablePackageLogging, getRemoteManagementState, initiateRemoteManagement };
|
|
663
|
+
export { type AdditionalForwarding, type DisconnectListener, type ErrorListener, type FinalConfig, type ITunnelManager, type ManagedTunnel, type ReconnectingListener, type ReconnectionCompletedListener, type ReconnectionFailedListener, RemoteManagementUnauthorizedError, type StartListener, type StatsListener, type Status, TunnelErrorCodeType, type TunnelList, TunnelManager, TunnelOperations, type TunnelResponse, TunnelStateType, type TunnelStatus, TunnelWarningCode, type TunnelWorkerErrorListner, type Warning, type WillReconnectListener, closeRemoteManagement, enablePackageLogging, getRemoteManagementState, initiateRemoteManagement, startRemoteManagement };
|
package/dist/index.d.ts
CHANGED
|
@@ -589,15 +589,15 @@ interface TunnelResponseV2 {
|
|
|
589
589
|
greetmsg?: string;
|
|
590
590
|
}
|
|
591
591
|
interface TunnelHandler {
|
|
592
|
-
handleStart(config: TunnelConfig): Promise<TunnelResponse | ErrorResponse>;
|
|
593
|
-
handleStartV2(config: TunnelConfigV1): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
594
|
-
handleUpdateConfig(config: TunnelConfig): Promise<TunnelResponse | ErrorResponse>;
|
|
595
|
-
handleUpdateConfigV2(config: TunnelConfigV1): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
592
|
+
handleStart(config: TunnelConfig, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
593
|
+
handleStartV2(config: TunnelConfigV1, noWait?: boolean): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
594
|
+
handleUpdateConfig(config: TunnelConfig, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
595
|
+
handleUpdateConfigV2(config: TunnelConfigV1, noWait?: boolean): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
596
596
|
handleList(): Promise<TunnelResponse[] | ErrorResponse>;
|
|
597
597
|
handleListV2(): Promise<TunnelResponseV2[] | ErrorResponse>;
|
|
598
598
|
handleStop(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
599
599
|
handleGet(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
600
|
-
handleRestart(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
600
|
+
handleRestart(tunnelid: string, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
601
601
|
handleRegisterStatsListener(tunnelid: string, listener: (tunnelId: string, stats: TunnelUsageType) => void): void;
|
|
602
602
|
handleUnregisterStatsListener(tunnelid: string, listnerId: string): void;
|
|
603
603
|
handleGetTunnelStats(tunnelid: string): TunnelUsageType[] | ErrorResponse;
|
|
@@ -609,18 +609,20 @@ declare class TunnelOperations implements TunnelHandler {
|
|
|
609
609
|
private tunnelManager;
|
|
610
610
|
constructor();
|
|
611
611
|
private buildStatus;
|
|
612
|
+
private buildPendingTunnelResponse;
|
|
613
|
+
private buildPendingTunnelResponseV2;
|
|
612
614
|
private buildTunnelResponse;
|
|
613
615
|
private buildTunnelResponseV2;
|
|
614
616
|
private error;
|
|
615
|
-
handleStart(config: TunnelConfig): Promise<TunnelResponse | ErrorResponse>;
|
|
616
|
-
handleStartV2(config: TunnelConfigV1): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
617
|
-
handleUpdateConfig(config: TunnelConfig): Promise<TunnelResponse | ErrorResponse>;
|
|
618
|
-
handleUpdateConfigV2(config: TunnelConfigV1): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
617
|
+
handleStart(config: TunnelConfig, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
618
|
+
handleStartV2(config: TunnelConfigV1, noWait?: boolean): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
619
|
+
handleUpdateConfig(config: TunnelConfig, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
620
|
+
handleUpdateConfigV2(config: TunnelConfigV1, noWait?: boolean): Promise<TunnelResponseV2 | ErrorResponse>;
|
|
619
621
|
handleListV2(): Promise<TunnelResponseV2[] | ErrorResponse>;
|
|
620
622
|
handleList(): Promise<TunnelResponse[] | ErrorResponse>;
|
|
621
623
|
handleStop(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
622
624
|
handleGet(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
623
|
-
handleRestart(tunnelid: string): Promise<TunnelResponse | ErrorResponse>;
|
|
625
|
+
handleRestart(tunnelid: string, noWait?: boolean): Promise<TunnelResponse | ErrorResponse>;
|
|
624
626
|
handleRegisterStatsListener(tunnelid: string, listener: (tunnelId: string, stats: TunnelUsageType) => void): void;
|
|
625
627
|
handleUnregisterStatsListener(tunnelid: string, listnerId: string): void;
|
|
626
628
|
handleGetTunnelStats(tunnelid: string): TunnelUsageType[] | ErrorResponse;
|
|
@@ -640,6 +642,9 @@ interface BaseLogConfig {
|
|
|
640
642
|
type BaseLogConfigType = BaseLogConfig;
|
|
641
643
|
declare function enablePackageLogging(opts?: BaseLogConfigType): winston.Logger;
|
|
642
644
|
|
|
645
|
+
declare class RemoteManagementUnauthorizedError extends Error {
|
|
646
|
+
constructor();
|
|
647
|
+
}
|
|
643
648
|
/**
|
|
644
649
|
* Initiate remote management mode with a WebSocket connection.
|
|
645
650
|
* - Connect with Authorization: Bearer <token>
|
|
@@ -649,6 +654,10 @@ declare function enablePackageLogging(opts?: BaseLogConfigType): winston.Logger;
|
|
|
649
654
|
*/
|
|
650
655
|
declare function initiateRemoteManagement(remoteManagementConfig: RemoteManagementConfig): Promise<RemoteManagementState>;
|
|
651
656
|
declare function closeRemoteManagement(timeoutMs?: number): Promise<RemoteManagementState>;
|
|
657
|
+
/**
|
|
658
|
+
* Start remote management loop in background; returns after first connection attempt.
|
|
659
|
+
*/
|
|
660
|
+
declare function startRemoteManagement(remoteManagementConfig: RemoteManagementConfig): Promise<RemoteManagementState>;
|
|
652
661
|
declare function getRemoteManagementState(): RemoteManagementState;
|
|
653
662
|
|
|
654
|
-
export { type AdditionalForwarding, type DisconnectListener, type ErrorListener, type FinalConfig, type ITunnelManager, type ManagedTunnel, type ReconnectingListener, type ReconnectionCompletedListener, type ReconnectionFailedListener, type StartListener, type StatsListener, type Status, TunnelErrorCodeType, type TunnelList, TunnelManager, TunnelOperations, type TunnelResponse, TunnelStateType, type TunnelStatus, TunnelWarningCode, type TunnelWorkerErrorListner, type Warning, type WillReconnectListener, closeRemoteManagement, enablePackageLogging, getRemoteManagementState, initiateRemoteManagement };
|
|
663
|
+
export { type AdditionalForwarding, type DisconnectListener, type ErrorListener, type FinalConfig, type ITunnelManager, type ManagedTunnel, type ReconnectingListener, type ReconnectionCompletedListener, type ReconnectionFailedListener, RemoteManagementUnauthorizedError, type StartListener, type StatsListener, type Status, TunnelErrorCodeType, type TunnelList, TunnelManager, TunnelOperations, type TunnelResponse, TunnelStateType, type TunnelStatus, TunnelWarningCode, type TunnelWorkerErrorListner, type Warning, type WillReconnectListener, closeRemoteManagement, enablePackageLogging, getRemoteManagementState, initiateRemoteManagement, startRemoteManagement };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
RemoteManagementUnauthorizedError,
|
|
3
4
|
TunnelErrorCodeType,
|
|
4
5
|
TunnelManager,
|
|
5
6
|
TunnelOperations,
|
|
@@ -8,11 +9,12 @@ import {
|
|
|
8
9
|
closeRemoteManagement,
|
|
9
10
|
getRemoteManagementState,
|
|
10
11
|
initiateRemoteManagement,
|
|
11
|
-
printer_default
|
|
12
|
-
|
|
12
|
+
printer_default,
|
|
13
|
+
startRemoteManagement
|
|
14
|
+
} from "./chunk-STEISST3.js";
|
|
13
15
|
import {
|
|
14
16
|
enablePackageLogging
|
|
15
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-3RTRUYNW.js";
|
|
16
18
|
|
|
17
19
|
// src/utils/detect_vc_redist_on_windows.ts
|
|
18
20
|
import fs from "fs";
|
|
@@ -104,13 +106,13 @@ async function verifyAndLoad() {
|
|
|
104
106
|
process.exit(1);
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
|
-
await import("./main-
|
|
109
|
+
await import("./main-XKFFUSKJ.js");
|
|
108
110
|
}
|
|
109
111
|
verifyAndLoad().catch((err) => {
|
|
110
|
-
printer_default.
|
|
111
|
-
process.exit(1);
|
|
112
|
+
printer_default.fatal(`Failed to start CLI:, ${err}`);
|
|
112
113
|
});
|
|
113
114
|
export {
|
|
115
|
+
RemoteManagementUnauthorizedError,
|
|
114
116
|
TunnelErrorCodeType,
|
|
115
117
|
TunnelManager,
|
|
116
118
|
TunnelOperations,
|
|
@@ -119,5 +121,6 @@ export {
|
|
|
119
121
|
closeRemoteManagement,
|
|
120
122
|
enablePackageLogging,
|
|
121
123
|
getRemoteManagementState,
|
|
122
|
-
initiateRemoteManagement
|
|
124
|
+
initiateRemoteManagement,
|
|
125
|
+
startRemoteManagement
|
|
123
126
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
RemoteManagementUnauthorizedError,
|
|
3
4
|
TunnelManager,
|
|
4
5
|
TunnelOperations,
|
|
5
6
|
closeRemoteManagement,
|
|
@@ -10,12 +11,12 @@ import {
|
|
|
10
11
|
isValidPort,
|
|
11
12
|
parseRemoteManagement,
|
|
12
13
|
printer_default
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-STEISST3.js";
|
|
14
15
|
import {
|
|
15
16
|
configureLogger,
|
|
16
17
|
enablePackageLogging,
|
|
17
18
|
logger
|
|
18
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-3RTRUYNW.js";
|
|
19
20
|
|
|
20
21
|
// src/cli/options.ts
|
|
21
22
|
var cliOptions = {
|
|
@@ -264,7 +265,9 @@ function removeIPv6Brackets(ip) {
|
|
|
264
265
|
}
|
|
265
266
|
function isValidServerAddress(host) {
|
|
266
267
|
const normalized = removeIPv6Brackets(host.trim());
|
|
267
|
-
if (!normalized)
|
|
268
|
+
if (!normalized) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
268
271
|
return domainRegex.test(normalized) || isIP2(normalized) !== 0;
|
|
269
272
|
}
|
|
270
273
|
var KEYWORDS = /* @__PURE__ */ new Set([
|
|
@@ -285,7 +288,9 @@ function parseUserAndDomain(str) {
|
|
|
285
288
|
let server;
|
|
286
289
|
let qrCode;
|
|
287
290
|
let forceFlag;
|
|
288
|
-
if (!str)
|
|
291
|
+
if (!str) {
|
|
292
|
+
return { token, type, server, qrCode, forceFlag };
|
|
293
|
+
}
|
|
289
294
|
if (str.includes("@")) {
|
|
290
295
|
const [user, domain] = str.split("@", 2);
|
|
291
296
|
if (isValidServerAddress(domain)) {
|
|
@@ -338,21 +343,39 @@ function parseUsers(positionalArgs, explicitToken) {
|
|
|
338
343
|
let remaining = [...positionalArgs];
|
|
339
344
|
if (typeof explicitToken === "string") {
|
|
340
345
|
const parsed = parseUserAndDomain(explicitToken);
|
|
341
|
-
if (parsed.server)
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
if (parsed.
|
|
345
|
-
|
|
346
|
+
if (parsed.server) {
|
|
347
|
+
server = parsed.server;
|
|
348
|
+
}
|
|
349
|
+
if (parsed.type) {
|
|
350
|
+
type = parsed.type;
|
|
351
|
+
}
|
|
352
|
+
if (parsed.token) {
|
|
353
|
+
token = parsed.token;
|
|
354
|
+
}
|
|
355
|
+
if (parsed.forceFlag) {
|
|
356
|
+
forceFlag = true;
|
|
357
|
+
}
|
|
358
|
+
if (parsed.qrCode) {
|
|
359
|
+
qrCode = true;
|
|
360
|
+
}
|
|
346
361
|
}
|
|
347
362
|
if (remaining.length > 0) {
|
|
348
363
|
const first = remaining[0];
|
|
349
364
|
const parsed = parseUserAndDomain(first);
|
|
350
365
|
if (parsed.server) {
|
|
351
366
|
server = parsed.server;
|
|
352
|
-
if (parsed.type)
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if (parsed.
|
|
367
|
+
if (parsed.type) {
|
|
368
|
+
type = parsed.type;
|
|
369
|
+
}
|
|
370
|
+
if (parsed.token) {
|
|
371
|
+
token = parsed.token;
|
|
372
|
+
}
|
|
373
|
+
if (parsed.forceFlag) {
|
|
374
|
+
forceFlag = true;
|
|
375
|
+
}
|
|
376
|
+
if (parsed.qrCode) {
|
|
377
|
+
qrCode = true;
|
|
378
|
+
}
|
|
356
379
|
remaining = remaining.slice(1);
|
|
357
380
|
}
|
|
358
381
|
}
|
|
@@ -365,7 +388,9 @@ function parseType(finalConfig, values, inferredType) {
|
|
|
365
388
|
}
|
|
366
389
|
}
|
|
367
390
|
function parseLocalPort(finalConfig, values) {
|
|
368
|
-
if (typeof values.localport !== "string")
|
|
391
|
+
if (typeof values.localport !== "string") {
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
369
394
|
let lp = values.localport.trim();
|
|
370
395
|
let isHttps = false;
|
|
371
396
|
if (lp.startsWith("https://")) {
|
|
@@ -397,7 +422,9 @@ function parseLocalPort(finalConfig, values) {
|
|
|
397
422
|
}
|
|
398
423
|
function isValidHostAddress(host) {
|
|
399
424
|
const normalized = removeIPv6Brackets(host.trim());
|
|
400
|
-
if (normalized.length === 0)
|
|
425
|
+
if (normalized.length === 0) {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
401
428
|
return normalized === "localhost" || isIP2(normalized) !== 0;
|
|
402
429
|
}
|
|
403
430
|
function ipv6SafeSplitColon(s) {
|
|
@@ -441,7 +468,9 @@ function parseDefaultForwarding(forwarding) {
|
|
|
441
468
|
}
|
|
442
469
|
function parseAdditionalForwarding(forwarding) {
|
|
443
470
|
const toPort = (v) => {
|
|
444
|
-
if (!v)
|
|
471
|
+
if (!v) {
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
445
474
|
const n = parseInt(v, 10);
|
|
446
475
|
return Number.isNaN(n) ? null : n;
|
|
447
476
|
};
|
|
@@ -520,7 +549,9 @@ function parseReverseTunnelAddr(finalConfig, values, primaryType) {
|
|
|
520
549
|
});
|
|
521
550
|
} else if (slicedForwarding.length === 4) {
|
|
522
551
|
const parsed = parseAdditionalForwarding(forwarding);
|
|
523
|
-
if (parsed instanceof Error)
|
|
552
|
+
if (parsed instanceof Error) {
|
|
553
|
+
return parsed;
|
|
554
|
+
}
|
|
524
555
|
forwardingData.push(parsed);
|
|
525
556
|
} else {
|
|
526
557
|
return new Error(
|
|
@@ -532,7 +563,9 @@ function parseReverseTunnelAddr(finalConfig, values, primaryType) {
|
|
|
532
563
|
return null;
|
|
533
564
|
}
|
|
534
565
|
function parseLocalTunnelAddr(finalConfig, values) {
|
|
535
|
-
if (!Array.isArray(values.L) || values.L.length === 0)
|
|
566
|
+
if (!Array.isArray(values.L) || values.L.length === 0) {
|
|
567
|
+
return null;
|
|
568
|
+
}
|
|
536
569
|
const firstL = values.L[0];
|
|
537
570
|
const parts = ipv6SafeSplitColon(firstL);
|
|
538
571
|
let debuggerHost = "localhost";
|
|
@@ -556,7 +589,9 @@ function parseLocalTunnelAddr(finalConfig, values) {
|
|
|
556
589
|
}
|
|
557
590
|
function parseDebugger(finalConfig, values) {
|
|
558
591
|
let dbg = values.debugger;
|
|
559
|
-
if (typeof dbg !== "string")
|
|
592
|
+
if (typeof dbg !== "string") {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
560
595
|
dbg = dbg.startsWith(":") ? dbg.slice(1) : dbg;
|
|
561
596
|
const d = parseInt(dbg, 10);
|
|
562
597
|
if (!Number.isNaN(d) && isValidPort(d)) {
|
|
@@ -615,7 +650,9 @@ function isSaveConfOption(values) {
|
|
|
615
650
|
}
|
|
616
651
|
function parseServe(finalConfig, values) {
|
|
617
652
|
const sv = values.serve;
|
|
618
|
-
if (typeof sv !== "string" || sv.trim().length === 0)
|
|
653
|
+
if (typeof sv !== "string" || sv.trim().length === 0) {
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
619
656
|
finalConfig.optional.serve = sv;
|
|
620
657
|
return null;
|
|
621
658
|
}
|
|
@@ -667,18 +704,32 @@ async function buildFinalConfig(values, positionals) {
|
|
|
667
704
|
type = parseType(finalConfig, values, type);
|
|
668
705
|
parseToken(finalConfig, token || values.token);
|
|
669
706
|
const dbgErr = parseDebugger(finalConfig, values);
|
|
670
|
-
if (dbgErr instanceof Error)
|
|
707
|
+
if (dbgErr instanceof Error) {
|
|
708
|
+
throw dbgErr;
|
|
709
|
+
}
|
|
671
710
|
const lpErr = parseLocalPort(finalConfig, values);
|
|
672
|
-
if (lpErr instanceof Error)
|
|
711
|
+
if (lpErr instanceof Error) {
|
|
712
|
+
throw lpErr;
|
|
713
|
+
}
|
|
673
714
|
const rErr = parseReverseTunnelAddr(finalConfig, values, type);
|
|
674
|
-
if (rErr instanceof Error)
|
|
715
|
+
if (rErr instanceof Error) {
|
|
716
|
+
throw rErr;
|
|
717
|
+
}
|
|
675
718
|
const lErr = parseLocalTunnelAddr(finalConfig, values);
|
|
676
|
-
if (lErr instanceof Error)
|
|
719
|
+
if (lErr instanceof Error) {
|
|
720
|
+
throw lErr;
|
|
721
|
+
}
|
|
677
722
|
const serveErr = parseServe(finalConfig, values);
|
|
678
|
-
if (serveErr instanceof Error)
|
|
723
|
+
if (serveErr instanceof Error) {
|
|
724
|
+
throw serveErr;
|
|
725
|
+
}
|
|
679
726
|
const autoReconnectErr = parseAutoReconnect(finalConfig, values);
|
|
680
|
-
if (autoReconnectErr instanceof Error)
|
|
681
|
-
|
|
727
|
+
if (autoReconnectErr instanceof Error) {
|
|
728
|
+
throw autoReconnectErr;
|
|
729
|
+
}
|
|
730
|
+
if (forceFlag || values.force) {
|
|
731
|
+
finalConfig.force = true;
|
|
732
|
+
}
|
|
682
733
|
parseArgs(finalConfig, remainingPositionals);
|
|
683
734
|
storeJson(finalConfig, saveconf);
|
|
684
735
|
return finalConfig;
|
|
@@ -691,15 +742,26 @@ function isAttachedReverseOrLocalFlag(arg) {
|
|
|
691
742
|
return /^-[RL].+/.test(arg);
|
|
692
743
|
}
|
|
693
744
|
function shouldMergeReverseOrLocalFragment(current, next) {
|
|
694
|
-
if (next.startsWith("-"))
|
|
695
|
-
|
|
745
|
+
if (next.startsWith("-")) {
|
|
746
|
+
return false;
|
|
747
|
+
}
|
|
748
|
+
if (next.startsWith(".")) {
|
|
749
|
+
return true;
|
|
750
|
+
}
|
|
696
751
|
const body = current.slice(2);
|
|
697
|
-
if (body.endsWith(":"))
|
|
698
|
-
|
|
752
|
+
if (body.endsWith(":")) {
|
|
753
|
+
return true;
|
|
754
|
+
}
|
|
755
|
+
if (body.includes("//") && !body.includes(":")) {
|
|
756
|
+
return true;
|
|
757
|
+
}
|
|
699
758
|
return false;
|
|
700
759
|
}
|
|
701
760
|
function preprocessWindowsArgs(args) {
|
|
702
|
-
if (os.platform() !== "win32")
|
|
761
|
+
if (os.platform() !== "win32") {
|
|
762
|
+
return args;
|
|
763
|
+
}
|
|
764
|
+
;
|
|
703
765
|
const out = [];
|
|
704
766
|
let i = 0;
|
|
705
767
|
while (i < args.length) {
|
|
@@ -777,13 +839,12 @@ import QRCode from "qrcode";
|
|
|
777
839
|
async function createQrCodes(urls) {
|
|
778
840
|
const codes = [];
|
|
779
841
|
for (const url of urls) {
|
|
780
|
-
const
|
|
781
|
-
type: "
|
|
782
|
-
|
|
783
|
-
margin: 0,
|
|
842
|
+
const raw = await QRCode.toString(url, {
|
|
843
|
+
type: "utf8",
|
|
844
|
+
margin: 2,
|
|
784
845
|
errorCorrectionLevel: "L"
|
|
785
846
|
});
|
|
786
|
-
codes.push(
|
|
847
|
+
codes.push(raw);
|
|
787
848
|
}
|
|
788
849
|
return codes;
|
|
789
850
|
}
|
|
@@ -795,6 +856,7 @@ import WebSocket from "ws";
|
|
|
795
856
|
var defaultTuiConfig = {
|
|
796
857
|
maxRequestPairs: 100,
|
|
797
858
|
visibleRequestCount: 10,
|
|
859
|
+
visibleUrlCount: 7,
|
|
798
860
|
viewportScrollMargin: 2,
|
|
799
861
|
inactivityHttpSelectorTimeoutMs: 1e4
|
|
800
862
|
};
|
|
@@ -802,6 +864,7 @@ function getTuiConfig() {
|
|
|
802
864
|
return {
|
|
803
865
|
maxRequestPairs: defaultTuiConfig.maxRequestPairs,
|
|
804
866
|
visibleRequestCount: defaultTuiConfig.visibleRequestCount,
|
|
867
|
+
visibleUrlCount: defaultTuiConfig.visibleUrlCount,
|
|
805
868
|
viewportScrollMargin: defaultTuiConfig.viewportScrollMargin,
|
|
806
869
|
inactivityHttpSelectorTimeoutMs: defaultTuiConfig.inactivityHttpSelectorTimeoutMs
|
|
807
870
|
};
|
|
@@ -1029,7 +1092,7 @@ function createFullUI(screen, urls, greet, tunnelConfig) {
|
|
|
1029
1092
|
width: "100%-2",
|
|
1030
1093
|
height: `100%-${lowerSectionTop + 6}`
|
|
1031
1094
|
});
|
|
1032
|
-
const isQrCodeRequested = tunnelConfig?.
|
|
1095
|
+
const isQrCodeRequested = tunnelConfig?.isQRCode || false;
|
|
1033
1096
|
const requestsBox = blessed.box({
|
|
1034
1097
|
parent: lowerSection,
|
|
1035
1098
|
top: 0,
|
|
@@ -1172,8 +1235,24 @@ function getBytesInt(b) {
|
|
|
1172
1235
|
// src/tui/blessed/components/DisplayUpdaters.ts
|
|
1173
1236
|
function updateUrlsDisplay(urlsBox, screen, urls, currentQrIndex) {
|
|
1174
1237
|
if (!urlsBox) return;
|
|
1175
|
-
|
|
1176
|
-
|
|
1238
|
+
const config = getTuiConfig();
|
|
1239
|
+
const { visibleUrlCount } = config;
|
|
1240
|
+
let viewportStart = 0;
|
|
1241
|
+
if (urls.length > visibleUrlCount) {
|
|
1242
|
+
viewportStart = Math.max(0, Math.min(
|
|
1243
|
+
currentQrIndex - Math.floor(visibleUrlCount / 2),
|
|
1244
|
+
urls.length - visibleUrlCount
|
|
1245
|
+
));
|
|
1246
|
+
}
|
|
1247
|
+
const viewportEnd = Math.min(viewportStart + visibleUrlCount, urls.length);
|
|
1248
|
+
const visibleUrls = urls.slice(viewportStart, viewportEnd);
|
|
1249
|
+
let content = "{green-fg}{bold}Public URLs{/bold}{/green-fg}";
|
|
1250
|
+
if (viewportStart > 0) {
|
|
1251
|
+
content += ` {gray-fg}\u2191 ${viewportStart} more{/gray-fg}`;
|
|
1252
|
+
}
|
|
1253
|
+
content += "\n";
|
|
1254
|
+
visibleUrls.forEach((url, i) => {
|
|
1255
|
+
const index = viewportStart + i;
|
|
1177
1256
|
const isSelected = index === currentQrIndex;
|
|
1178
1257
|
const prefix = isSelected ? "\u2192 " : "\u2022 ";
|
|
1179
1258
|
const color = isSelected ? "yellow" : "magenta";
|
|
@@ -1185,6 +1264,11 @@ function updateUrlsDisplay(urlsBox, screen, urls, currentQrIndex) {
|
|
|
1185
1264
|
`;
|
|
1186
1265
|
}
|
|
1187
1266
|
});
|
|
1267
|
+
const itemsBelow = urls.length - viewportEnd;
|
|
1268
|
+
if (itemsBelow > 0) {
|
|
1269
|
+
content += `{gray-fg}\u2193 ${itemsBelow} more{/gray-fg}
|
|
1270
|
+
`;
|
|
1271
|
+
}
|
|
1188
1272
|
urlsBox.setContent(content);
|
|
1189
1273
|
screen.render();
|
|
1190
1274
|
}
|
|
@@ -1852,7 +1936,7 @@ var TunnelTui = class {
|
|
|
1852
1936
|
}
|
|
1853
1937
|
}
|
|
1854
1938
|
async generateQrCodes() {
|
|
1855
|
-
if (this.tunnelConfig?.
|
|
1939
|
+
if (this.tunnelConfig?.isQRCode && this.urls.length > 0) {
|
|
1856
1940
|
this.qrCodes = await createQrCodes(this.urls);
|
|
1857
1941
|
this.updateQrCodeDisplay();
|
|
1858
1942
|
}
|
|
@@ -2085,7 +2169,7 @@ async function startCli(finalConfig, manager) {
|
|
|
2085
2169
|
});
|
|
2086
2170
|
}
|
|
2087
2171
|
manager2.registerWorkerErrorListner(tunnel.tunnelid, (_tunnelid, error) => {
|
|
2088
|
-
printer_default.
|
|
2172
|
+
printer_default.fatal(`${error.message}`);
|
|
2089
2173
|
});
|
|
2090
2174
|
await manager2.startTunnel(tunnel.tunnelid);
|
|
2091
2175
|
printer_default.stopSpinnerSuccess(" Connected to Pinggy");
|
|
@@ -2210,7 +2294,7 @@ async function startCli(finalConfig, manager) {
|
|
|
2210
2294
|
}
|
|
2211
2295
|
} catch (err) {
|
|
2212
2296
|
printer_default.stopSpinnerFail("Failed to connect");
|
|
2213
|
-
printer_default.
|
|
2297
|
+
printer_default.fatal(err.message || "Unknown error");
|
|
2214
2298
|
throw err;
|
|
2215
2299
|
}
|
|
2216
2300
|
}
|
|
@@ -2241,9 +2325,8 @@ async function main() {
|
|
|
2241
2325
|
}
|
|
2242
2326
|
const parseResult = await parseRemoteManagement(values);
|
|
2243
2327
|
if (parseResult?.ok === false) {
|
|
2244
|
-
printer_default.error(parseResult.error);
|
|
2245
2328
|
logger.error("Failed to initiate remote management:", parseResult.error);
|
|
2246
|
-
|
|
2329
|
+
printer_default.fatal(parseResult.error);
|
|
2247
2330
|
}
|
|
2248
2331
|
logger.debug("Building final config from CLI values and positionals", { values, positionals });
|
|
2249
2332
|
const finalConfig = await buildFinalConfig(values, positionals);
|
|
@@ -2251,7 +2334,7 @@ async function main() {
|
|
|
2251
2334
|
await startCli(finalConfig, manager);
|
|
2252
2335
|
} catch (error) {
|
|
2253
2336
|
logger.error("Unhandled error in CLI:", error);
|
|
2254
|
-
printer_default.
|
|
2337
|
+
printer_default.fatal(error);
|
|
2255
2338
|
}
|
|
2256
2339
|
}
|
|
2257
2340
|
var currentFile = fileURLToPath(import.meta.url);
|
|
@@ -2265,6 +2348,7 @@ if (entryFile && entryFile === currentFile) {
|
|
|
2265
2348
|
main();
|
|
2266
2349
|
}
|
|
2267
2350
|
export {
|
|
2351
|
+
RemoteManagementUnauthorizedError,
|
|
2268
2352
|
TunnelManager,
|
|
2269
2353
|
TunnelOperations,
|
|
2270
2354
|
closeRemoteManagement,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pinggy",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Create secure, shareable tunnels to your localhost and manage them from the command line. ",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
]
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@pinggy/pinggy": "^0.4.
|
|
54
|
+
"@pinggy/pinggy": "^0.4.3",
|
|
55
55
|
"blessed": "^0.1.81",
|
|
56
56
|
"clipboardy": "^5.0.0",
|
|
57
57
|
"mime": "^4.1.0",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"@types/blessed": "^0.1.25",
|
|
66
66
|
"@types/jest": "^30.0.0",
|
|
67
67
|
"@types/node": "^24.3.0",
|
|
68
|
+
"@types/qrcode": "^1.5.6",
|
|
68
69
|
"@types/qrcode-terminal": "^0.12.2",
|
|
69
70
|
"@types/ws": "^8.18.1",
|
|
70
71
|
"@yao-pkg/pkg": "^6.11.0",
|