pinggy 0.4.9 → 0.5.0
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/CLAUDE.md +112 -0
- package/README.md +214 -97
- package/dist/TunnelManager-OPUMAZFX.js +11 -0
- package/dist/TunnelTui-QZEWWH2H.js +1338 -0
- package/dist/{chunk-3RTRUYNW.js → chunk-7G6SJEEA.js} +35 -7
- package/dist/chunk-BFARGPGP.js +164 -0
- package/dist/chunk-DLNUDW6G.js +1690 -0
- package/dist/chunk-FVLXFHBL.js +2157 -0
- package/dist/chunk-GBYF2H4H.js +77 -0
- package/dist/chunk-HUP6YWH6.js +269 -0
- package/dist/chunk-MT44NAXX.js +36 -0
- package/dist/chunk-UB26QJ4T.js +10 -0
- package/dist/chunk-YJQC6LQN.js +3407 -0
- package/dist/configStore-TSGRNOE3.js +42 -0
- package/dist/daemonChild-E2CORSSB.js +24 -0
- package/dist/daemonConfig-G6S46GPJ.js +9 -0
- package/dist/index.cjs +5153 -1596
- package/dist/index.d.cts +473 -13
- package/dist/index.d.ts +473 -13
- package/dist/index.js +12 -5
- package/dist/ipcClient-LZQCCNMR.js +6 -0
- package/dist/main-F4U5R4SW.js +42 -0
- package/dist/workers/file_serve_worker.cjs +70 -21
- package/dist/workers/file_serve_worker.js +15 -9
- package/eslint.config.js +27 -0
- package/package.json +8 -4
- package/dist/chunk-YFTL44B3.js +0 -2857
- package/dist/main-4WTJG54V.js +0 -2925
|
@@ -3,6 +3,22 @@ import winston from "winston";
|
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { pinggy, LogLevel } from "@pinggy/pinggy";
|
|
6
|
+
var _currentLevel = process.env.PINGGY_LOG_LEVEL || "info";
|
|
7
|
+
var _sdkLogFilePath = null;
|
|
8
|
+
function getLogLevel() {
|
|
9
|
+
return _currentLevel;
|
|
10
|
+
}
|
|
11
|
+
function setLogLevel(level) {
|
|
12
|
+
_currentLevel = level;
|
|
13
|
+
getLogger().level = level;
|
|
14
|
+
if (_sdkLogFilePath) {
|
|
15
|
+
enableLoggingByLogLevelInSdk(level, _sdkLogFilePath);
|
|
16
|
+
}
|
|
17
|
+
import("./daemonConfig-G6S46GPJ.js").then(({ writeDaemonConfig }) => writeDaemonConfig({ logLevel: level })).catch(() => {
|
|
18
|
+
});
|
|
19
|
+
import("./TunnelManager-OPUMAZFX.js").then(({ TunnelManager }) => TunnelManager.getInstance().applyLogLevelToActiveTunnels(level)).catch(() => {
|
|
20
|
+
});
|
|
21
|
+
}
|
|
6
22
|
var _logger = null;
|
|
7
23
|
function getLogger() {
|
|
8
24
|
if (!_logger) {
|
|
@@ -22,6 +38,7 @@ function applyLoggingConfig(cfg) {
|
|
|
22
38
|
} = cfg;
|
|
23
39
|
if (enableSdkLog) {
|
|
24
40
|
enableLoggingByLogLevelInSdk(level ?? "info", filePath);
|
|
41
|
+
_sdkLogFilePath = filePath ?? null;
|
|
25
42
|
}
|
|
26
43
|
if (filePath) {
|
|
27
44
|
const dir = path.dirname(filePath);
|
|
@@ -34,22 +51,30 @@ function applyLoggingConfig(cfg) {
|
|
|
34
51
|
format: winston.format.combine(
|
|
35
52
|
winston.format.colorize(),
|
|
36
53
|
winston.format.timestamp(),
|
|
37
|
-
winston.format.printf(({ level: level2, message, timestamp, ...meta }) => {
|
|
38
|
-
const srcLabel = source ?
|
|
39
|
-
|
|
54
|
+
winston.format.printf(({ level: level2, message, timestamp, tunnelId, source: src, ...meta }) => {
|
|
55
|
+
const srcLabel = source && src && src !== "libpinggy" && src !== "sdk-js" ? `[${src}] ` : "";
|
|
56
|
+
const tunnelLabel = tunnelId ? `[tunnel:${String(tunnelId).slice(0, 8)}] ` : "";
|
|
57
|
+
return `${timestamp} ${tunnelLabel}[${level2}] ${srcLabel}${message}${Object.keys(meta).length ? " " + JSON.stringify(meta) : ""}`;
|
|
40
58
|
})
|
|
41
59
|
)
|
|
42
60
|
})
|
|
43
61
|
);
|
|
44
62
|
}
|
|
45
63
|
if (filePath) {
|
|
64
|
+
const daemonFilter = winston.format((info) => {
|
|
65
|
+
if (info.source === "libpinggy" || info.source === "sdk-js") return false;
|
|
66
|
+
return info;
|
|
67
|
+
});
|
|
46
68
|
transports.push(
|
|
47
69
|
new winston.transports.File({
|
|
48
70
|
filename: filePath,
|
|
49
71
|
format: winston.format.combine(
|
|
72
|
+
daemonFilter(),
|
|
50
73
|
winston.format.timestamp(),
|
|
51
|
-
winston.format.printf(({ level: level2, message, timestamp, ...meta }) => {
|
|
52
|
-
|
|
74
|
+
winston.format.printf(({ level: level2, message, timestamp, tunnelId, source: src, ...meta }) => {
|
|
75
|
+
const srcLabel = src ? `[${src}] ` : "";
|
|
76
|
+
const tunnelLabel = tunnelId ? `[tunnel:${String(tunnelId).slice(0, 8)}] ` : "";
|
|
77
|
+
return `${timestamp} ${tunnelLabel}[${level2}] ${srcLabel}${message}${Object.keys(meta).length ? " " + JSON.stringify(meta) : ""}`;
|
|
53
78
|
})
|
|
54
79
|
)
|
|
55
80
|
})
|
|
@@ -61,6 +86,7 @@ function applyLoggingConfig(cfg) {
|
|
|
61
86
|
log.add(t);
|
|
62
87
|
}
|
|
63
88
|
log.level = (level || process.env.PINGGY_LOG_LEVEL || "info").toLowerCase();
|
|
89
|
+
_currentLevel = log.level;
|
|
64
90
|
log.silent = silent || transports.length === 0;
|
|
65
91
|
return log;
|
|
66
92
|
}
|
|
@@ -87,9 +113,9 @@ function enableLoggingByLogLevelInSdk(loglevel, logFilePath) {
|
|
|
87
113
|
return;
|
|
88
114
|
}
|
|
89
115
|
const l = loglevel.toUpperCase();
|
|
90
|
-
if (
|
|
116
|
+
if (l === "DEBUG") {
|
|
91
117
|
pinggy.setDebugLogging(true, LogLevel.DEBUG, logFilePath);
|
|
92
|
-
} else if (
|
|
118
|
+
} else if (l === "ERROR") {
|
|
93
119
|
pinggy.setDebugLogging(true, LogLevel.ERROR, logFilePath);
|
|
94
120
|
} else {
|
|
95
121
|
pinggy.setDebugLogging(true, LogLevel.INFO, logFilePath);
|
|
@@ -97,6 +123,8 @@ function enableLoggingByLogLevelInSdk(loglevel, logFilePath) {
|
|
|
97
123
|
}
|
|
98
124
|
|
|
99
125
|
export {
|
|
126
|
+
getLogLevel,
|
|
127
|
+
setLogLevel,
|
|
100
128
|
logger,
|
|
101
129
|
configureLogger,
|
|
102
130
|
enablePackageLogging
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// src/daemon/ipc/ipcClient.ts
|
|
2
|
+
import http from "http";
|
|
3
|
+
|
|
4
|
+
// src/daemon/ipc/ipcRoutes.ts
|
|
5
|
+
var Route = {
|
|
6
|
+
Ping: "GET /ping",
|
|
7
|
+
ListTunnels: "GET /tunnels",
|
|
8
|
+
ListTunnelsV1: "GET /tunnels-v1",
|
|
9
|
+
StartTunnel: "POST /tunnels/start",
|
|
10
|
+
StartTunnelConfig: "POST /tunnels/start-config",
|
|
11
|
+
StartTunnelV1: "POST /tunnels/start-v1",
|
|
12
|
+
StopTunnel: "POST /tunnels/stop",
|
|
13
|
+
RestartTunnel: "POST /tunnels/restart",
|
|
14
|
+
UpdateConfig: "POST /tunnels/update-config",
|
|
15
|
+
UpdateConfigV2: "POST /tunnels/update-config-v2",
|
|
16
|
+
RemoveStopped: "POST /tunnels/remove-stopped",
|
|
17
|
+
Shutdown: "POST /shutdown",
|
|
18
|
+
GetLogLevel: "GET /loglevel",
|
|
19
|
+
SetLogLevel: "POST /loglevel",
|
|
20
|
+
GetTunnelLogging: "GET /config/tunnel-logging",
|
|
21
|
+
SetTunnelLogging: "POST /config/tunnel-logging",
|
|
22
|
+
GetLogPaths: "GET /logs/paths"
|
|
23
|
+
};
|
|
24
|
+
var SessionMode = {
|
|
25
|
+
Foreground: "foreground",
|
|
26
|
+
Detached: "detached"
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/daemon/ipc/ipcClient.ts
|
|
30
|
+
var REQUEST_TIMEOUT_MS = 1e4;
|
|
31
|
+
var IPCClient = class {
|
|
32
|
+
constructor(port, origin = "cli") {
|
|
33
|
+
this.port = port;
|
|
34
|
+
this.origin = origin;
|
|
35
|
+
}
|
|
36
|
+
async ping(timeoutMs) {
|
|
37
|
+
return this.call(Route.Ping, void 0, timeoutMs);
|
|
38
|
+
}
|
|
39
|
+
async listTunnels() {
|
|
40
|
+
return this.call(Route.ListTunnels, void 0);
|
|
41
|
+
}
|
|
42
|
+
async getTunnel(tunnelId) {
|
|
43
|
+
return this.request("GET", `/tunnels/${tunnelId}`);
|
|
44
|
+
}
|
|
45
|
+
async getTunnelStats(tunnelId) {
|
|
46
|
+
return this.request("GET", `/tunnels/${encodeURIComponent(tunnelId)}/stats`);
|
|
47
|
+
}
|
|
48
|
+
async startTunnel(name, mode) {
|
|
49
|
+
return this.call(Route.StartTunnel, { name, mode });
|
|
50
|
+
}
|
|
51
|
+
async startTunnelWithConfig(config, mode, noWait) {
|
|
52
|
+
return this.call(Route.StartTunnelConfig, { config, mode, noWait });
|
|
53
|
+
}
|
|
54
|
+
async stopTunnel(tunnelid) {
|
|
55
|
+
return this.call(Route.StopTunnel, { tunnelid });
|
|
56
|
+
}
|
|
57
|
+
async restartTunnel(tunnelid) {
|
|
58
|
+
return this.call(Route.RestartTunnel, { tunnelid });
|
|
59
|
+
}
|
|
60
|
+
// v1 operations (used by remote management via daemon)
|
|
61
|
+
async startTunnelV1(config, mode, noWait) {
|
|
62
|
+
return this.call(Route.StartTunnelV1, { config, mode, noWait });
|
|
63
|
+
}
|
|
64
|
+
async listTunnelsV1() {
|
|
65
|
+
return this.call(Route.ListTunnelsV1, void 0);
|
|
66
|
+
}
|
|
67
|
+
async updateConfig(config, noWait) {
|
|
68
|
+
return this.call(Route.UpdateConfig, { config, noWait });
|
|
69
|
+
}
|
|
70
|
+
async updateConfigV2(config, noWait) {
|
|
71
|
+
return this.call(Route.UpdateConfigV2, { config, noWait });
|
|
72
|
+
}
|
|
73
|
+
async removeStoppedTunnel(opts) {
|
|
74
|
+
return this.call(Route.RemoveStopped, opts);
|
|
75
|
+
}
|
|
76
|
+
async shutdown() {
|
|
77
|
+
return this.call(Route.Shutdown, {});
|
|
78
|
+
}
|
|
79
|
+
async getLogLevel() {
|
|
80
|
+
return this.call(Route.GetLogLevel, void 0);
|
|
81
|
+
}
|
|
82
|
+
async setLogLevel(level) {
|
|
83
|
+
return this.call(Route.SetLogLevel, { level });
|
|
84
|
+
}
|
|
85
|
+
async getTunnelLogging() {
|
|
86
|
+
return this.call(Route.GetTunnelLogging, void 0);
|
|
87
|
+
}
|
|
88
|
+
async setTunnelLogging(enabled) {
|
|
89
|
+
return this.call(Route.SetTunnelLogging, { enabled });
|
|
90
|
+
}
|
|
91
|
+
async getLogPaths() {
|
|
92
|
+
return this.call(Route.GetLogPaths, void 0);
|
|
93
|
+
}
|
|
94
|
+
async resolveLogPath(q) {
|
|
95
|
+
return this.request("GET", `/logs/resolve?q=${encodeURIComponent(q)}`);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get the WebSocket URL for event streaming.
|
|
99
|
+
*/
|
|
100
|
+
getWsUrl() {
|
|
101
|
+
return `ws://127.0.0.1:${this.port}/ws`;
|
|
102
|
+
}
|
|
103
|
+
getPort() {
|
|
104
|
+
return this.port;
|
|
105
|
+
}
|
|
106
|
+
call(key, body, timeoutMs) {
|
|
107
|
+
const spaceIdx = key.indexOf(" ");
|
|
108
|
+
const method = key.slice(0, spaceIdx);
|
|
109
|
+
const path = key.slice(spaceIdx + 1);
|
|
110
|
+
const payload = method === "GET" ? void 0 : JSON.stringify(body ?? {});
|
|
111
|
+
return this.request(method, path, payload, timeoutMs);
|
|
112
|
+
}
|
|
113
|
+
request(method, path, body, timeoutMs) {
|
|
114
|
+
return new Promise((resolve, reject) => {
|
|
115
|
+
const headers = {
|
|
116
|
+
"X-Pinggy-Origin": this.origin
|
|
117
|
+
};
|
|
118
|
+
if (body) {
|
|
119
|
+
headers["Content-Type"] = "application/json";
|
|
120
|
+
headers["Content-Length"] = Buffer.byteLength(body);
|
|
121
|
+
}
|
|
122
|
+
const req = http.request(
|
|
123
|
+
{
|
|
124
|
+
hostname: "127.0.0.1",
|
|
125
|
+
port: this.port,
|
|
126
|
+
path,
|
|
127
|
+
method,
|
|
128
|
+
headers,
|
|
129
|
+
timeout: timeoutMs ?? REQUEST_TIMEOUT_MS
|
|
130
|
+
},
|
|
131
|
+
(res) => {
|
|
132
|
+
const chunks = [];
|
|
133
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
134
|
+
res.on("end", () => {
|
|
135
|
+
const text = Buffer.concat(chunks).toString("utf-8");
|
|
136
|
+
const statusCode = res.statusCode ?? 0;
|
|
137
|
+
if (statusCode < 200 || statusCode >= 300) {
|
|
138
|
+
reject(new Error(`Daemon returned HTTP ${statusCode}: ${text.slice(0, 200)}`));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
resolve(JSON.parse(text));
|
|
143
|
+
} catch {
|
|
144
|
+
reject(new Error(`Invalid JSON from daemon: ${text.slice(0, 200)}`));
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
req.on("error", (err) => reject(new Error(`Cannot connect to daemon: ${err.message}`)));
|
|
150
|
+
req.on("timeout", () => {
|
|
151
|
+
req.destroy();
|
|
152
|
+
reject(new Error("Daemon request timed out"));
|
|
153
|
+
});
|
|
154
|
+
if (body) req.write(body);
|
|
155
|
+
req.end();
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export {
|
|
161
|
+
Route,
|
|
162
|
+
SessionMode,
|
|
163
|
+
IPCClient
|
|
164
|
+
};
|