didit-sdk 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.
Files changed (234) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +25 -0
  3. data/LICENSE +21 -0
  4. data/README.md +277 -0
  5. data/lib/didit/authentication/base64_url.rb +34 -0
  6. data/lib/didit/authentication/cache.rb +201 -0
  7. data/lib/didit/authentication/http.rb +150 -0
  8. data/lib/didit/authentication/issuer.rb +115 -0
  9. data/lib/didit/authentication/jws.rb +231 -0
  10. data/lib/didit/authentication/key_set.rb +89 -0
  11. data/lib/didit/authentication/pkce.rb +64 -0
  12. data/lib/didit/authentication/types.rb +175 -0
  13. data/lib/didit/authentication.rb +546 -0
  14. data/lib/didit/client.rb +211 -0
  15. data/lib/didit/errors.rb +153 -0
  16. data/lib/didit/file_part.rb +85 -0
  17. data/lib/didit/internal/config.rb +94 -0
  18. data/lib/didit/internal/errors.rb +83 -0
  19. data/lib/didit/internal/log.rb +41 -0
  20. data/lib/didit/internal/multipart.rb +60 -0
  21. data/lib/didit/internal/request.rb +322 -0
  22. data/lib/didit/internal/transport.rb +198 -0
  23. data/lib/didit/internal/util.rb +76 -0
  24. data/lib/didit/internal.rb +15 -0
  25. data/lib/didit/model.rb +199 -0
  26. data/lib/didit/page.rb +130 -0
  27. data/lib/didit/raw_response.rb +57 -0
  28. data/lib/didit/resource.rb +15 -0
  29. data/lib/didit/resources/account.rb +309 -0
  30. data/lib/didit/resources/address_validation.rb +73 -0
  31. data/lib/didit/resources/age_estimation.rb +110 -0
  32. data/lib/didit/resources/aml.rb +166 -0
  33. data/lib/didit/resources/aml_monitoring.rb +30 -0
  34. data/lib/didit/resources/analytics.rb +87 -0
  35. data/lib/didit/resources/bank.rb +65 -0
  36. data/lib/didit/resources/billing.rb +61 -0
  37. data/lib/didit/resources/biometric_templates.rb +234 -0
  38. data/lib/didit/resources/blocklist.rb +130 -0
  39. data/lib/didit/resources/business_sessions.rb +29 -0
  40. data/lib/didit/resources/businesses.rb +471 -0
  41. data/lib/didit/resources/cases.rb +2116 -0
  42. data/lib/didit/resources/customization.rb +153 -0
  43. data/lib/didit/resources/database_validation.rb +327 -0
  44. data/lib/didit/resources/document_ai.rb +145 -0
  45. data/lib/didit/resources/email.rb +254 -0
  46. data/lib/didit/resources/face_match.rb +103 -0
  47. data/lib/didit/resources/face_search.rb +103 -0
  48. data/lib/didit/resources/fraud_checks.rb +130 -0
  49. data/lib/didit/resources/id_verification.rb +163 -0
  50. data/lib/didit/resources/id_wallets.rb +1468 -0
  51. data/lib/didit/resources/investigator.rb +419 -0
  52. data/lib/didit/resources/ip.rb +68 -0
  53. data/lib/didit/resources/kyb.rb +256 -0
  54. data/lib/didit/resources/lists.rb +332 -0
  55. data/lib/didit/resources/monitoring_events.rb +466 -0
  56. data/lib/didit/resources/networks.rb +427 -0
  57. data/lib/didit/resources/passive_liveness.rb +103 -0
  58. data/lib/didit/resources/phone.rb +271 -0
  59. data/lib/didit/resources/pricing.rb +40 -0
  60. data/lib/didit/resources/proof_of_address.rb +167 -0
  61. data/lib/didit/resources/questionnaires.rb +170 -0
  62. data/lib/didit/resources/regulatory_reports.rb +314 -0
  63. data/lib/didit/resources/report_templates.rb +146 -0
  64. data/lib/didit/resources/sessions.rb +2820 -0
  65. data/lib/didit/resources/transactions.rb +981 -0
  66. data/lib/didit/resources/travel_rule.rb +1202 -0
  67. data/lib/didit/resources/users.rb +521 -0
  68. data/lib/didit/resources/wallet_screening.rb +190 -0
  69. data/lib/didit/resources/webhooks.rb +396 -0
  70. data/lib/didit/resources/workflows.rb +214 -0
  71. data/lib/didit/resources.rb +263 -0
  72. data/lib/didit/types/account.rb +11 -0
  73. data/lib/didit/types/account_components.rb +105 -0
  74. data/lib/didit/types/address_validation.rb +8 -0
  75. data/lib/didit/types/age_estimation.rb +89 -0
  76. data/lib/didit/types/aml.rb +193 -0
  77. data/lib/didit/types/aml_monitoring.rb +73 -0
  78. data/lib/didit/types/analytics.rb +62 -0
  79. data/lib/didit/types/bank.rb +8 -0
  80. data/lib/didit/types/billing.rb +18 -0
  81. data/lib/didit/types/biometric_templates.rb +292 -0
  82. data/lib/didit/types/blocklist.rb +31 -0
  83. data/lib/didit/types/businesses.rb +45 -0
  84. data/lib/didit/types/cases.rb +368 -0
  85. data/lib/didit/types/components.rb +12206 -0
  86. data/lib/didit/types/customization.rb +8 -0
  87. data/lib/didit/types/database_validation.rb +177 -0
  88. data/lib/didit/types/document_ai.rb +135 -0
  89. data/lib/didit/types/email.rb +116 -0
  90. data/lib/didit/types/face_match.rb +93 -0
  91. data/lib/didit/types/face_search.rb +129 -0
  92. data/lib/didit/types/fraud_checks.rb +8 -0
  93. data/lib/didit/types/id_verification.rb +231 -0
  94. data/lib/didit/types/id_wallets.rb +8 -0
  95. data/lib/didit/types/investigator.rb +221 -0
  96. data/lib/didit/types/ip.rb +8 -0
  97. data/lib/didit/types/kyb.rb +1391 -0
  98. data/lib/didit/types/lists.rb +111 -0
  99. data/lib/didit/types/monitoring_events.rb +235 -0
  100. data/lib/didit/types/networks.rb +120 -0
  101. data/lib/didit/types/passive_liveness.rb +95 -0
  102. data/lib/didit/types/phone.rb +69 -0
  103. data/lib/didit/types/proof_of_address.rb +166 -0
  104. data/lib/didit/types/questionnaires.rb +29 -0
  105. data/lib/didit/types/regulatory_reports.rb +100 -0
  106. data/lib/didit/types/report_templates.rb +41 -0
  107. data/lib/didit/types/sessions.rb +1441 -0
  108. data/lib/didit/types/transactions.rb +245 -0
  109. data/lib/didit/types/travel_rule.rb +168 -0
  110. data/lib/didit/types/users.rb +180 -0
  111. data/lib/didit/types/wallet_screening.rb +49 -0
  112. data/lib/didit/types/webhooks.rb +355 -0
  113. data/lib/didit/types/workflows.rb +32 -0
  114. data/lib/didit/types.rb +1681 -0
  115. data/lib/didit/version.rb +5 -0
  116. data/lib/didit/webhooks/canonical_json.rb +187 -0
  117. data/lib/didit/webhooks/client_methods.rb +23 -0
  118. data/lib/didit/webhooks/events.rb +221 -0
  119. data/lib/didit/webhooks/headers.rb +83 -0
  120. data/lib/didit/webhooks/verifier.rb +260 -0
  121. data/lib/didit/webhooks.rb +99 -0
  122. data/lib/didit-sdk.rb +4 -0
  123. data/lib/didit.rb +31 -0
  124. data/sig/didit/authentication/base64_url.rbs +10 -0
  125. data/sig/didit/authentication/cache.rbs +60 -0
  126. data/sig/didit/authentication/http.rbs +37 -0
  127. data/sig/didit/authentication/issuer.rbs +17 -0
  128. data/sig/didit/authentication/jws.rbs +41 -0
  129. data/sig/didit/authentication/jwt.rbs +14 -0
  130. data/sig/didit/authentication/key_set.rbs +25 -0
  131. data/sig/didit/authentication/pkce.rbs +20 -0
  132. data/sig/didit/authentication/types.rbs +114 -0
  133. data/sig/didit/authentication.rbs +81 -0
  134. data/sig/didit/client.rbs +61 -0
  135. data/sig/didit/errors.rbs +80 -0
  136. data/sig/didit/file_part.rbs +19 -0
  137. data/sig/didit/internal.rbs +199 -0
  138. data/sig/didit/model.rbs +42 -0
  139. data/sig/didit/page.rbs +34 -0
  140. data/sig/didit/raw_response.rbs +20 -0
  141. data/sig/didit/resource.rbs +8 -0
  142. data/sig/didit/resources/account.rbs +23 -0
  143. data/sig/didit/resources/address_validation.rbs +9 -0
  144. data/sig/didit/resources/age_estimation.rbs +9 -0
  145. data/sig/didit/resources/aml.rbs +10 -0
  146. data/sig/didit/resources/aml_monitoring.rbs +9 -0
  147. data/sig/didit/resources/analytics.rbs +9 -0
  148. data/sig/didit/resources/bank.rbs +9 -0
  149. data/sig/didit/resources/billing.rbs +10 -0
  150. data/sig/didit/resources/biometric_templates.rbs +13 -0
  151. data/sig/didit/resources/blocklist.rbs +11 -0
  152. data/sig/didit/resources/business_sessions.rbs +9 -0
  153. data/sig/didit/resources/businesses.rbs +22 -0
  154. data/sig/didit/resources/cases.rbs +103 -0
  155. data/sig/didit/resources/customization.rbs +10 -0
  156. data/sig/didit/resources/database_validation.rbs +9 -0
  157. data/sig/didit/resources/document_ai.rbs +9 -0
  158. data/sig/didit/resources/email.rbs +11 -0
  159. data/sig/didit/resources/face_match.rbs +9 -0
  160. data/sig/didit/resources/face_search.rbs +9 -0
  161. data/sig/didit/resources/fraud_checks.rbs +11 -0
  162. data/sig/didit/resources/id_verification.rbs +9 -0
  163. data/sig/didit/resources/id_wallets.rbs +37 -0
  164. data/sig/didit/resources/investigator.rbs +23 -0
  165. data/sig/didit/resources/ip.rbs +9 -0
  166. data/sig/didit/resources/kyb.rbs +12 -0
  167. data/sig/didit/resources/lists.rbs +20 -0
  168. data/sig/didit/resources/monitoring_events.rbs +16 -0
  169. data/sig/didit/resources/networks.rbs +25 -0
  170. data/sig/didit/resources/passive_liveness.rbs +9 -0
  171. data/sig/didit/resources/phone.rbs +11 -0
  172. data/sig/didit/resources/pricing.rbs +9 -0
  173. data/sig/didit/resources/proof_of_address.rbs +9 -0
  174. data/sig/didit/resources/questionnaires.rbs +13 -0
  175. data/sig/didit/resources/regulatory_reports.rbs +16 -0
  176. data/sig/didit/resources/report_templates.rbs +13 -0
  177. data/sig/didit/resources/sessions.rbs +78 -0
  178. data/sig/didit/resources/transactions.rbs +43 -0
  179. data/sig/didit/resources/travel_rule.rbs +62 -0
  180. data/sig/didit/resources/users.rbs +21 -0
  181. data/sig/didit/resources/wallet_screening.rbs +11 -0
  182. data/sig/didit/resources/webhooks.rbs +23 -0
  183. data/sig/didit/resources/workflows.rbs +13 -0
  184. data/sig/didit/resources.rbs +50 -0
  185. data/sig/didit/types/account.rbs +22 -0
  186. data/sig/didit/types/account_components.rbs +94 -0
  187. data/sig/didit/types/address_validation.rbs +7 -0
  188. data/sig/didit/types/age_estimation.rbs +80 -0
  189. data/sig/didit/types/aml.rbs +174 -0
  190. data/sig/didit/types/aml_monitoring.rbs +67 -0
  191. data/sig/didit/types/analytics.rbs +57 -0
  192. data/sig/didit/types/bank.rbs +9 -0
  193. data/sig/didit/types/billing.rbs +19 -0
  194. data/sig/didit/types/biometric_templates.rbs +268 -0
  195. data/sig/didit/types/blocklist.rbs +33 -0
  196. data/sig/didit/types/businesses.rbs +54 -0
  197. data/sig/didit/types/cases.rbs +414 -0
  198. data/sig/didit/types/components.rbs +10920 -0
  199. data/sig/didit/types/customization.rbs +7 -0
  200. data/sig/didit/types/database_validation.rbs +152 -0
  201. data/sig/didit/types/document_ai.rbs +123 -0
  202. data/sig/didit/types/email.rbs +112 -0
  203. data/sig/didit/types/face_match.rbs +86 -0
  204. data/sig/didit/types/face_search.rbs +112 -0
  205. data/sig/didit/types/fraud_checks.rbs +9 -0
  206. data/sig/didit/types/id_verification.rbs +196 -0
  207. data/sig/didit/types/id_wallets.rbs +55 -0
  208. data/sig/didit/types/investigator.rbs +212 -0
  209. data/sig/didit/types/ip.rbs +7 -0
  210. data/sig/didit/types/kyb.rbs +1254 -0
  211. data/sig/didit/types/lists.rbs +106 -0
  212. data/sig/didit/types/monitoring_events.rbs +234 -0
  213. data/sig/didit/types/networks.rbs +113 -0
  214. data/sig/didit/types/passive_liveness.rbs +87 -0
  215. data/sig/didit/types/phone.rbs +65 -0
  216. data/sig/didit/types/proof_of_address.rbs +144 -0
  217. data/sig/didit/types/questionnaires.rbs +30 -0
  218. data/sig/didit/types/regulatory_reports.rbs +101 -0
  219. data/sig/didit/types/report_templates.rbs +42 -0
  220. data/sig/didit/types/sessions.rbs +1349 -0
  221. data/sig/didit/types/transactions.rbs +273 -0
  222. data/sig/didit/types/travel_rule.rbs +188 -0
  223. data/sig/didit/types/users.rbs +181 -0
  224. data/sig/didit/types/wallet_screening.rbs +40 -0
  225. data/sig/didit/types/webhooks.rbs +311 -0
  226. data/sig/didit/types/workflows.rbs +30 -0
  227. data/sig/didit/webhooks/canonical_json.rbs +25 -0
  228. data/sig/didit/webhooks/client_methods.rbs +11 -0
  229. data/sig/didit/webhooks/events.rbs +125 -0
  230. data/sig/didit/webhooks/headers.rbs +22 -0
  231. data/sig/didit/webhooks/verifier.rbs +54 -0
  232. data/sig/didit/webhooks.rbs +37 -0
  233. data/sig/didit.rbs +20 -0
  234. metadata +300 -0
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+ require "json"
5
+ require "time"
6
+
7
+ module Didit
8
+ # Base class of every response type.
9
+ #
10
+ # A model wraps the JSON object the API returned. Typed readers convert values
11
+ # on access (nested objects become models, date-times become +Time+) and never
12
+ # raise: a value that does not have the documented shape is returned as is.
13
+ # Fields the SDK does not know yet stay readable with {#[]} and {#to_h}.
14
+ #
15
+ # Field types are written as +:string+, +:integer+, +:float+, +:boolean+,
16
+ # +:datetime+, +:date+, +:any+, a model class (or its name under +Didit::Types+),
17
+ # +[:array, type]+, +[:map, type]+ or +[:union, [type, ...]]+ (the first type that fits the value).
18
+ class Model
19
+ class << self
20
+ # The typed fields of this class and its ancestors: reader name => [JSON name, type].
21
+ #
22
+ # @return [Hash{Symbol => Array}]
23
+ def fields
24
+ @fields ||= begin
25
+ parent = superclass
26
+ parent.is_a?(Class) && parent < Model ? Model.fields_of(parent) : {}
27
+ end
28
+ end
29
+
30
+ # @api private
31
+ def fields_of(klass)
32
+ # @type var klass: singleton(Model)
33
+ klass.fields.dup
34
+ end
35
+
36
+ # Declares a typed reader +name+ for the JSON property +wire+.
37
+ #
38
+ # @return [void]
39
+ def field(name, wire, type = :any)
40
+ fields[name] = [wire, type]
41
+ define_method(name) do
42
+ # @type self: Didit::Model
43
+ read_field(name)
44
+ end
45
+ end
46
+
47
+ # Builds an instance from a parsed JSON value; anything but an object is returned unchanged.
48
+ def from_json(value)
49
+ value.is_a?(Hash) ? new(value) : value
50
+ end
51
+
52
+ # Converts a parsed JSON +value+ to +type+, leniently.
53
+ def coerce(value, type)
54
+ return value if value.nil?
55
+
56
+ case type
57
+ when Array then coerce_container(value, type)
58
+ when :float then value.is_a?(Integer) ? value.to_f : value
59
+ when :datetime then parse_time(value)
60
+ when :date then parse_date(value)
61
+ when Symbol then value
62
+ else coerce_model(value, type)
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def coerce_container(value, type)
69
+ kind, inner = type
70
+ if kind == :union
71
+ member = inner.find { |m| fits?(value, m) }
72
+ member ? coerce(value, member) : value
73
+ elsif kind == :array && value.is_a?(Array)
74
+ value.map { |item| coerce(item, inner) }
75
+ elsif kind == :map && value.is_a?(Hash)
76
+ value.transform_values { |item| coerce(item, inner) }
77
+ else
78
+ value
79
+ end
80
+ end
81
+
82
+ # Whether +value+ has the JSON shape of +type+ (for unions).
83
+ def fits?(value, type)
84
+ case value
85
+ when Hash then type.is_a?(String) || type.is_a?(Class) || (type.is_a?(Array) && type.first == :map)
86
+ when Array then type.is_a?(Array) && type.first == :array
87
+ when String then %i[string datetime date].include?(type)
88
+ when Integer then %i[integer float].include?(type)
89
+ when Float then type == :float
90
+ when true, false then type == :boolean
91
+ else false
92
+ end
93
+ end
94
+
95
+ def coerce_model(value, type)
96
+ klass = type.is_a?(String) ? Didit::Types.const_get(type, false) : type
97
+ value.is_a?(Hash) && klass.is_a?(Class) && klass <= Model ? klass.new(value) : value
98
+ end
99
+
100
+ def parse_time(value)
101
+ return value unless value.is_a?(String)
102
+
103
+ Time.iso8601(value.sub(" ", "T"))
104
+ rescue ArgumentError
105
+ value
106
+ end
107
+
108
+ def parse_date(value)
109
+ return value unless value.is_a?(String)
110
+
111
+ Date.iso8601(value)
112
+ rescue ArgumentError
113
+ value
114
+ end
115
+ end
116
+
117
+ # @param data [Hash] the JSON object, as parsed (string keys); symbol keys are accepted too
118
+ def initialize(data = {})
119
+ raise ArgumentError, "#{self.class.name} needs a Hash, got #{data.class}" unless data.is_a?(Hash)
120
+
121
+ # @type var normalized: Hash[String, untyped]
122
+ normalized = data.each_key.all?(String) ? (_ = data.dup) : data.transform_keys(&:to_s)
123
+ @data = normalized.freeze
124
+ @cache = {}
125
+ end
126
+
127
+ # The raw JSON value of any property, known to the SDK or not.
128
+ #
129
+ # @param key [String, Symbol] the property name as the API sends it
130
+ def [](key)
131
+ @data[key.to_s]
132
+ end
133
+
134
+ # Whether the API sent the property (also when its value is +null+).
135
+ def key?(key)
136
+ @data.key?(key.to_s)
137
+ end
138
+
139
+ # The JSON object as a Hash with symbol keys, nested objects included.
140
+ #
141
+ # @return [Hash{Symbol => Object}]
142
+ def to_h
143
+ Model.symbolize(@data)
144
+ end
145
+
146
+ # @return [String] the JSON object, unchanged
147
+ def to_json(*args)
148
+ JSON.generate(@data, args.first)
149
+ end
150
+
151
+ # Pattern matching on the typed readers: +in {status: "Approved"}+.
152
+ def deconstruct_keys(keys)
153
+ fields = self.class.fields
154
+ # @type var out: Hash[Symbol, untyped]
155
+ out = {}
156
+ (keys || fields.keys).each { |name| out[name] = public_send(name) if fields.key?(name) }
157
+ out
158
+ end
159
+
160
+ def ==(other)
161
+ other.class == self.class && other.raw_data == @data
162
+ end
163
+ alias eql? ==
164
+
165
+ def hash
166
+ [self.class, @data].hash
167
+ end
168
+
169
+ def inspect
170
+ "#<#{self.class.name} #{@data.inspect}>"
171
+ end
172
+ alias to_s inspect
173
+
174
+ # @api private
175
+ def self.symbolize(value)
176
+ case value
177
+ when Hash then value.to_h { |k, v| [k.to_sym, symbolize(v)] }
178
+ when Array then value.map { |v| symbolize(v) }
179
+ else value
180
+ end
181
+ end
182
+
183
+ protected
184
+
185
+ # @api private
186
+ def raw_data
187
+ @data
188
+ end
189
+
190
+ private
191
+
192
+ def read_field(name)
193
+ return @cache[name] if @cache.key?(name)
194
+
195
+ wire, type = self.class.fields.fetch(name)
196
+ @cache[name] = Model.coerce(@data[wire], type)
197
+ end
198
+ end
199
+ end
data/lib/didit/page.rb ADDED
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+
5
+ module Didit
6
+ # One page of a list (docs/DESIGN.md section 8): the API's +{count, next, previous, results}+.
7
+ #
8
+ # page = didit.sessions.list(limit: 50)
9
+ # page.each { |session| ... } # this page
10
+ # page.auto_paging_each { |session| ... } # every page, fetched as needed
11
+ #
12
+ # +total_count+ is the API's +count+ (Enumerable#count counts the items of this page).
13
+ class Page
14
+ include Enumerable
15
+
16
+ # @return [Array] the items of this page, typed
17
+ attr_reader :results
18
+
19
+ # @api private
20
+ def initialize(client:, prepared:, item:, data:, seen: nil)
21
+ @client = client
22
+ @prepared = prepared
23
+ @item = item
24
+ @data = data.is_a?(Hash) ? data : {}
25
+ list = @data["results"]
26
+ @results = list.is_a?(Array) ? list.map { |value| Model.coerce(value, item) } : []
27
+ @seen = seen || [Page.normalize(prepared.uri)]
28
+ end
29
+
30
+ # @return [Integer, nil] the total number of items across pages
31
+ def total_count
32
+ @data["count"]
33
+ end
34
+
35
+ # @return [String, nil]
36
+ def next_url
37
+ link(@data["next"])
38
+ end
39
+
40
+ # @return [String, nil]
41
+ def previous_url
42
+ link(@data["previous"])
43
+ end
44
+
45
+ # Iterates the items of this page.
46
+ def each(&)
47
+ return enum_for(:each) unless block_given?
48
+
49
+ results.each(&)
50
+ self
51
+ end
52
+
53
+ def next_page?
54
+ !next_url.nil?
55
+ end
56
+
57
+ # Fetches the next page, or returns nil on the last one.
58
+ # @return [Didit::Page, nil]
59
+ def next_page
60
+ url = next_url
61
+ return nil if url.nil?
62
+
63
+ target = resolve(url)
64
+ key = Page.normalize(target)
65
+ if @seen.include?(key)
66
+ raise APIResponseValidationError.new(
67
+ "The API returned the pagination link #{Internal::Util.display_url(target)} twice; stopping to avoid " \
68
+ "a loop.", status: 200
69
+ )
70
+ end
71
+ @client.fetch_page(@prepared, target, @item, @seen + [key])
72
+ end
73
+
74
+ # Iterates every item of every page, fetching pages as needed.
75
+ # @return [Enumerator] without a block
76
+ def auto_paging_each(&block)
77
+ return enum_for(:auto_paging_each) unless block
78
+
79
+ # @type var page: Page[untyped]?
80
+ page = self
81
+ while page
82
+ page.results.each(&block)
83
+ page = page.next_page
84
+ end
85
+ nil
86
+ end
87
+
88
+ # The raw value of any property of the page.
89
+ def [](key)
90
+ @data[key.to_s]
91
+ end
92
+
93
+ # @return [Hash{Symbol => Object}]
94
+ def to_h
95
+ Model.symbolize(@data)
96
+ end
97
+
98
+ def inspect
99
+ "#<Didit::Page total_count=#{total_count.inspect} results=#{results.size} next=#{next_page?}>"
100
+ end
101
+
102
+ # @api private
103
+ def self.normalize(uri)
104
+ uri = uri.dup
105
+ uri.fragment = nil
106
+ # @type var query: Array[[String, String]]
107
+ query = uri.query ? URI.decode_www_form(uri.query).sort : []
108
+ [Internal::Util.origin(uri), uri.path, query]
109
+ end
110
+
111
+ private
112
+
113
+ def link(value)
114
+ value.is_a?(String) && !value.strip.empty? ? value.strip : nil
115
+ end
116
+
117
+ def resolve(url)
118
+ target = URI.join(@prepared.uri.to_s, url)
119
+ unless %w[http https].include?(target.scheme) && Internal::Util.origin(target) == @prepared.origin
120
+ raise APIResponseValidationError.new(
121
+ "Refusing to follow a pagination link to another origin (#{Internal::Util.origin(target)}); " \
122
+ "the API key is only sent to #{@prepared.origin}.", status: 200
123
+ )
124
+ end
125
+ target
126
+ rescue URI::Error => e
127
+ raise APIResponseValidationError.new("The API returned an invalid pagination link: #{e.message}", status: 200)
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Didit
4
+ # The HTTP response behind a result, from +didit.with_raw_response+:
5
+ #
6
+ # raw = didit.with_raw_response.sessions.create(workflow_id: "...")
7
+ # raw.status # => 201
8
+ # raw.request_id # => "..."
9
+ # session = raw.parse
10
+ class RawResponse
11
+ # @return [Integer]
12
+ attr_reader :status
13
+ # @return [Hash{String => String}] header names in lower case
14
+ attr_reader :headers
15
+ # @return [String, nil] the body bytes (nil when a block received them)
16
+ attr_reader :body
17
+ # @return [Integer] how many retries it took
18
+ attr_reader :retries_taken
19
+ # @return [Float] seconds the last attempt took
20
+ attr_reader :elapsed
21
+
22
+ # @api private
23
+ def initialize(status:, headers:, body:, retries_taken:, elapsed:, parser:)
24
+ @status = status
25
+ @headers = headers
26
+ @body = body
27
+ @retries_taken = retries_taken
28
+ @elapsed = elapsed
29
+ @parser = parser
30
+ @parsed = false
31
+ @value = nil
32
+ end
33
+
34
+ # @return [Integer] alias of {#status}
35
+ def status_code
36
+ status
37
+ end
38
+
39
+ # @return [String, nil]
40
+ def request_id
41
+ Internal::Util.request_id(headers)
42
+ end
43
+
44
+ # The typed result the method returns without +with_raw_response+.
45
+ def parse
46
+ unless @parsed
47
+ @value = @parser.call
48
+ @parsed = true
49
+ end
50
+ @value
51
+ end
52
+
53
+ def inspect
54
+ "#<Didit::RawResponse status=#{status} request_id=#{request_id.inspect}>"
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Didit
4
+ # Base class of the generated resources (+didit.sessions+, +didit.sessions.imports+, ...).
5
+ class Resource
6
+ # @param client [Didit::Client]
7
+ def initialize(client)
8
+ @client = client
9
+ end
10
+
11
+ def inspect
12
+ "#<#{self.class.name}>"
13
+ end
14
+ end
15
+ end