npm package diff
Package: @forge/tunnel
Versions: 5.8.2-next.0-experimental-147ff14 - 5.9.0-next.1
File: package/out/services/create-tunnel-service.js
Index: package/out/services/create-tunnel-service.js
===================================================================
--- package/out/services/create-tunnel-service.js
+++ package/out/services/create-tunnel-service.js
@@ -1,9 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CloudflareCreateTunnelService = exports.CloudflareError = void 0;
-const cloudflared_1 = require("cloudflared");
+const tslib_1 = require("tslib");
const url_1 = require("url");
+const child_process_1 = require("child_process");
+const which_1 = tslib_1.__importDefault(require("which"));
+const fs_1 = tslib_1.__importDefault(require("fs"));
const cli_shared_1 = require("@forge/cli-shared");
class CloudflareError extends cli_shared_1.BaseError {
}
exports.CloudflareError = CloudflareError;
@@ -12,52 +15,78 @@
stopFunction;
constructor(logger) {
this.logger = logger;
}
- handleTunnleEstablishError(e) {
+ handleTunnelEstablishError(e, usingLocalCloudflareBinary) {
const UNKNOWN_SYS_ERROR = 'Unknown system error -86';
const userSysErrors = [UNKNOWN_SYS_ERROR, 'EPERM'];
- if (userSysErrors.some((error) => e.message.includes(error))) {
+ if (userSysErrors.some((error) => e.message.includes(error)) || usingLocalCloudflareBinary) {
let errorMessage = e.message;
if (e.message.includes(UNKNOWN_SYS_ERROR)) {
errorMessage += ': Running `softwareupdate --install-rosetta` may help fix the problem';
}
- throw new cli_shared_1.UserError(undefined, errorMessage);
+ return new cli_shared_1.UserError(errorMessage);
}
- throw e;
+ return e;
}
+ handleChildProcessData(child) {
+ child.stdout?.on('data', (chunk) => this.logger.debug(cli_shared_1.Text.tunnel.cloudflaredLog(chunk)));
+ child.stderr?.on('data', (chunk) => this.logger.debug(cli_shared_1.Text.tunnel.cloudflaredLog(chunk)));
+ child.on('error', (err) => {
+ this.logger.error(err);
+ throw new cli_shared_1.BaseError(undefined, cli_shared_1.Text.tunnel.error.cloudflaredError);
+ });
+ child.on('exit', (code) => {
+ if (code !== 0 && code !== null) {
+ throw new cli_shared_1.BaseError(undefined, cli_shared_1.Text.tunnel.error.cloudflaredExit(code));
+ }
+ });
+ }
async establishTunnel({ port, id, token, tunnelUrl }) {
if (!id || !token || !tunnelUrl) {
throw new CloudflareError(undefined, 'Missing configuration to create tunnel');
}
- const options = {
- run: null,
- '--token': token,
- '--url': `localhost:${port}`,
- '--protocol': 'http2'
- };
- options[id] = null;
+ const options = [
+ 'tunnel',
+ 'run',
+ '--token',
+ token,
+ '--url',
+ `localhost:${port}`,
+ '--protocol',
+ 'http2'
+ ];
process.env['TUNNEL_LOGLEVEL'] = 'debug';
+ let cloudflaredBinary = null;
+ let usingLocalCloudflareBinary = false;
try {
- const { connections, stop, child } = (0, cloudflared_1.tunnel)(options);
- child.stdout?.on('data', (chunk) => this.logger.debug(cli_shared_1.Text.tunnel.cloudflaredLog(chunk)));
- child.stderr?.on('data', (chunk) => this.logger.debug(cli_shared_1.Text.tunnel.cloudflaredLog(chunk)));
- child.on('error', (err) => {
- this.logger.error(err);
- throw new cli_shared_1.BaseError(undefined, cli_shared_1.Text.tunnel.error.cloudflaredError);
- });
- child.on('exit', (code) => {
- if (code !== 0 && code !== null) {
- throw new cli_shared_1.BaseError(undefined, cli_shared_1.Text.tunnel.error.cloudflaredExit(code));
+ const cloudflaredBin = require('cloudflared').bin;
+ if (fs_1.default.existsSync(cloudflaredBin)) {
+ cloudflaredBinary = cloudflaredBin;
+ }
+ }
+ catch (error) { }
+ try {
+ if (!cloudflaredBinary) {
+ cloudflaredBinary = await (0, which_1.default)('cloudflared', { nothrow: true });
+ if (cloudflaredBinary) {
+ usingLocalCloudflareBinary = true;
+ this.logger.warn(cli_shared_1.Text.tunnel.tunnelWithLocalCloudflared);
}
- });
- await Promise.all(connections);
- this.stopFunction = stop;
+ }
+ if (!cloudflaredBinary) {
+ throw new cli_shared_1.UserError(cli_shared_1.Text.tunnel.error.cloudflaredUnavailableError);
+ }
+ const cloudflareTunnelProcess = (0, child_process_1.spawn)(cloudflaredBinary, options, { stdio: ['ignore', 'pipe', 'pipe'] });
+ this.handleChildProcessData(cloudflareTunnelProcess);
+ this.stopFunction = (signal) => {
+ return cloudflareTunnelProcess.kill(signal);
+ };
this.logger.debug(cli_shared_1.Text.tunnel.startedTunnel(tunnelUrl));
return new url_1.URL(tunnelUrl);
}
catch (e) {
- throw this.handleTunnleEstablishError(e);
+ throw this.handleTunnelEstablishError(e, usingLocalCloudflareBinary);
}
}
async closeTunnel() {
if (this.stopFunction) {