sirv_rest_api 1.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.
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SirvRestApi
4
+ # Base error class for all Sirv API errors
5
+ class Error < StandardError; end
6
+
7
+ # Error raised when API returns an error response
8
+ class ApiError < Error
9
+ attr_reader :status_code, :error_code, :message
10
+
11
+ def initialize(message, status_code, error_code = nil)
12
+ @message = message
13
+ @status_code = status_code
14
+ @error_code = error_code
15
+ super(build_message)
16
+ end
17
+
18
+ private
19
+
20
+ def build_message
21
+ if @error_code
22
+ "#{@message} (status #{@status_code}, code #{@error_code})"
23
+ else
24
+ "#{@message} (status #{@status_code})"
25
+ end
26
+ end
27
+ end
28
+
29
+ # Error raised when authentication fails
30
+ class AuthenticationError < ApiError
31
+ def initialize(message = "Authentication failed", status_code = 401)
32
+ super(message, status_code, "authentication_error")
33
+ end
34
+ end
35
+
36
+ # Error raised when rate limit is exceeded
37
+ class RateLimitError < ApiError
38
+ def initialize(message = "Rate limit exceeded", status_code = 429)
39
+ super(message, status_code, "rate_limit_error")
40
+ end
41
+ end
42
+
43
+ # Error raised for invalid parameters
44
+ class ValidationError < ApiError
45
+ def initialize(message, status_code = 400)
46
+ super(message, status_code, "validation_error")
47
+ end
48
+ end
49
+
50
+ # Error raised when resource is not found
51
+ class NotFoundError < ApiError
52
+ def initialize(message = "Resource not found", status_code = 404)
53
+ super(message, status_code, "not_found")
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,319 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SirvRestApi
4
+ # Token response from authentication
5
+ class TokenResponse
6
+ attr_accessor :token, :expires_in, :scope
7
+
8
+ def initialize(data = {})
9
+ @token = data["token"]
10
+ @expires_in = data["expiresIn"]
11
+ @scope = data["scope"] || []
12
+ end
13
+ end
14
+
15
+ # Account information
16
+ class AccountInfo
17
+ attr_accessor :alias, :cdn_url, :date_created, :fetching, :minify, :aliases, :file_size_limit
18
+
19
+ def initialize(data = {})
20
+ @alias = data["alias"]
21
+ @cdn_url = data["cdnURL"]
22
+ @date_created = data["dateCreated"]
23
+ @fetching = data["fetching"]
24
+ @minify = data["minify"]
25
+ @aliases = data["aliases"]
26
+ @file_size_limit = data["fileSizeLimit"]
27
+ end
28
+ end
29
+
30
+ # Rate limit information
31
+ class RateLimitInfo
32
+ attr_accessor :limit, :remaining, :reset, :count
33
+
34
+ def initialize(data = {})
35
+ @limit = data["limit"]
36
+ @remaining = data["remaining"]
37
+ @reset = data["reset"]
38
+ @count = data["count"]
39
+ end
40
+ end
41
+
42
+ # Account limits
43
+ class AccountLimits
44
+ attr_accessor :s3, :rest, :ftp
45
+
46
+ def initialize(data = {})
47
+ @s3 = data["s3"] ? RateLimitInfo.new(data["s3"]) : nil
48
+ @rest = data["rest"] ? RateLimitInfo.new(data["rest"]) : nil
49
+ @ftp = data["ftp"] ? RateLimitInfo.new(data["ftp"]) : nil
50
+ end
51
+ end
52
+
53
+ # Storage information
54
+ class StorageInfo
55
+ attr_accessor :allowance, :used, :files, :burstable
56
+
57
+ def initialize(data = {})
58
+ @allowance = data["allowance"]
59
+ @used = data["used"]
60
+ @files = data["files"]
61
+ @burstable = data["burstable"]
62
+ end
63
+ end
64
+
65
+ # Account user
66
+ class AccountUser
67
+ attr_accessor :user_id, :email, :first_name, :last_name, :role, :date_created
68
+
69
+ def initialize(data = {})
70
+ @user_id = data["userId"]
71
+ @email = data["email"]
72
+ @first_name = data["firstName"]
73
+ @last_name = data["lastName"]
74
+ @role = data["role"]
75
+ @date_created = data["dateCreated"]
76
+ end
77
+ end
78
+
79
+ # Plan price
80
+ class PlanPrice
81
+ attr_accessor :month, :year, :quarter
82
+
83
+ def initialize(data = {})
84
+ @month = data["month"]
85
+ @year = data["year"]
86
+ @quarter = data["quarter"]
87
+ end
88
+ end
89
+
90
+ # Billing plan
91
+ class BillingPlan
92
+ attr_accessor :id, :name, :description, :period, :storage, :data_transfer_limit, :price, :date_active
93
+
94
+ def initialize(data = {})
95
+ @id = data["id"]
96
+ @name = data["name"]
97
+ @description = data["description"]
98
+ @period = data["period"]
99
+ @storage = data["storage"]
100
+ @data_transfer_limit = data["dataTransferLimit"]
101
+ @price = data["price"] ? PlanPrice.new(data["price"]) : nil
102
+ @date_active = data["dateActive"]
103
+ end
104
+ end
105
+
106
+ # Account event
107
+ class AccountEvent
108
+ attr_accessor :id, :module, :type, :level, :message, :filename, :timestamp, :seen
109
+
110
+ def initialize(data = {})
111
+ @id = data["id"]
112
+ @module = data["module"]
113
+ @type = data["type"]
114
+ @level = data["level"]
115
+ @message = data["message"]
116
+ @filename = data["filename"]
117
+ @timestamp = data["timestamp"]
118
+ @seen = data["seen"]
119
+ end
120
+ end
121
+
122
+ # User information
123
+ class UserInfo
124
+ attr_accessor :user_id, :email, :first_name, :last_name, :date_created, :s3_key, :s3_secret
125
+
126
+ def initialize(data = {})
127
+ @user_id = data["userId"]
128
+ @email = data["email"]
129
+ @first_name = data["firstName"]
130
+ @last_name = data["lastName"]
131
+ @date_created = data["dateCreated"]
132
+ @s3_key = data["s3Key"]
133
+ @s3_secret = data["s3Secret"]
134
+ end
135
+ end
136
+
137
+ # File metadata
138
+ class FileMeta
139
+ attr_accessor :title, :description, :tags, :approved
140
+
141
+ def initialize(data = {})
142
+ @title = data["title"]
143
+ @description = data["description"]
144
+ @tags = data["tags"]
145
+ @approved = data["approved"]
146
+ end
147
+
148
+ def to_h
149
+ {
150
+ title: @title,
151
+ description: @description,
152
+ tags: @tags,
153
+ approved: @approved
154
+ }.compact
155
+ end
156
+ end
157
+
158
+ # File information
159
+ class FileInfo
160
+ attr_accessor :filename, :dirname, :basename, :is_directory, :size, :ctime, :mtime, :content_type, :meta
161
+
162
+ def initialize(data = {})
163
+ @filename = data["filename"]
164
+ @dirname = data["dirname"]
165
+ @basename = data["basename"]
166
+ @is_directory = data["isDirectory"]
167
+ @size = data["size"]
168
+ @ctime = data["ctime"]
169
+ @mtime = data["mtime"]
170
+ @content_type = data["contentType"]
171
+ @meta = data["meta"] ? FileMeta.new(data["meta"]) : nil
172
+ end
173
+
174
+ def directory?
175
+ @is_directory
176
+ end
177
+ end
178
+
179
+ # Product metadata
180
+ class ProductMeta
181
+ attr_accessor :id, :name, :brand, :category, :sku
182
+
183
+ def initialize(data = {})
184
+ @id = data["id"]
185
+ @name = data["name"]
186
+ @brand = data["brand"]
187
+ @category = data["category"]
188
+ @sku = data["sku"]
189
+ end
190
+
191
+ def to_h
192
+ {
193
+ id: @id,
194
+ name: @name,
195
+ brand: @brand,
196
+ category: @category,
197
+ sku: @sku
198
+ }.compact
199
+ end
200
+ end
201
+
202
+ # Folder contents
203
+ class FolderContents
204
+ attr_accessor :contents, :continuation
205
+
206
+ def initialize(data = {})
207
+ @contents = (data["contents"] || []).map { |item| FileInfo.new(item) }
208
+ @continuation = data["continuation"]
209
+ end
210
+ end
211
+
212
+ # Search result
213
+ class SearchResult
214
+ attr_accessor :hits, :total, :scroll_id
215
+
216
+ def initialize(data = {})
217
+ raw_hits = data["hits"] || []
218
+ @hits = raw_hits.map do |hit|
219
+ # Handle Elasticsearch _source format
220
+ source = hit["_source"] || hit
221
+ FileInfo.new(source)
222
+ end
223
+ # Handle Elasticsearch total format
224
+ total_data = data["total"]
225
+ @total = total_data.is_a?(Hash) ? total_data["value"] : total_data
226
+ @scroll_id = data["scrollId"]
227
+ end
228
+ end
229
+
230
+ # Batch delete result
231
+ class BatchDeleteResult
232
+ attr_accessor :job_id, :status, :results
233
+
234
+ def initialize(data = {})
235
+ @job_id = data["jobId"]
236
+ @status = data["status"]
237
+ @results = data["results"]
238
+ end
239
+ end
240
+
241
+ # Batch ZIP result
242
+ class BatchZipResult
243
+ attr_accessor :job_id, :status, :filename
244
+
245
+ def initialize(data = {})
246
+ @job_id = data["jobId"]
247
+ @status = data["status"]
248
+ @filename = data["filename"]
249
+ end
250
+ end
251
+
252
+ # JWT response
253
+ class JwtResponse
254
+ attr_accessor :url, :token
255
+
256
+ def initialize(data = {})
257
+ @url = data["url"]
258
+ @token = data["token"]
259
+ end
260
+ end
261
+
262
+ # Point of interest
263
+ class PointOfInterest
264
+ attr_accessor :name, :x, :y, :frame
265
+
266
+ def initialize(data = {})
267
+ @name = data["name"]
268
+ @x = data["x"]
269
+ @y = data["y"]
270
+ @frame = data["frame"]
271
+ end
272
+
273
+ def to_h
274
+ {
275
+ name: @name,
276
+ x: @x,
277
+ y: @y,
278
+ frame: @frame
279
+ }.compact
280
+ end
281
+ end
282
+
283
+ # HTTP statistics
284
+ class HttpStats
285
+ attr_accessor :date, :transfer, :requests
286
+
287
+ def initialize(data = {})
288
+ @date = data["date"]
289
+ @transfer = data["transfer"]
290
+ @requests = data["requests"]
291
+ end
292
+ end
293
+
294
+ # Spin view statistics
295
+ class SpinViewStats
296
+ attr_accessor :date, :views, :spins, :zooms, :fullscreens, :user_agent, :country
297
+
298
+ def initialize(data = {})
299
+ @date = data["date"]
300
+ @views = data["views"]
301
+ @spins = data["spins"]
302
+ @zooms = data["zooms"]
303
+ @fullscreens = data["fullscreens"]
304
+ @user_agent = data["userAgent"]
305
+ @country = data["country"]
306
+ end
307
+ end
308
+
309
+ # Storage statistics
310
+ class StorageStats
311
+ attr_accessor :date, :storage, :files
312
+
313
+ def initialize(data = {})
314
+ @date = data["date"]
315
+ @storage = data["storage"]
316
+ @files = data["files"]
317
+ end
318
+ end
319
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SirvRestApi
4
+ VERSION = "1.0.0"
5
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "sirv_rest_api/version"
4
+ require_relative "sirv_rest_api/errors"
5
+ require_relative "sirv_rest_api/models"
6
+ require_relative "sirv_rest_api/client"
7
+
8
+ # Sirv REST API SDK for Ruby
9
+ #
10
+ # @example Basic usage
11
+ # require 'sirv_rest_api'
12
+ #
13
+ # client = SirvRestApi::Client.new(
14
+ # client_id: 'your-client-id',
15
+ # client_secret: 'your-client-secret'
16
+ # )
17
+ #
18
+ # client.connect
19
+ # account = client.get_account_info
20
+ # puts "CDN URL: #{account.cdn_url}"
21
+ #
22
+ module SirvRestApi
23
+ class << self
24
+ # Create a new client instance
25
+ #
26
+ # @param options [Hash] Client options
27
+ # @return [Client] New client instance
28
+ def new(**options)
29
+ Client.new(**options)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/sirv_rest_api/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "sirv_rest_api"
7
+ spec.version = SirvRestApi::VERSION
8
+ spec.authors = ["Sirv"]
9
+ spec.email = ["support@sirv.com"]
10
+
11
+ spec.summary = "Official Ruby SDK for the Sirv REST API"
12
+ spec.description = "A simple, type-safe way to interact with Sirv's image hosting and processing platform. " \
13
+ "Features include automatic token management, retry logic, and comprehensive coverage of all 40+ API endpoints."
14
+ spec.homepage = "https://github.com/sirv/sirv-rest-api-ruby"
15
+ spec.license = "MIT"
16
+ spec.required_ruby_version = ">= 2.7.0"
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "https://github.com/sirv/sirv-rest-api-ruby"
20
+ spec.metadata["changelog_uri"] = "https://github.com/sirv/sirv-rest-api-ruby/blob/main/CHANGELOG.md"
21
+ spec.metadata["documentation_uri"] = "https://www.rubydoc.info/gems/sirv_rest_api"
22
+ spec.metadata["bug_tracker_uri"] = "https://github.com/sirv/sirv-rest-api-ruby/issues"
23
+
24
+ # Specify which files should be added to the gem when it is released.
25
+ spec.files = Dir.chdir(__dir__) do
26
+ `git ls-files -z`.split("\x0").reject do |f|
27
+ (File.expand_path(f) == __FILE__) ||
28
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
29
+ end
30
+ end
31
+ spec.bindir = "exe"
32
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
33
+ spec.require_paths = ["lib"]
34
+
35
+ # Runtime dependencies - none required, uses stdlib only
36
+
37
+ # Development dependencies
38
+ spec.add_development_dependency "bundler", "~> 2.0"
39
+ spec.add_development_dependency "rake", "~> 13.0"
40
+ spec.add_development_dependency "minitest", "~> 5.0"
41
+ spec.add_development_dependency "rubocop", "~> 1.0"
42
+ spec.add_development_dependency "yard", "~> 0.9"
43
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sirv_rest_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Sirv
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2026-01-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '13.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '13.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.9'
83
+ description: A simple, type-safe way to interact with Sirv's image hosting and processing
84
+ platform. Features include automatic token management, retry logic, and comprehensive
85
+ coverage of all 40+ API endpoints.
86
+ email:
87
+ - support@sirv.com
88
+ executables: []
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - LICENSE
93
+ - README.md
94
+ - Rakefile
95
+ - docs/index.html
96
+ - examples/basic_usage.rb
97
+ - icon.png
98
+ - lib/sirv_rest_api.rb
99
+ - lib/sirv_rest_api/client.rb
100
+ - lib/sirv_rest_api/errors.rb
101
+ - lib/sirv_rest_api/models.rb
102
+ - lib/sirv_rest_api/version.rb
103
+ - sirv_rest_api.gemspec
104
+ homepage: https://github.com/sirv/sirv-rest-api-ruby
105
+ licenses:
106
+ - MIT
107
+ metadata:
108
+ homepage_uri: https://github.com/sirv/sirv-rest-api-ruby
109
+ source_code_uri: https://github.com/sirv/sirv-rest-api-ruby
110
+ changelog_uri: https://github.com/sirv/sirv-rest-api-ruby/blob/main/CHANGELOG.md
111
+ documentation_uri: https://www.rubydoc.info/gems/sirv_rest_api
112
+ bug_tracker_uri: https://github.com/sirv/sirv-rest-api-ruby/issues
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: 2.7.0
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubygems_version: 3.0.3.1
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Official Ruby SDK for the Sirv REST API
132
+ test_files: []