Class: ShopifyCLI::Tunnel

Inherits:
Object
  • Object
show all
Extended by:
SingleForwardable
Defined in:
lib/shopify_cli/tunnel.rb

Overview

Wraps around ngrok functionality to allow you to spawn a ngrok proccess in the background and stop the process when you need to. It also allows control over the ngrok process between application runs.

Defined Under Namespace

Classes: FetchUrlError, NgrokError

Constant Summary collapse

PORT =

port that ngrok will bind to

8081
DOWNLOAD_URLS =

mapping for supported operating systems for where to download ngrok from.

{
  mac: "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-amd64.zip",
  mac_m1: "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-arm64.zip",
  linux: "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip",
  windows: "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-windows-amd64.zip",
}
NGROK_TUNNELS_URI =
URI.parse("http://localhost:4040/api/tunnels")
TUNNELS_FIELD =
"tunnels"
TUNNEL_ADDRESS_KEY_PATH =
["config", "addr"]
PUBLIC_URL_FIELD =
"public_url"

Instance Method Summary collapse

Instance Method Details

#auth(ctx, token) ⇒ Object

will add the users authentication token to our version of ngrok to unlock the extended ngrok features

#### Paramters

  • ‘ctx` - running context from your command

  • ‘token` - authentication token provided by ngrok for extended features



84
85
86
87
# File 'lib/shopify_cli/tunnel.rb', line 84

def auth(ctx, token)
  install(ctx)
  ctx.system(ngrok_path(ctx), "authtoken", token)
end

#authenticated?Boolean

returns a boolean: if the user has a ngrok token to authenticate

Returns:

  • (Boolean)


92
93
94
95
96
# File 'lib/shopify_cli/tunnel.rb', line 92

def authenticated?
  ngrok_config_path = File.join(Dir.home, ".ngrok2/ngrok.yml")
  return false unless File.exist?(ngrok_config_path)
  File.read(ngrok_config_path).include?("authtoken")
end

#running_on?(port) ⇒ Boolean

Returns Boolean if a tunnel is running on a given port

#### Parameters

  • ‘port` - port to check

#### Returns

  • true / false

Returns:

  • (Boolean)


137
138
139
140
141
142
143
# File 'lib/shopify_cli/tunnel.rb', line 137

def running_on?(port)
  extract_port = ->(tunnel) { URI(tunnel.dig(*TUNNEL_ADDRESS_KEY_PATH)).port }
  matches_port = ->(occupied_port) { occupied_port == port }
  stats.fetch(TUNNELS_FIELD, []).map(&extract_port).any?(&matches_port)
rescue
  false
end

#start(ctx, port: PORT) ⇒ Object

start will start a running ngrok process running in the background. It will also output the success of this operation

#### Paramters

  • ‘ctx` - running context from your command

  • ‘port` - port to use to open the ngrok tunnel

#### Returns

  • ‘url` - the url that the tunnel is now bound to and available to the public



67
68
69
70
71
72
73
# File 'lib/shopify_cli/tunnel.rb', line 67

def start(ctx, port: PORT)
  install(ctx)
  ctx.abort(ctx.message("core.tunnel.error.signup_required", ShopifyCLI::TOOL_NAME)) unless authenticated?
  url,  = start_ngrok(ctx, port)
  ctx.puts(ctx.message("core.tunnel.start_with_account", url, ))
  url
end

#statsObject

will return the statistics of the current running tunnels

#### Returns

  • ‘stats` - the hash of running statistics returning from the ngrok api



105
106
107
108
109
110
# File 'lib/shopify_cli/tunnel.rb', line 105

def stats
  response = Net::HTTP.get_response(NGROK_TUNNELS_URI)
  JSON.parse(response.body)
rescue
  {}
end

#stop(ctx) ⇒ Object

will find and stop a running tunnel process. It will also output if the operation was successful or not

#### Paramters

  • ‘ctx` - running context from your command



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/shopify_cli/tunnel.rb', line 42

def stop(ctx)
  if ShopifyCLI::ProcessSupervision.running?(:ngrok)
    if ShopifyCLI::ProcessSupervision.stop(:ngrok)
      ctx.puts(ctx.message("core.tunnel.stopped"))
    else
      ctx.abort(ctx.message("core.tunnel.error.stop"))
    end
  else
    ctx.puts(ctx.message("core.tunnel.not_running"))
  end
end

#urlsObject

will return the urls of the current running tunnels

#### Returns

  • ‘stats` - the array of urls



119
120
121
122
123
124
# File 'lib/shopify_cli/tunnel.rb', line 119

def urls
  tunnels = stats.dig(TUNNELS_FIELD)
  tunnels.map { |tunnel| tunnel.dig(PUBLIC_URL_FIELD) }
rescue
  []
end