noresponse 2.0.17

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 (231) hide show
  1. checksums.yaml +7 -0
  2. data/lib/crystalline/enum.rbi +17 -0
  3. data/lib/crystalline/metadata_fields.rb +263 -0
  4. data/lib/crystalline/module.rb +186 -0
  5. data/lib/crystalline/types.rb +168 -0
  6. data/lib/crystalline/utils.rb +67 -0
  7. data/lib/crystalline.rb +11 -0
  8. data/lib/no_response/assessments.rb +1252 -0
  9. data/lib/no_response/auth.rb +263 -0
  10. data/lib/no_response/issued_credential.rb +21 -0
  11. data/lib/no_response/keys.rb +318 -0
  12. data/lib/no_response/late_results.rb +301 -0
  13. data/lib/no_response/models/callbacks.rb +10 -0
  14. data/lib/no_response/models/errors/apistatuserror.rb +41 -0
  15. data/lib/no_response/models/errors/apistatuserror.rbi +30 -0
  16. data/lib/no_response/models/errors/authenticationerror.rb +108 -0
  17. data/lib/no_response/models/errors/authenticationerror.rbi +56 -0
  18. data/lib/no_response/models/errors/badrequesterror.rb +108 -0
  19. data/lib/no_response/models/errors/badrequesterror.rbi +56 -0
  20. data/lib/no_response/models/errors/conflicterror.rb +108 -0
  21. data/lib/no_response/models/errors/conflicterror.rbi +56 -0
  22. data/lib/no_response/models/errors/notfounderror.rb +108 -0
  23. data/lib/no_response/models/errors/notfounderror.rbi +56 -0
  24. data/lib/no_response/models/errors/permissiondeniederror.rb +108 -0
  25. data/lib/no_response/models/errors/permissiondeniederror.rbi +56 -0
  26. data/lib/no_response/models/errors/ratelimiterror.rb +108 -0
  27. data/lib/no_response/models/errors/ratelimiterror.rbi +56 -0
  28. data/lib/no_response/models/errors.rb +16 -0
  29. data/lib/no_response/models/operations/createassessment_request.rb +36 -0
  30. data/lib/no_response/models/operations/createassessment_request.rbi +20 -0
  31. data/lib/no_response/models/operations/createassessment_response.rb +32 -0
  32. data/lib/no_response/models/operations/createassessment_response.rbi +20 -0
  33. data/lib/no_response/models/operations/getassessment_request.rb +41 -0
  34. data/lib/no_response/models/operations/getassessment_request.rbi +20 -0
  35. data/lib/no_response/models/operations/getassessment_response.rb +32 -0
  36. data/lib/no_response/models/operations/getassessment_response.rbi +20 -0
  37. data/lib/no_response/models/operations/queryaccountassessments_response.rb +44 -0
  38. data/lib/no_response/models/operations/queryaccountassessments_response.rbi +20 -0
  39. data/lib/no_response/models/operations/recordassessmentoutcome_request.rb +52 -0
  40. data/lib/no_response/models/operations/recordassessmentoutcome_request.rbi +26 -0
  41. data/lib/no_response/models/operations/recordassessmentoutcome_response.rb +32 -0
  42. data/lib/no_response/models/operations/recordassessmentoutcome_response.rbi +20 -0
  43. data/lib/no_response/models/operations/rotateapikey_response.rb +32 -0
  44. data/lib/no_response/models/operations/rotateapikey_response.rbi +20 -0
  45. data/lib/no_response/models/operations.rb +17 -0
  46. data/lib/no_response/models/shared/alternate_name.rb +23 -0
  47. data/lib/no_response/models/shared/alternate_name.rbi +9 -0
  48. data/lib/no_response/models/shared/alternate_name_union.rb +23 -0
  49. data/lib/no_response/models/shared/alternate_name_union.rbi +9 -0
  50. data/lib/no_response/models/shared/assessment.rb +235 -0
  51. data/lib/no_response/models/shared/assessment.rbi +116 -0
  52. data/lib/no_response/models/shared/assessmentlist.rb +78 -0
  53. data/lib/no_response/models/shared/assessmentlist.rbi +38 -0
  54. data/lib/no_response/models/shared/assessmentoutcome.rb +61 -0
  55. data/lib/no_response/models/shared/assessmentoutcome.rbi +32 -0
  56. data/lib/no_response/models/shared/assessmentoutcomerequest.rb +71 -0
  57. data/lib/no_response/models/shared/assessmentoutcomerequest.rbi +32 -0
  58. data/lib/no_response/models/shared/assessmentquery.rb +70 -0
  59. data/lib/no_response/models/shared/assessmentquery.rbi +32 -0
  60. data/lib/no_response/models/shared/assessmentrequest.rb +125 -0
  61. data/lib/no_response/models/shared/assessmentrequest.rbi +62 -0
  62. data/lib/no_response/models/shared/assessmentrequestclientcontext.rb +125 -0
  63. data/lib/no_response/models/shared/assessmentrequestclientcontext.rbi +62 -0
  64. data/lib/no_response/models/shared/assessmentrequestidentifiers.rb +74 -0
  65. data/lib/no_response/models/shared/assessmentrequestidentifiers.rbi +38 -0
  66. data/lib/no_response/models/shared/assessmentrequestissuedcredential.rb +33 -0
  67. data/lib/no_response/models/shared/assessmentrequestissuedcredential.rbi +14 -0
  68. data/lib/no_response/models/shared/assessmentrequestpolicycontext.rb +46 -0
  69. data/lib/no_response/models/shared/assessmentrequestpolicycontext.rbi +20 -0
  70. data/lib/no_response/models/shared/assessmenttiming.rb +41 -0
  71. data/lib/no_response/models/shared/assessmenttiming.rbi +20 -0
  72. data/lib/no_response/models/shared/assurancelevel.rb +18 -0
  73. data/lib/no_response/models/shared/assurancelevel.rbi +9 -0
  74. data/lib/no_response/models/shared/authcontext.rb +285 -0
  75. data/lib/no_response/models/shared/authcontext.rbi +152 -0
  76. data/lib/no_response/models/shared/authcontextmfa.rb +55 -0
  77. data/lib/no_response/models/shared/authcontextmfa.rbi +26 -0
  78. data/lib/no_response/models/shared/authenticationerrorcode.rb +18 -0
  79. data/lib/no_response/models/shared/authenticationerrorcode.rbi +9 -0
  80. data/lib/no_response/models/shared/badrequesterrorcode.rb +20 -0
  81. data/lib/no_response/models/shared/badrequesterrorcode.rbi +9 -0
  82. data/lib/no_response/models/shared/band.rb +21 -0
  83. data/lib/no_response/models/shared/band.rbi +9 -0
  84. data/lib/no_response/models/shared/breach.rb +108 -0
  85. data/lib/no_response/models/shared/breach.rbi +56 -0
  86. data/lib/no_response/models/shared/breachexposed.rb +28 -0
  87. data/lib/no_response/models/shared/breachexposed.rbi +9 -0
  88. data/lib/no_response/models/shared/breachkind.rb +24 -0
  89. data/lib/no_response/models/shared/breachkind.rbi +9 -0
  90. data/lib/no_response/models/shared/breachselector.rb +20 -0
  91. data/lib/no_response/models/shared/breachselector.rbi +9 -0
  92. data/lib/no_response/models/shared/breachsummary.rb +109 -0
  93. data/lib/no_response/models/shared/breachsummary.rbi +56 -0
  94. data/lib/no_response/models/shared/confidence.rb +21 -0
  95. data/lib/no_response/models/shared/confidence.rbi +9 -0
  96. data/lib/no_response/models/shared/conflicterrorcode.rb +19 -0
  97. data/lib/no_response/models/shared/conflicterrorcode.rbi +9 -0
  98. data/lib/no_response/models/shared/consistency.rb +85 -0
  99. data/lib/no_response/models/shared/consistency.rbi +32 -0
  100. data/lib/no_response/models/shared/consistencyvalue.rb +21 -0
  101. data/lib/no_response/models/shared/consistencyvalue.rbi +9 -0
  102. data/lib/no_response/models/shared/country.rb +20 -0
  103. data/lib/no_response/models/shared/country.rbi +9 -0
  104. data/lib/no_response/models/shared/email.rb +23 -0
  105. data/lib/no_response/models/shared/email.rbi +9 -0
  106. data/lib/no_response/models/shared/email_union.rb +23 -0
  107. data/lib/no_response/models/shared/email_union.rbi +9 -0
  108. data/lib/no_response/models/shared/failurereason.rb +24 -0
  109. data/lib/no_response/models/shared/failurereason.rbi +9 -0
  110. data/lib/no_response/models/shared/flow.rb +18 -0
  111. data/lib/no_response/models/shared/flow.rbi +9 -0
  112. data/lib/no_response/models/shared/freshness.rb +20 -0
  113. data/lib/no_response/models/shared/freshness.rbi +9 -0
  114. data/lib/no_response/models/shared/hookpoint.rb +19 -0
  115. data/lib/no_response/models/shared/hookpoint.rbi +9 -0
  116. data/lib/no_response/models/shared/identifierkind.rb +21 -0
  117. data/lib/no_response/models/shared/identifierkind.rbi +9 -0
  118. data/lib/no_response/models/shared/incompletereason.rb +23 -0
  119. data/lib/no_response/models/shared/incompletereason.rbi +9 -0
  120. data/lib/no_response/models/shared/incompletesource.rb +53 -0
  121. data/lib/no_response/models/shared/incompletesource.rbi +20 -0
  122. data/lib/no_response/models/shared/ipsummary.rb +61 -0
  123. data/lib/no_response/models/shared/ipsummary.rbi +26 -0
  124. data/lib/no_response/models/shared/ipsummarytype.rb +24 -0
  125. data/lib/no_response/models/shared/ipsummarytype.rbi +9 -0
  126. data/lib/no_response/models/shared/keyrotation.rb +79 -0
  127. data/lib/no_response/models/shared/keyrotation.rbi +44 -0
  128. data/lib/no_response/models/shared/keyrotationrequest.rb +33 -0
  129. data/lib/no_response/models/shared/keyrotationrequest.rbi +14 -0
  130. data/lib/no_response/models/shared/lane.rb +21 -0
  131. data/lib/no_response/models/shared/lane.rbi +9 -0
  132. data/lib/no_response/models/shared/linetype.rb +22 -0
  133. data/lib/no_response/models/shared/linetype.rbi +9 -0
  134. data/lib/no_response/models/shared/location.rb +23 -0
  135. data/lib/no_response/models/shared/location.rbi +9 -0
  136. data/lib/no_response/models/shared/location_union.rb +23 -0
  137. data/lib/no_response/models/shared/location_union.rbi +9 -0
  138. data/lib/no_response/models/shared/name_candidate.rb +23 -0
  139. data/lib/no_response/models/shared/name_candidate.rbi +9 -0
  140. data/lib/no_response/models/shared/name_candidate_union.rb +23 -0
  141. data/lib/no_response/models/shared/name_candidate_union.rbi +9 -0
  142. data/lib/no_response/models/shared/notfounderrorcode.rb +18 -0
  143. data/lib/no_response/models/shared/notfounderrorcode.rbi +9 -0
  144. data/lib/no_response/models/shared/outcome.rb +23 -0
  145. data/lib/no_response/models/shared/outcome.rbi +9 -0
  146. data/lib/no_response/models/shared/permissiondeniederrorcode.rb +18 -0
  147. data/lib/no_response/models/shared/permissiondeniederrorcode.rbi +9 -0
  148. data/lib/no_response/models/shared/phoneenrichment.rb +32 -0
  149. data/lib/no_response/models/shared/phoneenrichment.rbi +14 -0
  150. data/lib/no_response/models/shared/phoneenrichmentfields.rb +451 -0
  151. data/lib/no_response/models/shared/phoneenrichmentfields.rbi +212 -0
  152. data/lib/no_response/models/shared/platform.rb +18 -0
  153. data/lib/no_response/models/shared/platform.rbi +9 -0
  154. data/lib/no_response/models/shared/probleminvalidparam.rb +48 -0
  155. data/lib/no_response/models/shared/probleminvalidparam.rbi +26 -0
  156. data/lib/no_response/models/shared/ratelimiterrorcode.rb +18 -0
  157. data/lib/no_response/models/shared/ratelimiterrorcode.rbi +9 -0
  158. data/lib/no_response/models/shared/reasoncode.rb +52 -0
  159. data/lib/no_response/models/shared/reasoncode.rbi +9 -0
  160. data/lib/no_response/models/shared/reasonidentifier.rb +23 -0
  161. data/lib/no_response/models/shared/reasonidentifier.rbi +9 -0
  162. data/lib/no_response/models/shared/recommendation.rb +20 -0
  163. data/lib/no_response/models/shared/recommendation.rbi +9 -0
  164. data/lib/no_response/models/shared/responsemode.rb +16 -0
  165. data/lib/no_response/models/shared/responsemode.rbi +9 -0
  166. data/lib/no_response/models/shared/risk.rb +171 -0
  167. data/lib/no_response/models/shared/risk.rbi +80 -0
  168. data/lib/no_response/models/shared/riskconfidence.rb +20 -0
  169. data/lib/no_response/models/shared/riskconfidence.rbi +9 -0
  170. data/lib/no_response/models/shared/riskcoverage.rb +49 -0
  171. data/lib/no_response/models/shared/riskcoverage.rbi +26 -0
  172. data/lib/no_response/models/shared/riskdetails.rb +55 -0
  173. data/lib/no_response/models/shared/riskdetails.rbi +26 -0
  174. data/lib/no_response/models/shared/riskdetailsbreachname.rb +40 -0
  175. data/lib/no_response/models/shared/riskdetailsbreachname.rbi +20 -0
  176. data/lib/no_response/models/shared/riskdetailsphonename.rb +40 -0
  177. data/lib/no_response/models/shared/riskdetailsphonename.rbi +20 -0
  178. data/lib/no_response/models/shared/riskreason.rb +67 -0
  179. data/lib/no_response/models/shared/riskreason.rbi +26 -0
  180. data/lib/no_response/models/shared/risksummary.rb +73 -0
  181. data/lib/no_response/models/shared/risksummary.rbi +38 -0
  182. data/lib/no_response/models/shared/risksummaryemail.rb +55 -0
  183. data/lib/no_response/models/shared/risksummaryemail.rbi +26 -0
  184. data/lib/no_response/models/shared/risksummaryphone.rb +69 -0
  185. data/lib/no_response/models/shared/risksummaryphone.rbi +32 -0
  186. data/lib/no_response/models/shared/risksummaryusername.rb +41 -0
  187. data/lib/no_response/models/shared/risksummaryusername.rbi +20 -0
  188. data/lib/no_response/models/shared/scope.rb +21 -0
  189. data/lib/no_response/models/shared/scope.rbi +9 -0
  190. data/lib/no_response/models/shared/security.rb +32 -0
  191. data/lib/no_response/models/shared/security.rbi +14 -0
  192. data/lib/no_response/models/shared/signal.rb +149 -0
  193. data/lib/no_response/models/shared/signal.rbi +68 -0
  194. data/lib/no_response/models/shared/signaloutcome.rb +22 -0
  195. data/lib/no_response/models/shared/signaloutcome.rbi +9 -0
  196. data/lib/no_response/models/shared/social_profile.rb +23 -0
  197. data/lib/no_response/models/shared/social_profile.rbi +9 -0
  198. data/lib/no_response/models/shared/social_profile_union.rb +23 -0
  199. data/lib/no_response/models/shared/social_profile_union.rbi +9 -0
  200. data/lib/no_response/models/shared/status.rb +20 -0
  201. data/lib/no_response/models/shared/status.rbi +9 -0
  202. data/lib/no_response/models/shared/timezone.rb +23 -0
  203. data/lib/no_response/models/shared/timezone.rbi +9 -0
  204. data/lib/no_response/models/shared/timezone_union.rb +23 -0
  205. data/lib/no_response/models/shared/timezone_union.rbi +9 -0
  206. data/lib/no_response/models/shared/transport.rb +17 -0
  207. data/lib/no_response/models/shared/transport.rbi +9 -0
  208. data/lib/no_response/models/shared/website.rb +23 -0
  209. data/lib/no_response/models/shared/website.rbi +9 -0
  210. data/lib/no_response/models/shared/website_union.rb +23 -0
  211. data/lib/no_response/models/shared/website_union.rbi +9 -0
  212. data/lib/no_response/models/shared.rb +92 -0
  213. data/lib/no_response/noresponseclient.rb +110 -0
  214. data/lib/no_response/sdk_hooks/hooks.rb +97 -0
  215. data/lib/no_response/sdk_hooks/idempotency_key_hook.rb +25 -0
  216. data/lib/no_response/sdk_hooks/registration.rb +43 -0
  217. data/lib/no_response/sdk_hooks/types.rb +178 -0
  218. data/lib/no_response/sdkconfiguration.rb +107 -0
  219. data/lib/no_response/sdkconfiguration.rbi +83 -0
  220. data/lib/no_response/utils/forms.rb +230 -0
  221. data/lib/no_response/utils/headers.rb +80 -0
  222. data/lib/no_response/utils/query_params.rb +165 -0
  223. data/lib/no_response/utils/request_bodies.rb +77 -0
  224. data/lib/no_response/utils/retries.rb +137 -0
  225. data/lib/no_response/utils/security.rb +156 -0
  226. data/lib/no_response/utils/url.rb +122 -0
  227. data/lib/no_response/utils/utils.rb +243 -0
  228. data/lib/no_response/wait.rb +66 -0
  229. data/lib/no_response/webhooks.rb +177 -0
  230. data/lib/noresponse.rb +25 -0
  231. metadata +501 -0
@@ -0,0 +1,230 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "cgi"
5
+ require "date"
6
+ require "base64"
7
+ require "sorbet-runtime"
8
+
9
+ module NoResponse
10
+ module Utils
11
+ extend T::Sig
12
+
13
+ sig do
14
+ params(
15
+ field_name: String,
16
+ explode: T::Boolean,
17
+ obj: Object,
18
+ delimiter: String,
19
+ get_field_name_lambda: T.proc.params(obj_field: ::Crystalline::MetadataFields::Field).returns(String)
20
+ )
21
+ .returns(T::Hash[String, T::Array[String]])
22
+ end
23
+ def self._populate_form(field_name, explode, obj, delimiter, &get_field_name_lambda)
24
+ params = {}
25
+
26
+ return params if obj.nil?
27
+
28
+ if obj.respond_to?(:fields)
29
+ items = []
30
+ T.unsafe(obj).fields.each do |obj_field|
31
+ obj_field_name = get_field_name_lambda.call(obj_field)
32
+ next if obj_field_name == ""
33
+
34
+ val = obj.send(obj_field.name.to_sym)
35
+ next if val.nil?
36
+
37
+ if explode
38
+ params[obj_field_name] = [val_to_string(val)]
39
+ else
40
+ items.append("#{obj_field_name}#{delimiter}#{val_to_string(val)}")
41
+ end
42
+ end
43
+
44
+ params[field_name] = [items.join(delimiter)] if !items.empty?
45
+ elsif obj.is_a?(Hash)
46
+ items = []
47
+ obj.each do |key, value|
48
+ next if value.nil?
49
+
50
+ if explode
51
+ params[key] = val_to_string(value)
52
+ else
53
+ items.append("#{key}#{delimiter}#{val_to_string(value)}")
54
+ end
55
+ end
56
+
57
+ params[field_name] = [items.join(delimiter)] if !items.empty?
58
+
59
+ elsif obj.is_a?(Array)
60
+ items = []
61
+ obj.each do |value|
62
+ next if value.nil?
63
+
64
+ if explode
65
+ params[field_name] = [] if !params.key?(field_name)
66
+
67
+ params[field_name].append(val_to_string(value))
68
+ else
69
+ items.append(val_to_string(value))
70
+ end
71
+ end
72
+
73
+ params[field_name] = items.map(&:to_s).join(delimiter) if !items.empty?
74
+
75
+ else
76
+ params[field_name] = val_to_string(obj)
77
+ end
78
+
79
+ params
80
+ end
81
+
82
+ sig {
83
+ params(media_type: String, request: Object).returns(
84
+ [String, Object, T::Array[T::Array[T.any(T::Array[T.nilable(String)], String)]]]
85
+ )
86
+ }
87
+ def self.serialize_multipart_form(media_type, request)
88
+ form = []
89
+ T.unsafe(request).fields.each do |field|
90
+ val = request.send(field.name)
91
+ next if val.nil?
92
+
93
+ field_metadata = field.metadata[:multipart_form]
94
+ next if field_metadata.nil?
95
+
96
+ if field_metadata[:file] == true
97
+ field_name = field_metadata[:field_name]
98
+
99
+ # Handle arrays of files
100
+ if val.is_a?(Array)
101
+ val.each do |file_obj|
102
+ file_name = T.let("", String)
103
+ content = nil
104
+
105
+ T.must(file_obj).fields.each do |file_field|
106
+ file_metadata = file_field.metadata[:multipart_form]
107
+ next if file_metadata.nil?
108
+
109
+ if file_metadata[:content] == true
110
+ content = T.let(file_obj.send(file_field.name), String)
111
+ else
112
+ file_name = T.let(file_obj.send(file_field.name), String)
113
+ end
114
+ end
115
+
116
+ if T.unsafe(file_name) == "" || T.unsafe(content).nil?
117
+ raise StandardError, "invalid multipart/form-data file"
118
+ end
119
+
120
+ form.append([field_name, [file_name, content]])
121
+ end
122
+ else
123
+ # Handle single file
124
+ file_name = T.let("", String)
125
+ content = nil
126
+
127
+ T.must(val).fields.each do |file_field|
128
+ file_metadata = file_field.metadata[:multipart_form]
129
+ next if file_metadata.nil?
130
+
131
+ if file_metadata[:content] == true
132
+ content = T.let(val.send(file_field.name), String)
133
+ else
134
+ file_name = T.let(val.send(file_field.name), String)
135
+ end
136
+ end
137
+
138
+ if T.unsafe(file_name) == "" || T.unsafe(content).nil?
139
+ raise StandardError, "invalid multipart/form-data file"
140
+ end
141
+
142
+ form.append([field_name, [file_name, content]])
143
+ end
144
+ elsif field_metadata[:json] == true
145
+ to_append = [
146
+ field_metadata.fetch(:field_name, field.name),
147
+ [
148
+ nil,
149
+ ::Crystalline.to_json(val),
150
+ "application/json"
151
+ ]
152
+ ]
153
+ form.append(to_append)
154
+ else
155
+ field_name = field_metadata.fetch(
156
+ :field_name,
157
+ field.name
158
+ )
159
+ if val.is_a?(Array)
160
+ val.each do |value|
161
+ next if value.nil?
162
+
163
+ form.append(
164
+ [field_name, [nil, val_to_string(value)]]
165
+ )
166
+ end
167
+ else
168
+ form.append([field_name, [nil, val_to_string(val)]])
169
+ end
170
+ end
171
+ end
172
+
173
+ [media_type, nil, form]
174
+ end
175
+
176
+ sig do
177
+ params(data: T.any(Object, T::Hash[String, String]))
178
+ .returns(T::Hash[T.any(String, Symbol), Object])
179
+ end
180
+ def self.serialize_form_data(data)
181
+ get_form_field_name = lambda do |obj_field|
182
+ obj_param_metadata = obj_field.metadata[:form]
183
+
184
+ return T.let({}, T::Hash[T.any(String, Symbol), Object]) if obj_param_metadata.nil?
185
+
186
+ return obj_param_metadata.fetch(:field_name, obj_field.name)
187
+ end
188
+
189
+ form = T.let({}, T::Hash[T.any(String, Symbol), Object])
190
+ if data.respond_to?(:fields)
191
+ T.unsafe(data).fields.each do |field|
192
+ val = data.send(field.name)
193
+ next if val.nil?
194
+
195
+ metadata = field.metadata[:form]
196
+
197
+ next if metadata.nil?
198
+
199
+ field_name = metadata.fetch(:field_name, field.name)
200
+
201
+ if metadata[:json]
202
+ form[field_name] = ::Crystalline.to_json(val)
203
+ else
204
+ if metadata.fetch(:style, "form") == "form"
205
+ form = form.merge(
206
+ _populate_form(
207
+ field_name,
208
+ metadata.fetch(:explode, true),
209
+ val,
210
+ ",",
211
+ &get_form_field_name
212
+ )
213
+ )
214
+ else
215
+ raise StandardError, "Invalid form style for field #{field.name}"
216
+ end
217
+ end
218
+ end
219
+ elsif data.is_a?(Hash)
220
+ data.each do |key, value|
221
+ form[key] = [val_to_string(value)]
222
+ end
223
+ else
224
+ raise StandardError, "Invalid request body type #{data.class}"
225
+ end
226
+
227
+ form
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,80 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "cgi"
5
+ require "date"
6
+ require "base64"
7
+ require "sorbet-runtime"
8
+
9
+ module NoResponse
10
+ module Utils
11
+ extend T::Sig
12
+
13
+ sig {
14
+ params(headers_params: Object, gbls: T.nilable(T::Hash[Symbol, T::Hash[Symbol, T::Hash[Symbol, Object]]])).returns(
15
+ T::Hash[Symbol, String]
16
+ )
17
+ }
18
+ def self.get_headers(headers_params, gbls = nil)
19
+ return {} if headers_params.nil?
20
+
21
+ headers = {}
22
+ T.unsafe(headers_params).fields.each do |f|
23
+ metadata = f.metadata[:header]
24
+ next if metadata.nil?
25
+
26
+ value = _populate_from_globals(f.name, headers_params&.send(f.name), "header", gbls)
27
+ value = _serialize_header(metadata.fetch(:explode, false), value)
28
+ headers[metadata.fetch(:field_name, f.name)] = value if !T.must(value).empty?
29
+ end
30
+
31
+ headers
32
+ end
33
+
34
+ sig { params(explode: T::Boolean, obj: Object).returns(T.nilable(String)) }
35
+ def self._serialize_header(explode, obj)
36
+ return "" if obj.nil?
37
+
38
+ if obj.respond_to?(:fields)
39
+ items = []
40
+ T.unsafe(obj).fields.each do |obj_field|
41
+ obj_param_metadata = obj_field.metadata[:header]
42
+ next if obj_param_metadata.nil?
43
+
44
+ obj_field_name = obj_param_metadata.fetch(:field_name, obj_field.name)
45
+ next if obj_field_name == ""
46
+
47
+ val = obj.send(obj_field.name)
48
+ next if val.nil?
49
+
50
+ if explode
51
+ items.append("#{obj_field_name}=#{val_to_string(val)}")
52
+ else
53
+ items.append(obj_field_name)
54
+ items.append(val_to_string(val))
55
+ end
56
+ end
57
+
58
+ items.join(",") if !items.empty?
59
+ elsif obj.is_a?(Hash)
60
+ items = []
61
+ obj.each do |key, value|
62
+ next if value.nil?
63
+
64
+ if explode
65
+ items.append("#{key}=#{val_to_string(value)}")
66
+ else
67
+ items.append(key)
68
+ items.append(val_to_string(value))
69
+ end
70
+ end
71
+
72
+ items.join(",") if !items.empty?
73
+ elsif obj.is_a?(Array)
74
+ items = obj.filter { |v| !v.nil? }.map { |v| val_to_string(v) }.join(",")
75
+ else
76
+ val_to_string(obj)
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,165 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "date"
5
+ require "base64"
6
+ require "sorbet-runtime"
7
+
8
+ module NoResponse
9
+ module Utils
10
+ extend T::Sig
11
+
12
+ sig {
13
+ params(
14
+ clazz: Object,
15
+ query_params: Object,
16
+ url_override: T.nilable(::String),
17
+ gbls: T.nilable(T::Hash[Symbol, T::Hash[Symbol, T::Hash[Symbol, Object]]])
18
+ )
19
+ .returns(T::Hash[T.any(String, Symbol), T::Array[String]])
20
+ }
21
+ def self.get_query_params(clazz, query_params, url_override = nil, gbls = nil)
22
+ parsed_params = T.let({}, T::Hash[T.any(String, Symbol), T::Array[String]])
23
+ if !url_override.nil?
24
+ parsed_url = URI.parse(url_override)
25
+ URI.decode_www_form(parsed_url.query.to_s).each do |key, value|
26
+ parsed_params[key] ||= []
27
+ T.must(parsed_params[key]) << value
28
+ end
29
+ end
30
+
31
+ params = T.let({}, T::Hash[T.any(String, Symbol), T::Array[String]])
32
+ T.unsafe(clazz).fields.each do |f|
33
+ request_metadata = f.metadata[:request]
34
+ next if !request_metadata.nil?
35
+
36
+ metadata = f.metadata[:query_param]
37
+ next if metadata.nil?
38
+
39
+ param_name = f.name
40
+ value = query_params&.send(param_name.to_sym)
41
+ value = _populate_from_globals(param_name, value, "queryParam", gbls)
42
+
43
+ f_name = metadata[:field_name]
44
+ serialization = metadata.fetch(:serialization, "")
45
+ if serialization != ""
46
+ params = params.merge(
47
+ _get_serialized_params(
48
+ metadata,
49
+ f_name,
50
+ value
51
+ )
52
+ )
53
+ else
54
+ style = metadata.fetch(:style, "form")
55
+ case style
56
+ when "deepObject"
57
+ params = params.merge(
58
+ _get_deep_object_query_params(
59
+ metadata,
60
+ f_name,
61
+ value
62
+ )
63
+ )
64
+ when "form"
65
+ params = params.merge(
66
+ _get_delimited_query_params(
67
+ metadata,
68
+ f_name,
69
+ value,
70
+ ","
71
+ )
72
+ )
73
+ when "pipeDelimited"
74
+ params = params.merge(
75
+ _get_delimited_query_params(
76
+ metadata,
77
+ f_name,
78
+ value,
79
+ "|"
80
+ )
81
+ )
82
+ else
83
+ raise StandardError, "not yet implemented"
84
+ end
85
+ end
86
+ end
87
+
88
+ params.merge(parsed_params)
89
+ end
90
+
91
+ sig do
92
+ params(metadata: T::Hash[Symbol, String], field_name: String, obj: Object)
93
+ .returns(T::Hash[T.any(String, Symbol), T::Array[String]])
94
+ end
95
+ def self._get_deep_object_query_params(metadata, field_name, obj)
96
+ params = T.let({}, T::Hash[T.any(String, Symbol), T::Array[String]])
97
+
98
+ return params if obj.nil?
99
+
100
+ if obj.respond_to?(:fields)
101
+ T.unsafe(obj).fields.each do |obj_field|
102
+ obj_param_metadata = obj_field.metadata[:query_param]
103
+ next if obj_param_metadata.nil?
104
+
105
+ val = obj.send(obj_field.name)
106
+ next if val.nil?
107
+
108
+ key = "#{metadata.fetch(:field_name, field_name)}[#{obj_param_metadata.fetch(:field_name, obj_field.name)}]"
109
+ if val.is_a?(Array)
110
+ val.each do |v|
111
+ next if v.nil?
112
+
113
+ params[key] = [] if !params.include?(key)
114
+
115
+ T.must(params[key]) << val_to_string(v)
116
+ end
117
+ else
118
+ params[key] = [val_to_string(val)]
119
+ end
120
+ end
121
+ elsif obj.is_a?(Hash)
122
+ obj.each do |key, value|
123
+ next if value.nil?
124
+
125
+ param_key = "#{metadata.fetch(:field_name, field_name)}[#{key}]"
126
+ if value.is_a?(Array)
127
+ value.each do |val|
128
+ next if val.nil?
129
+
130
+ params[param_key] = [] if !params.include?(param_key)
131
+
132
+ T.must(params[param_key]).append(val_to_string(val))
133
+ end
134
+ else
135
+ params[param_key] = [val_to_string(value)]
136
+ end
137
+ end
138
+ end
139
+
140
+ params
141
+ end
142
+
143
+ sig do
144
+ params(metadata: T::Hash[Symbol, String], field_name: String, obj: Object, delimiter: String)
145
+ .returns(T::Hash[T.any(String, Symbol), T::Array[String]])
146
+ end
147
+ def self._get_delimited_query_params(metadata, field_name, obj, delimiter)
148
+ get_query_param_field_name = lambda do |obj_field|
149
+ obj_param_metadata = obj_field.metadata[:query_param]
150
+
151
+ return {} if obj_param_metadata.nil?
152
+
153
+ return obj_param_metadata.fetch(:field_name, obj_field.name)
154
+ end
155
+
156
+ _populate_form(
157
+ field_name,
158
+ T.cast(metadata.fetch(:explode, true), T::Boolean),
159
+ obj,
160
+ delimiter,
161
+ &get_query_param_field_name
162
+ )
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,77 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "cgi"
5
+ require "date"
6
+ require "base64"
7
+ require "sorbet-runtime"
8
+
9
+ module NoResponse
10
+ module Utils
11
+ extend T::Sig
12
+
13
+ SERIALIZATION_METHOD_TO_CONTENT_TYPE = {
14
+ 'json': "application/json",
15
+ 'form': "application/x-www-form-urlencoded",
16
+ 'multipart': "multipart/form-data",
17
+ 'raw': "application/octet-stream",
18
+ 'string': "text/plain"
19
+ }.freeze
20
+
21
+ sig do
22
+ params(
23
+ request: Object,
24
+ nullable: T::Boolean,
25
+ optional: T::Boolean,
26
+ request_field_name: Symbol,
27
+ serialization_method: Symbol
28
+ )
29
+ .returns([String, Object, T.nilable(T::Array[T::Array[T.any(T::Array[T.nilable(String)], String)]])])
30
+ end
31
+ def self.serialize_request_body(request, nullable, optional, request_field_name, serialization_method)
32
+ return ["", nil, nil] if request.nil? && !nullable && optional
33
+
34
+ if !request.respond_to?(:fields) || !request.respond_to?(request_field_name)
35
+ return serialize_content_type(SERIALIZATION_METHOD_TO_CONTENT_TYPE[serialization_method], request)
36
+ end
37
+
38
+ request_metadata = T.let(nil, T.nilable(T::Array[T::Array[T.any(T::Array[T.nilable(String)], String)]]))
39
+ T.unsafe(request).fields.each do |f|
40
+ if f.name == request_field_name
41
+ request_metadata = f.metadata[:request]
42
+ break
43
+ end
44
+ end
45
+
46
+ if request_metadata.nil?
47
+ # Field name collision: model has a field matching request_field_name but without :request metadata.
48
+ # Serialize the entire object as the request body.
49
+ return serialize_content_type(SERIALIZATION_METHOD_TO_CONTENT_TYPE[serialization_method], request)
50
+ end
51
+
52
+ request_val = request.send(request_field_name)
53
+ return ["", nil, nil] if request_val.nil?
54
+
55
+ serialize_content_type(
56
+ request_metadata.fetch(:media_type, "application/octet-stream"),
57
+ request_val
58
+ )
59
+ end
60
+
61
+ sig do
62
+ params(media_type: String, request: Object)
63
+ .returns([String, Object, T.nilable(T::Array[T::Array[T.any(T::Array[T.nilable(String)], String)]])])
64
+ end
65
+ def self.serialize_content_type(media_type, request)
66
+ if media_type.match("^(application|text)\\/([^+]+\\+)*json.*")
67
+ return media_type, ::Crystalline.to_json(request), nil
68
+ end
69
+
70
+ return serialize_multipart_form(media_type, request) if media_type.match("^multipart\\/.*")
71
+ return media_type, serialize_form_data(request), nil if media_type.match("^application\\/x-www-form-urlencoded.*")
72
+ return media_type, request, nil if request.is_a?(String) || request.is_a?(Array)
73
+
74
+ raise StandardError, "invalid request body type #{request.class} for mediaType #{media_type}"
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,137 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "faraday/retry"
5
+ require "time"
6
+ require "sorbet-runtime"
7
+
8
+ module NoResponse
9
+ module Utils
10
+ class BackoffStrategy
11
+ extend T::Sig
12
+
13
+ sig { returns(T.nilable(::Float)) }
14
+ attr_accessor :exponent
15
+
16
+ sig { returns(T.nilable(::Integer)) }
17
+ attr_accessor :initial_interval
18
+
19
+ sig { returns(T.nilable(::Integer)) }
20
+ attr_accessor :max_elapsed_time
21
+
22
+ sig { returns(T.nilable(::Integer)) }
23
+ attr_accessor :max_interval
24
+
25
+ sig do
26
+ params(
27
+ exponent: T.nilable(::Float),
28
+ initial_interval: T.nilable(::Integer),
29
+ max_elapsed_time: T.nilable(::Integer),
30
+ max_interval: T.nilable(::Integer)
31
+ )
32
+ .void
33
+ end
34
+ def initialize(exponent: nil, initial_interval: nil, max_elapsed_time: nil, max_interval: nil)
35
+ @exponent = T.let(exponent, T.nilable(::Float))
36
+ @initial_interval = T.let(initial_interval, T.nilable(::Integer))
37
+ @max_elapsed_time = T.let(max_elapsed_time, T.nilable(::Integer))
38
+ @max_interval = T.let(max_interval, T.nilable(::Integer))
39
+ end
40
+ end
41
+
42
+ class RetryConfig
43
+ extend T::Sig
44
+
45
+ sig { returns(T.nilable(BackoffStrategy)) }
46
+ attr_accessor :backoff
47
+
48
+ sig { returns(T.nilable(T::Boolean)) }
49
+ attr_accessor :retry_connection_errors
50
+
51
+ sig { returns(T.nilable(::String)) }
52
+ attr_accessor :strategy
53
+
54
+ sig do
55
+ params(
56
+ backoff: T.nilable(BackoffStrategy),
57
+ retry_connection_errors: T.nilable(T::Boolean),
58
+ strategy: T.nilable(::String)
59
+ )
60
+ .void
61
+ end
62
+ def initialize(backoff: nil, retry_connection_errors: nil, strategy: nil)
63
+ @backoff = T.let(backoff, T.nilable(BackoffStrategy))
64
+ @retry_connection_errors = T.let(retry_connection_errors, T.nilable(T::Boolean))
65
+ @strategy = T.let(strategy, T.nilable(::String))
66
+ end
67
+
68
+ sig { params(initial_time: ::Time).returns(::Hash) }
69
+ def to_faraday_retry_options(initial_time:)
70
+ retry_options = {
71
+ # must overwrite default max of 2 retries and it must be positive
72
+ max: 1_000_000_000,
73
+ # ensure all HTTP methods are retried, especially via retry_if
74
+ methods: []
75
+ }
76
+
77
+ if @retry_connection_errors
78
+ retry_options[:exceptions] = Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS + [Faraday::ConnectionFailed]
79
+ end
80
+
81
+ if @strategy == "backoff" && @backoff
82
+ retry_options[:backoff_factor] = @backoff.exponent unless @backoff.exponent.nil?
83
+ retry_options[:interval] = (@backoff.initial_interval.to_f / 1000) unless @backoff.initial_interval.nil?
84
+ retry_options[:max_interval] = (@backoff.max_interval.to_f / 1000) unless @backoff.max_interval.nil?
85
+
86
+ unless @backoff.max_elapsed_time.nil?
87
+ stop_time = initial_time + (@backoff.max_elapsed_time.to_f / 1000)
88
+ retry_options[:retry_if] = -> (_env, _exc) { Time.now < stop_time }
89
+ end
90
+
91
+ end
92
+
93
+ retry_options
94
+ end
95
+ end
96
+
97
+ class RetryMiddleware < Faraday::Retry::Middleware
98
+ extend T::Sig
99
+
100
+ sig { params(retries: T.untyped, env: T.untyped).returns(T.untyped) }
101
+ def calculate_sleep_amount(retries, env)
102
+ retry_after = [calculate_retry_after(env), calculate_rate_limit_reset(env)].compact.max
103
+ retry_interval = calculate_retry_interval(retries)
104
+ return retry_interval if retry_after.nil?
105
+
106
+ # unlike the stock middleware, cap server delays at max_interval rather
107
+ # than abandoning the retry
108
+ [[retry_after, @options.max_interval].min, retry_interval].max
109
+ end
110
+
111
+ private
112
+
113
+ sig { params(env: T.untyped).returns(T.untyped) }
114
+ def calculate_retry_after(env)
115
+ response_headers = env[:response_headers]
116
+ return unless response_headers
117
+
118
+ ms_value = response_headers["retry-after-ms"]
119
+ return ms_value.to_f / 1000 if ms_value&.match?(/\A\s*\d+\s*\z/)
120
+
121
+ value = response_headers["retry-after"]
122
+ return if value.nil? || value.strip.empty?
123
+ return value.to_f if value.match?(/\A\s*\d+\s*\z/)
124
+
125
+ begin
126
+ Time.httpdate(value) - Time.now
127
+ rescue ArgumentError
128
+ begin
129
+ Time.iso8601(value) - Time.now
130
+ rescue ArgumentError
131
+ nil
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end