fastpixapi 1.1.1 → 1.1.3

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 (122) hide show
  1. checksums.yaml +4 -4
  2. data/lib/crystalline/metadata_fields.rb +56 -48
  3. data/lib/crystalline/types.rb +3 -3
  4. data/lib/crystalline.rb +4 -5
  5. data/lib/fastpix_client/dimensions.rb +55 -62
  6. data/lib/fastpix_client/drm_configurations.rb +51 -58
  7. data/lib/fastpix_client/errors.rb +36 -25
  8. data/lib/fastpix_client/fastpixapi.rb +2 -4
  9. data/lib/fastpix_client/in_video_ai_features.rb +108 -168
  10. data/lib/fastpix_client/input_video.rb +75 -83
  11. data/lib/fastpix_client/live_playback.rb +82 -99
  12. data/lib/fastpix_client/manage_live_stream.rb +145 -261
  13. data/lib/fastpix_client/manage_videos.rb +252 -567
  14. data/lib/fastpix_client/metrics.rb +82 -126
  15. data/lib/fastpix_client/models/components/addtrackrequest.rb +1 -1
  16. data/lib/fastpix_client/models/components/createlivestreamresponsedto.rb +10 -18
  17. data/lib/fastpix_client/models/components/createmediarequest.rb +10 -19
  18. data/lib/fastpix_client/models/components/deletesigningkeyresponse.rb +6 -2
  19. data/lib/fastpix_client/models/components/deletesigningkeyresponsedata.rb +33 -0
  20. data/lib/fastpix_client/models/components/getallmediaresponse.rb +13 -29
  21. data/lib/fastpix_client/models/components/getcreatelivestreamresponsedto.rb +9 -20
  22. data/lib/fastpix_client/models/components/getmediaresponse.rb +13 -29
  23. data/lib/fastpix_client/models/components/live_media_clips.rb +9 -21
  24. data/lib/fastpix_client/models/components/media.rb +11 -26
  25. data/lib/fastpix_client/models/components/patchresponsedata.rb +9 -18
  26. data/lib/fastpix_client/models/components/pullvideoinput.rb +1 -1
  27. data/lib/fastpix_client/models/components/sourceaccessmedia.rb +11 -26
  28. data/lib/fastpix_client/models/components/update_media.rb +11 -26
  29. data/lib/fastpix_client/models/components/views.rb +52 -125
  30. data/lib/fastpix_client/models/components/watermarkinput.rb +1 -1
  31. data/lib/fastpix_client/models/components.rb +1 -0
  32. data/lib/fastpix_client/models/errors/empty_response_error.rb +15 -0
  33. data/lib/fastpix_client/models/errors.rb +1 -0
  34. data/lib/fastpix_client/models/operations/add_media_to_playlist_response.rb +1 -1
  35. data/lib/fastpix_client/models/operations/add_media_track_response.rb +1 -1
  36. data/lib/fastpix_client/models/operations/cancel_upload_response.rb +1 -1
  37. data/lib/fastpix_client/models/operations/change_media_order_in_playlist_response.rb +1 -1
  38. data/lib/fastpix_client/models/operations/complete_live_stream_response.rb +1 -1
  39. data/lib/fastpix_client/models/operations/create_a_playlist_response.rb +1 -1
  40. data/lib/fastpix_client/models/operations/create_media_playback_id_response.rb +1 -1
  41. data/lib/fastpix_client/models/operations/create_media_response.rb +1 -1
  42. data/lib/fastpix_client/models/operations/create_new_stream_response.rb +1 -1
  43. data/lib/fastpix_client/models/operations/create_playbackid_of_stream_response.rb +1 -1
  44. data/lib/fastpix_client/models/operations/create_signing_key_response.rb +1 -1
  45. data/lib/fastpix_client/models/operations/create_simulcast_of_stream_response.rb +1 -1
  46. data/lib/fastpix_client/models/operations/delete_a_playlist_response.rb +1 -1
  47. data/lib/fastpix_client/models/operations/delete_live_stream_response.rb +1 -1
  48. data/lib/fastpix_client/models/operations/delete_media_from_playlist_response.rb +1 -1
  49. data/lib/fastpix_client/models/operations/delete_media_playback_id_response.rb +1 -1
  50. data/lib/fastpix_client/models/operations/delete_media_response.rb +1 -1
  51. data/lib/fastpix_client/models/operations/delete_media_track_response.rb +1 -1
  52. data/lib/fastpix_client/models/operations/delete_playbackid_of_stream_response.rb +1 -1
  53. data/lib/fastpix_client/models/operations/delete_signing_key_response.rb +1 -1
  54. data/lib/fastpix_client/models/operations/delete_simulcast_of_stream_response.rb +1 -1
  55. data/lib/fastpix_client/models/operations/direct_upload_video_media_request.rb +1 -1
  56. data/lib/fastpix_client/models/operations/direct_upload_video_media_response.rb +1 -1
  57. data/lib/fastpix_client/models/operations/disable_live_stream_response.rb +1 -1
  58. data/lib/fastpix_client/models/operations/enable_live_stream_response.rb +1 -1
  59. data/lib/fastpix_client/models/operations/generate_subtitle_track_response.rb +1 -1
  60. data/lib/fastpix_client/models/operations/get_all_playlists_response.rb +1 -1
  61. data/lib/fastpix_client/models/operations/get_all_streams_response.rb +1 -1
  62. data/lib/fastpix_client/models/operations/get_live_stream_by_id_response.rb +1 -1
  63. data/lib/fastpix_client/models/operations/get_live_stream_playback_id_response.rb +1 -1
  64. data/lib/fastpix_client/models/operations/get_live_stream_viewer_count_by_id_response.rb +1 -1
  65. data/lib/fastpix_client/models/operations/get_media_clips_response.rb +1 -1
  66. data/lib/fastpix_client/models/operations/get_media_response.rb +1 -1
  67. data/lib/fastpix_client/models/operations/get_media_summary_response.rb +1 -1
  68. data/lib/fastpix_client/models/operations/get_playback_id_response.rb +1 -1
  69. data/lib/fastpix_client/models/operations/get_playlist_by_id_response.rb +1 -1
  70. data/lib/fastpix_client/models/operations/get_signing_key_by_id_response.rb +1 -1
  71. data/lib/fastpix_client/models/operations/get_specific_simulcast_of_stream_response.rb +1 -1
  72. data/lib/fastpix_client/models/operations/get_timeseries_data_response.rb +1 -1
  73. data/lib/fastpix_client/models/operations/get_video_view_details_response.rb +1 -1
  74. data/lib/fastpix_client/models/operations/getdrmconfiguration_response.rb +1 -1
  75. data/lib/fastpix_client/models/operations/getdrmconfigurationbyid_response.rb +1 -1
  76. data/lib/fastpix_client/models/operations/list_breakdown_values_response.rb +1 -1
  77. data/lib/fastpix_client/models/operations/list_by_top_content_response.rb +1 -1
  78. data/lib/fastpix_client/models/operations/list_comparison_values_response.rb +1 -1
  79. data/lib/fastpix_client/models/operations/list_dimensions_response.rb +1 -1
  80. data/lib/fastpix_client/models/operations/list_errors_response.rb +1 -1
  81. data/lib/fastpix_client/models/operations/list_filter_values_for_dimension_response.rb +1 -1
  82. data/lib/fastpix_client/models/operations/list_live_clips_response.rb +1 -1
  83. data/lib/fastpix_client/models/operations/list_media_response.rb +1 -1
  84. data/lib/fastpix_client/models/operations/list_overall_values_response.rb +1 -1
  85. data/lib/fastpix_client/models/operations/list_playback_ids_response.rb +1 -1
  86. data/lib/fastpix_client/models/operations/list_signing_keys_response.rb +1 -1
  87. data/lib/fastpix_client/models/operations/list_uploads_response.rb +1 -1
  88. data/lib/fastpix_client/models/operations/list_video_views_response.rb +1 -1
  89. data/lib/fastpix_client/models/operations/push_media_settings.rb +10 -21
  90. data/lib/fastpix_client/models/operations/retrievemediainputinfo_response.rb +1 -1
  91. data/lib/fastpix_client/models/operations/update_a_playlist_response.rb +1 -1
  92. data/lib/fastpix_client/models/operations/update_domain_restrictions_response.rb +1 -1
  93. data/lib/fastpix_client/models/operations/update_live_stream_response.rb +1 -1
  94. data/lib/fastpix_client/models/operations/update_media_chapters_response.rb +1 -1
  95. data/lib/fastpix_client/models/operations/update_media_moderation_response.rb +1 -1
  96. data/lib/fastpix_client/models/operations/update_media_named_entities_response.rb +1 -1
  97. data/lib/fastpix_client/models/operations/update_media_summary_response.rb +1 -1
  98. data/lib/fastpix_client/models/operations/update_media_track_response.rb +1 -1
  99. data/lib/fastpix_client/models/operations/update_specific_simulcast_of_stream_response.rb +1 -1
  100. data/lib/fastpix_client/models/operations/update_user_agent_restrictions_response.rb +1 -1
  101. data/lib/fastpix_client/models/operations/updated_media_response.rb +1 -1
  102. data/lib/fastpix_client/models/operations/updated_mp4support_response.rb +1 -1
  103. data/lib/fastpix_client/models/operations/updated_source_access_response.rb +1 -1
  104. data/lib/fastpix_client/playback.rb +123 -214
  105. data/lib/fastpix_client/playlist.rb +151 -297
  106. data/lib/fastpix_client/sdk_hooks/registration.rb +2 -2
  107. data/lib/fastpix_client/sdk_hooks/types.rb +4 -0
  108. data/lib/fastpix_client/sdkconfiguration.rb +4 -4
  109. data/lib/fastpix_client/signing_keys.rb +79 -123
  110. data/lib/fastpix_client/simulcast_stream.rb +101 -145
  111. data/lib/fastpix_client/start_live_stream.rb +54 -36
  112. data/lib/fastpix_client/utils/forms.rb +97 -101
  113. data/lib/fastpix_client/utils/headers.rb +44 -34
  114. data/lib/fastpix_client/utils/query_params.rb +39 -29
  115. data/lib/fastpix_client/utils/request_bodies.rb +4 -8
  116. data/lib/fastpix_client/utils/security.rb +30 -18
  117. data/lib/fastpix_client/utils/url.rb +83 -55
  118. data/lib/fastpix_client/utils/utils.rb +19 -37
  119. data/lib/fastpix_client/views.rb +71 -95
  120. data/lib/fastpixapi.rb +10 -10
  121. data/lib/openssl_patch.rb +24 -24
  122. metadata +20 -4
@@ -23,54 +23,66 @@ module FastpixClient
23
23
  return params if obj.nil?
24
24
 
25
25
  if obj.respond_to? :fields
26
- items = []
27
- T.unsafe(obj).fields.each do |obj_field|
28
- obj_field_name = get_field_name_lambda.call(obj_field)
29
- next if obj_field_name == ''
26
+ _populate_form_from_object(params, field_name, explode, obj, delimiter, &get_field_name_lambda)
27
+ elsif obj.is_a? Hash
28
+ _populate_form_from_hash(params, field_name, explode, obj, delimiter)
29
+ elsif obj.is_a? Array
30
+ _populate_form_from_array(params, field_name, explode, obj, delimiter)
31
+ else
32
+ params[field_name] = val_to_string(obj)
33
+ end
34
+ params
35
+ end
30
36
 
31
- val = obj.send(obj_field.name.to_sym)
32
- next if val.nil?
37
+ # Populates form params from a MetadataFields object (mutates `params`).
38
+ def self._populate_form_from_object(params, field_name, explode, obj, delimiter, &get_field_name_lambda)
39
+ items = []
40
+ T.unsafe(obj).fields.each do |obj_field|
41
+ obj_field_name = get_field_name_lambda.call(obj_field)
42
+ next if obj_field_name == ''
33
43
 
34
- if explode
35
- params[obj_field_name] = [val_to_string(val)]
36
- else
37
- items.append("#{obj_field_name}#{delimiter}#{val_to_string(val)}")
38
- end
44
+ val = obj.send(obj_field.name.to_sym)
45
+ next if val.nil?
46
+
47
+ if explode
48
+ params[obj_field_name] = [val_to_string(val)]
49
+ else
50
+ items.append("#{obj_field_name}#{delimiter}#{val_to_string(val)}")
39
51
  end
52
+ end
53
+ params[field_name] = [items.join(delimiter)] unless items.empty?
54
+ end
40
55
 
41
- params[field_name] = [items.join(delimiter)] if !items.empty?
42
- elsif obj.is_a? Hash
43
- items = []
44
- obj.each do |key, value|
45
- next if value.nil?
56
+ # Populates form params from a Hash (mutates `params`).
57
+ def self._populate_form_from_hash(params, field_name, explode, obj, delimiter)
58
+ items = []
59
+ obj.each do |key, value|
60
+ next if value.nil?
46
61
 
47
- if explode
48
- params[key] = val_to_string(value)
49
- else
50
- items.append("#{key}#{delimiter}#{val_to_string(value)}")
51
- end
62
+ if explode
63
+ params[key] = val_to_string(value)
64
+ else
65
+ items.append("#{key}#{delimiter}#{val_to_string(value)}")
52
66
  end
53
- params[field_name] = [items.join(delimiter)] if !items.empty?
67
+ end
68
+ params[field_name] = [items.join(delimiter)] unless items.empty?
69
+ end
54
70
 
55
- elsif obj.is_a? Array
56
- items = []
57
- obj.each do |value|
58
- next if value.nil?
71
+ # Populates form params from an Array (mutates `params`).
72
+ def self._populate_form_from_array(params, field_name, explode, obj, delimiter)
73
+ items = []
74
+ obj.each do |value|
75
+ next if value.nil?
59
76
 
60
- if explode
61
- params[field_name] = [] if !params.key? field_name
77
+ if explode
78
+ params[field_name] = [] unless params.key? field_name
62
79
 
63
- params[field_name].append(val_to_string(value))
64
- else
65
- items.append(val_to_string(value))
66
- end
80
+ params[field_name].append(val_to_string(value))
81
+ else
82
+ items.append(val_to_string(value))
67
83
  end
68
- params[field_name] = items.map(&:to_s).join(delimiter) if !items.empty?
69
-
70
- else
71
- params[field_name] = val_to_string(obj)
72
84
  end
73
- params
85
+ params[field_name] = items.map(&:to_s).join(delimiter) unless items.empty?
74
86
  end
75
87
 
76
88
  sig { params(media_type: String, request: Object).returns([String, Object, T::Array[T::Array[T.any(T::Array[T.nilable(String)], String)]]]) }
@@ -83,73 +95,57 @@ module FastpixClient
83
95
  field_metadata = field.metadata[:multipart_form]
84
96
  next if field_metadata.nil?
85
97
 
86
- if field_metadata[:file] == true
87
- field_name = field_metadata[:field_name]
88
-
89
- # Handle arrays of files
90
- if val.is_a? Array
91
- val.each do |file_obj|
92
- file_name = T.let('', String)
93
- content = nil
94
-
95
- T.must(file_obj).fields.each do |file_field|
96
- file_metadata = file_field.metadata[:multipart_form]
97
- next if file_metadata.nil?
98
-
99
- if file_metadata[:content] == true
100
- content = T.let(file_obj.send(file_field.name), String)
101
- else
102
- file_name = T.let(file_obj.send(file_field.name), String)
103
- end
104
- end
105
- raise StandardError, 'invalid multipart/form-data file' if T.unsafe(file_name) == '' || T.unsafe(content).nil?
106
-
107
- form.append([field_name, [file_name, content]])
108
- end
109
- else
110
- # Handle single file
111
- file_name = T.let('', String)
112
- content = nil
113
-
114
- T.must(val).fields.each do |file_field|
115
- file_metadata = file_field.metadata[:multipart_form]
116
- next if file_metadata.nil?
117
-
118
- if file_metadata[:content] == true
119
- content = T.let(val.send(file_field.name), String)
120
- else
121
- file_name = T.let(val.send(file_field.name), String)
122
- end
123
- end
124
- raise StandardError, 'invalid multipart/form-data file' if T.unsafe(file_name) == '' || T.unsafe(content).nil?
98
+ _append_multipart_field(form, field, field_metadata, val)
99
+ end
100
+ [media_type, nil, form]
101
+ end
125
102
 
126
- form.append([field_name, [file_name, content]])
127
- end
128
- elsif field_metadata[:json] == true
129
- to_append = [
130
- field_metadata.fetch(:field_name, field.name), [
131
- nil, ::Crystalline.to_json(val), 'application/json'
132
- ]
133
- ]
134
- form.append(to_append)
103
+ # Extracts [file_name, content] from a multipart file object, raising if invalid.
104
+ def self._extract_multipart_file(file_obj)
105
+ file_name = T.let('', String)
106
+ content = nil
107
+
108
+ T.must(file_obj).fields.each do |file_field|
109
+ file_metadata = file_field.metadata[:multipart_form]
110
+ next if file_metadata.nil?
111
+
112
+ if file_metadata[:content] == true
113
+ content = T.let(file_obj.send(file_field.name), String)
135
114
  else
136
- field_name = field_metadata.fetch(
137
- :field_name, field.name
138
- )
139
- if val.is_a? Array
140
- val.each do |value|
141
- next if value.nil?
142
-
143
- form.append(
144
- [field_name, [nil, val_to_string(value)]]
145
- )
146
- end
147
- else
148
- form.append([field_name, [nil, val_to_string(val)]])
115
+ file_name = T.let(file_obj.send(file_field.name), String)
116
+ end
117
+ end
118
+ raise ArgumentError, 'invalid multipart/form-data file' if T.unsafe(file_name) == '' || T.unsafe(content).nil?
119
+
120
+ [file_name, content]
121
+ end
122
+
123
+ # Appends a single request field to the multipart form (mutates `form`).
124
+ def self._append_multipart_field(form, field, field_metadata, val)
125
+ if field_metadata[:file] == true
126
+ field_name = field_metadata[:field_name]
127
+ # Handle arrays of files and single files alike
128
+ if val.is_a? Array
129
+ val.each { |file_obj| form.append([field_name, _extract_multipart_file(file_obj)]) }
130
+ else
131
+ form.append([field_name, _extract_multipart_file(val)])
132
+ end
133
+ elsif field_metadata[:json] == true
134
+ form.append(
135
+ [field_metadata.fetch(:field_name, field.name), [nil, ::Crystalline.to_json(val), 'application/json']]
136
+ )
137
+ else
138
+ field_name = field_metadata.fetch(:field_name, field.name)
139
+ if val.is_a? Array
140
+ val.each do |value|
141
+ next if value.nil?
142
+
143
+ form.append([field_name, [nil, val_to_string(value)]])
149
144
  end
145
+ else
146
+ form.append([field_name, [nil, val_to_string(val)]])
150
147
  end
151
148
  end
152
- [media_type, nil, form]
153
149
  end
154
150
 
155
151
 
@@ -188,7 +184,7 @@ module FastpixClient
188
184
  )
189
185
  )
190
186
  else
191
- raise StandardError, "Invalid form style for field #{field.name}"
187
+ raise ArgumentError, "Invalid form style for field #{field.name}"
192
188
  end
193
189
  end
194
190
  end
@@ -197,7 +193,7 @@ module FastpixClient
197
193
  form[key] = [val_to_string(value)]
198
194
  end
199
195
  else
200
- raise StandardError, "Invalid request body type #{data.class}"
196
+ raise ArgumentError, "Invalid request body type #{data.class}"
201
197
  end
202
198
 
203
199
  form
@@ -33,45 +33,55 @@ module FastpixClient
33
33
  return '' if obj.nil?
34
34
 
35
35
  if obj.respond_to? :fields
36
- items = []
37
- T.unsafe(obj).fields.each do |obj_field|
38
- obj_param_metadata = obj_field.metadata[:header]
39
- next if obj_param_metadata.nil?
40
-
41
- obj_field_name = obj_param_metadata.fetch(:field_name, obj_field.name)
42
- next if obj_field_name == ''
43
-
44
- val = obj.send(obj_field.name)
45
- next if val.nil?
46
-
47
- if explode
48
- items.append("#{obj_field_name}=#{val_to_string(val)}")
49
- else
50
- items.append(obj_field_name)
51
- items.append(val_to_string(val))
52
- end
53
- end
54
-
55
- items.join(',') if !items.empty?
36
+ _serialize_header_from_object(explode, obj)
56
37
  elsif obj.is_a? Hash
57
- items = []
58
- obj.each do |key, value|
59
- next if value.nil?
60
-
61
- if explode
62
- items.append("#{key}=#{val_to_string(value)}")
63
- else
64
- items.append(key)
65
- items.append(val_to_string(value))
66
- end
67
- end
68
-
69
- items.join(',') if !items.empty?
38
+ _serialize_header_from_hash(explode, obj)
70
39
  elsif obj.is_a? Array
71
- items = obj.filter { |v| !v.nil? }.map { |v| val_to_string(v) }.join(',')
40
+ obj.filter { |v| !v.nil? }.map { |v| val_to_string(v) }.join(',')
72
41
  else
73
42
  val_to_string(obj)
74
43
  end
75
44
  end
45
+
46
+ # Serializes a MetadataFields object into a header string (nil when empty).
47
+ def self._serialize_header_from_object(explode, obj)
48
+ items = []
49
+ T.unsafe(obj).fields.each do |obj_field|
50
+ obj_param_metadata = obj_field.metadata[:header]
51
+ next if obj_param_metadata.nil?
52
+
53
+ obj_field_name = obj_param_metadata.fetch(:field_name, obj_field.name)
54
+ next if obj_field_name == ''
55
+
56
+ val = obj.send(obj_field.name)
57
+ next if val.nil?
58
+
59
+ if explode
60
+ items.append("#{obj_field_name}=#{val_to_string(val)}")
61
+ else
62
+ items.append(obj_field_name)
63
+ items.append(val_to_string(val))
64
+ end
65
+ end
66
+
67
+ items.join(',') unless items.empty?
68
+ end
69
+
70
+ # Serializes a Hash into a header string (nil when empty).
71
+ def self._serialize_header_from_hash(explode, obj)
72
+ items = []
73
+ obj.each do |key, value|
74
+ next if value.nil?
75
+
76
+ if explode
77
+ items.append("#{key}=#{val_to_string(value)}")
78
+ else
79
+ items.append(key)
80
+ items.append(val_to_string(value))
81
+ end
82
+ end
83
+
84
+ items.join(',') unless items.empty?
85
+ end
76
86
  end
77
87
  end
@@ -14,7 +14,7 @@ module FastpixClient
14
14
  sig { params(clazz: Object, query_params: Object, url_override: T.nilable(::String), gbls: T.nilable(T::Hash[Symbol, T::Hash[Symbol, T::Hash[Symbol, Object]]])).returns(T::Hash[T.any(String, Symbol), T::Array[String]]) }
15
15
  def self.get_query_params(clazz, query_params, url_override = nil, gbls = nil)
16
16
  parsed_params = T.let({}, T::Hash[T.any(String, Symbol), T::Array[String]])
17
- if !url_override.nil?
17
+ unless url_override.nil?
18
18
  parsed_url = URI.parse url_override
19
19
  URI.decode_www_form(parsed_url.query.to_s).each do |key, value|
20
20
  parsed_params[key] ||= []
@@ -55,7 +55,7 @@ module FastpixClient
55
55
  metadata, f_name, value, '|'
56
56
  )
57
57
  else
58
- raise StandardError, 'not yet implemented'
58
+ raise ArgumentError, 'not yet implemented'
59
59
  end
60
60
  end
61
61
  end
@@ -72,45 +72,55 @@ module FastpixClient
72
72
  return params if obj.nil?
73
73
 
74
74
  if obj.respond_to? :fields
75
- T.unsafe(obj).fields.each do |obj_field|
76
- obj_param_metadata = obj_field.metadata[:query_param]
77
- next if obj_param_metadata.nil?
75
+ _deep_object_from_object(params, metadata, field_name, obj)
76
+ elsif obj.is_a? Hash
77
+ _deep_object_from_hash(params, metadata, field_name, obj)
78
+ end
79
+ params
80
+ end
78
81
 
79
- val = obj.send(obj_field.name)
80
- next if val.nil?
82
+ # Adds deepObject query params from a MetadataFields object (mutates `params`).
83
+ def self._deep_object_from_object(params, metadata, field_name, obj)
84
+ T.unsafe(obj).fields.each do |obj_field|
85
+ obj_param_metadata = obj_field.metadata[:query_param]
86
+ next if obj_param_metadata.nil?
81
87
 
82
- key = "#{metadata.fetch(:field_name, field_name)}[#{obj_param_metadata.fetch(:field_name, obj_field.name)}]"
83
- if val.is_a? Array
84
- val.each do |v|
85
- next if v.nil?
88
+ val = obj.send(obj_field.name)
89
+ next if val.nil?
86
90
 
87
- params[key] = [] if !params.include? key
91
+ key = "#{metadata.fetch(:field_name, field_name)}[#{obj_param_metadata.fetch(:field_name, obj_field.name)}]"
92
+ if val.is_a? Array
93
+ val.each do |v|
94
+ next if v.nil?
88
95
 
89
- T.must(params[key]) << val_to_string(v)
90
- end
91
- else
92
- params[key] = [val_to_string(val)]
96
+ params[key] = [] unless params.include? key
97
+
98
+ T.must(params[key]) << val_to_string(v)
93
99
  end
100
+ else
101
+ params[key] = [val_to_string(val)]
94
102
  end
95
- elsif obj.is_a? Hash
96
- obj.each do |key, value|
97
- next if value.nil?
103
+ end
104
+ end
98
105
 
99
- param_key = "#{metadata.fetch(:field_name, field_name)}[#{key}]"
100
- if value.is_a? Array
101
- value.each do |val|
102
- next if val.nil?
106
+ # Adds deepObject query params from a Hash (mutates `params`).
107
+ def self._deep_object_from_hash(params, metadata, field_name, obj)
108
+ obj.each do |key, value|
109
+ next if value.nil?
103
110
 
104
- params[param_key] = [] if !params.include? param_key
111
+ param_key = "#{metadata.fetch(:field_name, field_name)}[#{key}]"
112
+ if value.is_a? Array
113
+ value.each do |val|
114
+ next if val.nil?
105
115
 
106
- T.must(params[param_key]).append(val_to_string(val))
107
- end
108
- else
109
- params[param_key] = [val_to_string(value)]
116
+ params[param_key] = [] unless params.include? param_key
117
+
118
+ T.must(params[param_key]).append(val_to_string(val))
110
119
  end
120
+ else
121
+ params[param_key] = [val_to_string(value)]
111
122
  end
112
123
  end
113
- params
114
124
  end
115
125
 
116
126
 
@@ -32,13 +32,9 @@ module FastpixClient
32
32
  request_val = request.send(request_field_name)
33
33
 
34
34
  request_metadata = T.let(nil, T.nilable(T::Array[T::Array[T.any(T::Array[T.nilable(String)], String)]]))
35
- T.unsafe(request).fields.each do |f|
36
- if f.name == request_field_name
37
- request_metadata = f.metadata[:request]
38
- break
39
- end
40
- end
41
- raise StandardError, 'invalid request type' if request_metadata.nil?
35
+ matched_field = T.unsafe(request).fields.find { |f| f.name == request_field_name }
36
+ request_metadata = matched_field.metadata[:request] unless matched_field.nil?
37
+ raise ArgumentError, 'invalid request type' if request_metadata.nil?
42
38
 
43
39
  serialize_content_type(
44
40
  request_metadata.fetch(:media_type, 'application/octet-stream'), request_val
@@ -55,7 +51,7 @@ module FastpixClient
55
51
  return media_type, serialize_form_data(request), nil if media_type.match('^application\/x-www-form-urlencoded.*')
56
52
  return media_type, request, nil if request.is_a?(String) || request.is_a?(Array)
57
53
 
58
- raise StandardError, "invalid request body type #{request.class} for mediaType #{media_type}"
54
+ raise ArgumentError, "invalid request body type #{request.class} for mediaType #{media_type}"
59
55
  end
60
56
  end
61
57
  end
@@ -12,6 +12,9 @@ module FastpixClient
12
12
  module Utils
13
13
  extend T::Sig
14
14
 
15
+ SECURITY_NOT_SUPPORTED = 'not supported'
16
+ BEARER_PREFIX = 'bearer '
17
+
15
18
  sig { params(req: Faraday::Request, security: Object).void }
16
19
  def self.configure_request_security(req, security)
17
20
  return if security.nil?
@@ -75,33 +78,42 @@ module FastpixClient
75
78
  def self._parse_security_scheme_value(req, scheme_metadata, security_metadata, value)
76
79
  scheme_type = scheme_metadata[:type]
77
80
  sub_type = scheme_metadata[:sub_type]
78
-
79
81
  header_name = security_metadata[:field_name]
80
82
 
81
83
  case scheme_type
82
84
  when 'apiKey'
83
- case sub_type
84
- when 'header'
85
- req.headers[header_name] = value
86
- when 'query'
87
- req.params[header_name] = value
88
- when 'cookie'
89
- req.headers['Cookie'][header_name] = value
90
- else
91
- raise StandardError, 'not supported'
92
- end
93
- when 'openIdConnect'
94
- req.headers[header_name] = value.downcase.start_with?('bearer ') ? value : "Bearer #{value}"
95
- when 'oauth2'
96
- req.headers[header_name] = value.downcase.start_with?('bearer ') ? value : "Bearer #{value}"
85
+ _apply_api_key_scheme(req, sub_type, header_name, value)
86
+ when 'openIdConnect', 'oauth2'
87
+ req.headers[header_name] = _bearerize(value)
97
88
  when 'http'
98
89
  if sub_type == 'bearer'
99
- req.headers[header_name] = value.downcase.start_with?('bearer ') ? value : "Bearer #{value}"
90
+ req.headers[header_name] = _bearerize(value)
100
91
  elsif sub_type != 'custom'
101
- raise StandardError, 'not supported'
92
+ raise ArgumentError, SECURITY_NOT_SUPPORTED
102
93
  end
103
94
  else
104
- raise StandardError, 'not supported'
95
+ raise ArgumentError, SECURITY_NOT_SUPPORTED
96
+ end
97
+ end
98
+
99
+ # Prefixes the value with `Bearer ` unless it is already a bearer token.
100
+ sig { params(value: String).returns(String) }
101
+ def self._bearerize(value)
102
+ value.downcase.start_with?(BEARER_PREFIX) ? value : "Bearer #{value}"
103
+ end
104
+
105
+ # Applies an apiKey security scheme to the request for the given sub_type.
106
+ sig { params(req: Faraday::Request, sub_type: T.nilable(String), header_name: T.nilable(String), value: String).void }
107
+ def self._apply_api_key_scheme(req, sub_type, header_name, value)
108
+ case sub_type
109
+ when 'header'
110
+ req.headers[header_name] = value
111
+ when 'query'
112
+ req.params[header_name] = value
113
+ when 'cookie'
114
+ req.headers['Cookie'][header_name] = value
115
+ else
116
+ raise ArgumentError, SECURITY_NOT_SUPPORTED
105
117
  end
106
118
  end
107
119
 
@@ -21,65 +21,93 @@ module FastpixClient
21
21
 
22
22
  f_name = param_metadata.fetch(:field_name, f.name)
23
23
  serialization = param_metadata.fetch(:serialization, '')
24
- if serialization != ''
25
- serialized_params = _get_serialized_params(param_metadata, f_name, param)
26
- serialized_params.each do |k, v|
27
- path = path.sub("{#{k}}", v.join(', '))
28
- end
24
+ path = _substitute_path_param(path, param_metadata, f, f_name, serialization, param)
25
+ end
26
+
27
+ server_url.delete_suffix('/') + path
28
+ end
29
+
30
+ # Substitutes a single path param into the path, returning the updated path.
31
+ def self._substitute_path_param(path, param_metadata, f, f_name, serialization, param)
32
+ if serialization != ''
33
+ serialized_params = _get_serialized_params(param_metadata, f_name, param)
34
+ serialized_params.each do |k, v|
35
+ path = path.sub("{#{k}}", v.join(', '))
36
+ end
37
+ return path
38
+ end
39
+
40
+ placeholder = "{#{param_metadata.fetch(:field_name, f.name)}}"
41
+ if param.is_a? Array
42
+ path.sub(placeholder, _path_param_from_array(param))
43
+ elsif param.is_a? Hash
44
+ path.sub(placeholder, _path_param_from_hash(param_metadata, param))
45
+ elsif param.class.include?(::Crystalline::MetadataFields)
46
+ path.sub(placeholder, _path_param_from_object(param_metadata, f, param))
47
+ else
48
+ path.sub(placeholder, _path_param_scalar(param))
49
+ end
50
+ end
51
+
52
+ def self._path_param_from_array(param)
53
+ pp_vals = []
54
+ param.each do |pp_val|
55
+ pp_vals.append(pp_val.to_s)
56
+ end
57
+ pp_vals.join(',')
58
+ end
59
+
60
+ def self._path_param_from_hash(param_metadata, param)
61
+ pp_vals = []
62
+ param.each do |pp_key, pp_val|
63
+ value = val_to_string(pp_val)
64
+
65
+ if param_metadata.fetch(:explode, false)
66
+ pp_vals.append("#{pp_key}=#{value}")
29
67
  else
30
- if param.is_a? Array
31
- pp_vals = []
32
- param.each do |pp_val|
33
- pp_vals.append(pp_val.to_s)
34
- end
35
- path = path.sub("{#{param_metadata.fetch(:field_name, f.name)}}", pp_vals.join(','))
36
- elsif param.is_a? Hash
37
- pp_vals = []
38
- param.each do |pp_key, pp_val|
39
- value = val_to_string(pp_val)
40
-
41
- if param_metadata.fetch(:explode, false)
42
- pp_vals.append("#{pp_key}=#{value}")
43
- else
44
- pp_vals.append("#{pp_key},#{value}")
45
- end
46
- end
47
- path = path.sub("{#{param_metadata.fetch(:field_name, f.name)}}", pp_vals.join(','))
48
- elsif param.class.include?(::Crystalline::MetadataFields)
49
- pp_vals = []
50
- attrs = T.unsafe(param).fields.filter { |field| field.name && param.respond_to?(field.name.to_sym) }.map(&:name)
51
- attrs.each do |attr|
52
- field = T.unsafe(param).field(attr)
53
-
54
- param_value_metadata = field.metadata[:path_param]
55
-
56
- next if param_value_metadata.nil?
57
-
58
- parm_name = param_value_metadata.fetch(:field_name, f.name)
59
-
60
- param_field_val = param.send(attr)
61
-
62
- if param_field_val.class.respond_to?(:enums)
63
- param_field_val = param_field_val.serialize
64
- elsif param_field_val.is_a? DateTime
65
- param_field_val = param_field_val.strftime('%Y-%m-%dT%H:%M:%S.%NZ')
66
- end
67
- if !field.nil? && ::Crystalline::Utils.nilable?(field.type) && param_field_val.nil?
68
- next
69
- elsif param_metadata.fetch(:explode, false)
70
- pp_vals.append("#{parm_name}=#{param_field_val}")
71
- else
72
- pp_vals.append("#{parm_name},#{param_field_val}")
73
- end
74
- end
75
- path = path.sub("{#{param_metadata.fetch(:field_name, f.name)}}", pp_vals.join(','))
76
- else
77
- path = path.sub("{#{param_metadata.fetch(:field_name, f.name)}}", param.to_s)
78
- end
68
+ pp_vals.append("#{pp_key},#{value}")
79
69
  end
80
70
  end
71
+ pp_vals.join(',')
72
+ end
81
73
 
82
- server_url.delete_suffix('/') + path
74
+ def self._path_param_from_object(param_metadata, f, param)
75
+ pp_vals = []
76
+ attrs = T.unsafe(param).fields.filter { |field| field.name && param.respond_to?(field.name.to_sym) }.map(&:name)
77
+ attrs.each do |attr|
78
+ field = T.unsafe(param).field(attr)
79
+
80
+ param_value_metadata = field.metadata[:path_param]
81
+
82
+ next if param_value_metadata.nil?
83
+
84
+ parm_name = param_value_metadata.fetch(:field_name, f.name)
85
+
86
+ param_field_val = param.send(attr)
87
+
88
+ if param_field_val.class.respond_to?(:enums)
89
+ param_field_val = param_field_val.serialize
90
+ elsif param_field_val.is_a? DateTime
91
+ param_field_val = param_field_val.strftime('%Y-%m-%dT%H:%M:%S.%NZ')
92
+ end
93
+ if !field.nil? && ::Crystalline::Utils.nilable?(field.type) && param_field_val.nil?
94
+ next
95
+ elsif param_metadata.fetch(:explode, false)
96
+ pp_vals.append("#{parm_name}=#{param_field_val}")
97
+ else
98
+ pp_vals.append("#{parm_name},#{param_field_val}")
99
+ end
100
+ end
101
+ pp_vals.join(',')
102
+ end
103
+
104
+ def self._path_param_scalar(param)
105
+ if param.class.respond_to?(:enums)
106
+ param = T.cast(param, T::Enum).serialize
107
+ elsif param.is_a? DateTime
108
+ param = param.strftime('%Y-%m-%dT%H:%M:%S.%NZ')
109
+ end
110
+ param.to_s
83
111
  end
84
112
 
85
113
  sig { params(url_with_params: String, params: T::Hash[Symbol, T.any(String, T::Enum)]).returns(String) }