opentunnel-cli 1.0.23 → 1.0.25

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 (50) hide show
  1. package/README.md +39 -2
  2. package/dist/cli/index.js +678 -84
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/client/CloudflareTunnelClient.d.ts +110 -0
  5. package/dist/client/CloudflareTunnelClient.d.ts.map +1 -0
  6. package/dist/client/CloudflareTunnelClient.js +531 -0
  7. package/dist/client/CloudflareTunnelClient.js.map +1 -0
  8. package/dist/client/NgrokClient.d.ts +18 -1
  9. package/dist/client/NgrokClient.d.ts.map +1 -1
  10. package/dist/client/NgrokClient.js +130 -4
  11. package/dist/client/NgrokClient.js.map +1 -1
  12. package/dist/client/TunnelClient.d.ts +0 -1
  13. package/dist/client/TunnelClient.d.ts.map +1 -1
  14. package/dist/client/TunnelClient.js +2 -96
  15. package/dist/client/TunnelClient.js.map +1 -1
  16. package/dist/client/index.d.ts +1 -0
  17. package/dist/client/index.d.ts.map +1 -1
  18. package/dist/client/index.js +3 -1
  19. package/dist/client/index.js.map +1 -1
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +3 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/lib/index.d.ts +2 -0
  25. package/dist/lib/index.d.ts.map +1 -0
  26. package/dist/lib/index.js +18 -0
  27. package/dist/lib/index.js.map +1 -0
  28. package/dist/lib/pages/index.d.ts +2 -0
  29. package/dist/lib/pages/index.d.ts.map +1 -0
  30. package/dist/lib/pages/index.js +6 -0
  31. package/dist/lib/pages/index.js.map +1 -0
  32. package/dist/lib/pages/not-running.d.ts +10 -0
  33. package/dist/lib/pages/not-running.d.ts.map +1 -0
  34. package/dist/lib/pages/not-running.js +117 -0
  35. package/dist/lib/pages/not-running.js.map +1 -0
  36. package/dist/server/TunnelServer.d.ts +1 -3
  37. package/dist/server/TunnelServer.d.ts.map +1 -1
  38. package/dist/server/TunnelServer.js +7 -58
  39. package/dist/server/TunnelServer.js.map +1 -1
  40. package/dist/shared/credentials.d.ts +101 -0
  41. package/dist/shared/credentials.d.ts.map +1 -0
  42. package/dist/shared/credentials.js +302 -0
  43. package/dist/shared/credentials.js.map +1 -0
  44. package/dist/shared/ip-filter.d.ts +75 -0
  45. package/dist/shared/ip-filter.d.ts.map +1 -0
  46. package/dist/shared/ip-filter.js +203 -0
  47. package/dist/shared/ip-filter.js.map +1 -0
  48. package/dist/shared/types.d.ts +34 -0
  49. package/dist/shared/types.d.ts.map +1 -1
  50. package/package.json +6 -3
@@ -0,0 +1,110 @@
1
+ import { EventEmitter } from "events";
2
+ import { TunnelProtocol, IpAccessConfig } from "../shared/types";
3
+ export interface CloudflareTunnelConfig {
4
+ hostname?: string;
5
+ protocol?: "http" | "https";
6
+ noTlsVerify?: boolean;
7
+ tunnelName?: string;
8
+ credentialsPath?: string;
9
+ ipAccess?: IpAccessConfig;
10
+ }
11
+ export interface CloudflareTunnel {
12
+ id: string;
13
+ publicUrl: string;
14
+ protocol: TunnelProtocol;
15
+ localPort: number;
16
+ localHost: string;
17
+ }
18
+ /**
19
+ * Result from tunnel management operations
20
+ */
21
+ export interface TunnelOperationResult {
22
+ success: boolean;
23
+ message?: string;
24
+ error?: string;
25
+ }
26
+ export declare class CloudflareTunnelClient extends EventEmitter {
27
+ private config;
28
+ private process;
29
+ private proxyServer;
30
+ private proxyPort;
31
+ private tunnels;
32
+ private logger;
33
+ private started;
34
+ private binPath;
35
+ private ipFilter;
36
+ constructor(config?: CloudflareTunnelConfig);
37
+ /**
38
+ * Update IP access configuration
39
+ */
40
+ setIpAccess(config: IpAccessConfig): void;
41
+ connect(): Promise<void>;
42
+ disconnect(): Promise<void>;
43
+ /**
44
+ * Create a proxy server that forwards requests to the target and shows
45
+ * a nice error page when the target is not running.
46
+ * Also handles IP filtering before forwarding.
47
+ */
48
+ private createProxyServer;
49
+ /**
50
+ * Create a quick tunnel (no authentication required)
51
+ * This is the default mode - creates a random .trycloudflare.com URL
52
+ */
53
+ createTunnel(options: {
54
+ protocol: TunnelProtocol;
55
+ localHost: string;
56
+ localPort: number;
57
+ subdomain?: string;
58
+ remotePort?: number;
59
+ }): Promise<{
60
+ tunnelId: string;
61
+ publicUrl: string;
62
+ }>;
63
+ /**
64
+ * Run a named tunnel (requires prior cloudflared login and tunnel creation)
65
+ * Named tunnels provide a persistent hostname
66
+ */
67
+ runNamedTunnel(options: {
68
+ protocol: TunnelProtocol;
69
+ localHost: string;
70
+ localPort: number;
71
+ }): Promise<{
72
+ tunnelId: string;
73
+ publicUrl: string;
74
+ }>;
75
+ closeTunnel(tunnelId: string): Promise<void>;
76
+ getTunnels(): CloudflareTunnel[];
77
+ /**
78
+ * Check if cloudflared is installed
79
+ */
80
+ static isAvailable(): Promise<boolean>;
81
+ /**
82
+ * Install cloudflared if not present
83
+ */
84
+ static ensureInstalled(): Promise<string>;
85
+ /**
86
+ * Get cloudflared binary path
87
+ */
88
+ static getBinPath(): Promise<string>;
89
+ /**
90
+ * Create a new named tunnel
91
+ */
92
+ static createNamedTunnel(name: string): Promise<TunnelOperationResult>;
93
+ /**
94
+ * List all named tunnels
95
+ */
96
+ static listTunnels(): Promise<{
97
+ success: boolean;
98
+ tunnels?: string;
99
+ error?: string;
100
+ }>;
101
+ /**
102
+ * Delete a named tunnel
103
+ */
104
+ static deleteTunnel(name: string): Promise<TunnelOperationResult>;
105
+ /**
106
+ * Route DNS for a tunnel
107
+ */
108
+ static routeDns(tunnelName: string, hostname: string): Promise<TunnelOperationResult>;
109
+ }
110
+ //# sourceMappingURL=CloudflareTunnelClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CloudflareTunnelClient.d.ts","sourceRoot":"","sources":["../../src/client/CloudflareTunnelClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,531 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CloudflareTunnelClient = void 0;
37
+ const child_process_1 = require("child_process");
38
+ const events_1 = require("events");
39
+ const fs_1 = require("fs");
40
+ const http_1 = require("http");
41
+ const https_1 = require("https");
42
+ const utils_1 = require("../shared/utils");
43
+ const pages_1 = require("../lib/pages");
44
+ const ip_filter_1 = require("../shared/ip-filter");
45
+ // Import cloudflared package for automatic binary management
46
+ let cloudflaredModule = null;
47
+ async function getCloudflaredModule() {
48
+ if (!cloudflaredModule) {
49
+ cloudflaredModule = await Promise.resolve().then(() => __importStar(require("cloudflared")));
50
+ }
51
+ return cloudflaredModule;
52
+ }
53
+ class CloudflareTunnelClient extends events_1.EventEmitter {
54
+ constructor(config = {}) {
55
+ super();
56
+ this.process = null;
57
+ this.proxyServer = null;
58
+ this.proxyPort = 0;
59
+ this.tunnels = new Map();
60
+ this.started = false;
61
+ this.binPath = "";
62
+ this.ipFilter = null;
63
+ this.config = {
64
+ protocol: "http",
65
+ ...config,
66
+ };
67
+ this.logger = new utils_1.Logger("Cloudflare");
68
+ // Initialize IP filter if configured
69
+ if (config.ipAccess) {
70
+ this.ipFilter = new ip_filter_1.IpFilter(config.ipAccess);
71
+ }
72
+ }
73
+ /**
74
+ * Update IP access configuration
75
+ */
76
+ setIpAccess(config) {
77
+ this.config.ipAccess = config;
78
+ if (!this.ipFilter) {
79
+ this.ipFilter = new ip_filter_1.IpFilter(config);
80
+ }
81
+ else {
82
+ this.ipFilter.setConfig(config);
83
+ }
84
+ }
85
+ async connect() {
86
+ // Ensure cloudflared binary is installed via the npm package
87
+ const cf = await getCloudflaredModule();
88
+ this.binPath = cf.bin;
89
+ if (!(0, fs_1.existsSync)(this.binPath)) {
90
+ this.logger.info("Installing cloudflared binary...");
91
+ await cf.install(this.binPath);
92
+ this.logger.info("cloudflared installed successfully");
93
+ }
94
+ this.started = true;
95
+ this.logger.info("Cloudflare Tunnel client ready");
96
+ }
97
+ async disconnect() {
98
+ if (this.process) {
99
+ this.process.kill();
100
+ this.process = null;
101
+ }
102
+ if (this.proxyServer) {
103
+ this.proxyServer.close();
104
+ this.proxyServer = null;
105
+ }
106
+ this.tunnels.clear();
107
+ this.started = false;
108
+ }
109
+ /**
110
+ * Create a proxy server that forwards requests to the target and shows
111
+ * a nice error page when the target is not running.
112
+ * Also handles IP filtering before forwarding.
113
+ */
114
+ async createProxyServer(targetHost, targetPort, useHttps) {
115
+ return new Promise((resolve, reject) => {
116
+ this.proxyServer = (0, http_1.createServer)((req, res) => {
117
+ // IP filtering check
118
+ if (this.ipFilter) {
119
+ const clientIp = ip_filter_1.IpFilter.extractClientIp(req);
120
+ const ipCheck = this.ipFilter.isAllowed(clientIp);
121
+ if (!ipCheck.allowed) {
122
+ this.logger.warn(`Request blocked for IP ${clientIp}: ${ipCheck.reason}`);
123
+ res.writeHead(403, { "Content-Type": "application/json" });
124
+ res.end(JSON.stringify({
125
+ error: "Access denied",
126
+ reason: ipCheck.reason,
127
+ }));
128
+ return;
129
+ }
130
+ }
131
+ const requestFn = useHttps ? https_1.request : http_1.request;
132
+ const proxyReq = requestFn({
133
+ hostname: targetHost,
134
+ port: targetPort,
135
+ path: req.url,
136
+ method: req.method,
137
+ headers: req.headers,
138
+ rejectUnauthorized: !this.config.noTlsVerify,
139
+ }, (proxyRes) => {
140
+ res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
141
+ proxyRes.pipe(res);
142
+ });
143
+ proxyReq.on("error", (err) => {
144
+ // Check if it's a connection refused error
145
+ if (err.code === "ECONNREFUSED") {
146
+ res.writeHead(503, { "Content-Type": "text/html; charset=utf-8" });
147
+ res.end((0, pages_1.generateNotRunningPage)({
148
+ host: targetHost,
149
+ port: targetPort,
150
+ provider: "Cloudflare Tunnel"
151
+ }));
152
+ }
153
+ else {
154
+ res.writeHead(502, { "Content-Type": "text/plain" });
155
+ res.end(`Proxy Error: ${err.message}`);
156
+ }
157
+ });
158
+ req.pipe(proxyReq);
159
+ });
160
+ // Listen on a random available port
161
+ this.proxyServer.listen(0, "127.0.0.1", () => {
162
+ const address = this.proxyServer.address();
163
+ if (address && typeof address === "object") {
164
+ this.proxyPort = address.port;
165
+ resolve(this.proxyPort);
166
+ }
167
+ else {
168
+ reject(new Error("Failed to get proxy server port"));
169
+ }
170
+ });
171
+ this.proxyServer.on("error", reject);
172
+ });
173
+ }
174
+ /**
175
+ * Create a quick tunnel (no authentication required)
176
+ * This is the default mode - creates a random .trycloudflare.com URL
177
+ */
178
+ async createTunnel(options) {
179
+ // If a named tunnel is configured, use it instead
180
+ if (this.config.tunnelName) {
181
+ return this.runNamedTunnel(options);
182
+ }
183
+ // Ensure we have the binary path
184
+ if (!this.binPath) {
185
+ const cf = await getCloudflaredModule();
186
+ this.binPath = cf.bin;
187
+ }
188
+ const useHttps = options.protocol === "https";
189
+ // Create proxy server to handle "no app running" scenario and IP filtering
190
+ const proxyPort = await this.createProxyServer(options.localHost, options.localPort, useHttps);
191
+ // Build cloudflared arguments - point to our proxy server
192
+ const args = ["tunnel"];
193
+ const originUrl = `http://127.0.0.1:${proxyPort}`;
194
+ args.push("--url", originUrl);
195
+ // Add hostname if specified (for named tunnels)
196
+ if (this.config.hostname)
197
+ args.push("--hostname", this.config.hostname);
198
+ return new Promise((resolve, reject) => {
199
+ const tunnelId = `cf-${Date.now()}`;
200
+ let publicUrl = null;
201
+ let errorOutput = "";
202
+ // Start cloudflared process using the binary from npm package
203
+ this.process = (0, child_process_1.spawn)(this.binPath, args, {
204
+ stdio: ["ignore", "pipe", "pipe"],
205
+ // On Windows, we need shell: true for proper execution
206
+ shell: process.platform === "win32",
207
+ });
208
+ // cloudflared outputs the URL to stderr
209
+ const handleOutput = (data) => {
210
+ const output = data.toString();
211
+ // Look for the trycloudflare.com URL in the output
212
+ const urlMatch = output.match(/https:\/\/[a-zA-Z0-9-]+\.trycloudflare\.com/);
213
+ if (urlMatch && !publicUrl) {
214
+ publicUrl = urlMatch[0];
215
+ const tunnel = {
216
+ id: tunnelId,
217
+ publicUrl,
218
+ protocol: options.protocol,
219
+ localPort: options.localPort,
220
+ localHost: options.localHost,
221
+ };
222
+ this.tunnels.set(tunnel.id, tunnel);
223
+ this.emit("tunnel:created", { tunnelId: tunnel.id, publicUrl });
224
+ resolve({ tunnelId: tunnel.id, publicUrl });
225
+ }
226
+ // Also check for custom hostname URLs
227
+ if (this.config.hostname && !publicUrl) {
228
+ const customUrlMatch = output.match(/https:\/\/[^\s]+/);
229
+ if (customUrlMatch) {
230
+ publicUrl = customUrlMatch[0];
231
+ const tunnel = {
232
+ id: tunnelId,
233
+ publicUrl,
234
+ protocol: options.protocol,
235
+ localPort: options.localPort,
236
+ localHost: options.localHost,
237
+ };
238
+ this.tunnels.set(tunnel.id, tunnel);
239
+ this.emit("tunnel:created", { tunnelId: tunnel.id, publicUrl });
240
+ resolve({ tunnelId: tunnel.id, publicUrl });
241
+ }
242
+ }
243
+ // Collect error output
244
+ if (output.includes("ERR") || output.includes("error"))
245
+ errorOutput += output;
246
+ };
247
+ this.process.stdout?.on("data", handleOutput);
248
+ this.process.stderr?.on("data", handleOutput);
249
+ this.process.on("error", (err) => {
250
+ if (this.proxyServer) {
251
+ this.proxyServer.close();
252
+ this.proxyServer = null;
253
+ }
254
+ reject(new Error(`Failed to start cloudflared: ${err.message}`));
255
+ });
256
+ this.process.on("close", (code) => {
257
+ if (!publicUrl) {
258
+ if (this.proxyServer) {
259
+ this.proxyServer.close();
260
+ this.proxyServer = null;
261
+ }
262
+ reject(new Error(errorOutput || `cloudflared exited with code ${code}`));
263
+ }
264
+ });
265
+ // Set a timeout to fail if URL is not found within 30 seconds
266
+ setTimeout(() => {
267
+ if (!publicUrl) {
268
+ if (this.process) {
269
+ this.process.kill();
270
+ this.process = null;
271
+ }
272
+ if (this.proxyServer) {
273
+ this.proxyServer.close();
274
+ this.proxyServer = null;
275
+ }
276
+ reject(new Error("Timeout waiting for Cloudflare Tunnel URL. " + (errorOutput || "Check your internet connection.")));
277
+ }
278
+ }, 30000);
279
+ });
280
+ }
281
+ /**
282
+ * Run a named tunnel (requires prior cloudflared login and tunnel creation)
283
+ * Named tunnels provide a persistent hostname
284
+ */
285
+ async runNamedTunnel(options) {
286
+ if (!this.config.tunnelName) {
287
+ throw new Error("tunnelName is required for named tunnels");
288
+ }
289
+ // Ensure we have the binary path
290
+ if (!this.binPath) {
291
+ const cf = await getCloudflaredModule();
292
+ this.binPath = cf.bin;
293
+ }
294
+ const useHttps = options.protocol === "https";
295
+ // Create proxy server for IP filtering and error handling
296
+ const proxyPort = await this.createProxyServer(options.localHost, options.localPort, useHttps);
297
+ // Build cloudflared arguments for named tunnel
298
+ const args = ["tunnel", "run"];
299
+ // Add credentials file if specified
300
+ if (this.config.credentialsPath) {
301
+ args.push("--credentials-file", this.config.credentialsPath);
302
+ }
303
+ // Add origin configuration
304
+ args.push("--url", `http://127.0.0.1:${proxyPort}`);
305
+ // Add tunnel name
306
+ args.push(this.config.tunnelName);
307
+ return new Promise((resolve, reject) => {
308
+ const tunnelId = `cf-named-${Date.now()}`;
309
+ let started = false;
310
+ let errorOutput = "";
311
+ this.process = (0, child_process_1.spawn)(this.binPath, args, {
312
+ stdio: ["ignore", "pipe", "pipe"],
313
+ shell: process.platform === "win32",
314
+ });
315
+ const handleOutput = (data) => {
316
+ const output = data.toString();
317
+ // Look for "Registered tunnel connection" or similar success message
318
+ if ((output.includes("Registered tunnel connection") ||
319
+ output.includes("Connection registered") ||
320
+ output.includes("Started tunnel")) && !started) {
321
+ started = true;
322
+ // For named tunnels, the public URL is based on the hostname config
323
+ const publicUrl = this.config.hostname
324
+ ? `https://${this.config.hostname}`
325
+ : `https://${this.config.tunnelName}.cfargotunnel.com`;
326
+ const tunnel = {
327
+ id: tunnelId,
328
+ publicUrl,
329
+ protocol: options.protocol,
330
+ localPort: options.localPort,
331
+ localHost: options.localHost,
332
+ };
333
+ this.tunnels.set(tunnel.id, tunnel);
334
+ this.emit("tunnel:created", { tunnelId: tunnel.id, publicUrl });
335
+ resolve({ tunnelId: tunnel.id, publicUrl });
336
+ }
337
+ if (output.includes("ERR") || output.includes("error")) {
338
+ errorOutput += output;
339
+ }
340
+ };
341
+ this.process.stdout?.on("data", handleOutput);
342
+ this.process.stderr?.on("data", handleOutput);
343
+ this.process.on("error", (err) => {
344
+ if (this.proxyServer) {
345
+ this.proxyServer.close();
346
+ this.proxyServer = null;
347
+ }
348
+ reject(new Error(`Failed to start cloudflared: ${err.message}`));
349
+ });
350
+ this.process.on("close", (code) => {
351
+ if (!started) {
352
+ if (this.proxyServer) {
353
+ this.proxyServer.close();
354
+ this.proxyServer = null;
355
+ }
356
+ reject(new Error(errorOutput || `cloudflared exited with code ${code}`));
357
+ }
358
+ });
359
+ // Timeout for named tunnels
360
+ setTimeout(() => {
361
+ if (!started) {
362
+ if (this.process) {
363
+ this.process.kill();
364
+ this.process = null;
365
+ }
366
+ if (this.proxyServer) {
367
+ this.proxyServer.close();
368
+ this.proxyServer = null;
369
+ }
370
+ reject(new Error("Timeout waiting for named tunnel to start. " + (errorOutput || "Check credentials and tunnel name.")));
371
+ }
372
+ }, 60000); // Named tunnels may take longer
373
+ });
374
+ }
375
+ async closeTunnel(tunnelId) {
376
+ this.tunnels.delete(tunnelId);
377
+ if (this.process) {
378
+ this.process.kill();
379
+ this.process = null;
380
+ }
381
+ if (this.proxyServer) {
382
+ this.proxyServer.close();
383
+ this.proxyServer = null;
384
+ }
385
+ }
386
+ getTunnels() {
387
+ return Array.from(this.tunnels.values());
388
+ }
389
+ // =========================================================================
390
+ // Static tunnel management methods (for CLI commands)
391
+ // =========================================================================
392
+ /**
393
+ * Check if cloudflared is installed
394
+ */
395
+ static async isAvailable() {
396
+ try {
397
+ const cf = await getCloudflaredModule();
398
+ return (0, fs_1.existsSync)(cf.bin);
399
+ }
400
+ catch {
401
+ return false;
402
+ }
403
+ }
404
+ /**
405
+ * Install cloudflared if not present
406
+ */
407
+ static async ensureInstalled() {
408
+ const cf = await getCloudflaredModule();
409
+ if (!(0, fs_1.existsSync)(cf.bin)) {
410
+ await cf.install(cf.bin);
411
+ }
412
+ return cf.bin;
413
+ }
414
+ /**
415
+ * Get cloudflared binary path
416
+ */
417
+ static async getBinPath() {
418
+ const cf = await getCloudflaredModule();
419
+ return cf.bin;
420
+ }
421
+ /**
422
+ * Create a new named tunnel
423
+ */
424
+ static async createNamedTunnel(name) {
425
+ const binPath = await CloudflareTunnelClient.ensureInstalled();
426
+ return new Promise((resolve) => {
427
+ const proc = (0, child_process_1.spawn)(binPath, ["tunnel", "create", name], {
428
+ stdio: ["ignore", "pipe", "pipe"],
429
+ shell: process.platform === "win32",
430
+ });
431
+ let output = "";
432
+ let errorOutput = "";
433
+ proc.stdout?.on("data", (data) => { output += data.toString(); });
434
+ proc.stderr?.on("data", (data) => { errorOutput += data.toString(); });
435
+ proc.on("close", (code) => {
436
+ if (code === 0) {
437
+ resolve({ success: true, message: output.trim() });
438
+ }
439
+ else {
440
+ resolve({ success: false, error: errorOutput.trim() || `Exit code ${code}` });
441
+ }
442
+ });
443
+ proc.on("error", (err) => {
444
+ resolve({ success: false, error: err.message });
445
+ });
446
+ });
447
+ }
448
+ /**
449
+ * List all named tunnels
450
+ */
451
+ static async listTunnels() {
452
+ const binPath = await CloudflareTunnelClient.ensureInstalled();
453
+ return new Promise((resolve) => {
454
+ const proc = (0, child_process_1.spawn)(binPath, ["tunnel", "list"], {
455
+ stdio: ["ignore", "pipe", "pipe"],
456
+ shell: process.platform === "win32",
457
+ });
458
+ let output = "";
459
+ let errorOutput = "";
460
+ proc.stdout?.on("data", (data) => { output += data.toString(); });
461
+ proc.stderr?.on("data", (data) => { errorOutput += data.toString(); });
462
+ proc.on("close", (code) => {
463
+ if (code === 0) {
464
+ resolve({ success: true, tunnels: output.trim() });
465
+ }
466
+ else {
467
+ resolve({ success: false, error: errorOutput.trim() || `Exit code ${code}` });
468
+ }
469
+ });
470
+ proc.on("error", (err) => {
471
+ resolve({ success: false, error: err.message });
472
+ });
473
+ });
474
+ }
475
+ /**
476
+ * Delete a named tunnel
477
+ */
478
+ static async deleteTunnel(name) {
479
+ const binPath = await CloudflareTunnelClient.ensureInstalled();
480
+ return new Promise((resolve) => {
481
+ const proc = (0, child_process_1.spawn)(binPath, ["tunnel", "delete", name], {
482
+ stdio: ["ignore", "pipe", "pipe"],
483
+ shell: process.platform === "win32",
484
+ });
485
+ let output = "";
486
+ let errorOutput = "";
487
+ proc.stdout?.on("data", (data) => { output += data.toString(); });
488
+ proc.stderr?.on("data", (data) => { errorOutput += data.toString(); });
489
+ proc.on("close", (code) => {
490
+ if (code === 0) {
491
+ resolve({ success: true, message: output.trim() });
492
+ }
493
+ else {
494
+ resolve({ success: false, error: errorOutput.trim() || `Exit code ${code}` });
495
+ }
496
+ });
497
+ proc.on("error", (err) => {
498
+ resolve({ success: false, error: err.message });
499
+ });
500
+ });
501
+ }
502
+ /**
503
+ * Route DNS for a tunnel
504
+ */
505
+ static async routeDns(tunnelName, hostname) {
506
+ const binPath = await CloudflareTunnelClient.ensureInstalled();
507
+ return new Promise((resolve) => {
508
+ const proc = (0, child_process_1.spawn)(binPath, ["tunnel", "route", "dns", tunnelName, hostname], {
509
+ stdio: ["ignore", "pipe", "pipe"],
510
+ shell: process.platform === "win32",
511
+ });
512
+ let output = "";
513
+ let errorOutput = "";
514
+ proc.stdout?.on("data", (data) => { output += data.toString(); });
515
+ proc.stderr?.on("data", (data) => { errorOutput += data.toString(); });
516
+ proc.on("close", (code) => {
517
+ if (code === 0) {
518
+ resolve({ success: true, message: output.trim() });
519
+ }
520
+ else {
521
+ resolve({ success: false, error: errorOutput.trim() || `Exit code ${code}` });
522
+ }
523
+ });
524
+ proc.on("error", (err) => {
525
+ resolve({ success: false, error: err.message });
526
+ });
527
+ });
528
+ }
529
+ }
530
+ exports.CloudflareTunnelClient = CloudflareTunnelClient;
531
+ //# sourceMappingURL=CloudflareTunnelClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CloudflareTunnelClient.js","sourceRoot":"","sources":["../../src/client/CloudflareTunnelClient.ts"],"names":[],"mappings":"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"}