pinggy 0.4.7 → 0.4.8

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.
@@ -194,9 +194,10 @@ var TunnelManager = class _TunnelManager {
194
194
  * status information, and statistics
195
195
  */
196
196
  async createTunnel(config) {
197
- const { configId, tunnelid: requestedTunnelId, tunnelName, name, serve } = config;
197
+ const { configId, tunnelid: requestedTunnelId, tunnelName, name } = config;
198
198
  const tunnelid = requestedTunnelId || getRandomId();
199
199
  const autoReconnect = config.autoReconnect || false;
200
+ const serve = this.resolveServePath(config);
200
201
  if (!configId || typeof configId !== "string" || configId.trim() === "") {
201
202
  throw new Error("configId is required and must be a non-empty string");
202
203
  }
@@ -283,8 +284,11 @@ var TunnelManager = class _TunnelManager {
283
284
  throw error;
284
285
  }
285
286
  logger.info("Tunnel started", { tunnelId, urls });
287
+ logger.info("Checking serve config for tunnel", { tunnelId, serve: managed.serve });
286
288
  if (managed.serve) {
287
289
  this.startStaticFileServer(managed);
290
+ } else {
291
+ logger.debug("No serve path configured, skipping static file server", { tunnelId });
288
292
  }
289
293
  try {
290
294
  const startListeners = this.tunnelStartListeners.get(tunnelId);
@@ -616,6 +620,7 @@ var TunnelManager = class _TunnelManager {
616
620
  const currentTunnelName = existingTunnel.tunnelName;
617
621
  const currentServe = existingTunnel.serve;
618
622
  const currentAutoReconnect = existingTunnel.autoReconnect || false;
623
+ const requestedServe = this.resolveServePath(newConfig);
619
624
  try {
620
625
  if (!isStopped) {
621
626
  existingTunnel.instance.stop();
@@ -626,9 +631,9 @@ var TunnelManager = class _TunnelManager {
626
631
  ...newConfig,
627
632
  configId,
628
633
  tunnelName: newTunnelName !== void 0 ? newTunnelName : currentTunnelName,
629
- serve: newConfig.serve !== void 0 ? newConfig.serve : currentServe
634
+ serve: requestedServe !== void 0 ? requestedServe : currentServe
630
635
  };
631
- const effectiveServe = newConfig.serve !== void 0 ? newConfig.serve : currentServe;
636
+ const effectiveServe = requestedServe !== void 0 ? requestedServe : currentServe;
632
637
  const effectiveTunnelName = newTunnelName !== void 0 ? newTunnelName : currentTunnelName;
633
638
  let configWithForwarding;
634
639
  const newTunnel = await this._createTunnelWithProcessedConfig({
@@ -1387,21 +1392,35 @@ var TunnelManager = class _TunnelManager {
1387
1392
  const parsed = typeof value === "number" ? value : parseInt(String(value), 10);
1388
1393
  return isNaN(parsed) ? 0 : parsed;
1389
1394
  }
1395
+ /**
1396
+ * Read serve path only from config.optional.serve.
1397
+ */
1398
+ resolveServePath(config) {
1399
+ const optional = config.optional;
1400
+ const servePath = optional?.serve;
1401
+ logger.debug("resolveServePath", { servePath, hasOptional: !!optional, optionalKeys: optional ? Object.keys(optional) : [] });
1402
+ return servePath;
1403
+ }
1390
1404
  startStaticFileServer(managed) {
1391
1405
  try {
1392
1406
  const __filename4 = fileURLToPath2(import.meta.url);
1393
1407
  const __dirname4 = path.dirname(__filename4);
1394
1408
  const fileServerWorkerPath = path.join(__dirname4, "workers", "file_serve_worker.cjs");
1409
+ logger.info("Starting static file server worker", {
1410
+ dir: managed.serve,
1411
+ forwarding: JSON.stringify(managed.tunnelConfig?.forwarding),
1412
+ workerPath: fileServerWorkerPath
1413
+ });
1395
1414
  const staticServerWorker = new Worker(fileServerWorkerPath, {
1396
1415
  workerData: {
1397
1416
  dir: managed.serve,
1398
- port: managed.tunnelConfig?.forwarding
1417
+ forwarding: managed.tunnelConfig?.forwarding
1399
1418
  }
1400
1419
  });
1401
1420
  staticServerWorker.on("message", (msg) => {
1402
1421
  switch (msg.type) {
1403
1422
  case "started":
1404
- logger.info("Static file server started", { dir: managed.serve });
1423
+ logger.info("Static file server started", { dir: managed.serve, port: msg.portNum });
1405
1424
  break;
1406
1425
  case "warning":
1407
1426
  if (msg.code === "INVALID_TUNNEL_SERVE_PATH") {
package/dist/index.cjs CHANGED
@@ -367,9 +367,10 @@ var init_TunnelManager = __esm({
367
367
  * status information, and statistics
368
368
  */
369
369
  async createTunnel(config) {
370
- const { configId, tunnelid: requestedTunnelId, tunnelName, name, serve } = config;
370
+ const { configId, tunnelid: requestedTunnelId, tunnelName, name } = config;
371
371
  const tunnelid = requestedTunnelId || getRandomId();
372
372
  const autoReconnect = config.autoReconnect || false;
373
+ const serve = this.resolveServePath(config);
373
374
  if (!configId || typeof configId !== "string" || configId.trim() === "") {
374
375
  throw new Error("configId is required and must be a non-empty string");
375
376
  }
@@ -456,8 +457,11 @@ var init_TunnelManager = __esm({
456
457
  throw error;
457
458
  }
458
459
  logger.info("Tunnel started", { tunnelId, urls });
460
+ logger.info("Checking serve config for tunnel", { tunnelId, serve: managed.serve });
459
461
  if (managed.serve) {
460
462
  this.startStaticFileServer(managed);
463
+ } else {
464
+ logger.debug("No serve path configured, skipping static file server", { tunnelId });
461
465
  }
462
466
  try {
463
467
  const startListeners = this.tunnelStartListeners.get(tunnelId);
@@ -789,6 +793,7 @@ var init_TunnelManager = __esm({
789
793
  const currentTunnelName = existingTunnel.tunnelName;
790
794
  const currentServe = existingTunnel.serve;
791
795
  const currentAutoReconnect = existingTunnel.autoReconnect || false;
796
+ const requestedServe = this.resolveServePath(newConfig);
792
797
  try {
793
798
  if (!isStopped) {
794
799
  existingTunnel.instance.stop();
@@ -799,9 +804,9 @@ var init_TunnelManager = __esm({
799
804
  ...newConfig,
800
805
  configId,
801
806
  tunnelName: newTunnelName !== void 0 ? newTunnelName : currentTunnelName,
802
- serve: newConfig.serve !== void 0 ? newConfig.serve : currentServe
807
+ serve: requestedServe !== void 0 ? requestedServe : currentServe
803
808
  };
804
- const effectiveServe = newConfig.serve !== void 0 ? newConfig.serve : currentServe;
809
+ const effectiveServe = requestedServe !== void 0 ? requestedServe : currentServe;
805
810
  const effectiveTunnelName = newTunnelName !== void 0 ? newTunnelName : currentTunnelName;
806
811
  let configWithForwarding;
807
812
  const newTunnel = await this._createTunnelWithProcessedConfig({
@@ -1560,21 +1565,35 @@ var init_TunnelManager = __esm({
1560
1565
  const parsed = typeof value === "number" ? value : parseInt(String(value), 10);
1561
1566
  return isNaN(parsed) ? 0 : parsed;
1562
1567
  }
1568
+ /**
1569
+ * Read serve path only from config.optional.serve.
1570
+ */
1571
+ resolveServePath(config) {
1572
+ const optional = config.optional;
1573
+ const servePath = optional?.serve;
1574
+ logger.debug("resolveServePath", { servePath, hasOptional: !!optional, optionalKeys: optional ? Object.keys(optional) : [] });
1575
+ return servePath;
1576
+ }
1563
1577
  startStaticFileServer(managed) {
1564
1578
  try {
1565
1579
  const __filename4 = (0, import_node_url.fileURLToPath)(importMetaUrl);
1566
1580
  const __dirname3 = import_node_path.default.dirname(__filename4);
1567
1581
  const fileServerWorkerPath = import_node_path.default.join(__dirname3, "workers", "file_serve_worker.cjs");
1582
+ logger.info("Starting static file server worker", {
1583
+ dir: managed.serve,
1584
+ forwarding: JSON.stringify(managed.tunnelConfig?.forwarding),
1585
+ workerPath: fileServerWorkerPath
1586
+ });
1568
1587
  const staticServerWorker = new import_node_worker_threads.Worker(fileServerWorkerPath, {
1569
1588
  workerData: {
1570
1589
  dir: managed.serve,
1571
- port: managed.tunnelConfig?.forwarding
1590
+ forwarding: managed.tunnelConfig?.forwarding
1572
1591
  }
1573
1592
  });
1574
1593
  staticServerWorker.on("message", (msg) => {
1575
1594
  switch (msg.type) {
1576
1595
  case "started":
1577
- logger.info("Static file server started", { dir: managed.serve });
1596
+ logger.info("Static file server started", { dir: managed.serve, port: msg.portNum });
1578
1597
  break;
1579
1598
  case "warning":
1580
1599
  if (msg.code === "INVALID_TUNNEL_SERVE_PATH") {
@@ -3084,7 +3103,7 @@ var init_options = __esm({
3084
3103
  v: { type: "boolean", description: "Print logs to stdout for Cli. Overrides PINGGY_LOG_STDOUT environment variable" },
3085
3104
  vv: { type: "boolean", description: "Enable detailed logging for the Node.js SDK and Libpinggy, including both info and debug level logs." },
3086
3105
  vvv: { type: "boolean", description: "Enable all logs from Cli, SDK and internal components." },
3087
- autoreconnect: { type: "string", short: "a", description: "Automatically reconnect tunnel on failure (enabled by default). Use -a false to disable." },
3106
+ "no-autoreconnect": { type: "boolean", short: "a", description: "Disable auto reconnection on failure (enabled by default)." },
3088
3107
  // Save and load config (legacy file-based)
3089
3108
  saveconf: { type: "string", description: "Create the configuration file based on the options provided here" },
3090
3109
  conf: { type: "string", description: "Use the configuration file as base. Other options will be used to override this file" },
@@ -3794,16 +3813,8 @@ function parseServe(finalConfig, values) {
3794
3813
  return null;
3795
3814
  }
3796
3815
  function parseAutoReconnect(finalConfig, values) {
3797
- const autoReconnectValue = values.autoreconnect;
3798
- if (typeof autoReconnectValue === "string") {
3799
- const trimmed = autoReconnectValue.trim().toLowerCase();
3800
- if (trimmed === "true" || trimmed === "") {
3801
- finalConfig.autoReconnect = true;
3802
- } else if (trimmed === "false") {
3803
- finalConfig.autoReconnect = false;
3804
- } else {
3805
- return new Error(`Invalid autoreconnect value: ${autoReconnectValue}. Use true or false.`);
3806
- }
3816
+ if (values["no-autoreconnect"]) {
3817
+ finalConfig.autoReconnect = false;
3807
3818
  }
3808
3819
  return null;
3809
3820
  }
@@ -6120,13 +6131,15 @@ async function main() {
6120
6131
  try {
6121
6132
  const rawArgs = process.argv.slice(2);
6122
6133
  const manager = TunnelManager.getInstance();
6123
- process.on("SIGINT", () => {
6124
- logger.info("SIGINT received: stopping tunnels and exiting");
6134
+ const gracefulShutdown = (signal) => {
6135
+ logger.info(`${signal} received: stopping tunnels and exiting`);
6125
6136
  console.log("\nStopping all tunnels...");
6126
6137
  manager.stopAllTunnels();
6127
6138
  console.log("Tunnels stopped. Exiting.");
6128
6139
  process.exit(0);
6129
- });
6140
+ };
6141
+ process.on("SIGINT", () => gracefulShutdown("SIGINT"));
6142
+ process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
6130
6143
  if (isSubcommand(rawArgs)) {
6131
6144
  await handleSubcommand(rawArgs, manager);
6132
6145
  return;
package/dist/index.d.cts CHANGED
@@ -378,6 +378,10 @@ declare class TunnelManager implements ITunnelManager {
378
378
  */
379
379
  private normalizeStats;
380
380
  private parseNumber;
381
+ /**
382
+ * Read serve path only from config.optional.serve.
383
+ */
384
+ private resolveServePath;
381
385
  private startStaticFileServer;
382
386
  }
383
387
 
package/dist/index.d.ts CHANGED
@@ -378,6 +378,10 @@ declare class TunnelManager implements ITunnelManager {
378
378
  */
379
379
  private normalizeStats;
380
380
  private parseNumber;
381
+ /**
382
+ * Read serve path only from config.optional.serve.
383
+ */
384
+ private resolveServePath;
381
385
  private startStaticFileServer;
382
386
  }
383
387
 
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  initiateRemoteManagement,
12
12
  printer_default,
13
13
  startRemoteManagement
14
- } from "./chunk-443UO6IY.js";
14
+ } from "./chunk-YFTL44B3.js";
15
15
  import {
16
16
  enablePackageLogging
17
17
  } from "./chunk-3RTRUYNW.js";
@@ -106,7 +106,7 @@ async function verifyAndLoad() {
106
106
  process.exit(1);
107
107
  }
108
108
  }
109
- await import("./main-PUM4SD6B.js");
109
+ await import("./main-4WTJG54V.js");
110
110
  }
111
111
  verifyAndLoad().catch((err) => {
112
112
  printer_default.fatal(`Failed to start CLI:, ${err}`);
@@ -13,7 +13,7 @@ import {
13
13
  parseRemoteManagement,
14
14
  printer_default,
15
15
  startRemoteManagement
16
- } from "./chunk-443UO6IY.js";
16
+ } from "./chunk-YFTL44B3.js";
17
17
  import {
18
18
  configureLogger,
19
19
  enablePackageLogging,
@@ -46,7 +46,7 @@ var cliOptions = {
46
46
  v: { type: "boolean", description: "Print logs to stdout for Cli. Overrides PINGGY_LOG_STDOUT environment variable" },
47
47
  vv: { type: "boolean", description: "Enable detailed logging for the Node.js SDK and Libpinggy, including both info and debug level logs." },
48
48
  vvv: { type: "boolean", description: "Enable all logs from Cli, SDK and internal components." },
49
- autoreconnect: { type: "string", short: "a", description: "Automatically reconnect tunnel on failure (enabled by default). Use -a false to disable." },
49
+ "no-autoreconnect": { type: "boolean", short: "a", description: "Disable auto reconnection on failure (enabled by default)." },
50
50
  // Save and load config (legacy file-based)
51
51
  saveconf: { type: "string", description: "Create the configuration file based on the options provided here" },
52
52
  conf: { type: "string", description: "Use the configuration file as base. Other options will be used to override this file" },
@@ -744,16 +744,8 @@ function parseServe(finalConfig, values) {
744
744
  return null;
745
745
  }
746
746
  function parseAutoReconnect(finalConfig, values) {
747
- const autoReconnectValue = values.autoreconnect;
748
- if (typeof autoReconnectValue === "string") {
749
- const trimmed = autoReconnectValue.trim().toLowerCase();
750
- if (trimmed === "true" || trimmed === "") {
751
- finalConfig.autoReconnect = true;
752
- } else if (trimmed === "false") {
753
- finalConfig.autoReconnect = false;
754
- } else {
755
- return new Error(`Invalid autoreconnect value: ${autoReconnectValue}. Use true or false.`);
756
- }
747
+ if (values["no-autoreconnect"]) {
748
+ finalConfig.autoReconnect = false;
757
749
  }
758
750
  return null;
759
751
  }
@@ -2883,13 +2875,15 @@ async function main() {
2883
2875
  try {
2884
2876
  const rawArgs = process.argv.slice(2);
2885
2877
  const manager = TunnelManager.getInstance();
2886
- process.on("SIGINT", () => {
2887
- logger.info("SIGINT received: stopping tunnels and exiting");
2878
+ const gracefulShutdown = (signal) => {
2879
+ logger.info(`${signal} received: stopping tunnels and exiting`);
2888
2880
  console.log("\nStopping all tunnels...");
2889
2881
  manager.stopAllTunnels();
2890
2882
  console.log("Tunnels stopped. Exiting.");
2891
2883
  process.exit(0);
2892
- });
2884
+ };
2885
+ process.on("SIGINT", () => gracefulShutdown("SIGINT"));
2886
+ process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
2893
2887
  if (isSubcommand(rawArgs)) {
2894
2888
  await handleSubcommand(rawArgs, manager);
2895
2889
  return;
@@ -1449,11 +1449,23 @@ async function startFileServer(dirPath, port = 8080) {
1449
1449
  // src/workers/file_serve_worker.ts
1450
1450
  (async () => {
1451
1451
  try {
1452
- const { dir, port } = import_worker_threads.workerData;
1453
- const portNum = parseInt(port.split(":")[1]);
1452
+ const { dir, forwarding } = import_worker_threads.workerData;
1453
+ logger.debug("file_serve_worker received workerData", { dir, forwarding: JSON.stringify(forwarding) });
1454
+ let address;
1455
+ if (typeof forwarding === "string") {
1456
+ address = forwarding;
1457
+ } else if (Array.isArray(forwarding) && forwarding.length > 0) {
1458
+ address = forwarding[0]?.address;
1459
+ }
1460
+ logger.debug("file_serve_worker resolved address", { address });
1461
+ const match = typeof address === "string" ? address.match(/:(\d+)\/?$/) : null;
1462
+ const portNum = match ? parseInt(match[1], 10) : void 0;
1463
+ logger.debug("file_serve_worker resolved port", { portNum, defaultPort: portNum ?? 8080 });
1454
1464
  const result = await startFileServer(dir, portNum);
1465
+ logger.info("file_serve_worker static file server started", { dir, port: portNum ?? 8080 });
1455
1466
  import_worker_threads.parentPort?.postMessage({ type: "started", portNum });
1456
1467
  if (result.hasInvalidPath && result.error) {
1468
+ logger.warn("file_serve_worker invalid path warning", { message: result.error.message, code: result.error.code });
1457
1469
  import_worker_threads.parentPort?.postMessage({
1458
1470
  type: "warning",
1459
1471
  message: result.error.message,
@@ -1415,11 +1415,23 @@ async function startFileServer(dirPath, port = 8080) {
1415
1415
  // src/workers/file_serve_worker.ts
1416
1416
  (async () => {
1417
1417
  try {
1418
- const { dir, port } = workerData;
1419
- const portNum = parseInt(port.split(":")[1]);
1418
+ const { dir, forwarding } = workerData;
1419
+ logger.debug("file_serve_worker received workerData", { dir, forwarding: JSON.stringify(forwarding) });
1420
+ let address;
1421
+ if (typeof forwarding === "string") {
1422
+ address = forwarding;
1423
+ } else if (Array.isArray(forwarding) && forwarding.length > 0) {
1424
+ address = forwarding[0]?.address;
1425
+ }
1426
+ logger.debug("file_serve_worker resolved address", { address });
1427
+ const match = typeof address === "string" ? address.match(/:(\d+)\/?$/) : null;
1428
+ const portNum = match ? parseInt(match[1], 10) : void 0;
1429
+ logger.debug("file_serve_worker resolved port", { portNum, defaultPort: portNum ?? 8080 });
1420
1430
  const result = await startFileServer(dir, portNum);
1431
+ logger.info("file_serve_worker static file server started", { dir, port: portNum ?? 8080 });
1421
1432
  parentPort?.postMessage({ type: "started", portNum });
1422
1433
  if (result.hasInvalidPath && result.error) {
1434
+ logger.warn("file_serve_worker invalid path warning", { message: result.error.message, code: result.error.code });
1423
1435
  parentPort?.postMessage({
1424
1436
  type: "warning",
1425
1437
  message: result.error.message,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinggy",
3
- "version": "0.4.7",
3
+ "version": "0.4.8",
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. ",