galaxy-ruby 0.2.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.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +8 -0
  3. data/LICENSE +201 -0
  4. data/README.md +169 -0
  5. data/SECURITY.md +19 -0
  6. data/SKILL.md +83 -0
  7. data/api.md +188 -0
  8. data/lib/galaxy-ruby/client.rb +254 -0
  9. data/lib/galaxy-ruby/errors.rb +227 -0
  10. data/lib/galaxy-ruby/file_part.rb +58 -0
  11. data/lib/galaxy-ruby/internal/transport/base_client.rb +576 -0
  12. data/lib/galaxy-ruby/internal/transport/pooled_net_requester.rb +224 -0
  13. data/lib/galaxy-ruby/internal/type/array_of.rb +164 -0
  14. data/lib/galaxy-ruby/internal/type/base_model.rb +529 -0
  15. data/lib/galaxy-ruby/internal/type/base_page.rb +55 -0
  16. data/lib/galaxy-ruby/internal/type/boolean.rb +77 -0
  17. data/lib/galaxy-ruby/internal/type/converter.rb +333 -0
  18. data/lib/galaxy-ruby/internal/type/enum.rb +130 -0
  19. data/lib/galaxy-ruby/internal/type/file_input.rb +111 -0
  20. data/lib/galaxy-ruby/internal/type/hash_of.rb +184 -0
  21. data/lib/galaxy-ruby/internal/type/request_parameters.rb +42 -0
  22. data/lib/galaxy-ruby/internal/type/union.rb +234 -0
  23. data/lib/galaxy-ruby/internal/type/unknown.rb +81 -0
  24. data/lib/galaxy-ruby/internal/util.rb +960 -0
  25. data/lib/galaxy-ruby/internal.rb +15 -0
  26. data/lib/galaxy-ruby/models/authentication_create_token_params.rb +14 -0
  27. data/lib/galaxy-ruby/models/authentication_create_token_response.rb +16 -0
  28. data/lib/galaxy-ruby/models/authentication_create_user_params.rb +32 -0
  29. data/lib/galaxy-ruby/models/authentication_list_me_params.rb +14 -0
  30. data/lib/galaxy-ruby/models/celestial_body.rb +81 -0
  31. data/lib/galaxy-ruby/models/celestial_body_create_params.rb +20 -0
  32. data/lib/galaxy-ruby/models/credentials.rb +25 -0
  33. data/lib/galaxy-ruby/models/new_planet_webhook_event.rb +216 -0
  34. data/lib/galaxy-ruby/models/planet.rb +218 -0
  35. data/lib/galaxy-ruby/models/planet_create_params.rb +14 -0
  36. data/lib/galaxy-ruby/models/planet_delete_params.rb +20 -0
  37. data/lib/galaxy-ruby/models/planet_delte_image_params.rb +29 -0
  38. data/lib/galaxy-ruby/models/planet_delte_image_response.rb +48 -0
  39. data/lib/galaxy-ruby/models/planet_list_all_data_params.rb +30 -0
  40. data/lib/galaxy-ruby/models/planet_list_all_data_response.rb +51 -0
  41. data/lib/galaxy-ruby/models/planet_retrieve_params.rb +20 -0
  42. data/lib/galaxy-ruby/models/planet_update_params.rb +20 -0
  43. data/lib/galaxy-ruby/models/unwrap_webhook_event.rb +14 -0
  44. data/lib/galaxy-ruby/models/user.rb +26 -0
  45. data/lib/galaxy-ruby/models/webhook_unwrap_params.rb +14 -0
  46. data/lib/galaxy-ruby/models.rb +78 -0
  47. data/lib/galaxy-ruby/request_options.rb +77 -0
  48. data/lib/galaxy-ruby/resources/authentication.rb +80 -0
  49. data/lib/galaxy-ruby/resources/celestial_bodies.rb +37 -0
  50. data/lib/galaxy-ruby/resources/planets.rb +215 -0
  51. data/lib/galaxy-ruby/resources/webhooks.rb +34 -0
  52. data/lib/galaxy-ruby/version.rb +5 -0
  53. data/lib/galaxy-ruby.rb +78 -0
  54. data/rbi/galaxy-ruby/client.rbi +128 -0
  55. data/rbi/galaxy-ruby/errors.rbi +205 -0
  56. data/rbi/galaxy-ruby/file_part.rbi +37 -0
  57. data/rbi/galaxy-ruby/internal/transport/base_client.rbi +305 -0
  58. data/rbi/galaxy-ruby/internal/transport/pooled_net_requester.rbi +84 -0
  59. data/rbi/galaxy-ruby/internal/type/array_of.rbi +104 -0
  60. data/rbi/galaxy-ruby/internal/type/base_model.rbi +314 -0
  61. data/rbi/galaxy-ruby/internal/type/base_page.rbi +43 -0
  62. data/rbi/galaxy-ruby/internal/type/boolean.rbi +58 -0
  63. data/rbi/galaxy-ruby/internal/type/converter.rbi +222 -0
  64. data/rbi/galaxy-ruby/internal/type/enum.rbi +82 -0
  65. data/rbi/galaxy-ruby/internal/type/file_input.rbi +59 -0
  66. data/rbi/galaxy-ruby/internal/type/hash_of.rbi +104 -0
  67. data/rbi/galaxy-ruby/internal/type/request_parameters.rbi +31 -0
  68. data/rbi/galaxy-ruby/internal/type/union.rbi +128 -0
  69. data/rbi/galaxy-ruby/internal/type/unknown.rbi +58 -0
  70. data/rbi/galaxy-ruby/internal/util.rbi +515 -0
  71. data/rbi/galaxy-ruby/internal.rbi +18 -0
  72. data/rbi/galaxy-ruby/models/authentication_create_token_params.rbi +32 -0
  73. data/rbi/galaxy-ruby/models/authentication_create_token_response.rbi +29 -0
  74. data/rbi/galaxy-ruby/models/authentication_create_user_params.rbi +54 -0
  75. data/rbi/galaxy-ruby/models/authentication_list_me_params.rbi +32 -0
  76. data/rbi/galaxy-ruby/models/celestial_body.rbi +140 -0
  77. data/rbi/galaxy-ruby/models/celestial_body_create_params.rbi +53 -0
  78. data/rbi/galaxy-ruby/models/credentials.rbi +27 -0
  79. data/rbi/galaxy-ruby/models/new_planet_webhook_event.rbi +396 -0
  80. data/rbi/galaxy-ruby/models/planet.rbi +350 -0
  81. data/rbi/galaxy-ruby/models/planet_create_params.rbi +32 -0
  82. data/rbi/galaxy-ruby/models/planet_delete_params.rbi +38 -0
  83. data/rbi/galaxy-ruby/models/planet_delte_image_params.rbi +55 -0
  84. data/rbi/galaxy-ruby/models/planet_delte_image_response.rbi +85 -0
  85. data/rbi/galaxy-ruby/models/planet_list_all_data_params.rbi +60 -0
  86. data/rbi/galaxy-ruby/models/planet_list_all_data_response.rbi +110 -0
  87. data/rbi/galaxy-ruby/models/planet_retrieve_params.rbi +38 -0
  88. data/rbi/galaxy-ruby/models/planet_update_params.rbi +38 -0
  89. data/rbi/galaxy-ruby/models/unwrap_webhook_event.rbi +17 -0
  90. data/rbi/galaxy-ruby/models/user.rbi +33 -0
  91. data/rbi/galaxy-ruby/models/webhook_unwrap_params.rbi +32 -0
  92. data/rbi/galaxy-ruby/models.rbi +39 -0
  93. data/rbi/galaxy-ruby/request_options.rbi +59 -0
  94. data/rbi/galaxy-ruby/resources/authentication.rbi +47 -0
  95. data/rbi/galaxy-ruby/resources/celestial_bodies.rbi +28 -0
  96. data/rbi/galaxy-ruby/resources/planets.rbi +176 -0
  97. data/rbi/galaxy-ruby/resources/webhooks.rbi +29 -0
  98. data/rbi/galaxy-ruby/version.rbi +5 -0
  99. data/sig/galaxy-ruby/client.rbs +62 -0
  100. data/sig/galaxy-ruby/errors.rbs +117 -0
  101. data/sig/galaxy-ruby/file_part.rbs +21 -0
  102. data/sig/galaxy-ruby/internal/transport/base_client.rbs +133 -0
  103. data/sig/galaxy-ruby/internal/transport/pooled_net_requester.rbs +48 -0
  104. data/sig/galaxy-ruby/internal/type/array_of.rbs +48 -0
  105. data/sig/galaxy-ruby/internal/type/base_model.rbs +102 -0
  106. data/sig/galaxy-ruby/internal/type/base_page.rbs +24 -0
  107. data/sig/galaxy-ruby/internal/type/boolean.rbs +26 -0
  108. data/sig/galaxy-ruby/internal/type/converter.rbs +79 -0
  109. data/sig/galaxy-ruby/internal/type/enum.rbs +32 -0
  110. data/sig/galaxy-ruby/internal/type/file_input.rbs +25 -0
  111. data/sig/galaxy-ruby/internal/type/hash_of.rbs +48 -0
  112. data/sig/galaxy-ruby/internal/type/request_parameters.rbs +17 -0
  113. data/sig/galaxy-ruby/internal/type/union.rbs +52 -0
  114. data/sig/galaxy-ruby/internal/type/unknown.rbs +26 -0
  115. data/sig/galaxy-ruby/internal/util.rbs +199 -0
  116. data/sig/galaxy-ruby/internal.rbs +9 -0
  117. data/sig/galaxy-ruby/models/authentication_create_token_params.rbs +15 -0
  118. data/sig/galaxy-ruby/models/authentication_create_token_response.rbs +15 -0
  119. data/sig/galaxy-ruby/models/authentication_create_user_params.rbs +34 -0
  120. data/sig/galaxy-ruby/models/authentication_list_me_params.rbs +15 -0
  121. data/sig/galaxy-ruby/models/celestial_body.rbs +76 -0
  122. data/sig/galaxy-ruby/models/celestial_body_create_params.rbs +24 -0
  123. data/sig/galaxy-ruby/models/credentials.rbs +15 -0
  124. data/sig/galaxy-ruby/models/new_planet_webhook_event.rbs +211 -0
  125. data/sig/galaxy-ruby/models/planet.rbs +211 -0
  126. data/sig/galaxy-ruby/models/planet_create_params.rbs +15 -0
  127. data/sig/galaxy-ruby/models/planet_delete_params.rbs +23 -0
  128. data/sig/galaxy-ruby/models/planet_delte_image_params.rbs +32 -0
  129. data/sig/galaxy-ruby/models/planet_delte_image_response.rbs +50 -0
  130. data/sig/galaxy-ruby/models/planet_list_all_data_params.rbs +32 -0
  131. data/sig/galaxy-ruby/models/planet_list_all_data_response.rbs +64 -0
  132. data/sig/galaxy-ruby/models/planet_retrieve_params.rbs +23 -0
  133. data/sig/galaxy-ruby/models/planet_update_params.rbs +25 -0
  134. data/sig/galaxy-ruby/models/unwrap_webhook_event.rbs +11 -0
  135. data/sig/galaxy-ruby/models/user.rbs +19 -0
  136. data/sig/galaxy-ruby/models/webhook_unwrap_params.rbs +15 -0
  137. data/sig/galaxy-ruby/models.rbs +35 -0
  138. data/sig/galaxy-ruby/request_options.rbs +34 -0
  139. data/sig/galaxy-ruby/resources/authentication.rbs +24 -0
  140. data/sig/galaxy-ruby/resources/celestial_bodies.rbs +12 -0
  141. data/sig/galaxy-ruby/resources/planets.rbs +68 -0
  142. data/sig/galaxy-ruby/resources/webhooks.rbs +13 -0
  143. data/sig/galaxy-ruby/version.rbs +3 -0
  144. data/sig/manifest.yaml +6 -0
  145. metadata +245 -0
@@ -0,0 +1,254 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ScalarGalaxy
4
+ class Client < ScalarGalaxy::Internal::Transport::BaseClient
5
+ # Default max number of retries to attempt after a failed retryable request.
6
+ DEFAULT_MAX_RETRIES = 2
7
+
8
+ # Default per-request timeout.
9
+ DEFAULT_TIMEOUT_IN_SECONDS = 60.0
10
+
11
+ # Default initial retry delay in seconds.
12
+ # Overall delay is calculated using exponential backoff + jitter.
13
+ DEFAULT_INITIAL_RETRY_DELAY = 0.5
14
+
15
+ # Default max retry delay in seconds.
16
+ DEFAULT_MAX_RETRY_DELAY = 8.0
17
+
18
+ # rubocop:disable Style/MutableConstant
19
+ # @type [Hash{Symbol=>String}]
20
+ ENVIRONMENTS = {production: "https://galaxy.scalar.com", void: "https://void.scalar.com/"}
21
+ # rubocop:enable Style/MutableConstant
22
+
23
+ # JWT Bearer token authentication
24
+ # @return [String]
25
+ attr_reader :bearer_auth
26
+
27
+ # @return [String]
28
+ attr_reader :basic_auth_username
29
+
30
+ # @return [String]
31
+ attr_reader :basic_auth_password
32
+
33
+ # API key request header
34
+ # @return [String]
35
+ attr_reader :api_key_header
36
+
37
+ # API key query parameter
38
+ # @return [String, nil]
39
+ attr_reader :api_key_query
40
+
41
+ # API key browser cookie
42
+ # @return [String]
43
+ attr_reader :api_key_cookie
44
+
45
+ # OAuth 2.0 authentication
46
+ # @return [String, nil]
47
+ attr_reader :o_auth2
48
+
49
+ # OpenID Connect Authentication
50
+ # @return [String, nil]
51
+ attr_reader :open_id_connect
52
+
53
+ # Secret used to verify incoming webhook signatures.
54
+ # @return [String, nil]
55
+ attr_reader :webhook_secret
56
+
57
+ # Everything about planets
58
+ # @return [ScalarGalaxy::Resources::Planets]
59
+ attr_reader :planets
60
+
61
+ # Celestial bodies are the planets and satellites in the Scalar Galaxy.
62
+ # @return [ScalarGalaxy::Resources::CelestialBodies]
63
+ attr_reader :celestial_bodies
64
+
65
+ # Some endpoints are public, but some require authentication. We provide all the
66
+ # required endpoints to create an account and authorize yourself.
67
+ # @return [ScalarGalaxy::Resources::Authentication]
68
+ attr_reader :authentication
69
+
70
+ # @return [ScalarGalaxy::Resources::Webhooks]
71
+ attr_reader :webhooks
72
+
73
+ # @api private
74
+ #
75
+ # @return [Hash{String=>String}]
76
+ private def auth_headers
77
+ {
78
+ **auth_bearer_auth,
79
+ **basic_auth,
80
+ **auth_api_key_header,
81
+ **cookie_auth,
82
+ **auth_o_auth2,
83
+ **auth_open_id_connect
84
+ }
85
+ end
86
+
87
+ # @api private
88
+ #
89
+ # @return [Hash{String=>String}]
90
+ private def auth_bearer_auth
91
+ {"authorization" => "Bearer #{@bearer_auth}"}
92
+ end
93
+
94
+ # @api private
95
+ #
96
+ # @return [Hash{String=>String}]
97
+ private def basic_auth
98
+ return {} if @basic_auth_username.nil? || @basic_auth_password.nil?
99
+
100
+ base64_credentials = ["#{@basic_auth_username}:#{@basic_auth_password}"].pack("m0")
101
+ {"authorization" => "Basic #{base64_credentials}"}
102
+ end
103
+
104
+ # @api private
105
+ #
106
+ # @return [Hash{String=>String}]
107
+ private def auth_api_key_header
108
+ {"x-api-key" => @api_key_header}
109
+ end
110
+
111
+ # @api private
112
+ #
113
+ # @return [Hash{String=>String}]
114
+ private def cookie_auth
115
+ cookies = []
116
+ cookies << "api_key=#{@api_key_cookie}" unless @api_key_cookie.nil?
117
+ {"cookie" => cookies.join("; ")}
118
+ end
119
+
120
+ # @api private
121
+ #
122
+ # @return [Hash{String=>String}]
123
+ private def auth_o_auth2
124
+ {"authorization" => "Bearer #{@o_auth2}"}
125
+ end
126
+
127
+ # @api private
128
+ #
129
+ # @return [Hash{String=>String}]
130
+ private def auth_open_id_connect
131
+ {"authorization" => "Bearer #{@open_id_connect}"}
132
+ end
133
+
134
+ # Creates and returns a new client for interacting with the API.
135
+ #
136
+ # @param bearer_auth [String, nil] JWT Bearer token authentication Defaults to `ENV["BEARER_AUTH"]`
137
+ #
138
+ # @param basic_auth_username [String, nil] Defaults to `ENV["BASIC_AUTH_USERNAME"]`
139
+ #
140
+ # @param basic_auth_password [String, nil] Defaults to `ENV["BASIC_AUTH_PASSWORD"]`
141
+ #
142
+ # @param api_key_header [String, nil] API key request header Defaults to `ENV["API_KEY_HEADER"]`
143
+ #
144
+ # @param api_key_query [String, nil] API key query parameter Defaults to `ENV["API_KEY_QUERY"]`
145
+ #
146
+ # @param api_key_cookie [String, nil] API key browser cookie Defaults to `ENV["API_KEY_COOKIE"]`
147
+ #
148
+ # @param o_auth2 [String, nil] OAuth 2.0 authentication Defaults to `ENV["SCALAR_O_AUTH2"]`
149
+ #
150
+ # @param open_id_connect [String, nil] OpenID Connect Authentication Defaults to `ENV["SCALAR_OPEN_ID_CONNECT"]`
151
+ #
152
+ # @param webhook_secret [String, nil] Secret used to verify incoming webhook signatures. Defaults to
153
+ # `ENV["SCALAR_WEBHOOK_SECRET"]`
154
+ #
155
+ # @param environment [:production, :void, nil] Specifies the environment to use for the API.
156
+ #
157
+ # Each environment maps to a different base URL:
158
+ #
159
+ # - `production` corresponds to `https://galaxy.scalar.com`
160
+ # - `void` corresponds to `https://void.scalar.com/`
161
+ #
162
+ # @param base_url [String, nil] Override the default base URL for the API, e.g.,
163
+ # `"https://api.example.com/v2/"`. Defaults to `ENV["SCALAR_BASE_URL"]`
164
+ #
165
+ # @param max_retries [Integer] Max number of retries to attempt after a failed retryable request.
166
+ #
167
+ # @param timeout [Float]
168
+ #
169
+ # @param initial_retry_delay [Float]
170
+ #
171
+ # @param max_retry_delay [Float]
172
+ def initialize(
173
+ bearer_auth: ENV["BEARER_AUTH"],
174
+ basic_auth_username: ENV["BASIC_AUTH_USERNAME"],
175
+ basic_auth_password: ENV["BASIC_AUTH_PASSWORD"],
176
+ api_key_header: ENV["API_KEY_HEADER"],
177
+ api_key_query: ENV["API_KEY_QUERY"],
178
+ api_key_cookie: ENV["API_KEY_COOKIE"],
179
+ o_auth2: ENV["SCALAR_O_AUTH2"],
180
+ open_id_connect: ENV["SCALAR_OPEN_ID_CONNECT"],
181
+ webhook_secret: ENV["SCALAR_WEBHOOK_SECRET"],
182
+ environment: nil,
183
+ base_url: ENV["SCALAR_BASE_URL"],
184
+ max_retries: self.class::DEFAULT_MAX_RETRIES,
185
+ timeout: self.class::DEFAULT_TIMEOUT_IN_SECONDS,
186
+ initial_retry_delay: self.class::DEFAULT_INITIAL_RETRY_DELAY,
187
+ max_retry_delay: self.class::DEFAULT_MAX_RETRY_DELAY
188
+ )
189
+ base_url ||=
190
+ ScalarGalaxy::Client::ENVIRONMENTS.fetch(environment&.to_sym || :production) do
191
+ message =
192
+ "environment must be one of #{ScalarGalaxy::Client::ENVIRONMENTS.keys}, got #{environment}"
193
+ raise ArgumentError.new(message)
194
+ end
195
+
196
+ if bearer_auth.nil?
197
+ raise ArgumentError.new("bearer_auth is required, and can be set via environ: \"BEARER_AUTH\"")
198
+ end
199
+ if basic_auth_username.nil?
200
+ raise ArgumentError.new(
201
+ "basic_auth_username is required, and can be set via environ: \"BASIC_AUTH_USERNAME\""
202
+ )
203
+ end
204
+ if basic_auth_password.nil?
205
+ raise ArgumentError.new(
206
+ "basic_auth_password is required, and can be set via environ: \"BASIC_AUTH_PASSWORD\""
207
+ )
208
+ end
209
+ if api_key_header.nil?
210
+ raise ArgumentError.new("api_key_header is required, and can be set via environ: \"API_KEY_HEADER\"")
211
+ end
212
+ if api_key_cookie.nil?
213
+ raise ArgumentError.new("api_key_cookie is required, and can be set via environ: \"API_KEY_COOKIE\"")
214
+ end
215
+
216
+ headers = {}
217
+ custom_headers_env = ENV["SCALAR_CUSTOM_HEADERS"]
218
+ unless custom_headers_env.nil?
219
+ parsed = {}
220
+ custom_headers_env
221
+ .split("\n")
222
+ .each do |line|
223
+ colon = line.index(":")
224
+ parsed[line[0...colon].strip] = line[(colon + 1)..].strip unless colon.nil?
225
+ end
226
+ headers = parsed.merge(headers)
227
+ end
228
+
229
+ @bearer_auth = bearer_auth.to_s
230
+ @basic_auth_username = basic_auth_username.to_s
231
+ @basic_auth_password = basic_auth_password.to_s
232
+ @api_key_header = api_key_header.to_s
233
+ @api_key_query = api_key_query&.to_s
234
+ @api_key_cookie = api_key_cookie.to_s
235
+ @o_auth2 = o_auth2&.to_s
236
+ @open_id_connect = open_id_connect&.to_s
237
+ @webhook_secret = webhook_secret&.to_s
238
+
239
+ super(
240
+ base_url: base_url,
241
+ timeout: timeout,
242
+ max_retries: max_retries,
243
+ initial_retry_delay: initial_retry_delay,
244
+ max_retry_delay: max_retry_delay,
245
+ headers: headers
246
+ )
247
+
248
+ @planets = ScalarGalaxy::Resources::Planets.new(client: self)
249
+ @celestial_bodies = ScalarGalaxy::Resources::CelestialBodies.new(client: self)
250
+ @authentication = ScalarGalaxy::Resources::Authentication.new(client: self)
251
+ @webhooks = ScalarGalaxy::Resources::Webhooks.new(client: self)
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,227 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ScalarGalaxy
4
+ module Errors
5
+ class Error < StandardError
6
+ # @!attribute cause
7
+ #
8
+ # @return [StandardError, nil]
9
+ end
10
+
11
+ class ConversionError < ScalarGalaxy::Errors::Error
12
+ # @return [StandardError, nil]
13
+ def cause = @cause.nil? ? super : @cause
14
+
15
+ # @api private
16
+ #
17
+ # @param on [Class<StandardError>]
18
+ # @param method [Symbol]
19
+ # @param target [Object]
20
+ # @param value [Object]
21
+ # @param cause [StandardError, nil]
22
+ def initialize(on:, method:, target:, value:, cause: nil)
23
+ cls = on.name.split("::").last
24
+
25
+ message = [
26
+ "Failed to parse #{cls}.#{method} from #{value.class} to #{target.inspect}.",
27
+ "To get the unparsed API response, use #{cls}[#{method.inspect}].",
28
+ cause && "Cause: #{cause.message}"
29
+ ].filter(&:itself).join(" ")
30
+
31
+ @cause = cause
32
+ super(message)
33
+ end
34
+ end
35
+
36
+ class APIError < ScalarGalaxy::Errors::Error
37
+ # @return [URI::Generic]
38
+ attr_accessor :url
39
+
40
+ # @return [Integer, nil]
41
+ attr_accessor :status
42
+
43
+ # @return [Hash{String=>String}, nil]
44
+ attr_accessor :headers
45
+
46
+ # @return [Object, nil]
47
+ attr_accessor :body
48
+
49
+ # @api private
50
+ #
51
+ # @param url [URI::Generic]
52
+ # @param status [Integer, nil]
53
+ # @param headers [Hash{String=>String}, nil]
54
+ # @param body [Object, nil]
55
+ # @param request [nil]
56
+ # @param response [nil]
57
+ # @param message [String, nil]
58
+ def initialize(url:, status: nil, headers: nil, body: nil, request: nil, response: nil, message: nil)
59
+ @url = url
60
+ @status = status
61
+ @headers = headers
62
+ @body = body
63
+ @request = request
64
+ @response = response
65
+ super(message)
66
+ end
67
+ end
68
+
69
+ class APIConnectionError < ScalarGalaxy::Errors::APIError
70
+ # @!attribute status
71
+ #
72
+ # @return [nil]
73
+
74
+ # @!attribute body
75
+ #
76
+ # @return [nil]
77
+
78
+ # @api private
79
+ #
80
+ # @param url [URI::Generic]
81
+ # @param status [nil]
82
+ # @param headers [Hash{String=>String}, nil]
83
+ # @param body [nil]
84
+ # @param request [nil]
85
+ # @param response [nil]
86
+ # @param message [String, nil]
87
+ def initialize(
88
+ url:,
89
+ status: nil,
90
+ headers: nil,
91
+ body: nil,
92
+ request: nil,
93
+ response: nil,
94
+ message: "Connection error."
95
+ )
96
+ super
97
+ end
98
+ end
99
+
100
+ class APITimeoutError < ScalarGalaxy::Errors::APIConnectionError
101
+ # @api private
102
+ #
103
+ # @param url [URI::Generic]
104
+ # @param status [nil]
105
+ # @param headers [Hash{String=>String}, nil]
106
+ # @param body [nil]
107
+ # @param request [nil]
108
+ # @param response [nil]
109
+ # @param message [String, nil]
110
+ def initialize(
111
+ url:,
112
+ status: nil,
113
+ headers: nil,
114
+ body: nil,
115
+ request: nil,
116
+ response: nil,
117
+ message: "Request timed out."
118
+ )
119
+ super
120
+ end
121
+ end
122
+
123
+ class APIStatusError < ScalarGalaxy::Errors::APIError
124
+ # @api private
125
+ #
126
+ # @param url [URI::Generic]
127
+ # @param status [Integer]
128
+ # @param headers [Hash{String=>String}, nil]
129
+ # @param body [Object, nil]
130
+ # @param request [nil]
131
+ # @param response [nil]
132
+ # @param message [String, nil]
133
+ #
134
+ # @return [self]
135
+ def self.for(url:, status:, headers:, body:, request:, response:, message: nil)
136
+ kwargs = {
137
+ url: url,
138
+ status: status,
139
+ headers: headers,
140
+ body: body,
141
+ request: request,
142
+ response: response,
143
+ message: message
144
+ }
145
+
146
+ case status
147
+ in 400
148
+ ScalarGalaxy::Errors::BadRequestError.new(**kwargs)
149
+ in 401
150
+ ScalarGalaxy::Errors::AuthenticationError.new(**kwargs)
151
+ in 403
152
+ ScalarGalaxy::Errors::PermissionDeniedError.new(**kwargs)
153
+ in 404
154
+ ScalarGalaxy::Errors::NotFoundError.new(**kwargs)
155
+ in 409
156
+ ScalarGalaxy::Errors::ConflictError.new(**kwargs)
157
+ in 422
158
+ ScalarGalaxy::Errors::UnprocessableEntityError.new(**kwargs)
159
+ in 429
160
+ ScalarGalaxy::Errors::RateLimitError.new(**kwargs)
161
+ in 500.. then
162
+ ScalarGalaxy::Errors::InternalServerError.new(**kwargs)
163
+ else
164
+ ScalarGalaxy::Errors::APIStatusError.new(**kwargs)
165
+ end
166
+ end
167
+
168
+ # @!parse
169
+ # # @return [Integer]
170
+ # attr_accessor :status
171
+
172
+ # @api private
173
+ #
174
+ # @param url [URI::Generic]
175
+ # @param status [Integer]
176
+ # @param headers [Hash{String=>String}, nil]
177
+ # @param body [Object, nil]
178
+ # @param request [nil]
179
+ # @param response [nil]
180
+ # @param message [String, nil]
181
+ def initialize(url:, status:, headers:, body:, request:, response:, message: nil)
182
+ message ||= {url: url.to_s, status: status, body: body}
183
+ super(
184
+ url: url,
185
+ status: status,
186
+ headers: headers,
187
+ body: body,
188
+ request: request,
189
+ response: response,
190
+ message: message&.to_s
191
+ )
192
+ end
193
+ end
194
+
195
+ class BadRequestError < ScalarGalaxy::Errors::APIStatusError
196
+ HTTP_STATUS = 400
197
+ end
198
+
199
+ class AuthenticationError < ScalarGalaxy::Errors::APIStatusError
200
+ HTTP_STATUS = 401
201
+ end
202
+
203
+ class PermissionDeniedError < ScalarGalaxy::Errors::APIStatusError
204
+ HTTP_STATUS = 403
205
+ end
206
+
207
+ class NotFoundError < ScalarGalaxy::Errors::APIStatusError
208
+ HTTP_STATUS = 404
209
+ end
210
+
211
+ class ConflictError < ScalarGalaxy::Errors::APIStatusError
212
+ HTTP_STATUS = 409
213
+ end
214
+
215
+ class UnprocessableEntityError < ScalarGalaxy::Errors::APIStatusError
216
+ HTTP_STATUS = 422
217
+ end
218
+
219
+ class RateLimitError < ScalarGalaxy::Errors::APIStatusError
220
+ HTTP_STATUS = 429
221
+ end
222
+
223
+ class InternalServerError < ScalarGalaxy::Errors::APIStatusError
224
+ HTTP_STATUS = (500..)
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ScalarGalaxy
4
+ class FilePart
5
+ # @return [Pathname, StringIO, IO, String]
6
+ attr_reader :content
7
+
8
+ # @return [String, nil]
9
+ attr_reader :content_type
10
+
11
+ # @return [String, nil]
12
+ attr_reader :filename
13
+
14
+ # @api private
15
+ #
16
+ # @return [String]
17
+ private def read
18
+ case content
19
+ in Pathname
20
+ content.read(binmode: true)
21
+ in StringIO
22
+ content.string
23
+ in IO
24
+ content.read
25
+ in String
26
+ content
27
+ end
28
+ end
29
+
30
+ # @param a [Object]
31
+ #
32
+ # @return [String]
33
+ def to_json(*a) = read.to_json(*a)
34
+
35
+ # @param a [Object]
36
+ #
37
+ # @return [String]
38
+ def to_yaml(*a) = read.to_yaml(*a)
39
+
40
+ # @param content [Pathname, StringIO, IO, String]
41
+ # @param filename [Pathname, String, nil]
42
+ # @param content_type [String, nil]
43
+ def initialize(content, filename: nil, content_type: nil)
44
+ @content_type = content_type
45
+ @filename =
46
+ case [filename, (@content = content)]
47
+ in [String | Pathname, _]
48
+ ::File.basename(filename)
49
+ in [nil, Pathname]
50
+ content.basename.to_path
51
+ in [nil, IO]
52
+ content.to_path
53
+ else
54
+ filename
55
+ end
56
+ end
57
+ end
58
+ end