Class: Everywhere::MobileConfigEndpoint

Inherits:
Object
  • Object
show all
Defined in:
lib/everywhere/mobile_config_endpoint.rb

Overview

Rack middleware serving the mobile shells' remote path configuration:

GET /everywhere/ios_v1.json      (android_v1.json when that shell lands)

The JSON is built from config/everywhere.yml on each request (it's a tiny file, and re-reading means tab changes deploy with the app — the whole point: no app-store release to change tabs). This middleware is the SINATRA/HANAMI strategy — add it to config.ru:

use Everywhere::MobileConfigEndpoint

Rails apps don't need it: Everywhere::Engine appends a real route to MobileConfigsController instead (logging, instrumentation, overridable).

The native shells load it as a Hotwire Native path-configuration source (after their bundled copy), so both rules and settings.tabs can be overridden server-side.

Constant Summary collapse

PATH =
%r{\A/everywhere/(ios|android)_v1\.json\z}
RESET =
"/everywhere/reset"
AASA =
"/.well-known/apple-app-site-association"
"/.well-known/assetlinks.json"

Instance Method Summary collapse

Constructor Details

#initialize(app, root: Dir.pwd) ⇒ MobileConfigEndpoint

Returns a new instance of MobileConfigEndpoint.



29
30
31
32
# File 'lib/everywhere/mobile_config_endpoint.rb', line 29

def initialize(app, root: Dir.pwd)
  @app = app
  @root = root
end

Instance Method Details

#call(env) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/everywhere/mobile_config_endpoint.rb', line 34

def call(env)
  return @app.call(env) unless env["REQUEST_METHOD"] == "GET"

  if env["PATH_INFO"] == RESET
    require "rack/utils"
    to = Rack::Utils.parse_query(env["QUERY_STRING"])["to"]
    return html(Everywhere.mobile_reset_html(to))
  end

  # Deep-linking association files (generated from everywhere.yml). Pass
  # through when not configured so the host app can serve its own.
  if env["PATH_INFO"] == AASA
    body = Config.load(@root).apple_app_site_association_json
    return body ? json(body) : @app.call(env)
  end
  if env["PATH_INFO"] == ASSETLINKS
    body = Config.load(@root).asset_links_json
    return body ? json(body) : @app.call(env)
  end

  match = PATH.match(env["PATH_INFO"]) or return @app.call(env)

  os = match[1]
  config = Config.load(@root)
  tabs = Everywhere.resolve_tabs(config.tabs_for(os), request_for(env))
  json(config.path_configuration_json(os, tabs: tabs))
end