trmnl-api 0.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0ba1eee66530c227b2e43b24de28e6913753d4f627af3d979c3add5cbba3846c
4
+ data.tar.gz: da5463562b79f6b883f90925cb61ffc44b357c3e64eec615f5cbb0a433f3a36a
5
+ SHA512:
6
+ metadata.gz: 03430a130bfa5a302b67c674ece3951b88e0629f256c7937351d562a7f52117b7b0a0704817fbda6a4d771ee0ddd59542f80e9cccd5970c6ab5a8dfe1e9be0ba
7
+ data.tar.gz: 71d6d93f75797dad4ef0ae37e6b454d65adcff265149de1f6e32175ae7d5970b4aa590283eed5d95ae93ccfad89672c1a835ce4529af8e1ea5d53a4844a5f532
checksums.yaml.gz.sig ADDED
Binary file
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 TRMNL
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.adoc ADDED
@@ -0,0 +1,211 @@
1
+ :toc: macro
2
+ :toclevels: 5
3
+ :figure-caption!:
4
+
5
+ :trmnl_link: link:https://usetrmnl.com[TRMNL]
6
+ :dry_monads_link: link:https://dry-rb.org/gems/dry-monads[Dry Monads]
7
+
8
+ = TRMNL API
9
+
10
+ A monadic {trmnl_link} API client. You can use this client in your own code to interact with our APIs for any/all devices that you own.
11
+
12
+ toc::[]
13
+
14
+ == Features
15
+
16
+ * Provides {trmnl_link} API access.
17
+
18
+ == Requirements
19
+
20
+ . link:https://www.ruby-lang.org[Ruby].
21
+ . A {trmnl_link} device (physical or virtual).
22
+
23
+ == Setup
24
+
25
+ To install, run:
26
+
27
+ [source,bash]
28
+ ----
29
+ gem install trmnl-api
30
+ ----
31
+
32
+ You can also add the gem directly to your project:
33
+
34
+ [source,bash]
35
+ ----
36
+ bundle add trmnl-api
37
+ ----
38
+
39
+ Once the gem is installed, you only need to require it:
40
+
41
+ [source,ruby]
42
+ ----
43
+ require "trmnl/api"
44
+ ----
45
+
46
+ == Usage
47
+
48
+ This client provides access to multiple endpoints. Each endpoint will answer either a `Success` or `Failure` (as provided by {dry_monads_link}) based on result of the API call. This allows you pattern match in your own code when using each endpoint. Example:
49
+
50
+ ``` ruby
51
+ case endpoint.call token: "secret"
52
+ in Success(payload) then puts payload
53
+ in Failure(response) then puts response
54
+ else puts "Unknown HTTP response."
55
+ end
56
+ ```
57
+
58
+ See each endpoint for further details.
59
+
60
+ === Environment
61
+
62
+ You can configure the client via the following environment variables:
63
+
64
+ * `TRMNL_API_CONTENT_TYPE`: Defines the HTTP `Content-Type` header. You shouldn't need to change this but is here if you need it. Default: "application/json".
65
+ * `TRMNL_API_URI`: Defines the API URI. Default: "https://trmnl.app/api".
66
+
67
+ Any/all environment changes will be applied to all endpoint objects.
68
+
69
+ === Current Screen
70
+
71
+ Allows you to obtain current screen being displayed for your device. You must supply your device's API token as the `token`. Example:
72
+
73
+ [source,ruby]
74
+ ----
75
+ endpoint = TRMNL::API::Endpoints::CurrentScreen.new
76
+ endpoint.call token: "secret"
77
+
78
+ # Success(
79
+ # #<data TRMNL::API::Models::CurrentScreen
80
+ # refresh_rate=1773,
81
+ # image_url="https://usetrmnl.com/plugin-2025-04-10T11-34-38Z-380c77",
82
+ # filename="plugin-2025-04-10T11-34-38Z-380c77"
83
+ # >
84
+ # )
85
+ ----
86
+
87
+ === Display
88
+
89
+ Allows you to obtain current screen being displayed for your device. You must supply your device's API token as the `token`. Example:
90
+
91
+ [source,ruby]
92
+ ----
93
+ endpoint = TRMNL::API::Endpoints::Display.new
94
+ endpoint.call token: "secret"
95
+
96
+ # Success(
97
+ # #<struct TRMNL::API::Models::Display
98
+ # filename="plugin-1745348489",
99
+ # firmware_url="https://trmnl-fw.s3.us-east-2.amazonaws.com/FW1.4.8.bin",
100
+ # image_url="https://trmnl.s3.us-east-2.amazonaws.com/plugin-1745348489",
101
+ # image_url_timeout=0,
102
+ # refresh_rate=1771,
103
+ # reset_firmware=false,
104
+ # special_function="restart_playlist",
105
+ # update_firmware=true
106
+ # >
107
+ # )
108
+ ----
109
+
110
+ === Firmware
111
+
112
+ Allows you to obtain the current stable firmware version. Example:
113
+
114
+ [source,ruby]
115
+ ----
116
+ endpoint = TRMNL::API::Endpoints::Firmware.new
117
+ endpoint.call
118
+
119
+ # Success(#<data TRMNL::API::Models::Firmware url="https://trmnl-fw.s3.us-east-2.amazonaws.com/FW1.4.8.bin", version="1.4.8">)
120
+ ----
121
+
122
+ === Log
123
+
124
+ Allows you to create a log entry (which is what the device reports when it captures an error). You must supply your device's API token as the `token`. Example:
125
+
126
+ [source,ruby]
127
+ ----
128
+ endpoint = TRMNL::API::Endpoints::Log.new
129
+ endpoint.call token: "secret",
130
+ log: {
131
+ logs_array: [
132
+ {
133
+ log_id: 1,
134
+ creation_timestamp: 1742022124,
135
+ log_message: "returned code is not OK: 404",
136
+ log_codeline: 597,
137
+ device_status_stamp: {
138
+ wifi_status: "connected",
139
+ wakeup_reason: "timer",
140
+ current_fw_version: "1.4.7",
141
+ free_heap_size: 160656,
142
+ special_function: "none",
143
+ refresh_rate: 30,
144
+ battery_voltage: 4.772,
145
+ time_since_last_sleep_start: 31,
146
+ wifi_rssi_level: -54
147
+ },
148
+ additional_info: {
149
+ retry_attempt: 1
150
+ },
151
+ log_sourcefile: "src/bl.cpp"
152
+ }
153
+ ]
154
+ }
155
+
156
+ # Success(#<HTTP::Response/1.1 204 No Content...)
157
+ ----
158
+
159
+ You'll either get a 204 No Content or 200 OK response depending on if the device exists or not.
160
+
161
+ === Setup
162
+
163
+ Allows you to obtain the setup response for when a new device is setup. You must supply your device's MAC Address as the `id`. Example:
164
+
165
+
166
+ [source,ruby]
167
+ ----
168
+ endpoint = TRMNL::API::Endpoints::Setup.new
169
+ endpoint.call id: "B0:81:84:22:BD:E8"
170
+
171
+ # Success(
172
+ # #<data TRMNL::API::Models::Setup
173
+ # api_key="secret",
174
+ # friendly_id="40DEF8",
175
+ # image_url="https://usetrmnl.com/images/setup/setup-logo.bmp",
176
+ # message="Register at usetrmnl.com/signup with Device ID '40DEF8'"
177
+ # >
178
+ # )
179
+ ----
180
+
181
+ == Development
182
+
183
+ To contribute, run:
184
+
185
+ [source,bash]
186
+ ----
187
+ git clone https://github.com/usetrmnl/trmnl-api
188
+ cd trmnl-api
189
+ bin/setup
190
+ ----
191
+
192
+ You can also use the IRB console for direct access to all objects:
193
+
194
+ [source,bash]
195
+ ----
196
+ bin/console
197
+ ----
198
+
199
+ == Tests
200
+
201
+ To test, run:
202
+
203
+ [source,bash]
204
+ ----
205
+ bin/rake
206
+ ----
207
+
208
+ == Credits
209
+
210
+ * Built with link:https://alchemists.io/projects/gemsmith[Gemsmith].
211
+ * Engineered by link:https://usetrmnl.com/developers[TRMNL].
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+ require "http"
5
+
6
+ module TRMNL
7
+ module API
8
+ # Provides a low level configurable and monadic API client.
9
+ # :reek:DataClump
10
+ class Client
11
+ include Dry::Monads[:result]
12
+
13
+ HEADERS = {}.freeze
14
+
15
+ def initialize settings: TRMNL::API::Configuration::Loader.new.call, http: HTTP
16
+ @settings = settings
17
+ @http = http
18
+
19
+ yield settings if block_given?
20
+ end
21
+
22
+ def get(path, headers: HEADERS, **params) = call(__method__, path, headers, params:)
23
+
24
+ def post(path, headers: HEADERS, **json) = call(__method__, path, headers, json:)
25
+
26
+ private
27
+
28
+ attr_reader :settings, :http
29
+
30
+ # rubocop:todo Metrics/ParameterLists
31
+ def call method, path, headers, **options
32
+ http.headers(settings.headers.merge(headers))
33
+ .public_send(method, "#{settings.uri}/#{path}", options)
34
+ .then { |response| response.status.success? ? Success(response) : Failure(response) }
35
+ end
36
+ # rubocop:enable Metrics/ParameterLists
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRMNL
4
+ module API
5
+ module Configuration
6
+ # Provides API client configuration content.
7
+ Content = Struct.new :content_type, :uri do
8
+ def headers = {"Content-Type" => content_type}.compact
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRMNL
4
+ module API
5
+ module Configuration
6
+ # Loads configuration based on environment or falls back to defaults.
7
+ class Loader
8
+ def initialize model: Content, environment: ENV
9
+ @model = model
10
+ @environment = environment
11
+ end
12
+
13
+ def call
14
+ model[
15
+ content_type: environment.fetch("TRMNL_API_CONTENT_TYPE", "application/json"),
16
+ uri: environment.fetch("TRMNL_API_URI", "https://trmnl.app/api")
17
+ ]
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :model, :environment
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cogger"
4
+ require "containable"
5
+ require "http"
6
+
7
+ module TRMNL
8
+ module API
9
+ # Registers application dependencies.
10
+ module Container
11
+ extend Containable
12
+
13
+ register(:client) { API::Client.new }
14
+ register(:logger) { Cogger.new id: "trmnl-api", formatter: :json }
15
+
16
+ register :http do
17
+ HTTP.default_options = ::HTTP::Options.new features: {logging: {logger: self[:logger]}}
18
+ HTTP
19
+ end
20
+
21
+ namespace :contracts do
22
+ register :current_screen, Contracts::CurrentScreen
23
+ register :display, Contracts::Display
24
+ register :firmware, Contracts::Firmware
25
+ register :setup, Contracts::Setup
26
+ end
27
+
28
+ namespace :models do
29
+ register :current_screen, Models::CurrentScreen
30
+ register :display, Models::Display
31
+ register :firmware, Models::Firmware
32
+ register :setup, Models::Setup
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Contracts
8
+ # Validates API response.
9
+ CurrentScreen = Dry::Schema.JSON do
10
+ required(:refresh_rate).filled :integer
11
+ required(:image_url).filled :string
12
+ required(:filename).filled :string
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Contracts
8
+ # Validates API response.
9
+ Display = Dry::Schema.JSON do
10
+ required(:filename).filled :string
11
+ required(:firmware_url).filled :string
12
+ required(:image_url).filled :string
13
+ required(:refresh_rate).filled :integer
14
+ required(:reset_firmware).filled :bool
15
+ required(:special_function).filled :string
16
+ required(:update_firmware).filled :bool
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Contracts
8
+ # Validates API response.
9
+ Firmware = Dry::Schema.JSON do
10
+ required(:url).filled :string
11
+ required(:version).filled :string
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Contracts
8
+ # Validates API response.
9
+ Setup = Dry::Schema.JSON do
10
+ required(:api_key).filled :string
11
+ required(:friendly_id).filled :string
12
+ required(:image_url).filled :string
13
+ required(:message).filled :string
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "infusible"
4
+
5
+ module TRMNL
6
+ # Defines endpoint dependencies for automatic injection.
7
+ module API
8
+ Dependencies = Infusible[Container]
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pipeable"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Endpoints
8
+ # Handles API request/response.
9
+ class CurrentScreen
10
+ include Dependencies[
11
+ :client,
12
+ contract: "contracts.current_screen",
13
+ model: "models.current_screen"
14
+ ]
15
+
16
+ include Pipeable
17
+
18
+ def call token:
19
+ pipe client.get("current_screen", headers: {"Access-Token" => token}),
20
+ try(:parse, catch: JSON::ParserError),
21
+ validate(contract, as: :to_h),
22
+ to(model, :for)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pipeable"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Endpoints
8
+ # Handles API request/response.
9
+ class Display
10
+ include Dependencies[:client, contract: "contracts.display", model: "models.display"]
11
+ include Pipeable
12
+
13
+ def call token:
14
+ pipe client.get("display", headers: {"Access-Token" => token}),
15
+ try(:parse, catch: JSON::ParserError),
16
+ validate(contract, as: :to_h),
17
+ to(model, :for)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pipeable"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Endpoints
8
+ # Handles API request/response.
9
+ class Firmware
10
+ include Dependencies[:client, contract: "contracts.firmware", model: "models.firmware"]
11
+ include Pipeable
12
+
13
+ def call
14
+ pipe client.get("firmware/latest"),
15
+ try(:parse, catch: JSON::ParserError),
16
+ validate(contract, as: :to_h),
17
+ to(model, :for)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRMNL
4
+ module API
5
+ module Endpoints
6
+ # Handles API request/response.
7
+ class Log
8
+ include Dependencies[:client]
9
+
10
+ def call(token:, **) = client.post("log", headers: {"Access-Token" => token}, **)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pipeable"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Endpoints
8
+ # Handles API request/response.
9
+ class Setup
10
+ include Dependencies[:client, contract: "contracts.setup", model: "models.setup"]
11
+ include Pipeable
12
+
13
+ def call id:
14
+ pipe client.get("setup", headers: {"ID" => id}),
15
+ try(:parse, catch: JSON::ParserError),
16
+ validate(contract, as: :to_h),
17
+ to(model, :for)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRMNL
4
+ module API
5
+ module Models
6
+ # Models API response.
7
+ CurrentScreen = Data.define :refresh_rate, :image_url, :filename do
8
+ def self.for(attributes) = new(**attributes)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRMNL
4
+ module API
5
+ module Models
6
+ # Models data for API display responses.
7
+ Display = Struct.new(
8
+ :filename,
9
+ :firmware_url,
10
+ :image_url,
11
+ :image_url_timeout,
12
+ :refresh_rate,
13
+ :reset_firmware,
14
+ :special_function,
15
+ :update_firmware
16
+ ) do
17
+ def self.for(attributes) = new(**attributes)
18
+
19
+ def initialize(**)
20
+ super
21
+ apply_defaults
22
+ freeze
23
+ end
24
+
25
+ def to_json(*) = to_h.to_json(*)
26
+
27
+ private
28
+
29
+ def apply_defaults
30
+ self[:image_url_timeout] ||= 0
31
+ self[:refresh_rate] ||= 300
32
+ self[:reset_firmware] ||= false
33
+ self[:update_firmware] ||= false
34
+ self[:special_function] ||= "sleep"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRMNL
4
+ module API
5
+ module Models
6
+ # Models API response.
7
+ Firmware = Data.define :url, :version do
8
+ def self.for(attributes) = new(**attributes)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRMNL
4
+ module API
5
+ module Models
6
+ # Models API response.
7
+ Setup = Data.define :api_key, :friendly_id, :image_url, :message do
8
+ def self.for(attributes) = new(**attributes)
9
+ end
10
+ end
11
+ end
12
+ end
data/lib/trmnl/api.rb ADDED
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema"
4
+ require "zeitwerk"
5
+
6
+ Dry::Schema.load_extensions :monads
7
+
8
+ Zeitwerk::Loader.new.then do |loader|
9
+ loader.inflector.inflect "api" => "API", "trmnl" => "TRMNL"
10
+ loader.tag = "trmnl-api"
11
+ loader.push_dir "#{__dir__}/.."
12
+ loader.setup
13
+ end
14
+
15
+ module TRMNL
16
+ # Main namespace.
17
+ module API
18
+ def self.loader registry = Zeitwerk::Registry
19
+ @loader ||= registry.loaders.find { |loader| loader.tag == "trmnl-api" }
20
+ end
21
+ end
22
+ end
data/trmnl-api.gemspec ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "trmnl-api"
5
+ spec.version = "0.0.0"
6
+ spec.authors = ["TRMNL"]
7
+ spec.email = ["support@usetrmnl.com"]
8
+ spec.homepage = "https://github.com/usetrmnl/trmnl-api"
9
+ spec.summary = "A monadic TRMNL API client."
10
+ spec.license = "MIT"
11
+
12
+ spec.metadata = {
13
+ "bug_tracker_uri" => "https://github.com/usetrmnl/trmnl-api/issues",
14
+ "changelog_uri" => "https://github.com/usetrmnl/trmnl-api/tags",
15
+ "homepage_uri" => "https://github.com/usetrmnl/trmnl-api",
16
+ "label" => "TRMNL API",
17
+ "rubygems_mfa_required" => "true",
18
+ "source_code_uri" => "https://github.com/usetrmnl/trmnl-api"
19
+ }
20
+
21
+ spec.signing_key = Gem.default_key_path
22
+ spec.cert_chain = [Gem.default_cert_path]
23
+
24
+ spec.required_ruby_version = "~> 3.4"
25
+
26
+ spec.add_dependency "cogger", "~> 1.2"
27
+ spec.add_dependency "containable", "~> 1.2"
28
+ spec.add_dependency "dry-monads", "~> 1.8"
29
+ spec.add_dependency "dry-schema", "~> 1.14"
30
+ spec.add_dependency "http", "~> 5.2"
31
+ spec.add_dependency "infusible", "~> 4.3"
32
+ spec.add_dependency "pipeable", "~> 1.3"
33
+ spec.add_dependency "zeitwerk", "~> 2.7"
34
+
35
+ spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
36
+ spec.files = Dir["*.gemspec", "lib/**/*"]
37
+ end
data.tar.gz.sig ADDED
Binary file
metadata ADDED
@@ -0,0 +1,207 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trmnl-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - TRMNL
8
+ bindir: bin
9
+ cert_chain:
10
+ - |
11
+ -----BEGIN CERTIFICATE-----
12
+ MIIENjCCAp6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADBBMQ8wDQYDVQQDDAZicm9v
13
+ a2UxGjAYBgoJkiaJk/IsZAEZFgphbGNoZW1pc3RzMRIwEAYKCZImiZPyLGQBGRYC
14
+ aW8wHhcNMjUwMzIyMTQ1NDE3WhcNMjYwMzIyMTQ1NDE3WjBBMQ8wDQYDVQQDDAZi
15
+ cm9va2UxGjAYBgoJkiaJk/IsZAEZFgphbGNoZW1pc3RzMRIwEAYKCZImiZPyLGQB
16
+ GRYCaW8wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCro8tj5/E1Hg88
17
+ f4qfiwPVd2zJQHvdYt4GHVvuHRRgx4HGhJuNp+4BId08RBn7V6V1MW6MY3kezRBs
18
+ M+7QOQ4b1xNLTvY7FYQB1wGK5a4x7TTokDrPYQxDB2jmsdDYCzVbIMrAvUfcecRi
19
+ khyGZCdByiiCl4fKv77P12tTT+NfsvXkLt/AYCGwjOUyGKTQ01Z6eC09T27GayPH
20
+ QQvIkakyFgcJtzSyGzs8bzK5q9u7wQ12MNTjJoXzW69lqp0oNvDylu81EiSUb5S6
21
+ QzzPxZBiRB1sgtbt1gUbVI262ZDq1gR+HxPFmp+Cgt7ZLIJZAtesQvtcMzseXpfn
22
+ hpmm0Sw22KGhRAy/mqHBRhDl5HqS1SJp2Ko3lcnpXeFResp0HNlt8NSu13vhC08j
23
+ GUHU9MyIXbFOsnp3K3ADrAVjPWop8EZkmUR3MV/CUm00w2cZHCSGiXl1KMpiVKvk
24
+ Ywr1gd2ZME4QLSo+EXUtLxDUa/W3xnBS8dBOuMMz02FPWYr3PN8CAwEAAaM5MDcw
25
+ CQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFAFgmv0tYMZnItuPycSM
26
+ F5wykJEVMA0GCSqGSIb3DQEBCwUAA4IBgQBlzRfyAYx/fCFjizS0Npxw4+4T3aYL
27
+ hbXoDqQRWjxuhFZcXUymhz3r8/Ltyri9lSof8grzB+8/+mrMVms7Gwt5qolk6zdn
28
+ FkySGy/jmpN12ldOHFbBEnyVBZNBvOBVb8zkkw8PhiHdBdXOUm4Jy39yJvBLfjcC
29
+ iM1aeWPmgPy1GbvZU+leRGZLt6dRIR9oCDXcWLRjha8xLMoz6Yn9fJBYexBA3iEz
30
+ h5S7pn4AX/JhVRiSyl8pAy4jEKydpyQrliH3gHkpNmUS/XDczP+9xX1bAB4BvqL2
31
+ NCxMcQ+hiJNqCKpPgHxaOOHZfIxV33logIuPEQ8NryHAwZ9ZWnwtYDE8kQGGKskI
32
+ Kkm6QT474hZl7MpwiJjWgW313CR7jUEekQahX1QxCxHPI7LSrKpno0plH3uWIOQp
33
+ KUlkb9uyACBgyRO52ZHiDVI8YvtU5O/j9pSes9/3XgvBeC1onx4qWp+uRX7eVsYS
34
+ GiijocTc3enZVrXERetaXj8/9XWs3fB3HWY=
35
+ -----END CERTIFICATE-----
36
+ date: 1980-01-02 00:00:00.000000000 Z
37
+ dependencies:
38
+ - !ruby/object:Gem::Dependency
39
+ name: cogger
40
+ requirement: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - "~>"
43
+ - !ruby/object:Gem::Version
44
+ version: '1.2'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - "~>"
50
+ - !ruby/object:Gem::Version
51
+ version: '1.2'
52
+ - !ruby/object:Gem::Dependency
53
+ name: containable
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: '1.2'
59
+ type: :runtime
60
+ prerelease: false
61
+ version_requirements: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: '1.2'
66
+ - !ruby/object:Gem::Dependency
67
+ name: dry-monads
68
+ requirement: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - "~>"
71
+ - !ruby/object:Gem::Version
72
+ version: '1.8'
73
+ type: :runtime
74
+ prerelease: false
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '1.8'
80
+ - !ruby/object:Gem::Dependency
81
+ name: dry-schema
82
+ requirement: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '1.14'
87
+ type: :runtime
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: '1.14'
94
+ - !ruby/object:Gem::Dependency
95
+ name: http
96
+ requirement: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - "~>"
99
+ - !ruby/object:Gem::Version
100
+ version: '5.2'
101
+ type: :runtime
102
+ prerelease: false
103
+ version_requirements: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '5.2'
108
+ - !ruby/object:Gem::Dependency
109
+ name: infusible
110
+ requirement: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '4.3'
115
+ type: :runtime
116
+ prerelease: false
117
+ version_requirements: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '4.3'
122
+ - !ruby/object:Gem::Dependency
123
+ name: pipeable
124
+ requirement: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: '1.3'
129
+ type: :runtime
130
+ prerelease: false
131
+ version_requirements: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '1.3'
136
+ - !ruby/object:Gem::Dependency
137
+ name: zeitwerk
138
+ requirement: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: '2.7'
143
+ type: :runtime
144
+ prerelease: false
145
+ version_requirements: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '2.7'
150
+ email:
151
+ - support@usetrmnl.com
152
+ executables: []
153
+ extensions: []
154
+ extra_rdoc_files:
155
+ - LICENSE
156
+ - README.adoc
157
+ files:
158
+ - LICENSE
159
+ - README.adoc
160
+ - lib/trmnl/api.rb
161
+ - lib/trmnl/api/client.rb
162
+ - lib/trmnl/api/configuration/content.rb
163
+ - lib/trmnl/api/configuration/loader.rb
164
+ - lib/trmnl/api/container.rb
165
+ - lib/trmnl/api/contracts/current_screen.rb
166
+ - lib/trmnl/api/contracts/display.rb
167
+ - lib/trmnl/api/contracts/firmware.rb
168
+ - lib/trmnl/api/contracts/setup.rb
169
+ - lib/trmnl/api/dependencies.rb
170
+ - lib/trmnl/api/endpoints/current_screen.rb
171
+ - lib/trmnl/api/endpoints/display.rb
172
+ - lib/trmnl/api/endpoints/firmware.rb
173
+ - lib/trmnl/api/endpoints/log.rb
174
+ - lib/trmnl/api/endpoints/setup.rb
175
+ - lib/trmnl/api/models/current_screen.rb
176
+ - lib/trmnl/api/models/display.rb
177
+ - lib/trmnl/api/models/firmware.rb
178
+ - lib/trmnl/api/models/setup.rb
179
+ - trmnl-api.gemspec
180
+ homepage: https://github.com/usetrmnl/trmnl-api
181
+ licenses:
182
+ - MIT
183
+ metadata:
184
+ bug_tracker_uri: https://github.com/usetrmnl/trmnl-api/issues
185
+ changelog_uri: https://github.com/usetrmnl/trmnl-api/tags
186
+ homepage_uri: https://github.com/usetrmnl/trmnl-api
187
+ label: TRMNL API
188
+ rubygems_mfa_required: 'true'
189
+ source_code_uri: https://github.com/usetrmnl/trmnl-api
190
+ rdoc_options: []
191
+ require_paths:
192
+ - lib
193
+ required_ruby_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - "~>"
196
+ - !ruby/object:Gem::Version
197
+ version: '3.4'
198
+ required_rubygems_version: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ requirements: []
204
+ rubygems_version: 3.6.8
205
+ specification_version: 4
206
+ summary: A monadic TRMNL API client.
207
+ test_files: []
metadata.gz.sig ADDED
Binary file