Class: Backlex::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/backlex/client.rb

Overview

The official Ruby client for the backlex API — a thin, typed wrapper over the same REST + SSE surface the TypeScript SDK (@backlex/client) speaks. Three auth modes: server key, workspace app mode (token capture), or cookie session.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, api_key: nil, workspace: nil, token: nil, tenant: nil) ⇒ Client

Returns a new instance of Client.



15
16
17
18
19
20
21
# File 'lib/backlex/client.rb', line 15

def initialize(url, api_key: nil, workspace: nil, token: nil, tenant: nil)
  @url = url.chomp("/")
  @api_key = api_key
  @workspace = workspace
  @app_token = token
  @tenant = tenant
end

Instance Attribute Details

#app_tokenObject

Returns the value of attribute app_token.



13
14
15
# File 'lib/backlex/client.rb', line 13

def app_token
  @app_token
end

#workspaceObject (readonly)

Returns the value of attribute workspace.



12
13
14
# File 'lib/backlex/client.rb', line 12

def workspace
  @workspace
end

Class Method Details

.build_search(query) ⇒ Object

Serialize a ListQuery hash into a URL query string (mirrors buildSearch in index.ts). The filter is compact JSON, percent-encoded exactly once.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/backlex/client.rb', line 94

def self.build_search(query)
  return "" if query.nil?

  parts = []
  if query[:filter] && !query[:filter].empty?
    parts << "filter=#{URI.encode_www_form_component(JSON.generate(query[:filter]))}"
  end
  # sort/fields may be absent when a hand-built query (e.g. one(id, expand:)) is
  # passed rather than a full builder-produced ListQuery — default to [].
  parts << "sort=#{URI.encode_www_form_component(query[:sort].join(','))}" unless (query[:sort] || []).empty?
  parts << "fields=#{URI.encode_www_form_component(query[:fields].join(','))}" unless (query[:fields] || []).empty?
  unless (query[:expand] || []).empty?
    parts << "expand=#{URI.encode_www_form_component(query[:expand].join(','))}"
  end
  parts << "limit=#{query[:limit]}" unless query[:limit].nil?
  parts << "offset=#{query[:offset]}" unless query[:offset].nil?
  parts << "meta=#{URI.encode_www_form_component(query[:meta])}" if query[:meta]
  parts << "locale=#{URI.encode_www_form_component(query[:locale])}" if query[:locale]
  parts << "q=#{URI.encode_www_form_component(query[:q])}" if query[:q]
  parts.empty? ? "" : "?#{parts.join('&')}"
end

Instance Method Details

#authObject



28
29
30
# File 'lib/backlex/client.rb', line 28

def auth
  @auth ||= Auth.new(self)
end

#auth_header(req) ⇒ Object



83
84
85
86
87
88
89
90
# File 'lib/backlex/client.rb', line 83

def auth_header(req)
  if @api_key
    req["Authorization"] = "Bearer #{@api_key}"
  elsif @app_token
    req["Authorization"] = "Bearer #{@app_token}"
  end
  req["X-Backlex-Tenant"] = @tenant if @tenant
end

#from(slug) ⇒ Object

CRUD handle for a collection.



24
25
26
# File 'lib/backlex/client.rb', line 24

def from(slug)
  Collection.new(self, slug)
end

#get_raw(path) ⇒ Object

Raw byte download (storage). Returns the response body string.

Raises:



72
73
74
75
76
77
78
79
80
81
# File 'lib/backlex/client.rb', line 72

def get_raw(path)
  uri = URI(@url + path)
  req = Net::HTTP::Get.new(uri)
  auth_header(req)
  res = send_request(uri, req)
  code = res.code.to_i
  raise Backlex::Error.new(code, "UNKNOWN", "HTTP #{code}") if code < 200 || code >= 300

  res.body
end

#put_raw(path, body, content_type) ⇒ Object

Raw-body upload (storage). Returns the parsed JSON response.



58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/backlex/client.rb', line 58

def put_raw(path, body, content_type)
  uri = URI(@url + path)
  req = Net::HTTP::Put.new(uri)
  req["Content-Type"] = content_type if content_type
  req.body = body
  auth_header(req)
  res = send_request(uri, req)
  code = res.code.to_i
  raise Backlex::Error.from(code, res.body) if code < 200 || code >= 300

  res.body.nil? || res.body.empty? ? nil : JSON.parse(res.body)
end

#request(method, path, body = nil) ⇒ Object

Raw escape hatch — issues a JSON request with auth headers applied.



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/backlex/client.rb', line 43

def request(method, path, body = nil)
  uri = URI(@url + path)
  req = build_request(method, uri)
  req["Content-Type"] = "application/json"
  req.body = JSON.generate(body) unless body.nil?
  auth_header(req)
  res = send_request(uri, req)
  code = res.code.to_i
  raise Backlex::Error.from(code, res.body) if code < 200 || code >= 300
  return nil if code == 204 || res.body.nil? || res.body.empty?

  JSON.parse(res.body)
end

#storageObject



32
33
34
# File 'lib/backlex/client.rb', line 32

def storage
  @storage ||= Storage.new(self)
end

#subscribe(channel, on_event, on_error = nil) ⇒ Object

Subscribe to a realtime channel (e.g. “items:posts”). Returns a Subscription; #close unsubscribes. on_error may be nil.



38
39
40
# File 'lib/backlex/client.rb', line 38

def subscribe(channel, on_event, on_error = nil)
  Subscription.new(self, "#{@url}/api/realtime/#{channel}/subscribe", on_event, on_error)
end