tarpon 0.1.0 → 0.1.1
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 +4 -4
- data/lib/tarpon.rb +12 -0
- data/lib/tarpon/client.rb +19 -0
- data/lib/tarpon/configuration.rb +20 -0
- data/lib/tarpon/entity/entitlement.rb +22 -0
- data/lib/tarpon/entity/entitlement_list.rb +25 -0
- data/lib/tarpon/entity/subscriber.rb +14 -0
- data/lib/tarpon/errors.rb +8 -0
- data/lib/tarpon/request/base.rb +50 -0
- data/lib/tarpon/request/receipt.rb +12 -0
- data/lib/tarpon/request/subscriber.rb +80 -0
- data/lib/tarpon/response.rb +17 -0
- data/lib/tarpon/version.rb +5 -0
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8e5a49cefe2bedd26a02e959b6c8eb24aebb37ff5b434cc9ab2491449d2db68
|
4
|
+
data.tar.gz: ab2217bc86dbbf8277dc66f73368e9e6cde96c435e82c37a681dd93708c2aa34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6da4a1ee4c6f89cb585db622ab2a79be2fbea74b365a9f7967d197adbfbd116b555936b010a22064d1c50b99f9912e7b03dda6c3285680f9018407cfe226a66
|
7
|
+
data.tar.gz: fcf05f255081a6754289c3c459b0b86f5b83578681a786391cdf5229b108b926caa202f5663972c8b2c36fdbd74cbc9b2ad2069fbce515af249fa7c806aaea7d
|
data/lib/tarpon.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tarpon/client'
|
4
|
+
require 'tarpon/entity/entitlement'
|
5
|
+
require 'tarpon/entity/entitlement_list'
|
6
|
+
require 'tarpon/entity/subscriber'
|
7
|
+
require 'tarpon/errors'
|
8
|
+
require 'tarpon/request/base'
|
9
|
+
require 'tarpon/request/subscriber'
|
10
|
+
require 'tarpon/request/receipt'
|
11
|
+
require 'tarpon/response'
|
12
|
+
require 'tarpon/version'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tarpon/configuration'
|
4
|
+
|
5
|
+
module Tarpon
|
6
|
+
class Client
|
7
|
+
extend Configuration
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def subscriber(app_user_id)
|
11
|
+
Request::Subscriber.new(app_user_id: app_user_id)
|
12
|
+
end
|
13
|
+
|
14
|
+
def receipt
|
15
|
+
Request::Receipt.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tarpon
|
4
|
+
module Configuration
|
5
|
+
attr_accessor :public_api_key, :secret_api_key
|
6
|
+
attr_writer :base_uri, :timeout
|
7
|
+
|
8
|
+
def configure
|
9
|
+
yield self
|
10
|
+
end
|
11
|
+
|
12
|
+
def base_uri
|
13
|
+
@base_uri || 'https://api.revenuecat.com/v1'
|
14
|
+
end
|
15
|
+
|
16
|
+
def timeout
|
17
|
+
@timeout || 5
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tarpon
|
4
|
+
module Entity
|
5
|
+
class Entitlement
|
6
|
+
attr_reader :id, :raw
|
7
|
+
|
8
|
+
def initialize(id, attributes = {})
|
9
|
+
@id = id
|
10
|
+
@raw = attributes
|
11
|
+
end
|
12
|
+
|
13
|
+
def active?
|
14
|
+
expires_date > Time.now.utc
|
15
|
+
end
|
16
|
+
|
17
|
+
def expires_date
|
18
|
+
Time.iso8601(@raw[:expires_date])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tarpon
|
4
|
+
module Entity
|
5
|
+
class EntitlementList
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(entitlements = {})
|
9
|
+
@entitlements = entitlements.map { |id, params| Entitlement.new(id, params) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](index)
|
13
|
+
@entitlements[index]
|
14
|
+
end
|
15
|
+
|
16
|
+
def active
|
17
|
+
@entitlements.select(&:active?)
|
18
|
+
end
|
19
|
+
|
20
|
+
def each
|
21
|
+
@entitlements.each { |e| yield e }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tarpon
|
4
|
+
module Entity
|
5
|
+
class Subscriber
|
6
|
+
attr_reader :raw, :entitlements
|
7
|
+
|
8
|
+
def initialize(attributes = {})
|
9
|
+
@raw = attributes
|
10
|
+
@entitlements = EntitlementList.new(attributes[:entitlements])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'http'
|
4
|
+
|
5
|
+
module Tarpon
|
6
|
+
module Request
|
7
|
+
class Base
|
8
|
+
DEFAULT_HEADERS = {
|
9
|
+
accept: 'application/json',
|
10
|
+
content_type: 'application/json'
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def perform(method:, path:, key:, headers: {}, body: nil)
|
16
|
+
HTTP
|
17
|
+
.auth("Bearer #{translate_key(key)}")
|
18
|
+
.headers(headers.merge(DEFAULT_HEADERS))
|
19
|
+
.timeout(Client.timeout)
|
20
|
+
.send(method, "#{Client.base_uri}#{path}", json: body&.compact)
|
21
|
+
.yield_self { |response| handle_response(response) }
|
22
|
+
rescue HTTP::TimeoutError => e
|
23
|
+
raise Tarpon::TimeoutError, e
|
24
|
+
end
|
25
|
+
|
26
|
+
def translate_key(key)
|
27
|
+
Client.send("#{key}_api_key")
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def handle_response(response)
|
33
|
+
case response.code
|
34
|
+
when 401
|
35
|
+
raise Tarpon::InvalidCredentialsError,
|
36
|
+
'Invalid credentials, fix your API keys'
|
37
|
+
when 500..505
|
38
|
+
raise Tarpon::ServerError,
|
39
|
+
'RevenueCat failed to fulfill the request'
|
40
|
+
else
|
41
|
+
Tarpon::Response.new(response.status, parse_body(response.body))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse_body(body)
|
46
|
+
JSON.parse(body, symbolize_names: true)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tarpon
|
4
|
+
module Request
|
5
|
+
class Receipt < Base
|
6
|
+
def create(platform:, **data)
|
7
|
+
headers = { 'X-Platform' => platform }
|
8
|
+
perform(method: :post, headers: headers, path: '/receipts', key: :public, body: data)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tarpon
|
4
|
+
module Request
|
5
|
+
class Subscriber < Base
|
6
|
+
def initialize(app_user_id:)
|
7
|
+
@app_user_id = app_user_id
|
8
|
+
end
|
9
|
+
|
10
|
+
# rubocop:disable Naming/AccessorMethodName
|
11
|
+
def get_or_create
|
12
|
+
perform(method: :get, path: path, key: :public)
|
13
|
+
end
|
14
|
+
# rubocop:enable Naming/AccessorMethodName
|
15
|
+
|
16
|
+
def delete
|
17
|
+
perform(method: :delete, path: path, key: :secret)
|
18
|
+
end
|
19
|
+
|
20
|
+
def entitlements(entitlement_identifier)
|
21
|
+
self.class::Entitlement.new(subscriber_path: path, entitlement_identifier: entitlement_identifier)
|
22
|
+
end
|
23
|
+
|
24
|
+
def subscriptions(product_id)
|
25
|
+
self.class::Subscription.new(subscriber_path: path, product_id: product_id)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def path
|
31
|
+
"/subscribers/#{@app_user_id}"
|
32
|
+
end
|
33
|
+
|
34
|
+
class Entitlement < Base
|
35
|
+
def initialize(subscriber_path:, entitlement_identifier:)
|
36
|
+
@subscriber_path = subscriber_path
|
37
|
+
@entitlement_identifier = entitlement_identifier
|
38
|
+
end
|
39
|
+
|
40
|
+
def grant_promotional(duration:, start_time_ms: nil)
|
41
|
+
body = {
|
42
|
+
duration: duration,
|
43
|
+
start_time_ms: start_time_ms
|
44
|
+
}
|
45
|
+
|
46
|
+
perform(method: :post, path: "#{path}/promotional", key: :secret, body: body)
|
47
|
+
end
|
48
|
+
|
49
|
+
def revoke_promotional
|
50
|
+
perform(method: :post, path: "#{path}/revoke_promotionals", key: :secret)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def path
|
56
|
+
"#{@subscriber_path}/entitlements/#{@entitlement_identifier}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Subscription < Base
|
61
|
+
def initialize(subscriber_path:, product_id:)
|
62
|
+
@subscriber_path = subscriber_path
|
63
|
+
@product_id = product_id
|
64
|
+
end
|
65
|
+
|
66
|
+
def defer(expiry_time_ms:)
|
67
|
+
body = { expiry_time_ms: expiry_time_ms }
|
68
|
+
|
69
|
+
perform(method: :post, path: "#{path}/defer", key: :secret, body: body)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def path
|
75
|
+
"#{@subscriber_path}/subscriptions/#{@product_id}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tarpon
|
4
|
+
class Response
|
5
|
+
attr_reader :raw, :subscriber
|
6
|
+
|
7
|
+
def initialize(status, attributes)
|
8
|
+
@status = status
|
9
|
+
@raw = attributes
|
10
|
+
@subscriber = @raw[:subscriber].nil? ? nil : Entity::Subscriber.new(@raw[:subscriber])
|
11
|
+
end
|
12
|
+
|
13
|
+
def success?
|
14
|
+
@status.success?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tarpon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Belo
|
@@ -114,7 +114,19 @@ email:
|
|
114
114
|
executables: []
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
|
-
files:
|
117
|
+
files:
|
118
|
+
- lib/tarpon.rb
|
119
|
+
- lib/tarpon/client.rb
|
120
|
+
- lib/tarpon/configuration.rb
|
121
|
+
- lib/tarpon/entity/entitlement.rb
|
122
|
+
- lib/tarpon/entity/entitlement_list.rb
|
123
|
+
- lib/tarpon/entity/subscriber.rb
|
124
|
+
- lib/tarpon/errors.rb
|
125
|
+
- lib/tarpon/request/base.rb
|
126
|
+
- lib/tarpon/request/receipt.rb
|
127
|
+
- lib/tarpon/request/subscriber.rb
|
128
|
+
- lib/tarpon/response.rb
|
129
|
+
- lib/tarpon/version.rb
|
118
130
|
homepage: https://github.com/fishbrain/tarpon
|
119
131
|
licenses:
|
120
132
|
- MIT
|